PageSourceSearch

https://www.veryzofcin.com/templates/veryzofcin/javascripts/js.fetch.php

js veryzofcin.com collected 2026-09-26 17:53:29 UTC 973,991 bytes, 25,402 lines download raw bytes

1
2/* ==========================================================
3 * bootstrap-affix.js v2.2.1
4 * http://twitter.github.com/bootstrap/javascript.html#affix
5 * ==========================================================
6 * Copyright 2012 Twitter, Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ========================================================== */
20
21
22!function ($) {
23
24  "use strict"; // jshint ;_;
25
26
27 /* AFFIX CLASS DEFINITION
28  * ====================== */
29
30  var Affix = function (element, options) {
31    this.options = $.extend({}, $.fn.affix.defaults, options)
32    this.$window = $(window)
33      .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
34      .on('click.affix.data-api',  $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
35    this.$element = $(element)
36    this.checkPosition()
37  }
38
39  Affix.prototype.checkPosition = function () {
40    if (!this.$element.is(':visible')) return
41
42    var scrollHeight = $(document).height()
43      , scrollTop = this.$window.scrollTop()
44      , position = this.$element.offset()
45      , offset = this.options.offset
46      , offsetBottom = offset.bottom
47      , offsetTop = offset.top
48      , reset = 'affix affix-top affix-bottom'
49      , affix
50
51    if (typeof offset != 'object') offsetBottom = offsetTop = offset
52    if (typeof offsetTop == 'function') offsetTop = offset.top()
53    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
54
55    affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
56      false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
57      'bottom' : offsetTop != null && scrollTop <= offsetTop ?
58      'top'    : false
59
60    if (this.affixed === affix) return
61
62    this.affixed = affix
63    this.unpin = affix == 'bottom' ? position.top - scrollTop : null
64
65    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
66  }
67
68
69 /* AFFIX PLUGIN DEFINITION
70  * ======================= */
71
72  $.fn.affix = function (option) {
73    return this.each(function () {
74      var $this = $(this)
75        , data = $this.data('affix')
76        , options = typeof option == 'object' && option
77      if (!data) $this.data('affix', (data = new Affix(this, options)))
78      if (typeof option == 'string') data[option]()
79    })
80  }
81
82  $.fn.affix.Constructor = Affix
83
84  $.fn.affix.defaults = {
85    offset: 0
86  }
87
88
89 /* AFFIX DATA-API
90  * ============== */
91
92  $(window).on('load', function () {
93    $('[data-spy="affix"]').each(function () {
94      var $spy = $(this)
95        , data = $spy.data()
96
97      data.offset = data.offset || {}
98
99      data.offsetBottom && (data.offset.bottom = data.offsetBottom)
100      data.offsetTop && (data.offset.top = data.offsetTop)
101
102      $spy.affix(data)
103    })
104  })
105
106
107}(window.jQuery);
108/* ==========================================================
109 * bootstrap-alert.js v2.2.1
110 * http://twitter.github.com/bootstrap/javascript.html#alerts
111 * ==========================================================
112 * Copyright 2012 Twitter, Inc.
113 *
114 * Licensed under the Apache License, Version 2.0 (the "License");
115 * you may not use this file except in compliance with the License.
116 * You may obtain a copy of the License at
117 *
118 * http://www.apache.org/licenses/LICENSE-2.0
119 *
120 * Unless required by applicable law or agreed to in writing, software
121 * distributed under the License is distributed on an "AS IS" BASIS,
122 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123 * See the License for the specific language governing permissions and
124 * limitations under the License.
125 * ========================================================== */
126
127
128!function ($) {
129
130  "use strict"; // jshint ;_;
131
132
133 /* ALERT CLASS DEFINITION
134  * ====================== */
135
136  var dismiss = '[data-dismiss="alert"]'
137    , Alert = function (el) {
138        $(el).on('click', dismiss, this.close)
139      }
140
141  Alert.prototype.close = function (e) {
142    var $this = $(this)
143      , selector = $this.attr('data-target')
144      , $parent
145
146    if (!selector) {
147      selector = $this.attr('href')
148      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
149    }
150
151    $parent = $(selector)
152
153    e && e.preventDefault()
154
155    $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
156
157    $parent.trigger(e = $.Event('close'))
158
159    if (e.isDefaultPrevented()) return
160
161    $parent.removeClass('in')
162
163    function removeElement() {
164      $parent
165        .trigger('closed')
166        .remove()
167    }
168
169    $.support.transition && $parent.hasClass('fade') ?
170      $parent.on($.support.transition.end, removeElement) :
171      removeElement()
172  }
173
174
175 /* ALERT PLUGIN DEFINITION
176  * ======================= */
177
178  $.fn.alert = function (option) {
179    return this.each(function () {
180      var $this = $(this)
181        , data = $this.data('alert')
182      if (!data) $this.data('alert', (data = new Alert(this)))
183      if (typeof option == 'string') data[option].call($this)
184    })
185  }
186
187  $.fn.alert.Constructor = Alert
188
189
190 /* ALERT DATA-API
191  * ============== */
192
193  $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
194
195}(window.jQuery);
196/* ============================================================
197 * bootstrap-button.js v2.2.1
198 * http://twitter.github.com/bootstrap/javascript.html#buttons
199 * ============================================================
200 * Copyright 2012 Twitter, Inc.
201 *
202 * Licensed under the Apache License, Version 2.0 (the "License");
203 * you may not use this file except in compliance with the License.
204 * You may obtain a copy of the License at
205 *
206 * http://www.apache.org/licenses/LICENSE-2.0
207 *
208 * Unless required by applicable law or agreed to in writing, software
209 * distributed under the License is distributed on an "AS IS" BASIS,
210 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
211 * See the License for the specific language governing permissions and
212 * limitations under the License.
213 * ============================================================ */
214
215
216!function ($) {
217
218  "use strict"; // jshint ;_;
219
220
221 /* BUTTON PUBLIC CLASS DEFINITION
222  * ============================== */
223
224  var Button = function (element, options) {
225    this.$element = $(element)
226    this.options = $.extend({}, $.fn.button.defaults, options)
227  }
228
229  Button.prototype.setState = function (state) {
230    var d = 'disabled'
231      , $el = this.$element
232      , data = $el.data()
233      , val = $el.is('input') ? 'val' : 'html'
234
235    state = state + 'Text'
236    data.resetText || $el.data('resetText', $el[val]())
237
238    $el[val](data[state] || this.options[state])
239
240    // push to event loop to allow forms to submit
241    setTimeout(function () {
242      state == 'loadingText' ?
243        $el.addClass(d).attr(d, d) :
244        $el.removeClass(d).removeAttr(d)
245    }, 0)
246  }
247
248  Button.prototype.toggle = function () {
249    var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
250
251    $parent && $parent
252      .find('.active')
253      .removeClass('active')
254
255    this.$element.toggleClass('active')
256  }
257
258
259 /* BUTTON PLUGIN DEFINITION
260  * ======================== */
261
262  $.fn.button = function (option) {
263    return this.each(function () {
264      var $this = $(this)
265        , data = $this.data('button')
266        , options = typeof option == 'object' && option
267      if (!data) $this.data('button', (data = new Button(this, options)))
268      if (option == 'toggle') data.toggle()
269      else if (option) data.setState(option)
270    })
271  }
272
273  $.fn.button.defaults = {
274    loadingText: 'loading...'
275  }
276
277  $.fn.button.Constructor = Button
278
279
280 /* BUTTON DATA-API
281  * =============== */
282
283  $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
284    var $btn = $(e.target)
285    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
286    $btn.button('toggle')
287  })
288
289}(window.jQuery);
290/* ==========================================================
291 * bootstrap-carousel.js v2.2.1
292 * http://twitter.github.com/bootstrap/javascript.html#carousel
293 * ==========================================================
294 * Copyright 2012 Twitter, Inc.
295 *
296 * Licensed under the Apache License, Version 2.0 (the "License");
297 * you may not use this file except in compliance with the License.
298 * You may obtain a copy of the License at
299 *
300 * http://www.apache.org/licenses/LICENSE-2.0
301 *
302 * Unless required by applicable law or agreed to in writing, software
303 * distributed under the License is distributed on an "AS IS" BASIS,
304 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
305 * See the License for the specific language governing permissions and
306 * limitations under the License.
307 * ========================================================== */
308
309
310!function ($) {
311
312  "use strict"; // jshint ;_;
313
314
315 /* CAROUSEL CLASS DEFINITION
316  * ========================= */
317
318  var Carousel = function (element, options) {
319    this.$element = $(element)
320    this.options = options
321    this.options.slide && this.slide(this.options.slide)
322    this.options.pause == 'hover' && this.$element
323      .on('mouseenter', $.proxy(this.pause, this))
324      .on('mouseleave', $.proxy(this.cycle, this))
325  }
326
327  Carousel.prototype = {
328
329    cycle: function (e) {
330      if (!e) this.paused = false
331      this.options.interval
332        && !this.paused
333        && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
334      return this
335    }
336
337  , to: function (pos) {
338      var $active = this.$element.find('.item.active')
339        , children = $active.parent().children()
340        , activePos = children.index($active)
341        , that = this
342
343      if (pos > (children.length - 1) || pos < 0) return
344
345      if (this.sliding) {
346        return this.$element.one('slid', function () {
347          that.to(pos)
348        })
349      }
350
351      if (activePos == pos) {
352        return this.pause().cycle()
353      }
354
355      return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
356    }
357
358  , pause: function (e) {
359      if (!e) this.paused = true
360      if (this.$element.find('.next, .prev').length && $.support.transition.end) {
361        this.$element.trigger($.support.transition.end)
362        this.cycle()
363      }
364      clearInterval(this.interval)
365      this.interval = null
366      return this
367    }
368
369  , next: function () {
370      if (this.sliding) return
371      return this.slide('next')
372    }
373
374  , prev: function () {
375      if (this.sliding) return
376      return this.slide('prev')
377    }
378
379  , slide: function (type, next) {
380      var $active = this.$element.find('.item.active')
381        , $next = next || $active[type]()
382        , isCycling = this.interval
383        , direction = type == 'next' ? 'left' : 'right'
384        , fallback  = type == 'next' ? 'first' : 'last'
385        , that = this
386        , e
387
388      this.sliding = true
389
390      isCycling && this.pause()
391
392      $next = $next.length ? $next : this.$element.find('.item')[fallback]()
393
394      e = $.Event('slide', {
395        relatedTarget: $next[0]
396      })
397
398      if ($next.hasClass('active')) return
399
400      if ($.support.transition && this.$element.hasClass('slide')) {
401        this.$element.trigger(e)
402        if (e.isDefaultPrevented()) return
403        $next.addClass(type)
404        $next[0].offsetWidth // force reflow
405        $active.addClass(direction)
406        $next.addClass(direction)
407        this.$element.one($.support.transition.end, function () {
408          $next.removeClass([type, direction].join(' ')).addClass('active')
409          $active.removeClass(['active', direction].join(' '))
410          that.sliding = false
411          setTimeout(function () { that.$element.trigger('slid') }, 0)
412        })
413      } else {
414        this.$element.trigger(e)
415        if (e.isDefaultPrevented()) return
416        $active.removeClass('active')
417        $next.addClass('active')
418        this.sliding = false
419        this.$element.trigger('slid')
420      }
421
422      isCycling && this.cycle()
423
424      return this
425    }
426
427  }
428
429
430 /* CAROUSEL PLUGIN DEFINITION
431  * ========================== */
432
433  $.fn.carousel = function (option) {
434    return this.each(function () {
435      var $this = $(this)
436        , data = $this.data('carousel')
437        , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
438        , action = typeof option == 'string' ? option : options.slide
439      if (!data) $this.data('carousel', (data = new Carousel(this, options)))
440      if (typeof option == 'number') data.to(option)
441      else if (action) data[action]()
442      else if (options.interval) data.cycle()
443    })
444  }
445
446  $.fn.carousel.defaults = {
447    interval: 5000
448  , pause: 'hover'
449  }
450
451  $.fn.carousel.Constructor = Carousel
452
453
454 /* CAROUSEL DATA-API
455  * ================= */
456
457  $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
458    var $this = $(this), href
459      , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
460      , options = $.extend({}, $target.data(), $this.data())
461    $target.carousel(options)
462    e.preventDefault()
463  })
464
465}(window.jQuery);
466/* =============================================================
467 * bootstrap-collapse.js v2.2.1
468 * http://twitter.github.com/bootstrap/javascript.html#collapse
469 * =============================================================
470 * Copyright 2012 Twitter, Inc.
471 *
472 * Licensed under the Apache License, Version 2.0 (the "License");
473 * you may not use this file except in compliance with the License.
474 * You may obtain a copy of the License at
475 *
476 * http://www.apache.org/licenses/LICENSE-2.0
477 *
478 * Unless required by applicable law or agreed to in writing, software
479 * distributed under the License is distributed on an "AS IS" BASIS,
480 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
481 * See the License for the specific language governing permissions and
482 * limitations under the License.
483 * ============================================================ */
484
485
486!function ($) {
487
488  "use strict"; // jshint ;_;
489
490
491 /* COLLAPSE PUBLIC CLASS DEFINITION
492  * ================================ */
493
494  var Collapse = function (element, options) {
495    this.$element = $(element)
496    this.options = $.extend({}, $.fn.collapse.defaults, options)
497
498    if (this.options.parent) {
499      this.$parent = $(this.options.parent)
500    }
501
502    this.options.toggle && this.toggle()
503  }
504
505  Collapse.prototype = {
506
507    constructor: Collapse
508
509  , dimension: function () {
510      var hasWidth = this.$element.hasClass('width')
511      return hasWidth ? 'width' : 'height'
512    }
513
514  , show: function () {
515      var dimension
516        , scroll
517        , actives
518        , hasData
519
520      if (this.transitioning) return
521
522      dimension = this.dimension()
523      scroll = $.camelCase(['scroll', dimension].join('-'))
524      actives = this.$parent && this.$parent.find('> .accordion-group > .in')
525
526      if (actives && actives.length) {
527        hasData = actives.data('collapse')
528        if (hasData && hasData.transitioning) return
529        actives.collapse('hide')
530        hasData || actives.data('collapse', null)
531      }
532
533      this.$element[dimension](0)
534      this.transition('addClass', $.Event('show'), 'shown')
535      $.support.transition && this.$element[dimension](this.$element[0][scroll])
536    }
537
538  , hide: function () {
539      var dimension
540      if (this.transitioning) return
541      dimension = this.dimension()
542      this.reset(this.$element[dimension]())
543      this.transition('removeClass', $.Event('hide'), 'hidden')
544      this.$element[dimension](0)
545    }
546
547  , reset: function (size) {
548      var dimension = this.dimension()
549
550      this.$element
551        .removeClass('collapse')
552        [dimension](size || 'auto')
553        [0].offsetWidth
554
555      this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
556
557      return this
558    }
559
560  , transition: function (method, startEvent, completeEvent) {
561      var that = this
562        , complete = function () {
563            if (startEvent.type == 'show') that.reset()
564            that.transitioning = 0
565            that.$element.trigger(completeEvent)
566          }
567
568      this.$element.trigger(startEvent)
569
570      if (startEvent.isDefaultPrevented()) return
571
572      this.transitioning = 1
573
574      this.$element[method]('in')
575
576      $.support.transition && this.$element.hasClass('collapse') ?
577        this.$element.one($.support.transition.end, complete) :
578        complete()
579    }
580
581  , toggle: function () {
582      this[this.$element.hasClass('in') ? 'hide' : 'show']()
583    }
584
585  }
586
587
588 /* COLLAPSIBLE PLUGIN DEFINITION
589  * ============================== */
590
591  $.fn.collapse = function (option) {
592    return this.each(function () {
593      var $this = $(this)
594        , data = $this.data('collapse')
595        , options = typeof option == 'object' && option
596      if (!data) $this.data('collapse', (data = new Collapse(this, options)))
597      if (typeof option == 'string') data[option]()
598    })
599  }
600
601  $.fn.collapse.defaults = {
602    toggle: true
603  }
604
605  $.fn.collapse.Constructor = Collapse
606
607
608 /* COLLAPSIBLE DATA-API
609  * ==================== */
610
611  $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
612    var $this = $(this), href
613      , target = $this.attr('data-target')
614        || e.preventDefault()
615        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
616      , option = $(target).data('collapse') ? 'toggle' : $this.data()
617    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
618    $(target).collapse(option)
619  })
620
621}(window.jQuery);
622/* ============================================================
623 * bootstrap-dropdown.js v2.2.1
624 * http://twitter.github.com/bootstrap/javascript.html#dropdowns
625 * ============================================================
626 * Copyright 2012 Twitter, Inc.
627 *
628 * Licensed under the Apache License, Version 2.0 (the "License");
629 * you may not use this file except in compliance with the License.
630 * You may obtain a copy of the License at
631 *
632 * http://www.apache.org/licenses/LICENSE-2.0
633 *
634 * Unless required by applicable law or agreed to in writing, software
635 * distributed under the License is distributed on an "AS IS" BASIS,
636 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
637 * See the License for the specific language governing permissions and
638 * limitations under the License.
639 * ============================================================ */
640
641
642!function ($) {
643
644  "use strict"; // jshint ;_;
645
646
647 /* DROPDOWN CLASS DEFINITION
648  * ========================= */
649
650  var toggle = '[data-toggle=dropdown]'
651    , Dropdown = function (element) {
652        var $el = $(element).on('click.dropdown.data-api', this.toggle)
653        $('html').on('click.dropdown.data-api', function () {
654          $el.parent().removeClass('open')
655        })
656      }
657
658  Dropdown.prototype = {
659
660    constructor: Dropdown
661
662  , toggle: function (e) {
663      var $this = $(this)
664        , $parent
665        , isActive
666
667      if ($this.is('.disabled, :disabled')) return
668
669      $parent = getParent($this)
670
671      isActive = $parent.hasClass('open')
672
673      clearMenus()
674
675      if (!isActive) {
676        $parent.toggleClass('open')
677        $this.focus()
678      }
679
680      return false
681    }
682
683  , keydown: function (e) {
684      var $this
685        , $items
686        , $active
687        , $parent
688        , isActive
689        , index
690
691      if (!/(38|40|27)/.test(e.keyCode)) return
692
693      $this = $(this)
694
695      e.preventDefault()
696      e.stopPropagation()
697
698      if ($this.is('.disabled, :disabled')) return
699
700      $parent = getParent($this)
701
702      isActive = $parent.hasClass('open')
703
704      if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
705
706      $items = $('[role=menu] li:not(.divider) a', $parent)
707
708      if (!$items.length) return
709
710      index = $items.index($items.filter(':focus'))
711
712      if (e.keyCode == 38 && index > 0) index--                                        // up
713      if (e.keyCode == 40 && index < $items.length - 1) index++                        // down
714      if (!~index) index = 0
715
716      $items
717        .eq(index)
718        .focus()
719    }
720
721  }
722
723  function clearMenus() {
724    $(toggle).each(function () {
725      getParent($(this)).removeClass('open')
726    })
727  }
728
729  function getParent($this) {
730    var selector = $this.attr('data-target')
731      , $parent
732
733    if (!selector) {
734      selector = $this.attr('href')
735      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
736    }
737
738    $parent = $(selector)
739    $parent.length || ($parent = $this.parent())
740
741    return $parent
742  }
743
744
745  /* DROPDOWN PLUGIN DEFINITION
746   * ========================== */
747
748  $.fn.dropdown = function (option) {
749    return this.each(function () {
750      var $this = $(this)
751        , data = $this.data('dropdown')
752      if (!data) $this.data('dropdown', (data = new Dropdown(this)))
753      if (typeof option == 'string') data[option].call($this)
754    })
755  }
756
757  $.fn.dropdown.Constructor = Dropdown
758
759
760  /* APPLY TO STANDARD DROPDOWN ELEMENTS
761   * =================================== */
762
763  $(document)
764    .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
765    .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
766    .on('click.dropdown.data-api touchstart.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)
767    .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
768
769}(window.jQuery);
770/* =========================================================
771 * bootstrap-modal.js v2.2.1
772 * http://twitter.github.com/bootstrap/javascript.html#modals
773 * =========================================================
774 * Copyright 2012 Twitter, Inc.
775 *
776 * Licensed under the Apache License, Version 2.0 (the "License");
777 * you may not use this file except in compliance with the License.
778 * You may obtain a copy of the License at
779 *
780 * http://www.apache.org/licenses/LICENSE-2.0
781 *
782 * Unless required by applicable law or agreed to in writing, softw
782are
783 * distributed under the License is distributed on an "AS IS" BASIS,
784 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
785 * See the License for the specific language governing permissions and
786 * limitations under the License.
787 * ========================================================= */
788
789
790!function ($) {
791
792  "use strict"; // jshint ;_;
793
794
795 /* MODAL CLASS DEFINITION
796  * ====================== */
797
798  var Modal = function (element, options) {
799    this.options = options
800    this.$element = $(element)
801      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
802    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
803  }
804
805  Modal.prototype = {
806
807      constructor: Modal
808
809    , toggle: function () {
810        return this[!this.isShown ? 'show' : 'hide']()
811      }
812
813    , show: function () {
814        var that = this
815          , e = $.Event('show')
816
817        this.$element.trigger(e)
818
819        if (this.isShown || e.isDefaultPrevented()) return
820
821        this.isShown = true
822
823        this.escape()
824
825        this.backdrop(function () {
826          var transition = $.support.transition && that.$element.hasClass('fade')
827
828          if (!that.$element.parent().length) {
829            that.$element.appendTo(document.body) //don't move modals dom position
830          }
831
832          that.$element
833            .show()
834
835          if (transition) {
836            that.$element[0].offsetWidth // force reflow
837          }
838
839          that.$element
840            .addClass('in')
841            .attr('aria-hidden', false)
842
843          that.enforceFocus()
844
845          transition ?
846            that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
847            that.$element.focus().trigger('shown')
848
849        })
850      }
851
852    , hide: function (e) {
853        e && e.preventDefault()
854
855        var that = this
856
857        e = $.Event('hide')
858
859        this.$element.trigger(e)
860
861        if (!this.isShown || e.isDefaultPrevented()) return
862
863        this.isShown = false
864
865        this.escape()
866
867        $(document).off('focusin.modal')
868
869        this.$element
870          .removeClass('in')
871          .attr('aria-hidden', true)
872
873        $.support.transition && this.$element.hasClass('fade') ?
874          this.hideWithTransition() :
875          this.hideModal()
876      }
877
878    , enforceFocus: function () {
879        var that = this
880        $(document).on('focusin.modal', function (e) {
881          if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
882            that.$element.focus()
883          }
884        })
885      }
886
887    , escape: function () {
888        var that = this
889        if (this.isShown && this.options.keyboard) {
890          this.$element.on('keyup.dismiss.modal', function ( e ) {
891            e.which == 27 && that.hide()
892          })
893        } else if (!this.isShown) {
894          this.$element.off('keyup.dismiss.modal')
895        }
896      }
897
898    , hideWithTransition: function () {
899        var that = this
900          , timeout = setTimeout(function () {
901              that.$element.off($.support.transition.end)
902              that.hideModal()
903            }, 500)
904
905        this.$element.one($.support.transition.end, function () {
906          clearTimeout(timeout)
907          that.hideModal()
908        })
909      }
910
911    , hideModal: function (that) {
912        this.$element
913          .hide()
914          .trigger('hidden')
915
916        this.backdrop()
917      }
918
919    , removeBackdrop: function () {
920        this.$backdrop.remove()
921        this.$backdrop = null
922      }
923
924    , backdrop: function (callback) {
925        var that = this
926          , animate = this.$element.hasClass('fade') ? 'fade' : ''
927
928        if (this.isShown && this.options.backdrop) {
929          var doAnimate = $.support.transition && animate
930
931          this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
932            .appendTo(document.body)
933
934          this.$backdrop.click(
935            this.options.backdrop == 'static' ?
936              $.proxy(this.$element[0].focus, this.$element[0])
937            : $.proxy(this.hide, this)
938          )
939
940          if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
941
942          this.$backdrop.addClass('in')
943
944          doAnimate ?
945            this.$backdrop.one($.support.transition.end, callback) :
946            callback()
947
948        } else if (!this.isShown && this.$backdrop) {
949          this.$backdrop.removeClass('in')
950
951          $.support.transition && this.$element.hasClass('fade')?
952            this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
953            this.removeBackdrop()
954
955        } else if (callback) {
956          callback()
957        }
958      }
959  }
960
961
962 /* MODAL PLUGIN DEFINITION
963  * ======================= */
964
965  $.fn.modal = function (option) {
966    return this.each(function () {
967      var $this = $(this)
968        , data = $this.data('modal')
969        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
970      if (!data) $this.data('modal', (data = new Modal(this, options)))
971      if (typeof option == 'string') data[option]()
972      else if (options.show) data.show()
973    })
974  }
975
976  $.fn.modal.defaults = {
977      backdrop: true
978    , keyboard: true
979    , show: true
980  }
981
982  $.fn.modal.Constructor = Modal
983
984
985 /* MODAL DATA-API
986  * ============== */
987
988  $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
989    var $this = $(this)
990      , href = $this.attr('href')
991      , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
992      , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
993
994    e.preventDefault()
995
996    $target
997      .modal(option)
998      .one('hide', function () {
999        $this.focus()
1000      })
1001  })
1002
1003}(window.jQuery);
1004
1005/* ===========================================================
1006 * bootstrap-tooltip.js v2.2.1
1007 * http://twitter.github.com/bootstrap/javascript.html#tooltips
1008 * Inspired by the original jQuery.tipsy by Jason Frame
1009 * ===========================================================
1010 * Copyright 2012 Twitter, Inc.
1011 *
1012 * Licensed under the Apache License, Version 2.0 (the "License");
1013 * you may not use this file except in compliance with the License.
1014 * You may obtain a copy of the License at
1015 *
1016 * http://www.apache.org/licenses/LICENSE-2.0
1017 *
1018 * Unless required by applicable law or agreed to in writing, software
1019 * distributed under the License is distributed on an "AS IS" BASIS,
1020 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1021 * See the License for the specific language governing permissions and
1022 * limitations under the License.
1023 * ========================================================== */
1024
1025
1026!function ($) {
1027
1028  "use strict"; // jshint ;_;
1029
1030
1031 /* TOOLTIP PUBLIC CLASS DEFINITION
1032  * =============================== */
1033
1034  var Tooltip = function (element, options) {
1035    this.init('tooltip', element, options)
1036  }
1037
1038  Tooltip.prototype = {
1039
1040    constructor: Tooltip
1041
1042  , init: function (type, element, options) {
1043      var eventIn
1044        , eventOut
1045
1046      this.type = type
1047      this.$element = $(element)
1048      this.options = this.getOptions(options)
1049      this.enabled = true
1050
1051      if (this.options.trigger == 'click') {
1052        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
1053      } else if (this.options.trigger != 'manual') {
1054        eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
1055        eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
1056        this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
1057        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
1058      }
1059
1060      this.options.selector ?
1061        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
1062        this.fixTitle()
1063    }
1064
1065  , getOptions: function (options) {
1066      options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
1067
1068      if (options.delay && typeof options.delay == 'number') {
1069        options.delay = {
1070          show: options.delay
1071        , hide: options.delay
1072        }
1073      }
1074
1075      return options
1076    }
1077
1078  , enter: function (e) {
1079      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1080
1081      if (!self.options.delay || !self.options.delay.show) return self.show()
1082
1083      clearTimeout(this.timeout)
1084      self.hoverState = 'in'
1085      this.timeout = setTimeout(function() {
1086        if (self.hoverState == 'in') self.show()
1087      }, self.options.delay.show)
1088    }
1089
1090  , leave: function (e) {
1091      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1092
1093      if (this.timeout) clearTimeout(this.timeout)
1094      if (!self.options.delay || !self.options.delay.hide) return self.hide()
1095
1096      self.hoverState = 'out'
1097      this.timeout = setTimeout(function() {
1098        if (self.hoverState == 'out') self.hide()
1099      }, self.options.delay.hide)
1100    }
1101
1102  , show: function () {
1103      var $tip
1104        , inside
1105        , pos
1106        , actualWidth
1107        , actualHeight
1108        , placement
1109        , tp
1110
1111      if (this.hasContent() && this.enabled) {
1112        $tip = this.tip()
1113        this.setContent()
1114
1115        if (this.options.animation) {
1116          $tip.addClass('fade')
1117        }
1118
1119        placement = typeof this.options.placement == 'function' ?
1120          this.options.placement.call(this, $tip[0], this.$element[0]) :
1121          this.options.placement
1122
1123        inside = /in/.test(placement)
1124
1125        $tip
1126          .detach()
1127          .css({ top: 0, left: 0, display: 'block' })
1128          .insertAfter(this.$element)
1129
1130        pos = this.getPosition(inside)
1131
1132        actualWidth = $tip[0].offsetWidth
1133        actualHeight = $tip[0].offsetHeight
1134
1135        switch (inside ? placement.split(' ')[1] : placement) {
1136          case 'bottom':
1137            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
1138            break
1139          case 'top':
1140            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
1141            break
1142          case 'left':
1143            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
1144            break
1145          case 'right':
1146            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
1147            break
1148        }
1149
1150        $tip
1151          .offset(tp)
1152          .addClass(placement)
1153          .addClass('in')
1154      }
1155    }
1156
1157  , setContent: function () {
1158      var $tip = this.tip()
1159        , title = this.getTitle()
1160
1161      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
1162      $tip.removeClass('fade in top bottom left right')
1163    }
1164
1165  , hide: function () {
1166      var that = this
1167        , $tip = this.tip()
1168
1169      $tip.removeClass('in')
1170
1171      function removeWithAnimation() {
1172        var timeout = setTimeout(function () {
1173          $tip.off($.support.transition.end).detach()
1174        }, 500)
1175
1176        $tip.one($.support.transition.end, function () {
1177          clearTimeout(timeout)
1178          $tip.detach()
1179        })
1180      }
1181
1182      $.support.transition && this.$tip.hasClass('fade') ?
1183        removeWithAnimation() :
1184        $tip.detach()
1185
1186      return this
1187    }
1188
1189  , fixTitle: function () {
1190      var $e = this.$element
1191      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
1192        $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
1193      }
1194    }
1195
1196  , hasContent: function () {
1197      return this.getTitle()
1198    }
1199
1200  , getPosition: function (inside) {
1201      return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
1202        width: this.$element[0].offsetWidth
1203      , height: this.$element[0].offsetHeight
1204      })
1205    }
1206
1207  , getTitle: function () {
1208      var title
1209        , $e = this.$element
1210        , o = this.options
1211
1212      title = $e.attr('data-original-title')
1213        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
1214
1215      return title
1216    }
1217
1218  , tip: function () {
1219      return this.$tip = this.$tip || $(this.options.template)
1220    }
1221
1222  , validate: function () {
1223      if (!this.$element[0].parentNode) {
1224        this.hide()
1225        this.$element = null
1226        this.options = null
1227      }
1228    }
1229
1230  , enable: function () {
1231      this.enabled = true
1232    }
1233
1234  , disable: function () {
1235      this.enabled = false
1236    }
1237
1238  , toggleEnabled: function () {
1239      this.enabled = !this.enabled
1240    }
1241
1242  , toggle: function (e) {
1243      var self = $(e.currentTarget)[this.type](this._options).data(this.type)
1244      self[self.tip().hasClass('in') ? 'hide' : 'show']()
1245    }
1246
1247  , destroy: function () {
1248      this.hide().$element.off('.' + this.type).removeData(this.type)
1249    }
1250
1251  }
1252
1253
1254 /* TOOLTIP PLUGIN DEFINITION
1255  * ========================= */
1256
1257  $.fn.tooltip = function ( option ) {
1258    return this.each(function () {
1259      var $this = $(this)
1260        , data = $this.data('tooltip')
1261        , options = typeof option == 'object' && option
1262      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
1263      if (typeof option == 'string') data[option]()
1264    })
1265  }
1266
1267  $.fn.tooltip.Constructor = Tooltip
1268
1269  $.fn.tooltip.defaults = {
1270    animation: true
1271  , placement: 'top'
1272  , selector: false
1273  , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
1274  , trigger: 'hover'
1275  , title: ''
1276  , delay: 0
1277  , html: false
1278  }
1279
1280}(window.jQuery);
1281/* ===========================================================
1282 * bootstrap-popover.js v2.2.1
1283 * http://twitter.github.com/bootstrap/javascript.html#popovers
1284 * ===========================================================
1285 * Copyright 2012 Twitter, Inc.
1286 *
1287 * Licensed under the Apache License, Version 2.0 (the "License");
1288 * you may not use this file except in compliance with the License.
1289 * You may obtain a copy of the License at
1290 *
1291 * http://www.apache.org/licenses/LICENSE-2.0
1292 *
1293 * Unless required by applicable law or agreed to in writing, software
1294 * distributed under the License is distributed on an "AS IS" BASIS,
1295 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1296 * See the License for the specific language governing permissions and
1297 * limitations under the License.
1298 * =========================================================== */
1299
1300
1301!function ($) {
1302
1303  "use strict"; // jshint ;_;
1304
1305
1306 /* POPOVER PUBLIC CLASS DEFINITION
1307  * =============================== */
1308
1309  var Popover = function (element, options) {
1310    this.init('popover', element, options)
1311  }
1312
1313
1314  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
1315     ========================================== */
1316
1317  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
1318
1319    constructor: Popover
1320
1321  , setContent: function () {
1322      var $tip = this.tip()
1323        , title = this.getTitle()
1324        , content = this.getContent()
1325
1326      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
1327      $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
1328
1329      $tip.removeClass('fade top bottom left right in')
1330    }
1331
1332  , hasContent: function () {
1333      return this.getTitle() || this.getContent()
1334    }
1335
1336  , getContent: function () {
1337      var content
1338        , $e = this.$element
1339        , o = this.options
1340
1341      content = $e.attr('data-content')
1342        || (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)
1343
1344      return content
1345    }
1346
1347  , tip: function () {
1348      if (!this.$tip) {
1349        this.$tip = $(this.options.template)
1350      }
1351      return this.$tip
1352    }
1353
1354  , destroy: function () {
1355      this.hide().$element.off('.' + this.type).removeData(this.type)
1356    }
1357
1358  })
1359
1360
1361 /* POPOVER PLUGIN DEFINITION
1362  * ======================= */
1363
1364  $.fn.popover = function (option) {
1365    return this.each(function () {
1366      var $this = $(this)
1367        , data = $this.data('popover')
1368        , options = typeof option == 'object' && option
1369      if (!data) $this.data('popover', (data = new Popover(this, options)))
1370      if (typeof option == 'string') data[option]()
1371    })
1372  }
1373
1374  $.fn.popover.Constructor = Popover
1375
1376  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
1377    placement: 'right'
1378  , trigger: 'click'
1379  , content: ''
1380  , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
1381  })
1382
1383}(window.jQuery);
1384/* =============================================================
1385 * bootstrap-scrollspy.js v2.2.1
1386 * http://twitter.github.com/bootstrap/javascript.html#scrollspy
1387 * =============================================================
1388 * Copyright 2012 Twitter, Inc.
1389 *
1390 * Licensed under the Apache License, Version 2.0 (the "License");
1391 * you may not use this file except in compliance with the License.
1392 * You may obtain a copy of the License at
1393 *
1394 * http://www.apache.org/licenses/LICENSE-2.0
1395 *
1396 * Unless required by applicable law or agreed to in writing, software
1397 * distributed under the License is distributed on an "AS IS" BASIS,
1398 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1399 * See the License for the specific language governing permissions and
1400 * limitations under the License.
1401 * ============================================================== */
1402
1403
1404!function ($) {
1405
1406  "use strict"; // jshint ;_;
1407
1408
1409 /* SCROLLSPY CLASS DEFINITION
1410  * ========================== */
1411
1412  function ScrollSpy(element, options) {
1413    var process = $.proxy(this.process, this)
1414      , $element = $(element).is('body') ? $(window) : $(element)
1415      , href
1416    this.options = $.extend({}, $.fn.scrollspy.defaults, options)
1417    this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
1418    this.selector = (this.options.target
1419      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1420      || '') + ' .nav li > a'
1421    this.$body = $('body')
1422    this.refresh()
1423    this.process()
1424  }
1425
1426  ScrollSpy.prototype = {
1427
1428      constructor: ScrollSpy
1429
1430    , refresh: function () {
1431        var self = this
1432          , $targets
1433
1434        this.offsets = $([])
1435        this.targets = $([])
1436
1437        $targets = this.$body
1438          .find(this.selector)
1439          .map(function () {
1440            var $el = $(this)
1441              , href = $el.data('target') || $el.attr('href')
1442              , $href = /^#\w/.test(href) && $(href)
1443            return ( $href
1444              && $href.length
1445              && [[ $href.position().top, href ]] ) || null
1446          })
1447          .sort(function (a, b) { return a[0] - b[0] })
1448          .each(function () {
1449            self.offsets.push(this[0])
1450            self.targets.push(this[1])
1451          })
1452      }
1453
1454    , process: function () {
1455        var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
1456          , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
1457          , maxScroll = scrollHeight - this.$scrollElement.height()
1458          , offsets = this.offsets
1459          , targets = this.targets
1460          , activeTarget = this.activeTarget
1461          , i
1462
1463        if (scrollTop >= maxScroll) {
1464          return activeTarget != (i = targets.last()[0])
1465            && this.activate ( i )
1466        }
1467
1468        for (i = offsets.length; i--;) {
1469          activeTarget != targets[i]
1470            && scrollTop >= offsets[i]
1471            && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
1472            && this.activate( targets[i] )
1473        }
1474      }
1475
1476    , activate: function (target) {
1477        var active
1478          , selector
1479
1480        this.activeTarget = target
1481
1482        $(this.selector)
1483          .parent('.active')
1484          .removeClass('active')
1485
1486        selector = this.selector
1487          + '[data-target="' + target + '"],'
1488          + this.selector + '[href="' + target + '"]'
1489
1490        active = $(selector)
1491          .parent('li')
1492          .addClass('active')
1493
1494        if (active.parent('.dropdown-menu').length)  {
1495          active = active.closest('li.dropdown').addClass('active')
1496        }
1497
1498        active.trigger('activate')
1499      }
1500
1501  }
1502
1503
1504 /* SCROLLSPY PLUGIN DEFINITION
1505  * =========================== */
1506
1507  $.fn.scrollspy = function (option) {
1508    return this.each(function () {
1509      var $this = $(this)
1510        , data = $this.data('scrollspy')
1511        , options = typeof option == 'object' && option
1512      if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
1513      if (typeof option == 'string') data[option]()
1514    })
1515  }
1516
1517  $.fn.scrollspy.Constructor = ScrollSpy
1518
1519  $.fn.scrollspy.defaults = {
1520    offset: 10
1521  }
1522
1523
1524 /* SCROLLSPY DATA-API
1525  * ================== */
1526
1527  $(window).on('load', function () {
1528    $('[data-spy="scroll"]').each(function () {
1529      var $spy = $(this)
1530      $spy.scrollspy($spy.data())
1531    })
1532  })
1533
1534}(window.jQuery);
1535/* ========================================================
1536 * bootstrap-tab.js v2.2.1
1537 * http://twitter.github.com/bootstrap/javascript.html#tabs
1538 * ========================================================
1539 * Copyright 2012 Twitter, Inc.
1540 *
1541 * Licensed under the Apache License, Version 2.0 (the "License");
1542 * you may not use this file except in compliance with the License.
1543 * You may obtain a copy of the License at
1544 *
1545 * http://www.apache.org/licenses/LICENSE-2.0
1546 *
1547 * Unless required by applicable law or agreed to in writing, software
1548 * distributed under the License is distributed on an "AS IS" BASIS,
1549 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1550 * See the License for the specific language governing permissions and
1551 * limitations under the License.
1552 * ======================================================== */
1553
1554
1555!function ($) {
1556
1557  "use strict"; // jshint ;_;
1558
1559
1560 /* TAB CLASS DEFINITION
1561  * ==================== */
1562
1563  var Tab = function (element) {
1564    this.element = $(element)
1565  }
1566
1567  Tab.prototype = {
1568
1569    constructor: Tab
1570
1571  , show: function () {
1572      var $this = this.element
1573        , $ul = $this.closest('ul:not(.dropdown-menu)')
1574        , selector = $this.attr('data-target')
1575        , previous
1576        , $target
1577        , e
1578
1579      if (!selector) {
1580        selector = $this.attr('href')
1581        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1582      }
1583
1584      if ( $this.parent('li').hasClass('active') ) return
1585
1586      previous = $ul.find('.active:last a')[0]
1587
1588      e = $.Event('show', {
1589        relatedTarget: previous
1590      })
1591
1592      $this.trigger(e)
1593
1594      if (e.isDefaultPrevented()) return
1595
1596      $target = $(selector)
1597
1598      this.activate($this.parent('li'), $ul)
1599      this.activate($target, $target.parent(), function () {
1600        $this.trigger({
1601          type: 'shown'
1602        , relatedTarget: previous
1603        })
1604      })
1605    }
1606
1607  , activate: function ( element, container, callback) {
1608      var $active = container.find('> .active')
1609        , transition = callback
1610            && $.support.transition
1611            && $active.hasClass('fade')
1612
1613      function next() {
1614        $active
1615          .removeClass('active')
1616          .find('> .dropdown-menu > .active')
1617          .removeClass('active')
1618
1619        element.addClass('active')
1620
1621        if (transition) {
1622          element[0].offsetWidth // reflow for transition
1623          element.addClass('in')
1624        } else {
1625          element.removeClass('fade')
1626        }
1627
1628        if ( element.parent('.dropdown-menu') ) {
1629          element.closest('li.dropdown').addClass('active')
1630        }
1631
1632        callback && callback()
1633      }
1634
1635      transition ?
1636        $active.one($.support.transition.end, next) :
1637        next()
1638
1639      $active.removeClass('in')
1640    }
1641  }
1642
1643
1644 /* TAB PLUGIN DEFINITION
1645  * ===================== */
1646
1647  $.fn.tab = function ( option ) {
1648    return this.each(function () {
1649      var $this = $(this)
1650        , data = $this.data('tab')
1651      if (!data) $this.data('tab', (data = new Tab(this)))
1652      if (typeof option == 'string') data[option]()
1653    })
1654  }
1655
1656  $.fn.tab.Constructor = Tab
1657
1658
1659 /* TAB DATA-API
1660  * ============ */
1661
1662  $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
1663    e.preventDefault()
1664    $(this).tab('show')
1665  })
1666
1667}(window.jQuery);
1668/* ===================================================
1669 * bootstrap-transition.js v2.2.1
1670 * http://twitter.github.com/bootstrap/javascript.html#transitions
1671 * ===================================================
1672 * Copyright 2012 Twitter, Inc.
1673 *
1674 * Licensed under the Apache License, Version 2.0 (the "License");
1675 * you may not use this file except in compliance with the License.
1676 * You may obtain a copy of the License at
1677 *
1678 * http://www.apache.org/licenses/LICENSE-2.0
1679 *
1680 * Unless required by applicable law or agreed to in writing, software
1681 * distributed under the License is distributed on an "AS IS" BASIS,
1682 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1683 * See the License for the specific language governing permissions and
1684 * limitations under the License.
1685 * ========================================================== */
1686
1687
1688!function ($) {
1689
1690  "use strict"; // jshint ;_;
1691
1692
1693  /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
1694   * ======================================================= */
1695
1696  $(function () {
1697
1698    $.support.transition = (function () {
1699
1700      var transitionEnd = (function () {
1701
1702        var el = document.createElement('bootstrap')
1703          , transEndEventNames = {
1704               'WebkitTransition' : 'webkitTransitionEnd'
1705            ,  'MozTransition'    : 'transitionend'
1706            ,  'OTransition'      : 'oTransitionEnd otransitionend'
1707            ,  'transition'       : 'transitionend'
1708            }
1709          , name
1710
1711        for (name in transEndEventNames){
1712          if (el.style[name] !== undefined) {
1713            return transEndEventNames[name]
1714          }
1715        }
1716
1717      }())
1718
1719      return transitionEnd && {
1720        end: transitionEnd
1721      }
1722
1723    })()
1724
1725  })
1726
1727}(window.jQuery);
1728/* =============================================================
1729 * bootstrap-typeahead.js v2.2.1
1730 * http://twitter.github.com/bootstrap/javascript.html#typeahead
1731 * =============================================================
1732 * Copyright 2012 Twitter, Inc.
1733 *
1734 * Licensed under the Apache License, Version 2.0 (the "License");
vendor: 7,222 bytes, lines 1735-2029
1735 * you may not use this file except in compliance with the License.
1736 * You may obtain a copy of the License at
1737 *
1738 * http://www.apache.org/licenses/LICENSE-2.0
1739 *
1740 * Unless required by applicable law or agreed to in writing, software
1741 * distributed under the License is distributed on an "AS IS" BASIS,
1742 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1743 * See the License for the specific language governing permissions and
1744 * limitations under the License.
1745 * ============================================================ */
1746
1747
1748!function($){
1749
1750  "use strict"; // jshint ;_;
1751
1752
1753 /* TYPEAHEAD PUBLIC CLASS DEFINITION
1754  * ================================= */
1755
1756  var Typeahead = function (element, options) {
1757    this.$element = $(element)
1758    this.options = $.extend({}, $.fn.typeahead.defaults, options)
1759    this.matcher = this.options.matcher || this.matcher
1760    this.sorter = this.options.sorter || this.sorter
1761    this.highlighter = this.options.highlighter || this.highlighter
1762    this.updater = this.options.updater || this.updater
1763    this.$menu = $(this.options.menu).appendTo('body')
1764    this.source = this.options.source
1765    this.shown = false
1766    this.listen()
1767  }
1768
1769  Typeahead.prototype = {
1770
1771    constructor: Typeahead
1772
1773  , select: function () {
1774      var val = this.$menu.find('.active').attr('data-value')
1775      this.$element
1776        .val(this.updater(val))
1777        .change()
1778      return this.hide()
1779    }
1780
1781  , updater: function (item) {
1782      return item
1783    }
1784
1785  , show: function () {
1786      var pos = $.extend({}, this.$element.offset(), {
1787        height: this.$element[0].offsetHeight
1788      })
1789
1790      this.$menu.css({
1791        top: pos.top + pos.height
1792      , left: pos.left
1793      })
1794
1795      this.$menu.show()
1796      this.shown = true
1797      return this
1798    }
1799
1800  , hide: function () {
1801      this.$menu.hide()
1802      this.shown = false
1803      return this
1804    }
1805
1806  , lookup: function (event) {
1807      var items
1808
1809      this.query = this.$element.val()
1810
1811      if (!this.query || this.query.length < this.options.minLength) {
1812        return this.shown ? this.hide() : this
1813      }
1814
1815      items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
1816
1817      return items ? this.process(items) : this
1818    }
1819
1820  , process: function (items) {
1821      var that = this
1822
1823      items = $.grep(items, function (item) {
1824        return that.matcher(item)
1825      })
1826
1827      items = this.sorter(items)
1828
1829      if (!items.length) {
1830        return this.shown ? this.hide() : this
1831      }
1832
1833      return this.render(items.slice(0, this.options.items)).show()
1834    }
1835
1836  , matcher: function (item) {
1837      return ~item.toLowerCase().indexOf(this.query.toLowerCase())
1838    }
1839
1840  , sorter: function (items) {
1841      var beginswith = []
1842        , caseSensitive = []
1843        , caseInsensitive = []
1844        , item
1845
1846      while (item = items.shift()) {
1847        if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
1848        else if (~item.indexOf(this.query)) caseSensitive.push(item)
1849        else caseInsensitive.push(item)
1850      }
1851
1852      return beginswith.concat(caseSensitive, caseInsensitive)
1853    }
1854
1855  , highlighter: function (item) {
1856      var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
1857      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
1858        return '<strong>' + match + '</strong>'
1859      })
1860    }
1861
1862  , render: function (items) {
1863      var that = this
1864
1865      items = $(items).map(function (i, item) {
1866        i = $(that.options.item).attr('data-value', item)
1867        i.find('a').html(that.highlighter(item))
1868        return i[0]
1869      })
1870
1871      items.first().addClass('active')
1872      this.$menu.html(items)
1873      return this
1874    }
1875
1876  , next: function (event) {
1877      var active = this.$menu.find('.active').removeClass('active')
1878        , next = active.next()
1879
1880      if (!next.length) {
1881        next = $(this.$menu.find('li')[0])
1882      }
1883
1884      next.addClass('active')
1885    }
1886
1887  , prev: function (event) {
1888      var active = this.$menu.find('.active').removeClass('active')
1889        , prev = active.prev()
1890
1891      if (!prev.length) {
1892        prev = this.$menu.find('li').last()
1893      }
1894
1895      prev.addClass('active')
1896    }
1897
1898  , listen: function () {
1899      this.$element
1900        .on('blur',     $.proxy(this.blur, this))
1901        .on('keypress', $.proxy(this.keypress, this))
1902        .on('keyup',    $.proxy(this.keyup, this))
1903
1904      if (this.eventSupported('keydown')) {
1905        this.$element.on('keydown', $.proxy(this.keydown, this))
1906      }
1907
1908      this.$menu
1909        .on('click', $.proxy(this.click, this))
1910        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
1911    }
1912
1913  , eventSupported: function(eventName) {
1914      var isSupported = eventName in this.$element
1915      if (!isSupported) {
1916        this.$element.setAttribute(eventName, 'return;')
1917        isSupported = typeof this.$element[eventName] === 'function'
1918      }
1919      return isSupported
1920    }
1921
1922  , move: function (e) {
1923      if (!this.shown) return
1924
1925      switch(e.keyCode) {
1926        case 9: // tab
1927        case 13: // enter
1928        case 27: // escape
1929          e.preventDefault()
1930          break
1931
1932        case 38: // up arrow
1933          e.preventDefault()
1934          this.prev()
1935          break
1936
1937        case 40: // down arrow
1938          e.preventDefault()
1939          this.next()
1940          break
1941      }
1942
1943      e.stopPropagation()
1944    }
1945
1946  , keydown: function (e) {
1947      this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
1948      this.move(e)
1949    }
1950
1951  , keypress: function (e) {
1952      if (this.suppressKeyPressRepeat) return
1953      this.move(e)
1954    }
1955
1956  , keyup: function (e) {
1957      switch(e.keyCode) {
1958        case 40: // down arrow
1959        case 38: // up arrow
1960        case 16: // shift
1961        case 17: // ctrl
1962        case 18: // alt
1963          break
1964
1965        case 9: // tab
1966        case 13: // enter
1967          if (!this.shown) return
1968          this.select()
1969          break
1970
1971        case 27: // escape
1972          if (!this.shown) return
1973          this.hide()
1974          break
1975
1976        default:
1977          this.lookup()
1978      }
1979
1980      e.stopPropagation()
1981      e.preventDefault()
1982  }
1983
1984  , blur: function (e) {
1985      var that = this
1986      setTimeout(function () { that.hide() }, 150)
1987    }
1988
1989  , click: function (e) {
1990      e.stopPropagation()
1991      e.preventDefault()
1992      this.select()
1993    }
1994
1995  , mouseenter: function (e) {
1996      this.$menu.find('.active').removeClass('active')
1997      $(e.currentTarget).addClass('active')
1998    }
1999
2000  }
2001
2002
2003  /* TYPEAHEAD PLUGIN DEFINITION
2004   * =========================== */
2005
2006  $.fn.typeahead = function (option) {
2007    return this.each(function () {
2008      var $this = $(this)
2009        , data = $this.data('typeahead')
2010        , options = typeof option == 'object' && option
2011      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
2012      if (typeof option == 'string') data[option]()
2013    })
2014  }
2015
2016  $.fn.typeahead.defaults = {
2017    source: []
2018  , items: 8
2019  , menu: '<ul class="typeahead dropdown-menu"></ul>'
2020  , item: '<li><a href="#"></a></li>'
2021  , minLength: 1
2022  }
2023
2024  $.fn.typeahead.Constructor = Typeahead
2025
2026
2027 /*   TYPEAHEAD DATA-API
2028  * ================== */
2029
2030  $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
2031    var $this = $(this)
2032    if ($this.data('typeahead')) return
2033    e.preventDefault()
2034    $this.typeahead($this.data())
2035  })
2036
2037}(window.jQuery);
2038
2039/*!
2040 * jQuery Migrate - v1.2.1 - 2013-05-08
2041 * https://github.com/jquery/jquery-migrate
2042 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
2043 */
2044(function( jQuery, window, undefined ) {
2045// See http://bugs.jquery.com/ticket/13335
2046// "use strict";
2047
2048
2049var warnedAbout = {};
2050
2051// List of warnings already given; public read only
2052jQuery.migrateWarnings = [];
2053
2054// Set to true to prevent console output; migrateWarnings still maintained
2055// jQuery.migrateMute = false;
2056
2057// Show a message on the console so devs know we're active
2058if ( !jQuery.migrateMute && window.console && window.console.log ) {
2059	window.console.log("JQMIGRATE: Logging is active");
2060}
2061
2062// Set to false to disable traces that appear with warnings
2063if ( jQuery.migrateTrace === undefined ) {
2064	jQuery.migrateTrace = true;
2065}
2066
2067// Forget any warnings we've already given; public
2068jQuery.migrateReset = function() {
2069	warnedAbout = {};
2070	jQuery.migrateWarnings.length = 0;
2071};
2072
2073function migrateWarn( msg) {
2074	var console = window.console;
2075	if ( !warnedAbout[ msg ] ) {
2076		warnedAbout[ msg ] = true;
2077		jQuery.migrateWarnings.push( msg );
2078		if ( console && console.warn && !jQuery.migrateMute ) {
2079			console.warn( "JQMIGRATE: " + msg );
2080			if ( jQuery.migrateTrace && console.trace ) {
2081				console.trace();
2082			}
2083		}
2084	}
2085}
2086
2087function migrateWarnProp( obj, prop, value, msg ) {
2088	if ( Object.defineProperty ) {
2089		// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
2090		// allow property to be overwritten in case some other plugin wants it
2091		try {
2092			Object.defineProperty( obj, prop, {
2093				configurable: true,
2094				enumerable: true,
2095				get: function() {
2096					migrateWarn( msg );
2097					return value;
2098				},
2099				set: function( newValue ) {
2100					migrateWarn( msg );
2101					value = newValue;
2102				}
2103			});
2104			return;
2105		} catch( err ) {
2106			// IE8 is a dope about Object.defineProperty, can't warn there
2107		}
2108	}
2109
2110	// Non-ES5 (or broken) browser; just set the property
2111	jQuery._definePropertyBroken = true;
2112	obj[ prop ] = value;
2113}
2114
2115if ( document.compatMode === "BackCompat" ) {
2116	// jQuery has never supported or tested Quirks Mode
2117	migrateWarn( "jQuery is not compatible with Quirks Mode" );
2118}
2119
2120
2121var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
2122	oldAttr = jQuery.attr,
2123	valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
2124		function() { return null; },
2125	valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
2126		function() { return undefined; },
2127	rnoType = /^(?:input|button)$/i,
2128	rnoAttrNodeType = /^[238]$/,
2129	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2130	ruseDefault = /^(?:checked|selected)$/i;
2131
2132// jQuery.attrFn
2133migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
2134
2135jQuery.attr = function( elem, name, value, pass ) {
2136	var lowerName = name.toLowerCase(),
2137		nType = elem && elem.nodeType;
2138
2139	if ( pass ) {
2140		// Since pass is used internally, we only warn for new jQuery
2141		// versions where there isn't a pass arg in the formal params
2142		if ( oldAttr.length < 4 ) {
2143			migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
2144		}
2145		if ( elem && !rnoAttrNodeType.test( nType ) &&
2146			(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
2147			return jQuery( elem )[ name ]( value );
2148		}
2149	}
2150
2151	// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
2152	// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
2153	if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
2154		migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
2155	}
2156
2157	// Restore boolHook for boolean property/attribute synchronization
2158	if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
2159		jQuery.attrHooks[ lowerName ] = {
2160			get: function( elem, name ) {
2161				// Align boolean attributes with corresponding properties
2162				// Fall back to attribute presence where some booleans are not supported
2163				var attrNode,
2164					property = jQuery.prop( elem, name );
2165				return property === true || typeof property !== "boolean" &&
2166					( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2167
2168					name.toLowerCase() :
2169					undefined;
2170			},
2171			set: function( elem, value, name ) {
2172				var propName;
2173				if ( value === false ) {
2174					// Remove boolean attributes when set to false
2175					jQuery.removeAttr( elem, name );
2176				} else {
2177					// value is true since we know at this point it's type boolean and not false
2178					// Set boolean attributes to the same name and set the DOM property
2179					propName = jQuery.propFix[ name ] || name;
2180					if ( propName in elem ) {
2181						// Only set the IDL specifically if it already exists on the element
2182						elem[ propName ] = true;
2183					}
2184
2185					elem.setAttribute( name, name.toLowerCase() );
2186				}
2187				return name;
2188			}
2189		};
2190
2191		// Warn only for attributes that can remain distinct from their properties post-1.9
2192		if ( ruseDefault.test( lowerName ) ) {
2193			migrateWarn( "jQuery.fn.attr('" + lowerName + "') may use property instead of attribute" );
2194		}
2195	}
2196
2197	return oldAttr.call( jQuery, elem, name, value );
2198};
2199
2200// attrHooks: value
2201jQuery.attrHooks.value = {
2202	get: function( elem, name ) {
2203		var nodeName = ( elem.nodeName || "" ).toLowerCase();
2204		if ( nodeName === "button" ) {
2205			return valueAttrGet.apply( this, arguments );
2206		}
2207		if ( nodeName !== "input" && nodeName !== "option" ) {
2208			migrateWarn("jQuery.fn.attr('value') no longer gets properties");
2209		}
2210		return name in elem ?
2211			elem.value :
2212			null;
2213	},
2214	set: function( elem, value ) {
2215		var nodeName = ( elem.nodeName || "" ).toLowerCase();
2216		if ( nodeName === "button" ) {
2217			return valueAttrSet.apply( this, arguments );
2218		}
2219		if ( nodeName !== "input" && nodeName !== "option" ) {
2220			migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
2221		}
2222		// Does not return so that setAttribute is also used
2223		elem.value = value;
2224	}
2225};
2226
2227
2228var matched, browser,
2229	oldInit = jQuery.fn.init,
2230	oldParseJSON = jQuery.parseJSON,
2231	// Note: XSS check is done below after string is trimmed
2232	rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
2233
2234// $(html) "looks like html" rule change
2235jQuery.fn.init = function( selector, context, rootjQuery ) {
2236	var match;
2237
2238	if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
2239			(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
2240		// This is an HTML string according to the "old" rules; is it still?
2241		if ( selector.charAt( 0 ) !== "<" ) {
2242			migrateWarn("$(html) HTML strings must start with '<' character");
2243		}
2244		if ( match[ 3 ] ) {
2245			migrateWarn("$(html) HTML text after last tag is ignored");
2246		}
2247		// Consistently reject any HTML-like string starting with a hash (#9521)
2248		// Note that this may break jQuery 1.6.x code that otherwise would work.
2249		if ( match[ 0 ].charAt( 0 ) === "#" ) {
2250			migrateWarn("HTML string cannot start with a '#' character");
2251			jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
2252		}
2253		// Now process using loose rules; let pre-1.8 play too
2254		if ( context && context.context ) {
2255			// jQuery object as context; parseHTML expects a DOM object
2256			context = context.context;
2257		}
2258		if ( jQuery.parseHTML ) {
2259			return oldInit.call( this, jQuery.parseHTML( match[ 2 ], context, true ),
2260					context, rootjQuery );
2261		}
2262	}
2263	return oldInit.apply( this, arguments );
2264};
2265jQuery.fn.init.prototype = jQuery.fn;
2266
2267// Let $.parseJSON(falsy_value) return null
2268jQuery.parseJSON = function( json ) {
2269	if ( !json && json !== null ) {
2270		migrateWarn("jQuery.parseJSON requires a valid JSON string");
2271		return null;
2272	}
2273	return oldParseJSON.apply( this, arguments );
2274};
2275
2276jQuery.uaMatch = function( ua ) {
2277	ua = ua.toLowerCase();
2278
2279	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
2280		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
2281		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
2282		/(msie) ([\w.]+)/.exec( ua ) ||
2283		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
2284		[];
2285
2286	return {
2287		browser: match[ 1 ] || "",
2288		version: match[ 2 ] || "0"
2289	};
2290};
2291
2292// Don't clobber any existing jQuery.browser in case it's different
2293if ( !jQuery.browser ) {
2294	matched = jQuery.uaMatch( navigator.userAgent );
2295	browser = {};
2296
2297	if ( matched.browser ) {
2298		browser[ matched.browser ] = true;
2299		browser.version = matched.version;
2300	}
2301
2302	// Chrome is Webkit, but Webkit is also Safari.
2303	if ( browser.chrome ) {
2304		browser.webkit = true;
2305	} else if ( browser.webkit ) {
2306		browser.safari = true;
2307	}
2308
2309	jQuery.browser = browser;
2310}
2311
2312// Warn if the code tries to get jQuery.browser
2313migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
2314
2315jQuery.sub = function() {
2316	function jQuerySub( selector, context ) {
2317		return new jQuerySub.fn.init( selector, context );
2318	}
2319	jQuery.extend( true, jQuerySub, this );
2320	jQuerySub.superclass = this;
2321	jQuerySub.fn = jQuerySub.prototype = this();
2322	jQuerySub.fn.constructor = jQuerySub;
2323	jQuerySub.sub = this.sub;
2324	jQuerySub.fn.init = function init( selector, context ) {
2325		if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
2326			context = jQuerySub( context );
2327		}
2328
2329		return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
2330	};
2331	jQuerySub.fn.init.prototype = jQuerySub.fn;
2332	var rootjQuerySub = jQuerySub(document);
2333	migrateWarn( "jQuery.sub() is deprecated" );
2334	return jQuerySub;
2335};
2336
2337
2338// Ensure that $.ajax gets the new parseJSON defined in core.js
2339jQuery.ajaxSetup({
2340	converters: {
2341		"text json": jQuery.parseJSON
2342	}
2343});
2344
2345
2346var oldFnData = jQuery.fn.data;
2347
2348jQuery.fn.data = function( name ) {
2349	var ret, evt,
2350		elem = this[0];
2351
2352	// Handles 1.7 which has this behavior and 1.8 which doesn't
2353	if ( elem && name === "events" && arguments.length === 1 ) {
2354		ret = jQuery.data( elem, name );
2355		evt = jQuery._data( elem, name );
2356		if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
2357			migrateWarn("Use of jQuery.fn.data('events') is deprecated");
2358			return evt;
2359		}
2360	}
2361	return oldFnData.apply( this, arguments );
2362};
2363
2364
2365var rscriptType = /\/(java|ecma)script/i,
2366	oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
2367
2368jQuery.fn.andSelf = function() {
2369	migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
2370	return oldSelf.apply( this, arguments );
2371};
2372
2373// Since jQuery.clean is used internally on older versions, we only shim if it's missing
2374if ( !jQuery.clean ) {
2375	jQuery.clean = function( elems, context, fragment, scripts ) {
2376		// Set context per 1.8 logic
2377		context = context || document;
2378		context = !context.nodeType && context[0] || context;
2379		context = context.ownerDocument || context;
2380
2381		migrateWarn("jQuery.clean() is deprecated");
2382
2383		var i, elem, handleScript, jsTags,
2384			ret = [];
2385
2386		jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
2387
2388		// Complex logic lifted directly from jQuery 1.8
2389		if ( fragment ) {
2390			// Special handling of each script element
2391			handleScript = function( elem ) {
2392				// Check if we consider it executable
2393				if ( !elem.type || rscriptType.test( elem.type ) ) {
2394					// Detach the script and store it in the scripts array (if provided) or the fragment
2395					// Return truthy to indicate that it has been handled
2396					return scripts ?
2397						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
2398						fragment.appendChild( elem );
2399				}
2400			};
2401
2402			for ( i = 0; (elem = ret[i]) != null; i++ ) {
2403				// Check if we're done after handling an executable script
2404				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
2405					// Append to fragment and handle embedded scripts
2406					fragment.appendChild( elem );
2407					if ( typeof elem.getElementsByTagName !== "undefined" ) {
2408						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
2409						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
2410
2411						// Splice the scripts into ret after their former ancestor and advance our index beyond them
2412						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
2413						i += jsTags.length;
2414					}
2415				}
2416			}
2417		}
2418
2419		return ret;
2420	};
2421}
2422
2423var eventAdd = jQuery.event.add,
2424	eventRemove = jQuery.event.remove,
2425	eventTrigger = jQuery.event.trigger,
2426	oldToggle = jQuery.fn.toggle,
2427	oldLive = jQuery.fn.live,
2428	oldDie = jQuery.fn.die,
2429	ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
2430	rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
2431	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
2432	hoverHack = function( events ) {
2433		if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
2434			return events;
2435		}
2436		if ( rhoverHack.test( events ) ) {
2437			migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
2438		}
2439		return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2440	};
2441
2442// Event props removed in 1.9, put them back if needed; no practical way to warn them
2443if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
2444	jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
2445}
2446
2447// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
2448if ( jQuery.event.dispatch ) {
2449	migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
2450}
2451
2452// Support for 'hover' pseudo-event and ajax event warnings
2453jQuery.event.add = function( elem, types, handler, data, selector ){
2454	if ( elem !== document && rajaxEvent.test( types ) ) {
2455		migrateWarn( "AJAX events should be attached to document: " + types );
2456	}
2457	eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
2458};
2459jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
2460	eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
2461};
2462
2463jQuery.fn.error = function() {
2464	var args = Array.prototype.slice.call( arguments, 0);
2465	migrateWarn("jQuery.fn.error() is deprecated");
2466	args.splice( 0, 0, "error" );
2467	if ( arguments.length ) {
2468		return this.bind.apply( this, args );
2469	}
2470	// error event should not bubble to window, although it does pre-1.7
2471	this.triggerHandler.apply( this, args );
2472	return this;
2473};
2474
2475jQuery.fn.toggle = function( fn, fn2 ) {
2476
2477	// Don't mess with animation or css toggles
2478	if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
2479		return oldToggle.apply( this, arguments );
2480	}
2481	migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
2482
2483	// Save reference to arguments for access in closure
2484	var args = arguments,
2485		guid = fn.guid || jQuery.guid++,
2486		i = 0,
2487		toggler = function( event ) {
2488			// Figure out which function to execute
2489			var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2490			jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2491
2492			// Make sure that clicks stop
2493			event.preventDefault();
2494
2495			// and execute the function
2496			return args[ lastToggle ].apply( this, arguments ) || false;
2497		};
2498
2499	// link all the functions, so any of them can unbind this click handler
2500	toggler.guid = guid;
2501	while ( i < args.length ) {
2502		args[ i++ ].guid = guid;
2503	}
2504
2505	return this.click( toggler );
2506};
2507
2508jQuery.fn.live = function( types, data, fn ) {
2509	migrateWarn("jQuery.fn.live() is deprecated");
2510	if ( oldLive ) {
2511		return oldLive.apply( this, arguments );
2512	}
2513	jQuery( this.context ).on( types, this.selector, data, fn );
2514	return this;
2515};
2516
2517jQuery.fn.die = function( types, fn ) {
2518	migrateWarn("jQuery.fn.die() is deprecated");
2519	if ( oldDie ) {
2520		return oldDie.apply( this, arguments );
2521	}
2522	jQuery( this.context ).off( types, this.selector || "**", fn );
2523	return this;
2524};
2525
2526// Turn global events into document-triggered events
2527jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){
2528	if ( !elem && !rajaxEvent.test( event ) ) {
2529		migrateWarn( "Global events are undocumented and deprecated" );
2530	}
2531	return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );
2532};
2533jQuery.each( ajaxEvents.split("|"),
2534	function( _, name ) {
2535		jQuery.event.special[ name ] = {
2536			setup: function() {
2537				var elem = this;
2538
2539				// The document needs no shimming; must be !== for oldIE
2540				if ( elem !== document ) {
2541					jQuery.event.add( document, name + "." + jQuery.guid, function() {
2542						jQuery.event.trigger( name, null, elem, true );
2543					});
2544					jQuery._data( this, name, jQuery.guid++ );
2545				}
2546				return false;
2547			},
2548			teardown: function() {
2549				if ( this !== document ) {
2550					jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
2551				}
2552				return false;
2553			}
2554		};
2555	}
2556);
2557
2558
2559})( jQuery, window );
2560
2561/*
2562 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
2563 *
2564 * Uses the built in easing capabilities added In jQuery 1.1
2565 * to offer multiple easing options
2566 *
2567 * TERMS OF USE - jQuery Easing
2568 * 
2569 * Open source under the BSD License. 
2570 * 
2571 * Copyright © 2008 George McGinley Smith
2572 * All rights reserved.
2573 * 
2574 * Redistribution and use in source and binary forms, with or without modification, 
2575 * are permitted provided that the following conditions are met:
2576 * 
2577 * Redistributions of source code must retain the above copyright notice, this list of 
2578 * conditions and the following disclaimer.
2579 * Redistributions in binary form must reproduce the above copyright notice, this list 
2580 * of conditions and the following disclaimer in the documentation and/or other materials 
2581 * provided with the distribution.
2582 * 
2583 * Neither the name of the author nor the names of contributors may be used to endorse 
2584 * or promote products derived from this software without specific prior written permission.
2585 * 
2586 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
2587 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2588 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2589 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,692 bytes, lines 2590-2736
2590 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2591 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
2592 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2593 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
2594 * OF THE POSSIBILITY OF SUCH DAMAGE. 
2595 *
2596*/
2597 
2598// t: current time, b: begInnIng value, c: change In value, d: duration
2599jQuery.easing['jswing'] = jQuery.easing['swing'];
2600 
2601jQuery.extend( jQuery.easing,
2602{
2603    def: 'easeOutQuad',
2604    swing: function (x, t, b, c, d) {
2605        //alert(jQuery.easing.default);
2606        return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
2607    },
2608    easeInQuad: function (x, t, b, c, d) {
2609        return c*(t/=d)*t + b;
2610    },
2611    easeOutQuad: function (x, t, b, c, d) {
2612        return -c *(t/=d)*(t-2) + b;
2613    },
2614    easeInOutQuad: function (x, t, b, c, d) {
2615        if ((t/=d/2) < 1) return c/2*t*t + b;
2616        return -c/2 * ((--t)*(t-2) - 1) + b;
2617    },
2618    easeInCubic: function (x, t, b, c, d) {
2619        return c*(t/=d)*t*t + b;
2620    },
2621    easeOutCubic: function (x, t, b, c, d) {
2622        return c*((t=t/d-1)*t*t + 1) + b;
2623    },
2624    easeInOutCubic: function (x, t, b, c, d) {
2625        if ((t/=d/2) < 1) return c/2*t*t*t + b;
2626        return c/2*((t-=2)*t*t + 2) + b;
2627    },
2628    easeInQuart: function (x, t, b, c, d) {
2629        return c*(t/=d)*t*t*t + b;
2630    },
2631    easeOutQuart: function (x, t, b, c, d) {
2632        return -c * ((t=t/d-1)*t*t*t - 1) + b;
2633    },
2634    easeInOutQuart: function (x, t, b, c, d) {
2635        if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
2636        return -c/2 * ((t-=2)*t*t*t - 2) + b;
2637    },
2638    easeInQuint: function (x, t, b, c, d) {
2639        return c*(t/=d)*t*t*t*t + b;
2640    },
2641    easeOutQuint: function (x, t, b, c, d) {
2642        return c*((t=t/d-1)*t*t*t*t + 1) + b;
2643    },
2644    easeInOutQuint: function (x, t, b, c, d) {
2645        if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
2646        return c/2*((t-=2)*t*t*t*t + 2) + b;
2647    },
2648    easeInSine: function (x, t, b, c, d) {
2649        return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
2650    },
2651    easeOutSine: function (x, t, b, c, d) {
2652        return c * Math.sin(t/d * (Math.PI/2)) + b;
2653    },
2654    easeInOutSine: function (x, t, b, c, d) {
2655        return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
2656    },
2657    easeInExpo: function (x, t, b, c, d) {
2658        return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
2659    },
2660    easeOutExpo: function (x, t, b, c, d) {
2661        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
2662    },
2663
2664    easeInOutExpo: function (x, t, b, c, d) {
2665        if (t==0) return b;
2666        if (t==d) return b+c;
2667        if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
2668        return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
2669    },
2670    easeInCirc: function (x, t, b, c, d) {
2671        return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
2672    },
2673    easeOutCirc: function (x, t, b, c, d) {
2674        return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
2675    },
2676    easeInOutCirc: function (x, t, b, c, d) {
2677        if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
2678        return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
2679    },
2680    easeInElastic: function (x, t, b, c, d) {
2681        var s=1.70158;var p=0;var a=c;
2682        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
2683        if (a < Math.abs(c)) { a=c; var s=p/4; }
2684        else var s = p/(2*Math.PI) * Math.asin (c/a);
2685        return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
2686    },
2687    easeOutElastic: function (x, t, b, c, d) {
2688        var s=1.70158;var p=0;var a=c;
2689        if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
2690        if (a < Math.abs(c)) { a=c; var s=p/4; }
2691        else var s = p/(2*Math.PI) * Math.asin (c/a);
2692        return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
2693    },
2694    easeInOutElastic: function (x, t, b, c, d) {
2695        var s=1.70158;var p=0;var a=c;
2696        if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
2697        if (a < Math.abs(c)) { a=c; var s=p/4; }
2698        else var s = p/(2*Math.PI) * Math.asin (c/a);
2699        if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
2700        return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
2701    },
2702    easeInBack: function (x, t, b, c, d, s) {
2703        if (s == undefined) s = 1.70158;
2704        return c*(t/=d)*t*((s+1)*t - s) + b;
2705    },
2706    easeOutBack: function (x, t, b, c, d, s) {
2707        if (s == undefined) s = 1.70158;
2708        return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
2709    },
2710    easeInOutBack: function (x, t, b, c, d, s) {
2711        if (s == undefined) s = 1.70158; 
2712        if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
2713        return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
2714    },
2715    easeInBounce: function (x, t, b, c, d) {
2716        return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
2717    },
2718    easeOutBounce: function (x, t, b, c, d) {
2719        if ((t/=d) < (1/2.75)) {
2720            return c*(7.5625*t*t) + b;
2721        } else if (t < (2/2.75)) {
2722            return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
2723        } else if (t < (2.5/2.75)) {
2724            return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
2725        } else {
2726            return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
2727        }
2728    },
2729    easeInOutBounce: function (x, t, b, c, d) {
2730        if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
2731        return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
2732    }
2733});
2734 
2735/*
2736 *
2737 * TERMS OF USE - EASING EQUATIONS
2738 * 
2739 * Open source under the BSD License. 
2740 * 
2741 * Copyright © 2001 Robert Penner
2742 * All rights reserved.
2743 * 
2744 * Redistribution and use in source and binary forms, with or without modification, 
2745 * are permitted provided that the following conditions are met:
2746 * 
2747 * Redistributions of source code must retain the above copyright notice, this list of 
2748 * conditions and the following disclaimer.
2749 * Redistributions in binary form must reproduce the above copyright notice, this list 
2750 * of conditions and the following disclaimer in the documentation and/or other materials 
2751 * provided with the distribution.
2752 * 
2753 * Neither the name of the author nor the names of contributors may be used to endorse 
2754 * or promote products derived from this software without specific prior written permission.
2755 * 
2756 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
2757 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2758 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2759 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2760 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2761 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
2762 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2763 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
2764 * OF THE POSSIBILITY OF SUCH DAMAGE. 
2765 *
2766 */
2767/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
2768 * Licensed under the MIT License (LICENSE.txt).
2769 *
2770 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
2771 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
2772 * Thanks to: Seamus Leahy for adding deltaX and deltaY
2773 *
2774 * Version: 3.0.6
2775 * 
2776 * Requires: 1.2.2+
2777 */
2778(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.removeEventListener)for(var a=b.length;a;)this.removeEventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
2779
2780/**
2781  * Rhinoslider 1.05
2782  * http://rhinoslider.com/
2783  *
2784  * Copyright 2013: Sebastian Pontow, Rene Maas (http://renemaas.de/)
2785  * Dual licensed under the MIT or GPL Version 2 licenses.
2786  * http://rhinoslider.com/license/
2787  */
2788
2789(function($,window,undefined){$.extend($.easing,{def:'out',out:function(none,currentTime,startValue,endValue,totalTime){return-endValue*(currentTime/=totalTime)*(currentTime-2)+startValue;},kick:function(none,currentTime,startValue,endValue,totalTime){if((currentTime/=totalTime/2)<1){return endValue/2*Math.pow(2,10*(currentTime-1))+startValue;}
2790return endValue/2*(-Math.pow(2,-10*--currentTime)+2)+startValue;},shuffle:function(none,currentTime,startValue,endValue,totalTime){if((currentTime/=totalTime/2)<1){return endValue/2*currentTime*currentTime*currentTime*currentTime*currentTime+startValue;}
2791return endValue/2*((currentTime-=2)*currentTime*currentTime*currentTime*currentTime+2)+startValue;}});var rhinoSlider=function(element,opts){var
2792settings=$.extend({},$.fn.rhinoslider.defaults,opts),$slider=$(element),effects=$.fn.rhinoslider.effects,preparations=$.fn.rhinoslider.preparations,vars={isPlaying:false,intervalAutoPlay:false,active:'',next:'',container:'',items:'',buttons:[],prefix:'rhino-',playedArray:[],playedCounter:0,original:element};settings.callBeforeInit();var
2793setUpSettings=function(settings){settings.controlsPrevNext=String(settings.controlsPrevNext)=='true'?true:false;settings.controlsKeyboard=String(settings.controlsKeyboard)=='true'?true:false;settings.controlsMousewheel=String(settings.controlsMousewheel)=='true'?true:false;settings.controlsPlayPause=String(settings.controlsPlayPause)=='true'?true:false;settings.pauseOnHover=String(settings.pauseOnHover)=='true'?true:false;settings.animateActive=String(settings.animateActive)=='true'?true:false;settings.autoPlay=String(settings.autoPlay)=='true'?true:false;settings.cycled=String(settings.cycled)=='true'?true:false;settings.showTime=parseInt(settings.showTime,10);settings.effectTime=parseInt(settings.effectTime,10);settings.controlFadeTime=parseInt(settings.controlFadeTime,10);settings.captionsFadeTime=parseInt(settings.captionsFadeTime,10);tmpShiftValue=settings.shiftValue;tmpParts=settings.parts;settings.shiftValue=[];settings.parts=[];return settings;},init=function($slider,settings,vars){settings=setUpSettings(settings);
2793$slider.wrap('<div class="'+vars.prefix+'container">');vars.container=$slider.parent('.'+vars.prefix+'container');vars.isPlaying=settings.autoPlay;var buttons='';if(settings.controlsPrevNext){vars.container.addClass(vars.prefix+'controls-prev-next');buttons='<a class="'+vars.prefix+'prev '+vars.prefix+'btn">'+settings.prevText+'</a><a class="'+vars.prefix+'next '+vars.prefix+'btn">'+settings.nextText+'</a>';vars.container.append(buttons);vars.buttons.prev=vars.container.find('.'+vars.prefix+'prev');vars.buttons.next=vars.container.find('.'+vars.prefix+'next');vars.buttons.prev.click(function(){prev($slider,settings);if(settings.autoPlay){pause();}});vars.buttons.next.click(function(){next($slider,settings);if(settings.autoPlay){pause();}});}
2794if(settings.controlsPlayPause){vars.container.addClass(vars.prefix+'controls-play-pause');buttons=settings.autoPlay?'<a class="'+vars.prefix+'toggle '+vars.prefix+'pause '+vars.prefix+'btn">'+settings.pauseText+'</a>':'<a class="'+vars.prefix+'toggle '+vars.prefix+'play '+vars.prefix+'btn">'+settings.playText+'</a>';vars.container.append(buttons);vars.buttons.play=vars.container.find('.'+vars.prefix+'toggle');vars.buttons.play.click(function(){if(vars.isPlaying===false){play();}else{pause();}});}
2795vars.container.find('.'+vars.prefix+'btn').css({position:'absolute',display:'block',cursor:'pointer'});if(settings.showControls!=='always'){var allControls=vars.container.find('.'+vars.prefix+'btn');allControls.stop(true,true).fadeOut(0);if(settings.showControls==='hover'){vars.container.mouseenter(function(){allControls.stop(true,true).fadeIn(settings.controlFadeTime);}).mouseleave(function(){allControls.delay(200).fadeOut(settings.controlFadeTime);});}}
2796if(settings.showControls!=='never'){vars.container.addClass(vars.prefix+'show-controls');}
2797vars.items=$slider.children();vars.items.addClass(vars.prefix+'item');vars.items.first().addClass(vars.prefix+'active');var sliderStyles=settings.styles.split(','),style;$.each(sliderStyles,function(i,cssAttribute){style=$.trim(cssAttribute);vars.container.css(style,$slider.css(style));$slider.css(style,' ');switch(style){case'width':case'height':$slider.css(style,'100%');break;}});if(vars.container.css('position')=='static'){vars.container.css('position','relative');}
2798$slider.css({top:'auto',left:'auto',position:'relative'});vars.items.css({margin:0,width:$slider.css('width'),height:$slider.css('height'),position:'absolute',top:0,left:0,zIndex:0,opacity:0,overflow:'hidden'});vars.items.each(function(i){$(this).attr('id',vars.prefix+'item'+i);});if(settings.showBullets!=='never'){vars.container.addClass(vars.prefix+'show-bullets');var navi='<ol class="'+vars.prefix+'bullets">';vars.items.each(function(i){var $item=$(this);var id=vars.prefix+'item'+i;navi=navi+'<li><a id="'+id+'-bullet" class="'+vars.prefix+'bullet">'+parseInt(i+1,10)+'</a></li>';});navi=navi+'</ol>';vars.container.append(navi);vars.navigation=vars.container.find('.'+vars.prefix+'bullets');vars.buttons.bullets=vars.navigation.find('.'+vars.prefix+'bullet');vars.buttons.bullets.first().addClass(vars.prefix+'active-bullet '+vars.prefix+'first-bullet');vars.buttons.bullets.last().addClass(vars.prefix+'last-bullet');vars.buttons.bullets.click(function(){var itemID=$(this).attr('id').replace('-bullet','');var $next=vars.container.find('#'+itemID);var curID=parseInt(vars.navigation.find('.'+vars.prefix+'active-bullet').attr('id').replace('-bullet','').replace(vars.prefix+'item',''),10);var nextID=parseInt(itemID.replace(vars.prefix+'item',''),10);if(curID<nextID){next($slider,settings,$next);}else if(curID>nextID){prev($slider,settings,$next);}else{return false;}
2799if(settings.autoPlay){pause();}});}
2800if(settings.showBullets==='hover'){vars.navigation.hide();vars.container.mouseenter(function(){vars.navigation.stop(true,true).fadeIn(settings.controlFadeTime);}).mouseleave(function(){vars.navigation.delay(200).fadeOut(settings.controlFadeTime);});}
2801if(settings.showCaptions!=='never'){vars.container.addClass(vars.prefix+'show-captions');vars.items.each(function(){var $item=$(this);if($item.children('.'+vars.prefix+'caption').length==0){if($item.children('img').length>0){var title=$.trim($item.children('img:first').attr('title'));if(undefined!=title||''==title){$item.append('<div class="'+vars.prefix+'caption">'+title+'</div>');$item.children('.'+vars.prefix+'caption:empty').remove();}}}});if(settings.showCaptions==='hover'){$('.'+vars.prefix+'caption').hide();vars.container.mouseenter(function(){vars.active.find('.'+vars.prefix+'caption').stop(true,true).fadeTo(settings.captionFadeTime,settings.captionsOpacity);}).mouseleave(function(){vars.active.find('.'+vars.prefix+'caption').delay(200).fadeOut(settings.captionFadeTime);});}else if(settings.showCaptions==='always'){$('.'+vars.prefix+'caption').fadeTo(0,settings.captionsOpacity);}}
2802vars.items.each(function(){$(this).children('img').removeAttr('title');});if(settings.autoPlay){vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);}else{vars.intervalAutoPlay=false;}
2803if(settings.pauseOnHover){vars.container.addClass(vars.prefix+'pause-on-hover');$slider.mouseenter(function(){if(vars.isPlaying){clearInterval(vars.intervalAutoPlay);if(settings.controlsPlayPause){vars.buttons.play.text(settings.playText).removeClass(vars.prefix+'pause').addClass(vars.prefix+'play');}}}).mouseleave(function(){if(vars.isPlaying){vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);if(settings.controlsPlayPause){vars.buttons.play.text(settings.pauseText).removeClass(vars.prefix+'play').addClass(vars.prefix+'pause');}}});}
2804if(settings.controlsKeyboard){vars.container.addClass(vars.prefix+'controls-keyboard');$(document).keyup(function(e){switch(e.keyCode){case 37:pause();prev($slider,settings);break;case 39:pause();next($slider,settings);break;case 80:if(vars.isPlaying===false){play();}else{pause();}
2805break;}});}
2806if(settings.controlsMousewheel){vars.container.addClass(vars.prefix+'controls-mousewheel');if(!$.isFunction($.fn.mousewheel)){alert('$.fn.mousewheel is not a function. Please check that you have the mousewheel-plugin installed properly.');}else{$slider.mousewheel(function(e,delta){e.preventDefault();if(vars.container.hasClass('inProgress')){return false;}
2807var dir=delta>0?'up':'down';if(dir==='up'){pause();prev($slider,settings);}else{pause();next($slider,settings);}});}}
2808vars.active=$slider.find('.'+vars.prefix+'active');vars.active.css({zIndex:1,opacity:1});if(!settings.cycled){vars.items.each(function(){var $item=$(this);if($item.is(':first-child')){$item.addClass(vars.prefix+'firstItem');}
2809if($item.is(':last-child')){$item.addClass(vars.prefix+'lastItem');}});if(vars.active.is(':first-child')&&settings.controlsPrevNext){vars.buttons.prev.addClass('disabled');}
2810if(vars.active.is(':last-child')){if(settings.controlsPrevNext){vars.buttons.next.addClass('disabled');pause();}
2811if(settings.autoPlay){vars.buttons.play.addClass('disabled');}}}
2812if(preparations[settings.effect]==undefined){console.log('Effect for '+settings.effect+' not found.');}else{preparations[settings.effect]($slider,settings,vars);}
2813$slider.data('slider:vars',vars);settings.callBackInit();},isFirst=function($item){return $item.is(':first-child');},isLast=function($item){return $item.is(':last-child');},pause=function(){var vars=$slider.data('slider:vars');clearInterval(vars.intervalAutoPlay);vars.isPlaying=false;if(settings.controlsPlayPause){vars.buttons.play.text(settings.playText).removeClass(vars.prefix+'pause').addClass(vars.prefix+'play');}
2814settings.callBackPause();},play=function(){var vars=$slider.data('slider:vars');vars.intervalAutoPlay=setInterval(function(){next($slider,settings);},settings.showTime);vars.isPlaying=true;if(settings.controlsPlayPause){vars.buttons.play.text(settings.pauseText).removeClass(vars.prefix+'play').addClass(vars.prefix+'pause');}
2815settings.callBackPlay();},prev=function($slider,settings,$next){var vars=$slider.data('slider:vars');if(!settings.cycled&&isFirst(vars.active)){return false;}
2816settings.callBeforePrev();if(vars.container.hasClass('inProgress')){return false;}
2817vars.container.addClass('inProgress');if(!$next){if(settings.randomOrder){var nextID=getRandom(vars);vars.next=vars.container.find('#'+nextID);}else{vars.next=vars.items.first().hasClass(vars.prefix+'active')?vars.items.last():vars.active.prev();}}else{vars.next=$next;}
2818if(vars.next.hasClass(vars.prefix+'active')){return false;}
2819if(settings.showCaptions!=='never'){$('.'+vars.prefix+'caption').stop(true,true).fadeOut(settings.captionsFadeTime);}
2820if(settings.showBullets!=='never'&&settings.changeBullets=='before'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}
2821setTimeout(function(){var params=[];params.settings=settings;params.animateActive=settings.animateActive;params.direction=settings.slidePrevDirection;if(effects[settings.effect]==undefined){console.log('Preparations for '+settings.effect+' not found.');}else{effects[settings.effect]($slider,params,resetElements);}
2822setTimeout(function(){if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}
2823settings.callBackPrev();},settings.effectTime);},settings.captionsFadeTime);if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}},next=function($slider,settings,$next){var vars=$slider.data('slider:vars');if(!settings.cycled&&isLast(vars.active)){return false;}
2824settings.callBeforeNext();if(vars.container.hasClass('inProgress')){return false;}
2825vars.container.addClass('inProgress');if(!$next){if(settings.randomOrder){var nextID=getRandom(vars);vars.next=vars.container.find('#'+nextID);}
2825else{vars.next=vars.items.last().hasClass(vars.prefix+'active')?vars.items.first():vars.active.next();}}else{vars.next=$next;}
2826if(vars.next.hasClass(vars.prefix+'active')){return false;}
2827if(settings.showCaptions!=='never'){$('.'+vars.prefix+'caption').stop(true,true).fadeOut(settings.captionsFadeTime);}
2828if(settings.showBullets!=='never'&&settings.changeBullets=='before'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}
2829setTimeout(function(){var params=[];params.settings=settings;params.animateActive=settings.animateActive;params.direction=settings.slideNextDirection;if(effects[settings.effect]==undefined){console.log('Preparations for '+settings.effect+' not found.');}else{effects[settings.effect]($slider,params,resetElements);}
2830setTimeout(function(){if(settings.showBullets!=='never'&&settings.changeBullets=='after'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}
2831settings.callBackNext();},settings.effectTime);},settings.captionsFadeTime);},getRandom=function(vars){var curID=vars.active.attr('id');var itemCount=vars.items.length;var nextID=vars.prefix+'item'+parseInt((Math.random()*itemCount),10);var nextKey=nextID.replace(vars.prefix+'item','');if(vars.playedCounter>=itemCount){vars.playedCounter=0;vars.playedArray=[];}
2832if(curID==nextID||vars.playedArray[nextKey]===true){return getRandom(vars);}else{vars.playedArray[nextKey]=true;vars.playedCounter++;return nextID;}},resetElements=function($slider,settings){var vars=$slider.data('slider:vars');vars.next.addClass(vars.prefix+'active').css({zIndex:1,top:0,left:0,width:'100%',height:'100%',margin:0,opacity:1});vars.active.css({zIndex:0,top:0,left:0,margin:0,opacity:0}).removeClass(vars.prefix+'active');settings.additionalResets();if(!settings.cycled){if(settings.controlsPrevNext){if(isFirst(vars.next)){vars.buttons.prev.addClass('disabled');}else{vars.buttons.prev.removeClass('disabled');}
2833if(isLast(vars.next)){vars.buttons.next.addClass('disabled');pause();}else{vars.buttons.next.removeClass('disabled');}}
2834if(settings.controlsPlayPause){if(isLast(vars.next)){vars.buttons.play.addClass('disabled');pause();}else{vars.buttons.play.removeClass('disabled');}}}
2835if(settings.showBullets!=='never'){vars.navigation.find('.'+vars.prefix+'active-bullet').removeClass(vars.prefix+'active-bullet');vars.navigation.find('#'+vars.next.attr('id')+'-bullet').addClass(vars.prefix+'active-bullet');}
2836vars.active=vars.next;if(settings.showCaptions!=='never'){vars.active.find('.'+vars.prefix+'caption').stop(true,true).fadeTo(settings.captionsFadeTime,settings.captionsOpacity);}
2837vars.container.removeClass('inProgress');};this.pause=function(){pause();};this.play=function(){play();};this.prev=function($next){prev($slider,settings,$next);};this.next=function($next){next($slider,settings,$next);};this.uninit=function(){pause();vars.container.before($(element).data('slider:original'));$slider.data('slider:vars',null);vars.container.remove();$(element).data('rhinoslider',null);};init($slider,settings,vars);};$.fn.rhinoslider=function(opts){return this.each(function(){var element=$(this);if(element.data('rhinoslider')){return element.data('rhinoslider');}
2838element.data('slider:original',element.clone());var rhinoslider=new rhinoSlider(this,opts);element.data('rhinoslider',rhinoslider);});};$.fn.rhinoslider.defaults={effect:'slide',easing:'swing',randomOrder:false,controlsMousewheel:true,controlsKeyboard:true,controlsPrevNext:true,controlsPlayPause:true,pauseOnHover:true,animateActive:true,autoPlay:false,cycled:true,showTime:3000,effectTime:1000,controlFadeTime:650,captionsFadeTime:250,captionsOpacity:0.7,partDelay:100,shiftValue:'150',parts:'5,3',showCaptions:'never',showBullets:'hover',changeBullets:'after',showControls:'hover',slidePrevDirection:'toLeft',slideNextDirection:'toRight',prevText:'prev',nextText:'next',playText:'play',pauseText:'pause',styles:'position,top,right,bottom,left,margin-top,margin-right,margin-bottom,margin-left,width,height',callBeforeInit:function(){return false;},callBackInit:function(){return false;},callBeforeNext:function(){return false;},callBeforePrev:function(){return false;},callBackNext:function(){return false;},callBackPrev:function(){return false;},callBackPlay:function(){return false;},callBackPause:function(){return false;},additionalResets:function(){return false;}};$.fn.rhinoslider.effects={fade:function($slider,params,callback){var vars=$slider.data('slider:vars');var settings=params.settings;if(settings.animateActive){vars.active.animate({opacity:0}
vendor: 4,925 bytes, lines 2838-2989
2838,settings.effectTime);}
2839vars.next.css({zIndex:2}).animate({opacity:1},settings.effectTime,settings.easing,function(){callback($slider,settings);});}};$.fn.rhinoslider.preparations={fade:function($slider,settings,vars){}};})(jQuery,window);
2840/*! jQuery UI - v1.9.1 - 2012-10-25
2841* http://jqueryui.com
2842* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
2843* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */
2844
2845(function( $, undefined ) {
2846
2847var uuid = 0,
2848	runiqueId = /^ui-id-\d+$/;
2849
2850// prevent duplicate loading
2851// this is only a problem because we proxy existing functions
2852// and we don't want to double proxy them
2853$.ui = $.ui || {};
2854if ( $.ui.version ) {
2855	return;
2856}
2857
2858$.extend( $.ui, {
2859	version: "1.9.1",
2860
2861	keyCode: {
2862		BACKSPACE: 8,
2863		COMMA: 188,
2864		DELETE: 46,
2865		DOWN: 40,
2866		END: 35,
2867		ENTER: 13,
2868		ESCAPE: 27,
2869		HOME: 36,
2870		LEFT: 37,
2871		NUMPAD_ADD: 107,
2872		NUMPAD_DECIMAL: 110,
2873		NUMPAD_DIVIDE: 111,
2874		NUMPAD_ENTER: 108,
2875		NUMPAD_MULTIPLY: 106,
2876		NUMPAD_SUBTRACT: 109,
2877		PAGE_DOWN: 34,
2878		PAGE_UP: 33,
2879		PERIOD: 190,
2880		RIGHT: 39,
2881		SPACE: 32,
2882		TAB: 9,
2883		UP: 38
2884	}
2885});
2886
2887// plugins
2888$.fn.extend({
2889	_focus: $.fn.focus,
2890	focus: function( delay, fn ) {
2891		return typeof delay === "number" ?
2892			this.each(function() {
2893				var elem = this;
2894				setTimeout(function() {
2895					$( elem ).focus();
2896					if ( fn ) {
2897						fn.call( elem );
2898					}
2899				}, delay );
2900			}) :
2901			this._focus.apply( this, arguments );
2902	},
2903
2904	scrollParent: function() {
2905		var scrollParent;
2906		if (($.ui.ie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
2907			scrollParent = this.parents().filter(function() {
2908				return (/(relative|absolute|fixed)/).test($.css(this,'position')) && (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
2909			}).eq(0);
2910		} else {
2911			scrollParent = this.parents().filter(function() {
2912				return (/(auto|scroll)/).test($.css(this,'overflow')+$.css(this,'overflow-y')+$.css(this,'overflow-x'));
2913			}).eq(0);
2914		}
2915
2916		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
2917	},
2918
2919	zIndex: function( zIndex ) {
2920		if ( zIndex !== undefined ) {
2921			return this.css( "zIndex", zIndex );
2922		}
2923
2924		if ( this.length ) {
2925			var elem = $( this[ 0 ] ), position, value;
2926			while ( elem.length && elem[ 0 ] !== document ) {
2927				// Ignore z-index if position is set to a value where z-index is ignored by the browser
2928				// This makes behavior of this function consistent across browsers
2929				// WebKit always returns auto if the element is positioned
2930				position = elem.css( "position" );
2931				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
2932					// IE returns 0 when zIndex is not specified
2933					// other browsers return a string
2934					// we ignore the case of nested elements with an explicit value of 0
2935					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
2936					value = parseInt( elem.css( "zIndex" ), 10 );
2937					if ( !isNaN( value ) && value !== 0 ) {
2938						return value;
2939					}
2940				}
2941				elem = elem.parent();
2942			}
2943		}
2944
2945		return 0;
2946	},
2947
2948	uniqueId: function() {
2949		return this.each(function() {
2950			if ( !this.id ) {
2951				this.id = "ui-id-" + (++uuid);
2952			}
2953		});
2954	},
2955
2956	removeUniqueId: function() {
2957		return this.each(function() {
2958			if ( runiqueId.test( this.id ) ) {
2959				$( this ).removeAttr( "id" );
2960			}
2961		});
2962	}
2963});
2964
2965// support: jQuery <1.8
2966if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
2967	$.each( [ "Width", "Height" ], function( i, name ) {
2968		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
2969			type = name.toLowerCase(),
2970			orig = {
2971				innerWidth: $.fn.innerWidth,
2972				innerHeight: $.fn.innerHeight,
2973				outerWidth: $.fn.outerWidth,
2974				outerHeight: $.fn.outerHeight
2975			};
2976
2977		function reduce( elem, size, border, margin ) {
2978			$.each( side, function() {
2979				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
2980				if ( border ) {
2981					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
2982				}
2983				if ( margin ) {
2984					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
2985				}
2986			});
2987			return size;
2988		}
2989
2990		$.fn[ "inner" + name ] = function( size ) {
2991			if ( size === undefined ) {
2992				return orig[ "inner" + name ].call( this );
2993			}
2994
2995			return this.each(function() {
2996				$( this ).css( type, reduce( this, size ) + "px" );
2997			});
2998		};
2999
3000		$.fn[ "outer" + name] = function( size, margin ) {
3001			if ( typeof size !== "number" ) {
3002				return orig[ "outer" + name ].call( this, size );
3003			}
3004
3005			return this.each(function() {
3006				$( this).css( type, reduce( this, size, true, margin ) + "px" );
3007			});
3008		};
3009	});
3010}
3011
3012// selectors
3013function focusable( element, isTabIndexNotNaN ) {
3014	var map, mapName, img,
3015		nodeName = element.nodeName.toLowerCase();
3016	if ( "area" === nodeName ) {
3017		map = element.parentNode;
3018		mapName = map.name;
3019		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3020			return false;
3021		}
3022		img = $( "img[usemap=#" + mapName + "]" )[0];
3023		return !!img && visible( img );
3024	}
3025	return ( /input|select|textarea|button|object/.test( nodeName ) ?
3026		!element.disabled :
3027		"a" === nodeName ?
3028			element.href || isTabIndexNotNaN :
3029			isTabIndexNotNaN) &&
3030		// the element and all of its ancestors must be visible
3031		visible( element );
3032}
3033
3034function visible( element ) {
3035	return $.expr.filters.visible( element ) &&
3036		!$( element ).parents().andSelf().filter(function() {
3037			return $.css( this, "visibility" ) === "hidden";
3038		}).length;
3039}
3040
3041$.extend( $.expr[ ":" ], {
3042	data: $.expr.createPseudo ?
3043		$.expr.createPseudo(function( dataName ) {
3044			return function( elem ) {
3045				return !!$.data( elem, dataName );
3046			};
3047		}) :
3048		// support: jQuery <1.8
3049		function( elem, i, match ) {
3050			return !!$.data( elem, match[ 3 ] );
3051		},
3052
3053	focusable: function( element ) {
3054		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
3055	},
3056
3057	tabbable: function( element ) {
3058		var tabIndex = $.attr( element, "tabindex" ),
3059			isTabIndexNaN = isNaN( tabIndex );
3060		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
3061	}
3062});
3063
3064// support
3065$(function() {
3066	var body = document.body,
3067		div = body.appendChild( div = document.createElement( "div" ) );
3068
3069	// access offsetHeight before setting the style to prevent a layout bug
3070	// in IE 9 which causes the element to continue to take up space even
3071	// after it is removed from the DOM (#8026)
3072	div.offsetHeight;
3073
3074	$.extend( div.style, {
3075		minHeight: "100px",
3076		height: "auto",
3077		padding: 0,
3078		borderWidth: 0
3079	});
3080
3081	$.support.minHeight = div.offsetHeight === 100;
3082	$.support.selectstart = "onselectstart" in div;
3083
3084	// set display to none to avoid a layout bug in IE
3085	// http://dev.jquery.com/ticket/4014
3086	body.removeChild( div ).style.display = "none";
3087});
3088
3089
3090
3091
3092
3093// deprecated
3094
3095(function() {
3096	var uaMatch = /msie ([\w.]+)/.exec( navigator.userAgent.toLowerCase() ) || [];
3097	$.ui.ie = uaMatch.length ? true : false;
3098	$.ui.ie6 = parseFloat( uaMatch[ 1 ], 10 ) === 6;
3099})();
3100
3101$.fn.extend({
3102	disableSelection: function() {
3103		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
3104			".ui-disableSelection", function( event ) {
3105				event.preventDefault();
3106			});
3107	},
3108
3109	enableSelection: function() {
3110		return this.unbind( ".ui-disableSelection" );
3111	}
3112});
3113
3114$.extend( $.ui, {
3115	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
3116	plugin: {
3117		add: function( module, option, set ) {
3118			var i,
3119				proto = $.ui[ module ].prototype;
3120			for ( i in set ) {
3121				proto.plugins[ i ] = proto.plugins[ i ] || [];
3122				proto.plugins[ i ].push( [ option, set[ i ] ] );
3123			}
3124		},
3125		call: function( instance, name, args ) {
3126			var i,
3127				set = instance.plugins[ name ];
3128			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
3129				return;
3130			}
3131
3132			for ( i = 0; i < set.length; i++ ) {
3133				if ( instance.options[ set[ i ][ 0 ] ] ) {
3134					set[ i ][ 1 ].apply( instance.element, args );
3135				}
3136			}
3137		}
3138	},
3139
3140	contains: $.contains,
3141
3142	// only used by resizable
3143	hasScroll: function( el, a ) {
3144
3145		//If overflow is hidden, the element might have extra content, but the user wants to hide it
3146		if ( $( el ).css( "overflow" ) === "hidden") {
3147			return false;
3148		}
3149
3150		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3151			has = false;
3152
3153		if ( el[ scroll ] > 0 ) {
3154			return true;
3155		}
3156
3157		// TODO: determine which cases actually cause this to happen
3158		// if the element doesn't have the scroll set, see if it's possible to
3159		// set the scroll
3160		el[ scroll ] = 1;
3161		has = ( el[ scroll ] > 0 );
3162		el[ scroll ] = 0;
3163		return has;
3164	},
3165
3166	// these are odd functions, fix the API or move into individual plugins
3167	isOverAxis: function( x, reference, size ) {
3168		//Determines when x coordinate is over "b" element axis
3169		return ( x > reference ) && ( x < ( reference + size ) );
3170	},
3171	isOver: function( y, x, top, left, height, width ) {
3172		//Determines when x, y coordinates is over "b" element
3173		return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
3174	}
3175});
3176
3177})( jQuery );
3178
3179(function( $, undefined ) {
3180
3181var uuid = 0,
3182	slice = Array.prototype.slice,
3183	_cleanData = $.cleanData;
3184$.cleanData = function( elems ) {
3185	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
3186		try {
3187			$( elem ).triggerHandler( "remove" );
3188		// http://bugs.jquery.com/ticket/8235
3189		} catch( e ) {}
3190	}
3191	_cleanData( elems );
3192};
3193
3194$.widget = function( name, base, prototype ) {
3195	var fullName, existingConstructor, constructor, basePrototype,
3196		namespace = name.split( "." )[ 0 ];
3197
3198	name = name.split( "." )[ 1 ];
3199	fullName = namespace + "-" + name;
3200
3201	if ( !prototype ) {
3202		prototype = base;
3203		base = $.Widget;
3204	}
3205
3206	// create selector for plugin
3207	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
3208		return !!$.data( elem, fullName );
3209	};
3210
3211	$[ namespace ] = $[ namespace ] || {};
3212	existingConstructor = $[ namespace ][ name ];
3213	constructor = $[ namespace ][ name ] = function( options, element ) {
3214		// allow instantiation without "new" keyword
3215		if ( !this._createWidget ) {
3216			return new constructor( options, element );
3217		}
3218
3219		// allow instantiation without initializing for simple inheritance
3220		// must use "new" keyword (the code above always passes args)
3221		if ( arguments.length ) {
3222			this._createWidget( options, element );
3223		}
3224	};
3225	// extend with the existing constructor to carry over any static properties
3226	$.extend( constructor, existingConstructor, {
3227		version: prototype.version,
3228		// copy the object used to create the prototype in case we need to
3229		// redefine the widget later
3230		_proto: $.extend( {}, prototype ),
3231		// track widgets that inherit from this widget in case this widget is
3232		// redefined after a widget inherits from it
3233		_childConstructors: []
3234	});
3235
3236	basePrototype = new base();
3237	// we need to make the options hash a property directly on the new instance
3238	// otherwise we'll modify the options hash on the prototype that we're
3239	// inheriting from
3240	basePrototype.options = $.widget.extend( {}, basePrototype.options );
3241	$.each( prototype, function( prop, value ) {
3242		if ( $.isFunction( value ) ) {
3243			prototype[ prop ] = (function() {
3244				var _super = function() {
3245						return base.prototype[ prop ].apply( this, arguments );
3246					},
3247					_superApply = function( args ) {
3248						return base.prototype[ prop ].apply( this, args );
3249					};
3250				return function() {
3251					var __super = this._super,
3252						__superApply = this._superApply,
3253						returnValue;
3254
3255					this._super = _super;
3256					this._superApply = _superApply;
3257
3258					returnValue = value.apply( this, arguments );
3259
3260					this._super = __super;
3261					this._superApply = __superApply;
3262
3263					return returnValue;
3264				};
3265			})();
3266		}
3267	});
3268	constructor.prototype = $.widget.extend( basePrototype, {
3269		// TODO: remove support for widgetEventPrefix
3270		// always use the name + a colon as the prefix, e.g., draggable:start
3271		// don't prefix for widgets that aren't DOM-based
3272		widgetEventPrefix: basePrototype.widgetEventPrefix || name
3273	}, prototype, {
3274		constructor: constructor,
3275		namespace: namespace,
3276		widgetName: name,
3277		// TODO remove widgetBaseClass, see #8155
3278		widgetBaseClass: fullName,
3279		widgetFullName: fullName
3280	});
3281
3282	// If this widget is being redefined then we need to find all widgets that
3283	// are inheriting from it and redefine all of them so that they inherit from
3284	// the new version of this widget. We're essentially trying to replace one
3285	// level in the prototype chain.
vendor: 10,899 bytes, lines 3286-3666
3286	if ( existingConstructor ) {
3287		$.each( existingConstructor._childConstructors, function( i, child ) {
3288			var childPrototype = child.prototype;
3289
3290			// redefine the child widget using the same prototype that was
3291			// originally used, but inherit from the new version of the base
3292			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
3293		});
3294		// remove the list of existing child constructors from the old constructor
3295		// so the old child constructors can be garbage collected
3296		delete existingConstructor._childConstructors;
3297	} else {
3298		base._childConstructors.push( constructor );
3299	}
3300
3301	$.widget.bridge( name, constructor );
3302};
3303
3304$.widget.extend = function( target ) {
3305	var input = slice.call( arguments, 1 ),
3306		inputIndex = 0,
3307		inputLength = input.length,
3308		key,
3309		value;
3310	for ( ; inputIndex < inputLength; inputIndex++ ) {
3311		for ( key in input[ inputIndex ] ) {
3312			value = input[ inputIndex ][ key ];
3313			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
3314				// Clone objects
3315				if ( $.isPlainObject( value ) ) {
3316					target[ key ] = $.isPlainObject( target[ key ] ) ?
3317						$.widget.extend( {}, target[ key ], value ) :
3318						// Don't extend strings, arrays, etc. with objects
3319						$.widget.extend( {}, value );
3320				// Copy everything else by reference
3321				} else {
3322					target[ key ] = value;
3323				}
3324			}
3325		}
3326	}
3327	return target;
3328};
3329
3330$.widget.bridge = function( name, object ) {
3331	var fullName = object.prototype.widgetFullName;
3332	$.fn[ name ] = function( options ) {
3333		var isMethodCall = typeof options === "string",
3334			args = slice.call( arguments, 1 ),
3335			returnValue = this;
3336
3337		// allow multiple hashes to be passed on init
3338		options = !isMethodCall && args.length ?
3339			$.widget.extend.apply( null, [ options ].concat(args) ) :
3340			options;
3341
3342		if ( isMethodCall ) {
3343			this.each(function() {
3344				var methodValue,
3345					instance = $.data( this, fullName );
3346				if ( !instance ) {
3347					return $.error( "cannot call methods on " + name + " prior to initialization; " +
3348						"attempted to call method '" + options + "'" );
3349				}
3350				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
3351					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
3352				}
3353				methodValue = instance[ options ].apply( instance, args );
3354				if ( methodValue !== instance && methodValue !== undefined ) {
3355					returnValue = methodValue && methodValue.jquery ?
3356						returnValue.pushStack( methodValue.get() ) :
3357						methodValue;
3358					return false;
3359				}
3360			});
3361		} else {
3362			this.each(function() {
3363				var instance = $.data( this, fullName );
3364				if ( instance ) {
3365					instance.option( options || {} )._init();
3366				} else {
3367					new object( options, this );
3368				}
3369			});
3370		}
3371
3372		return returnValue;
3373	};
3374};
3375
3376$.Widget = function( /* options, element */ ) {};
3377$.Widget._childConstructors = [];
3378
3379$.Widget.prototype = {
3380	widgetName: "widget",
3381	widgetEventPrefix: "",
3382	defaultElement: "<div>",
3383	options: {
3384		disabled: false,
3385
3386		// callbacks
3387		create: null
3388	},
3389	_createWidget: function( options, element ) {
3390		element = $( element || this.defaultElement || this )[ 0 ];
3391		this.element = $( element );
3392		this.uuid = uuid++;
3393		this.eventNamespace = "." + this.widgetName + this.uuid;
3394		this.options = $.widget.extend( {},
3395			this.options,
3396			this._getCreateOptions(),
3397			options );
3398
3399		this.bindings = $();
3400		this.hoverable = $();
3401		this.focusable = $();
3402
3403		if ( element !== this ) {
3404			// 1.9 BC for #7810
3405			// TODO remove dual storage
3406			$.data( element, this.widgetName, this );
3407			$.data( element, this.widgetFullName, this );
3408			this._on( this.element, {
3409				remove: function( event ) {
3410					if ( event.target === element ) {
3411						this.destroy();
3412					}
3413				}
3414			});
3415			this.document = $( element.style ?
3416				// element within the document
3417				element.ownerDocument :
3418				// element is window or document
3419				element.document || element );
3420			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
3421		}
3422
3423		this._create();
3424		this._trigger( "create", null, this._getCreateEventData() );
3425		this._init();
3426	},
3427	_getCreateOptions: $.noop,
3428	_getCreateEventData: $.noop,
3429	_create: $.noop,
3430	_init: $.noop,
3431
3432	destroy: function() {
3433		this._destroy();
3434		// we can probably remove the unbind calls in 2.0
3435		// all event bindings should go through this._on()
3436		this.element
3437			.unbind( this.eventNamespace )
3438			// 1.9 BC for #7810
3439			// TODO remove dual storage
3440			.removeData( this.widgetName )
3441			.removeData( this.widgetFullName )
3442			// support: jquery <1.6.3
3443			// http://bugs.jquery.com/ticket/9413
3444			.removeData( $.camelCase( this.widgetFullName ) );
3445		this.widget()
3446			.unbind( this.eventNamespace )
3447			.removeAttr( "aria-disabled" )
3448			.removeClass(
3449				this.widgetFullName + "-disabled " +
3450				"ui-state-disabled" );
3451
3452		// clean up events and states
3453		this.bindings.unbind( this.eventNamespace );
3454		this.hoverable.removeClass( "ui-state-hover" );
3455		this.focusable.removeClass( "ui-state-focus" );
3456	},
3457	_destroy: $.noop,
3458
3459	widget: function() {
3460		return this.element;
3461	},
3462
3463	option: function( key, value ) {
3464		var options = key,
3465			parts,
3466			curOption,
3467			i;
3468
3469		if ( arguments.length === 0 ) {
3470			// don't return a reference to the internal hash
3471			return $.widget.extend( {}, this.options );
3472		}
3473
3474		if ( typeof key === "string" ) {
3475			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
3476			options = {};
3477			parts = key.split( "." );
3478			key = parts.shift();
3479			if ( parts.length ) {
3480				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
3481				for ( i = 0; i < parts.length - 1; i++ ) {
3482					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
3483					curOption = curOption[ parts[ i ] ];
3484				}
3485				key = parts.pop();
3486				if ( value === undefined ) {
3487					return curOption[ key ] === undefined ? null : curOption[ key ];
3488				}
3489				curOption[ key ] = value;
3490			} else {
3491				if ( value === undefined ) {
3492					return this.options[ key ] === undefined ? null : this.options[ key ];
3493				}
3494				options[ key ] = value;
3495			}
3496		}
3497
3498		this._setOptions( options );
3499
3500		return this;
3501	},
3502	_setOptions: function( options ) {
3503		var key;
3504
3505		for ( key in options ) {
3506			this._setOption( key, options[ key ] );
3507		}
3508
3509		return this;
3510	},
3511	_setOption: function( key, value ) {
3512		this.options[ key ] = value;
3513
3514		if ( key === "disabled" ) {
3515			this.widget()
3516				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
3517				.attr( "aria-disabled", value );
3518			this.hoverable.removeClass( "ui-state-hover" );
3519			this.focusable.removeClass( "ui-state-focus" );
3520		}
3521
3522		return this;
3523	},
3524
3525	enable: function() {
3526		return this._setOption( "disabled", false );
3527	},
3528	disable: function() {
3529		return this._setOption( "disabled", true );
3530	},
3531
3532	_on: function( element, handlers ) {
3533		var delegateElement,
3534			instance = this;
3535		// no element argument, shuffle and use this.element
3536		if ( !handlers ) {
3537			handlers = element;
3538			element = this.element;
3539			delegateElement = this.widget();
3540		} else {
3541			// accept selectors, DOM elements
3542			element = delegateElement = $( element );
3543			this.bindings = this.bindings.add( element );
3544		}
3545
3546		$.each( handlers, function( event, handler ) {
3547			function handlerProxy() {
3548				// allow widgets to customize the disabled handling
3549				// - disabled as an array instead of boolean
3550				// - disabled class as method for disabling individual parts
3551				if ( instance.options.disabled === true ||
3552						$( this ).hasClass( "ui-state-disabled" ) ) {
3553					return;
3554				}
3555				return ( typeof handler === "string" ? instance[ handler ] : handler )
3556					.apply( instance, arguments );
3557			}
3558
3559			// copy the guid so direct unbinding works
3560			if ( typeof handler !== "string" ) {
3561				handlerProxy.guid = handler.guid =
3562					handler.guid || handlerProxy.guid || $.guid++;
3563			}
3564
3565			var match = event.match( /^(\w+)\s*(.*)$/ ),
3566				eventName = match[1] + instance.eventNamespace,
3567				selector = match[2];
3568			if ( selector ) {
3569				delegateElement.delegate( selector, eventName, handlerProxy );
3570			} else {
3571				element.bind( eventName, handlerProxy );
3572			}
3573		});
3574	},
3575
3576	_off: function( element, eventName ) {
3577		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
3578		element.unbind( eventName ).undelegate( eventName );
3579	},
3580
3581	_delay: function( handler, delay ) {
3582		function handlerProxy() {
3583			return ( typeof handler === "string" ? instance[ handler ] : handler )
3584				.apply( instance, arguments );
3585		}
3586		var instance = this;
3587		return setTimeout( handlerProxy, delay || 0 );
3588	},
3589
3590	_hoverable: function( element ) {
3591		this.hoverable = this.hoverable.add( element );
3592		this._on( element, {
3593			mouseenter: function( event ) {
3594				$( event.currentTarget ).addClass( "ui-state-hover" );
3595			},
3596			mouseleave: function( event ) {
3597				$( event.currentTarget ).removeClass( "ui-state-hover" );
3598			}
3599		});
3600	},
3601
3602	_focusable: function( element ) {
3603		this.focusable = this.focusable.add( element );
3604		this._on( element, {
3605			focusin: function( event ) {
3606				$( event.currentTarget ).addClass( "ui-state-focus" );
3607			},
3608			focusout: function( event ) {
3609				$( event.currentTarget ).removeClass( "ui-state-focus" );
3610			}
3611		});
3612	},
3613
3614	_trigger: function( type, event, data ) {
3615		var prop, orig,
3616			callback = this.options[ type ];
3617
3618		data = data || {};
3619		event = $.Event( event );
3620		event.type = ( type === this.widgetEventPrefix ?
3621			type :
3622			this.widgetEventPrefix + type ).toLowerCase();
3623		// the original event may come from any element
3624		// so we need to reset the target on the new event
3625		event.target = this.element[ 0 ];
3626
3627		// copy original event properties over to the new event
3628		orig = event.originalEvent;
3629		if ( orig ) {
3630			for ( prop in orig ) {
3631				if ( !( prop in event ) ) {
3632					event[ prop ] = orig[ prop ];
3633				}
3634			}
3635		}
3636
3637		this.element.trigger( event, data );
3638		return !( $.isFunction( callback ) &&
3639			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
3640			event.isDefaultPrevented() );
3641	}
3642};
3643
3644$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
3645	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
3646		if ( typeof options === "string" ) {
3647			options = { effect: options };
3648		}
3649		var hasOptions,
3650			effectName = !options ?
3651				method :
3652				options === true || typeof options === "number" ?
3653					defaultEffect :
3654					options.effect || defaultEffect;
3655		options = options || {};
3656		if ( typeof options === "number" ) {
3657			options = { duration: options };
3658		}
3659		hasOptions = !$.isEmptyObject( options );
3660		options.complete = callback;
3661		if ( options.delay ) {
3662			element.delay( options.delay );
3663		}
3664		if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
3665			element[ method ]( options );
3666		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 4,171 bytes, lines 3667-3822
3667			element[ effectName ]( options.duration, options.easing, callback );
3668		} else {
3669			element.queue(function( next ) {
3670				$( this )[ method ]();
3671				if ( callback ) {
3672					callback.call( element[ 0 ] );
3673				}
3674				next();
3675			});
3676		}
3677	};
3678});
3679
3680// DEPRECATED
3681if ( $.uiBackCompat !== false ) {
3682	$.Widget.prototype._getCreateOptions = function() {
3683		return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
3684	};
3685}
3686
3687})( jQuery );
3688
3689(function( $, undefined ) {
3690
3691var mouseHandled = false;
3692$( document ).mouseup( function( e ) {
3693	mouseHandled = false;
3694});
3695
3696$.widget("ui.mouse", {
3697	version: "1.9.1",
3698	options: {
3699		cancel: 'input,textarea,button,select,option',
3700		distance: 1,
3701		delay: 0
3702	},
3703	_mouseInit: function() {
3704		var that = this;
3705
3706		this.element
3707			.bind('mousedown.'+this.widgetName, function(event) {
3708				return that._mouseDown(event);
3709			})
3710			.bind('click.'+this.widgetName, function(event) {
3711				if (true === $.data(event.target, that.widgetName + '.preventClickEvent')) {
3712					$.removeData(event.target, that.widgetName + '.preventClickEvent');
3713					event.stopImmediatePropagation();
3714					return false;
3715				}
3716			});
3717
3718		this.started = false;
3719	},
3720
3721	// TODO: make sure destroying one instance of mouse doesn't mess with
3722	// other instances of mouse
3723	_mouseDestroy: function() {
3724		this.element.unbind('.'+this.widgetName);
3725		if ( this._mouseMoveDelegate ) {
3726			$(document)
3727				.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
3728				.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
3729		}
3730	},
3731
3732	_mouseDown: function(event) {
3733		// don't let more than one widget handle mouseStart
3734		if( mouseHandled ) { return; }
3735
3736		// we may have missed mouseup (out of window)
3737		(this._mouseStarted && this._mouseUp(event));
3738
3739		this._mouseDownEvent = event;
3740
3741		var that = this,
3742			btnIsLeft = (event.which === 1),
3743			// event.target.nodeName works around a bug in IE 8 with
3744			// disabled inputs (#7620)
3745			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
3746		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
3747			return true;
3748		}
3749
3750		this.mouseDelayMet = !this.options.delay;
3751		if (!this.mouseDelayMet) {
3752			this._mouseDelayTimer = setTimeout(function() {
3753				that.mouseDelayMet = true;
3754			}, this.options.delay);
3755		}
3756
3757		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
3758			this._mouseStarted = (this._mouseStart(event) !== false);
3759			if (!this._mouseStarted) {
3760				event.preventDefault();
3761				return true;
3762			}
3763		}
3764
3765		// Click event may never have fired (Gecko & Opera)
3766		if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
3767			$.removeData(event.target, this.widgetName + '.preventClickEvent');
3768		}
3769
3770		// these delegates are required to keep context
3771		this._mouseMoveDelegate = function(event) {
3772			return that._mouseMove(event);
3773		};
3774		this._mouseUpDelegate = function(event) {
3775			return that._mouseUp(event);
3776		};
3777		$(document)
3778			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
3779			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
3780
3781		event.preventDefault();
3782
3783		mouseHandled = true;
3784		return true;
3785	},
3786
3787	_mouseMove: function(event) {
3788		// IE mouseup check - mouseup happened when mouse was out of window
3789		if ($.ui.ie && !(document.documentMode >= 9) && !event.button) {
3790			return this._mouseUp(event);
3791		}
3792
3793		if (this._mouseStarted) {
3794			this._mouseDrag(event);
3795			return event.preventDefault();
3796		}
3797
3798		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
3799			this._mouseStarted =
3800				(this._mouseStart(this._mouseDownEvent, event) !== false);
3801			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
3802		}
3803
3804		return !this._mouseStarted;
3805	},
3806
3807	_mouseUp: function(event) {
3808		$(document)
3809			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
3810			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
3811
3812		if (this._mouseStarted) {
3813			this._mouseStarted = false;
3814
3815			if (event.target === this._mouseDownEvent.target) {
3816				$.data(event.target, this.widgetName + '.preventClickEvent', true);
3817			}
3818
3819			this._mouseStop(event);
3820		}
3821
3822		return false;
3823	},
3824
3825	_mouseDistanceMet: function(event) {
3826		return (Math.max(
3827				Math.abs(this._mouseDownEvent.pageX - event.pageX),
3828				Math.abs(this._mouseDownEvent.pageY - event.pageY)
3829			) >= this.options.distance
3830		);
3831	},
3832
3833	_mouseDelayMet: function(event) {
3834		return this.mouseDelayMet;
3835	},
3836
3837	// These are placeholder methods, to be overriden by extending plugin
3838	_mouseStart: function(event) {},
3839	_mouseDrag: function(event) {},
3840	_mouseStop: function(event) {},
3841	_mouseCapture: function(event) { return true; }
3842});
3843
3844})(jQuery);
3845
3846(function( $, undefined ) {
3847
3848$.widget("ui.draggable", $.ui.mouse, {
3849	version: "1.9.1",
3850	widgetEventPrefix: "drag",
3851	options: {
3852		addClasses: true,
3853		appendTo: "parent",
3854		axis: false,
3855		connectToSortable: false,
3856		containment: false,
3857		cursor: "auto",
3858		cursorAt: false,
3859		grid: false,
3860		handle: false,
3861		helper: "original",
3862		iframeFix: false,
3863		opacity: false,
3864		refreshPositions: false,
3865		revert: false,
3866		revertDuration: 500,
3867		scope: "default",
3868		scroll: true,
3869		scrollSensitivity: 20,
3870		scrollSpeed: 20,
3871		snap: false,
3872		snapMode: "both",
3873		snapTolerance: 20,
3874		stack: false,
3875		zIndex: false
3876	},
3877	_create: function() {
3878
3879		if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
3880			this.element[0].style.position = 'relative';
3881
3882		(this.options.addClasses && this.element.addClass("ui-draggable"));
3883		(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
3884
3885		this._mouseInit();
3886
3887	},
3888
3889	_destroy: function() {
3890		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
3891		this._mouseDestroy();
3892	},
3893
3894	_mouseCapture: function(event) {
3895
3896		var o = this.options;
3897
3898		// among others, prevent a drag on a resizable-handle
3899		if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
3900			return false;
3901
3902		//Quit if we're not on a valid handle
3903		this.handle = this._getHandle(event);
3904		if (!this.handle)
3905			return false;
3906
3907		$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
3908			$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
3909			.css({
3910				width: this.offsetWidth+"px", height: this.offsetHeight+"px",
3911				position: "absolute", opacity: "0.001", zIndex: 1000
3912			})
3913			.css($(this).offset())
3914			.appendTo("body");
3915		});
3916
3917		return true;
3918
3919	},
3920
3921	_mouseStart: function(event) {
3922
3923		var o = this.options;
3924
3925		//Create and append the visible helper
3926		this.helper = this._createHelper(event);
3927
3928		this.helper.addClass("ui-draggable-dragging");
3929
3930		//Cache the helper size
3931		this._cacheHelperProportions();
3932
3933		//If ddmanager is used for droppables, set the global draggable
3934		if($.ui.ddmanager)
3935			$.ui.ddmanager.current = this;
3936
3937		/*
3938		 * - Position generation -
3939		 * This block generates everything position related - it's the core of draggables.
3940		 */
3941
3942		//Cache the margins of the original element
3943		this._cacheMargins();
3944
3945		//Store the helper's css position
3946		this.cssPosition = this.helper.css("position");
3947		this.scrollParent = this.helper.scrollParent();
3948
3949		//The element's absolute position on the page minus margins
3950		this.offset = this.positionAbs = this.element.offset();
3951		this.offset = {
3952			top: this.offset.top - this.margins.top,
3953			left: this.offset.left - this.margins.left
3954		};
3955
3956		$.extend(this.offset, {
3957			click: { //Where the click happened, relative to the element
3958				left: event.pageX - this.offset.left,
3959				top: event.pageY - this.offset.top
3960			},
3961			parent: this._getParentOffset(),
3962			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3963		});
3964
3965		//Generate the original position
3966		this.originalPosition = this.position = this._generatePosition(event);
3967		this.originalPageX = event.pageX;
3968		this.originalPageY = event.pageY;
3969
3970		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3971		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3972
3973		//Set a containment if given in the options
3974		if(o.containment)
3975			this._setContainment();
3976
3977		//Trigger event + callbacks
3978		if(this._trigger("start", event) === false) {
3979			this._clear();
3980			return false;
3981		}
3982
3983		//Recache the helper size
3984		this._cacheHelperProportions();
3985
3986		//Prepare the droppable offsets
3987		if ($.ui.ddmanager && !o.dropBehaviour)
3988			$.ui.ddmanager.prepareOffsets(this, event);
3989
3990
3991		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3992
3993		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
3994		if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
3995
3996		return true;
3997	},
3998
3999	_mouseDrag: function(event, noPropagation) {
4000
4001		//Compute the helpers position
4002		this.position = this._generatePosition(event);
4003		this.positionAbs = this._convertPositionTo("absolute");
4004
4005		//Call plugins and callbacks and use the resulting position if something is returned
4006		if (!noPropagation) {
4007			var ui = this._uiHash();
4008			if(this._trigger('drag', event, ui) === false) {
4009				this._mouseUp({});
4010				return false;
4011			}
4012			this.position = ui.position;
4013		}
4014
4015		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
4016		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
4017		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
4018
4019		return false;
4020	},
4021
4022	_mouseStop: function(event) {
4023
4024		//If we are using droppables, inform the manager about the drop
4025		var dropped = false;
4026		if ($.ui.ddmanager && !this.options.dropBehaviour)
4027			dropped = $.ui.ddmanager.drop(this, event);
4028
4029		//if a drop comes from outside (a sortable)
4030		if(this.dropped) {
4031			dropped = this.dropped;
4032			this.dropped = false;
4033		}
4034
4035		//if the original element is no longer in the DOM don't bother to continue (see #8269)
4036		var element = this.element[0], elementInDom = false;
4037		while ( element && (element = element.parentNode) ) {
4038			if (element == document ) {
4039				elementInDom = true;
4040			}
4041		}
4042		if ( !elementInDom && this.options.helper === "original" )
4043			return false;
4044
4045		if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
4046			var that = this;
4047			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
4048				if(that._trigger("stop", event) !== false) {
4049					that._clear();
4050				}
4051			});
4052		} else {
4053			if(this._trigger("stop", event) !== false) {
4054				this._clear();
4055			}
4056		}
4057
4058		return false;
4059	},
4060
4061	_mouseUp: function(event) {
4062		//Remove frame helpers
4063		$("div.ui-draggable-iframeFix").each(function() {
4064			this.parentNode.removeChild(this);
4065		});
4066
4067		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
4068		if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
4069
4070		return $.ui.mouse.prototype._mouseUp.call(this, event);
4071	},
4072
4073	cancel: function() {
4074
4075		if(this.helper.is(".ui-draggable-dragging")) {
4076			this._mouseUp({});
4077		} else {
4078			this._clear();
4079		}
4080
4081		return this;
4082
4083	},
4084
4085	_getHandle: function(event) {
4086
4087		var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
4088		$(this.options.handle, this.element)
4089			.find("*")
4090			.andSelf()
4091			.each(function() {
4092				if(this == event.target) handle = true;
4093			});
4094
4095		return handle;
4096
4097	},
4098
4099	_createHelper: function(event) {
4100
4101		var o = this.options;
4102		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
4103
4104		if(!helper.parents('body').length)
4105			helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
4106
4107		if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
4108			helper.css("position", "absolute");
4109
4110		return helper;
4111
4112	},
4113
4114	_adjustOffsetFromHelper: function(obj) {
4115		if (typeof obj == 'string') {
4116			obj = obj.split(' ');
4117		}
4118		if ($.isArray(obj)) {
4119			obj = {left: +obj[0], top: +obj[1] || 0};
4120		}
4121		if ('left' in obj) {
4122			this.offset.click.left = obj.left + this.margins.left;
4123		}
4124		if ('right' in obj) {
4125			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4126		}
4127		if ('top' in obj) {
4128			this.offset.click.top = obj.top + this.margins.top;
4129		}
4130		if ('bottom' in obj) {
4131			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4132		}
4133	},
4134
4135	_getParentOffset: function() {
4136
4137		//Get the offsetParent and cache its position
4138		this.offsetParent = this.helper.offsetParent();
4139		var po = this.offsetParent.offset();
4140
4141		// This is a special case where we need to modify a offset calculated on start, since the following happened:
4142		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4143		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4144		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4145		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4146			po.left += this.scrollParent.scrollLeft();
4147			po.top += this.scrollParent.scrollTop();
4148		}
4149
4150		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4151		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
4152			po = { top: 0, left: 0 };
4153
4154		return {
4155			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4156			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4157		};
4158
4159	},
4160
4161	_getRelativeOffset: function() {
4162
4163		if(this.cssPosition == "relative") {
4164			var p = this.element.position();
4165			return {
4166				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4167				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4168			};
4169		} else {
4170			return { top: 0, left: 0 };
4171		}
4172
4173	},
4174
4175	_cacheMargins: function() {
4176		this.margins = {
4177			left: (parseInt(this.element.css("marginLeft"),10) || 0),
4178			top: (parseInt(this.element.css("marginTop"),10) || 0),
4179			right: (parseInt(this.element.css("marginRight"),10) || 0),
4180			bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
4181		};
4182	},
4183
4184	_cacheHelperProportions: function() {
4185		this.helperProportions = {
4186			width: this.helper.outerWidth(),
4187			height: this.helper.outerHeight()
4188		};
4189	},
4190
4191	_setContainment: function() {
4192
4193		var o = this.options;
4194		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4195		if(o.containment == 'document' || o.containment == 'window') this.containment = [
4196			o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
4197			o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
4198			(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4199			(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4200		];
4201
4202		if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
4203			var c = $(o.containment);
4204			var ce = c[0]; if(!ce) return;
4205			var co = c.offset();
4206			var over = ($(ce).css("overflow") != 'hidden');
4207
4208			this.containment = [
4209				(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
4210				(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
4211				(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
4212				(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
4213			];
4214			this.relative_container = c;
4215
4216		} else if(o.containment.constructor == Array) {
4217			this.containment = o.containment;
4218		}
4219
4220	},
4221
4222	_convertPositionTo: function(d, pos) {
4223
4224		if(!pos) pos = this.position;
4225		var mod = d == "absolute" ? 1 : -1;
4226		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4227
4228		return {
4229			top: (
4230				pos.top																	// The absolute mouse position
4231				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4232				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
4233				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4234			),
4235			left: (
4236				pos.left																// The absolute mouse position
4237				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
4238				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
4239				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4240			)
4241		};
4242
4243	},
4244
4245	_generatePosition: function(event) {
4246
4247		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4248		var pageX = event.pageX;
4249		var pageY = event.pageY;
4250
4251		/*
4252		 * - Position constraining -
4253		 * Constrain the position to a mix of grid, containment.
4254		 */
4255
4256		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4257			var containment;
4258			if(this.containment) {
4259			if (this.relative_container){
4260				var co = this.relative_container.offset();
4261				containment = [ this.containment[0] + co.left,
4262					this.containment[1] + co.top,
4263					this.containment[2] + co.left,
4264					this.containment[3] + co.top ];
4265			}
4266			else {
4267				containment = this.containment;
4268			}
4269
4270				if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
4271				if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
4272				if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
4273				if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
4274			}
4275
4276			if(o.grid) {
4277				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
4278				var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
4279				pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4280
4281				var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
4282				pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4283			}
4284
4285		}
4286
4287		return {
4288			top: (
4289				pageY																// The absolute mouse position
4290				- this.offset.click.top													// Click offset (relative to the element)
4291				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
4292				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
4293				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4294			),
4295			left: (
4296				pageX																// The absolute mouse position
4297				- this.offset.click.left												// Click offset (relative to the element)
4298				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
4299				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
4300				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4301			)
4302		};
4303
4304	},
4305
4306	_clear: function() {
4307		this.helper.removeClass("ui-draggable-dragging");
4308		if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
4309		//if($.ui.ddmanager) $.ui.ddmanager.current = null;
4310		this.helper = null;
4311		this.cancelHelperRemoval = false;
4312	},
4313
4314	// From now on bulk stuff - mainly helpers
4315
4316	_trigger: function(type, event, ui) {
4317		ui = ui || this._uiHash();
4318		$.ui.plugin.call(this, type, [event, ui]);
4319		if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
4320		return $.Widget.prototype._trigger.call(this, type, event, ui);
4321	},
4322
4323	plugins: {},
4324
4325	_uiHash: function(event) {
4326		return {
4327			helper: this.helper,
4328			position: this.position,
4329			originalPosition: this.originalPosition,
4330			offset: this.positionAbs
4331		};
4332	}
4333
4334});
4335
4336$.ui.plugin.add("draggable", "connectToSortable", {
4337	start: function(event, ui) {
4338
4339		var inst = $(this).data("draggable"), o = inst.options,
4340			uiSortable = $.extend({}, ui, { item: inst.element });
4341		inst.sortables = [];
4342		$(o.connectToSortable).each(function() {
4343			var sortable = $.data(this, 'sortable');
4344			if (sortable && !sortable.options.disabled) {
4345				inst.sortables.push({
4346					instance: sortable,
4347					shouldRevert: sortable.options.revert
4348				});
4349				sortable.refreshPositions();	// Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
4350				sortable._trigger("activate", event, uiSortable);
4351			}
4352		});
4353
4354	},
4355	stop: function(event, ui) {
4356
4357		//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
4358		var inst = $(this).data("draggable"),
4359			uiSortable = $.extend({}, ui, { item: inst.element });
4360
4361		$.each(inst.sortables, function() {
4362			if(this.instance.isOver) {
4363
4364				this.instance.isOver = 0;
4365
4366				inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
4367				this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
4368
4369				//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
4370				if(this.shouldRevert) this.instance.options.revert = true;
4371
4372				//Trigger the stop of the sortable
4373				this.instance._mouseStop(event);
4374
4375				this.instance.options.helper = this.instance.options._helper;
4376
4377				//If the helper has been the original item, restore properties in the sortable
4378				if(inst.options.helper == 'original')
4379					this.instance.currentItem.css({ top: 'auto', left: 'auto' });
4380
4381			} else {
4382				this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
4383				this.instance._trigger("deactivate", event, uiSortable);
4384			}
4385
4386		});
4387
4388	},
4389	drag: function(event, ui) {
4390
4391		var inst = $(this).data("draggable"), that = this;
4392
4393		var checkPos = function(o) {
4394			var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
4395			var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
4396			var itemHeight = o.height, itemWidth = o.width;
4397			var itemTop = o.top, itemLeft = o.left;
4398
4399			return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
4400		};
4401
4402		$.each(inst.sortables, function(i) {
4403
4404			var innermostIntersecting = false;
4405			var thisSortable = this;
4406			//Copy over some variables to allow calling the sortable's native _intersectsWith
4407			this.instance.positionAbs = inst.positionAbs;
4408			this.instance.helperProportions = inst.helperProportions;
4409			this.instance.offset.click = inst.offset.click;
4410
4411			if(this.instance._intersectsWith(this.instance.containerCache)) {
4412				innermostIntersecting = true;
4413				$.each(inst.sortables, function () {
4414					this.instance.positionAbs = inst.positionAbs;
4415					this.instance.helperProportions = inst.helperProportions;
4416					this.instance.offset.click = inst.offset.click;
4417					if  (this != thisSortable
4418						&& this.instance._intersectsWith(this.instance.containerCache)
4419						&& $.ui.contains(thisSortable.instance.element[0], this.instance.element[0]))
4420						innermostIntersecting = false;
4421						return innermostIntersecting;
4422				});
4423			}
4424
4425
4426			if(innermostIntersecting) {
4427				//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
4428				if(!this.instance.isOver) {
4429
4430					this.instance.isOver = 1;
4431					//Now we fake the start of dragging for the sortable instance,
4432					//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
4433					//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
4434					this.instance.currentItem = $(that).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
4435					this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
4436					this.instance.options.helper = function() { return ui.helper[0]; };
4437
4438					event.target = this.instance.currentItem[0];
4439					this.instance._mouseCapture(event, true);
4440					this.instance._mouseStart(event, true, true);
4441
4442					//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
4443					this.instance.offset.click.top = inst.offset.click.top;
4444					this.instance.offset.click.left = inst.offset.click.left;
4445					this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
4446					this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
4447
4448					inst._trigger("toSortable", event);
4449					inst.dropped = this.instance.element; //draggable revert needs that
4450					//hack so receive/update callbacks work (mostly)
4451					inst.currentItem = inst.element;
4452					this.instance.fromOutside = inst;
4453
4454				}
4455
4456				//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
4457				if(this.instance.currentItem) this.instance._mouseDrag(event);
4458
4459			} else {
4460
4461				//If it doesn't intersect with the sortable, and it intersected before,
4462				//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
4463				if(this.instance.isOver) {
4464
4465					this.instance.isOver = 0;
4466					this.instance.cancelHelperRemoval = true;
4467
4468					//Prevent reverting on this forced stop
4469					this.instance.options.revert = false;
4470
4471					// The out event needs to be triggered independently
4472					this.instance._trigger('out', event, this.instance._uiHash(this.instance));
4473
4474					this.instance._mouseStop(event, true);
4475					this.instance.options.helper = this.instance.options._helper;
4476
4477					//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
4478					this.instance.currentItem.remove();
4479					if(this.instance.placeholder) this.instance.placeholder.remove();
4480
4481					inst._trigger("fromSortable", event);
4482					inst.dropped = false; //draggable revert needs that
4483				}
4484
4485			};
4486
4487		});
4488
4489	}
4490});
4491
4492$.ui.plugin.add("draggable", "cursor", {
4493	start: function(event, ui) {
4494		var t = $('body'), o = $(this).data('draggable').options;
4495		if (t.css("cursor")) o._cursor = t.css("cursor");
4496		t.css("cursor", o.cursor);
4497	},
4498	stop: function(event, ui) {
4499		var o = $(this).data('draggable').options;
4500		if (o._cursor) $('body').css("cursor", o._cursor);
4501	}
4502});
4503
4504$.ui.plugin.add("draggable", "opacity", {
4505	start: function(event, ui) {
4506		var t = $(ui.helper), o = $(this).data('draggable').options;
4507		if(t.css("opacity")) o._opacity = t.css("opacity");
4508		t.css('opacity', o.opacity);
4509	},
4510	stop: function(event, ui) {
4511		var o = $(this).data('draggable').options;
4512		if(o._opacity) $(ui.helper).css('opacity', o._opacity);
4513	}
4514});
4515
4516$.ui.plugin.add("draggable", "scroll", {
4517	start: function(event, ui) {
4518		var i = $(this).data("draggable");
4519		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
4520	},
4521	drag: function(event, ui) {
4522
4523		var i = $(this).data("draggable"), o = i.options, scrolled = false;
4524
4525		if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
4526
4527			if(!o.axis || o.axis != 'x') {
4528				if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
4529					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
4530				else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
4531					i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
4532			}
4533
4534			if(!o.axis || o.axis != 'y') {
4535				if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
4536					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
4537				else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
4538					i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
4539			}
4540
4541		} else {
4542
4543			if(!o.axis || o.axis != 'x') {
4544				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
4545					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4546				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
4547					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4548			}
4549
4550			if(!o.axis || o.axis != 'y') {
4551				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
4552					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4553				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
4554					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4555			}
4556
4557		}
4558
4559		if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
4560			$.ui.ddmanager.prepareOffsets(i, event);
4561
4562	}
4563});
4564
4565$.ui.plugin.add("draggable", "snap", {
4566	start: function(event, ui) {
4567
4568		var i = $(this).data("draggable"), o = i.options;
4569		i.snapElements = [];
4570
4571		$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
4572			var $t = $(this); var $o = $t.offset();
4573			if(this != i.element[0]) i.snapElements.push({
4574				item: this,
4575				width: $t.outerWidth(), height: $t.outerHeight(),
4576				top: $o.top, left: $o.left
4577			});
4578		});
4579
4580	},
4581	drag: function(event, ui) {
4582
4583		var inst = $(this).data("draggable"), o = inst.options;
4584		var d = o.snapTolerance;
4585
4586		var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
4587			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
4588
4589		for (var i = inst.snapElements.length - 1; i >= 0; i--){
4590
4591			var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
4592				t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
4593
4594			//Yes, I know, this is insane ;)
4595			if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
4596				if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
4597				inst.snapElements[i].snapping = false;
4598				continue;
4599			}
4600
4601			if(o.snapMode != 'inner') {
4602				var ts = Math.abs(t - y2) <= d;
4603				var bs = Math.abs(b - y1) <= d;
4604				var ls = Math.abs(l - x2) <= d;
4605				var rs = Math.abs(r - x1) <= d;
4606				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
4607				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
4608				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
4609				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
4610			}
4611
4612			var first = (ts || bs || ls || rs);
4613
4614			if(o.snapMode != 'outer') {
4615				var ts = Math.abs(t - y1) <= d;
4616				var bs = Math.abs(b - y2) <= d;
4617				var ls = Math.abs(l - x1) <= d;
4618				var rs = Math.abs(r - x2) <= d;
4619				if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
4620				if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
4621				if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
4622				if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
4623			}
4624
4625			if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
4626				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
4627			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
4628
4629		};
4630
4631	}
4632});
4633
4634$.ui.plugin.add("draggable", "stack", {
4635	start: function(event, ui) {
4636
4637		var o = $(this).data("draggable").options;
4638
4639		var group = $.makeArray($(o.stack)).sort(function(a,b) {
4640			return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
4641		});
4642		if (!group.length) { return; }
4643
4644		var min = parseInt(group[0].style.zIndex) || 0;
4645		$(group).each(function(i) {
4646			this.style.zIndex = min + i;
4647		});
4648
4649		this[0].style.zIndex = min + group.length;
4650
4651	}
4652});
4653
4654$.ui.plugin.add("draggable", "zIndex", {
4655	start: function(event, ui) {
4656		var t = $(ui.helper), o = $(this).data("draggable").options;
4657		if(t.css("zIndex")) o._zIndex = t.css("zIndex");
4658		t.css('zIndex', o.zIndex);
4659	},
4660	stop: function(event, ui) {
4661		var o = $(this).data("draggable").options;
4662		if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
4663	}
4664});
4665
4666})(jQuery);
4667
4668(function( $, undefined ) {
4669
4670$.widget("ui.droppable", {
4671	version: "1.9.1",
4672	widgetEventPrefix: "drop",
4673	options: {
4674		accept: '*',
4675		activeClass: false,
4676		addClasses: true,
4677		greedy: false,
4678		hoverClass: false,
4679		scope: 'default',
4680		tolerance: 'intersect'
4681	},
4682	_create: function() {
4683
4684		var o = this.options, accept = o.accept;
4685		this.isover = 0; this.isout = 1;
4686
4687		this.accept = $.isFunction(accept) ? accept : function(d) {
4688			return d.is(accept);
4689		};
4690
4691		//Store the droppable's proportions
4692		this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
4693
4694		// Add the reference and positions to the manager
4695		$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
4696		$.ui.ddmanager.droppables[o.scope].push(this);
4697
4698		(o.addClasses && this.element.addClass("ui-droppable"));
4699
4700	},
4701
4702	_destroy: function() {
4703		var drop = $.ui.ddmanager.droppables[this.options.scope];
4704		for ( var i = 0; i < drop.length; i++ )
4705			if ( drop[i] == this )
4706				drop.splice(i, 1);
4707
4708		this.element.removeClass("ui-droppable ui-droppable-disabled");
4709	},
4710
4711	_setOption: function(key, value) {
4712
4713		if(key == 'accept') {
4714			this.accept = $.isFunction(value) ? value : function(d) {
4715				return d.is(value);
4716			};
4717		}
4718		$.Widget.prototype._setOption.apply(this, arguments);
4719	},
4720
4721	_activate: function(event) {
4722		var draggable = $.ui.ddmanager.current;
4723		if(this.options.activeClass) this.element.addClass(this.options.activeClass);
4724		(draggable && this._trigger('activate', event, this.ui(draggable)));
4725	},
4726
4727	_deactivate: function(event) {
4728		var draggable = $.ui.ddmanager.current;
4729		if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
4730		(draggable && this._trigger('deactivate', event, this.ui(draggable)));
4731	},
4732
4733	_over: function(event) {
4734
4735		var draggable = $.ui.ddmanager.current;
4736		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
4737
4738		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
4739			if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
4740			this._trigger('over', event, this.ui(draggable));
4741		}
4742
4743	},
4744
4745	_out: function(event) {
4746
4747		var draggable = $.ui.ddmanager.current;
4748		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
4749
4750		if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
4751			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
4752			this._trigger('out', event, this.ui(draggable));
4753		}
4754
4755	},
4756
4757	_drop: function(event,custom) {
4758
4759		var draggable = custom || $.ui.ddmanager.current;
4760		if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
4761
4762		var childrenIntersection = false;
4763		this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
4764			var inst = $.data(this, 'droppable');
4765			if(
4766				inst.options.greedy
4767				&& !inst.options.disabled
4768				&& inst.options.scope == draggable.options.scope
4769				&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
4770				&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
4771			) { childrenIntersection = true; return false; }
4772		});
4773		if(childrenIntersection) return false;
4774
4775		if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
4776			if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
4777			if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
4778			this._trigger('drop', event, this.ui(draggable));
4779			return this.element;
4780		}
4781
4782		return false;
4783
4784	},
4785
4786	ui: function(c) {
4787		return {
4788			draggable: (c.currentItem || c.element),
4789			helper: c.helper,
4790			position: c.position,
4791			offset: c.positionAbs
4792		};
4793	}
4794
4795});
4796
4797$.ui.intersect = function(draggable, droppable, toleranceMode) {
4798
4799	if (!droppable.offset) return false;
4800
4801	var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
4802		y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
4803	var l = droppable.offset.left, r = l + droppable.proportions.width,
4804		t = droppable.offset.top, b = t + droppable.proportions.height;
4805
4806	switch (toleranceMode) {
4807		case 'fit':
4808			return (l <= x1 && x2 <= r
4809				&& t <= y1 && y2 <= b);
4810			break;
4811		case 'intersect':
4812			return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
4813				&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
4814				&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
4815				&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
4816			break;
4817		case 'pointer':
4818			var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
4819				draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
4820				isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
4821			return isOver;
4822			break;
4823		case 'touch':
4824			return (
4825					(y1 >= t && y1 <= b) ||	// Top edge touching
4826					(y2 >= t && y2 <= b) ||	// Bottom edge touching
4827					(y1 < t && y2 > b)		// Surrounded vertically
4828				) && (
4829					(x1 >= l && x1 <= r) ||	// Left edge touching
4830					(x2 >= l && x2 <= r) ||	// Right edge touching
4831					(x1 < l && x2 > r)		// Surrounded horizontally
4832				);
4833			break;
4834		default:
4835			return false;
4836			break;
4837		}
4838
4839};
4840
4841/*
4842	This manager tracks offsets of draggables and droppables
4843*/
4844$.ui.ddmanager = {
4845	current: null,
4846	droppables: { 'default': [] },
4847	prepareOffsets: function(t, event) {
4848
4849		var m = $.ui.ddmanager.droppables[t.options.scope] || [];
4850		var type = event ? event.type : null; // workaround for #2317
4851		var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
4852
4853		droppablesLoop: for (var i = 0; i < m.length; i++) {
4854
4855			if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;	//No disabled and non-accepted
4856			for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
4857			m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; 									//If the element is not visible, continue
4858
4859			if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
4860
4861			m[i].offset = m[i].element.offset();
4862			m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
4863
4864		}
4865
4866	},
4867	drop: function(draggable, event) {
4868
4869		var dropped = false;
4870		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
4871
4872			if(!this.options) return;
4873			if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
4874				dropped = this._drop.call(this, event) || dropped;
4875
4876			if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
4877				this.isout = 1; this.isover = 0;
4878				this._deactivate.call(this, event);
4879			}
4880
4881		});
4882		return dropped;
4883
4884	},
4885	dragStart: function( draggable, event ) {
4886		//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
4887		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
4888			if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
4889		});
4890	},
4891	drag: function(draggable, event) {
4892
4893		//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
4894		if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
4895
4896		//Run through all droppables and check their positions based on specific tolerance options
4897		$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
4898
4899			if(this.options.disabled || this.greedyChild || !this.visible) return;
4900			var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
4901
4902			var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
4903			if(!c) return;
4904
4905			var parentInstance;
4906			if (this.options.greedy) {
4907				// find droppable parents with same scope
4908				var scope = this.options.scope;
4909				var parent = this.element.parents(':data(droppable)').filter(function () {
4910					return $.data(this, 'droppable').options.scope === scope;
4911				});
4912
4913				if (parent.length) {
4914					parentInstance = $.data(parent[0], 'droppable');
4915					parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
4916				}
4917			}
4918
4919			// we just moved into a greedy child
4920			if (parentInstance && c == 'isover') {
4921				parentInstance['isover'] = 0;
4922				parentInstance['isout'] = 1;
4923				parentInstance._out.call(parentInstance, event);
4924			}
4925
4926			this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
4927			this[c == "isover" ? "_over" : "_out"].call(this, event);
4928
4929			// we just moved out of a greedy child
4930			if (parentInstance && c == 'isout') {
4931				parentInstance['isout'] = 0;
4932				parentInstance['isover'] = 1;
4933				parentInstance._over.call(parentInstance, event);
4934			}
4935		});
4936
4937	},
4938	dragStop: function( draggable, event ) {
4939		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
4940		//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
4941		if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
4942	}
4943};
4944
4945})(jQuery);
4946
4947(function( $, undefined ) {
4948
4949$.widget("ui.resizable", $.ui.mouse, {
4950	version: "1.9.1",
4951	widgetEventPrefix: "resize",
4952	options: {
4953		alsoResize: false,
4954		animate: false,
4955		animateDuration: "slow",
4956		animateEasing: "swing",
4957		aspectRatio: false,
4958		autoHide: false,
4959		containment: false,
4960		ghost: false,
4961		grid: false,
4962		handles: "e,s,se",
4963		helper: false,
4964		maxHeight: null,
4965		maxWidth: null,
4966		minHeight: 10,
4967		minWidth: 10,
4968		zIndex: 1000
4969	},
4970	_create: function() {
4971
4972		var that = this, o = this.options;
4973		this.element.addClass("ui-resizable");
4974
4975		$.extend(this, {
4976			_aspectRatio: !!(o.aspectRatio),
4977			aspectRatio: o.aspectRatio,
4978			originalElement: this.element,
4979			_proportionallyResizeElements: [],
4980			_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
4981		});
4982
4983		//Wrap the element if it cannot hold child nodes
4984		if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
4985
4986			//Create a wrapper element and set the wrapper to the new current internal element
4987			this.element.wrap(
4988				$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
4989					position: this.element.css('position'),
4990					width: this.element.outerWidth(),
4991					height: this.element.outerHeight(),
4992					top: this.element.css('top'),
4993					left: this.element.css('left')
4994				})
4995			);
4996
4997			//Overwrite the original this.element
4998			this.element = this.element.parent().data(
4999				"resizable", this.element.data('resizable')
5000			);
5001
5002			this.elementIsWrapper = true;
5003
5004			//Move margins to the wrapper
5005			this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
5006			this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
5007
5008			//Prevent Safari textarea resize
5009			this.originalResizeStyle = this.originalElement.css('resize');
5010			this.originalElement.css('resize', 'none');
5011
5012			//Push the actual element to our proportionallyResize internal array
5013			this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
5014
5015			// avoid IE jump (hard set the margin)
5016			this.originalElement.css({ margin: this.originalElement.css('margin') });
5017
5018			// fix handlers offset
5019			this._proportionallyResize();
5020
5021		}
5022
5023		this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
5024		if(this.handles.constructor == String) {
5025
5026			if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
5027			var n = this.handles.split(","); this.handles = {};
5028
5029			for(var i = 0; i < n.length; i++) {
5030
5031				var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
5032				var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
5033
5034				// Apply zIndex to all handles - see #7960
5035				axis.css({ zIndex: o.zIndex });
5036
5037				//TODO : What's going on here?
5038				if ('se' == handle) {
5039					axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
5040				};
5041
5042				//Insert into internal handles object and append to element
5043				this.handles[handle] = '.ui-resizable-'+handle;
5044				this.element.append(axis);
5045			}
5046
5047		}
5048
5049		this._renderAxis = function(target) {
5050
5051			target = target || this.element;
5052
5053			for(var i in this.handles) {
5054
5055				if(this.handles[i].constructor == String)
5056					this.handles[i] = $(this.handles[i], this.element).show();
5057
5058				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
5059				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
5060
5061					var axis = $(this.handles[i], this.element), padWrapper = 0;
5062
5063					//Checking the correct pad and border
5064					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
5065
5066					//The padding type i have to apply...
5067					var padPos = [ 'padding',
5068						/ne|nw|n/.test(i) ? 'Top' :
5069						/se|sw|s/.test(i) ? 'Bottom' :
5070						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
5071
5072					target.css(padPos, padWrapper);
5073
5074					this._proportionallyResize();
5075
5076				}
5077
5078				//TODO: What's that good for? There's not anything to be executed left
5079				if(!$(this.handles[i]).length)
5080					continue;
5081
5082			}
5083		};
5084
5085		//TODO: make renderAxis a prototype function
5086		this._renderAxis(this.element);
5087
5088		this._handles = $('.ui-resizable-handle', this.element)
5089			.disableSelection();
5090
5091		//Matching axis name
5092		this._handles.mouseover(function() {
5093			if (!that.resizing) {
5094				if (this.className)
5095					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
5096				//Axis, default = se
5097				that.axis = axis && axis[1] ? axis[1] : 'se';
5098			}
5099		});
5100
5101		//If we want to auto hide the elements
5102		if (o.autoHide) {
5103			this._handles.hide();
5104			$(this.element)
5105				.addClass("ui-resizable-autohide")
5106				.mouseenter(function() {
5107					if (o.disabled) return;
5108					$(this).removeClass("ui-resizable-autohide");
5109					that._handles.show();
5110				})
5111				.mouseleave(function(){
5112					if (o.disabled) return;
5113					if (!that.resizing) {
5114						$(this).addClass("ui-resizable-autohide");
5115						that._handles.hide();
5116					}
5117				});
5118		}
5119
5120		//Initialize the mouse interaction
5121		this._mouseInit();
5122
5123	},
5124
5125	_destroy: function() {
5126
5127		this._mouseDestroy();
5128
5129		var _destroy = function(exp) {
5130			$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
5131				.removeData("resizable").removeData("ui-resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
5132		};
5133
5134		//TODO: Unwrap at same DOM position
5135		if (this.elementIsWrapper) {
5136			_destroy(this.element);
5137			var wrapper = this.element;
5138			this.originalElement.css({
5139				position: wrapper.css('position'),
5140				width: wrapper.outerWidth(),
5141				height: wrapper.outerHeight(),
5142				top: wrapper.css('top'),
5143				left: wrapper.css('left')
5144			}).insertAfter( wrapper );
5145			wrapper.remove();
5146		}
5147
5148		this.originalElement.css('resize', this.originalResizeStyle);
5149		_destroy(this.originalElement);
5150
5151		return this;
5152	},
5153
5154	_mouseCapture: function(event) {
5155		var handle = false;
5156		for (var i in this.handles) {
5157			if ($(this.handles[i])[0] == event.target) {
5158				handle = true;
5159			}
5160		}
5161
5162		return !this.options.disabled && handle;
5163	},
5164
5165	_mouseStart: function(event) {
5166
5167		var o = this.options, iniPos = this.element.position(), el = this.element;
5168
5169		this.resizing = true;
5170		this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
5171
5172		// bugfix for http://dev.jquery.com/ticket/1749
5173		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
5174			el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
5175		}
5176
5177		this._renderProxy();
5178
5179		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
5180
5181		if (o.containment) {
5182			curleft += $(o.containment).scrollLeft() || 0;
5183			curtop += $(o.containment).scrollTop() || 0;
5184		}
5185
5186		//Store needed variables
5187		this.offset = this.helper.offset();
5188		this.position = { left: curleft, top: curtop };
5189		this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
5190		this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
5191		this.originalPosition = { left: curleft, top: curtop };
5192		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
5193		this.originalMousePosition = { left: event.pageX, top: event.pageY };
5194
5195		//Aspect Ratio
5196		this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
5197
5198		var cursor = $('.ui-resizable-' + this.axis).css('cursor');
5199		$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
5200
5201		el.addClass("ui-resizable-resizing");
5202		this._propagate("start", event);
5203		return true;
5204	},
5205
5206	_mouseDrag: function(event) {
5207
5208		//Increase performance, avoid regex
5209		var el = this.helper, o = this.options, props = {},
5210			that = this, smp = this.originalMousePosition, a = this.axis;
5211
5212		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
5213		var trigger = this._change[a];
5214		if (!trigger) return false;
5215
5216		// Calculate the attrs that will be change
5217		var data = trigger.apply(this, [event, dx, dy]);
5218
5219		// Put this in the mouseDrag handler since the user can start pressing shift while resizing
5220		this._updateVirtualBoundaries(event.shiftKey);
5221		if (this._aspectRatio || event.shiftKey)
5222			data = this._updateRatio(data, event);
5223
5224		data = this._respectSize(data, event);
5225
5226		// plugins callbacks need to be called first
5227		this._propagate("resize", event);
5228
5229		el.css({
5230			top: this.position.top + "px", left: this.position.left + "px",
5231			width: this.size.width + "px", height: this.size.height + "px"
5232		});
5233
5234		if (!this._helper && this._proportionallyResizeElements.length)
5235			this._proportionallyResize();
5236
5237		this._updateCache(data);
5238
5239		// calling the user callback at the end
5240		this._trigger('resize', event, this.ui());
5241
5242		return false;
5243	},
5244
5245	_mouseStop: function(event) {
5246
5247		this.resizing = false;
5248		var o = this.options, that = this;
5249
5250		if(this._helper) {
5251			var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
5252				soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
5253				soffsetw = ista ? 0 : that.sizeDiff.width;
5254
5255			var s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) },
5256				left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
5257				top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
5258
5259			if (!o.animate)
5260				this.element.css($.extend(s, { top: top, left: left }));
5261
5262			that.helper.height(that.size.height);
5263			that.helper.width(that.size.width);
5264
5265			if (this._helper && !o.animate) this._proportionallyResize();
5266		}
5267
5268		$('body').css('cursor', 'auto');
5269
5270		this.element.removeClass("ui-resizable-resizing");
5271
5272		this._propagate("stop", event);
5273
5274		if (this._helper) this.helper.remove();
5275		return false;
5276
5277	},
5278
5279	_updateVirtualBoundaries: function(forceAspectRatio) {
5280		var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
5281
5282		b = {
5283			minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
5284			maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
5285			minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
5286			maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
5287		};
5288
5289		if(this._aspectRatio || forceAspectRatio) {
5290			// We want to create an enclosing box whose aspect ration is the requested one
5291			// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
5292			pMinWidth = b.minHeight * this.aspectRatio;
5293			pMinHeight = b.minWidth / this.aspectRatio;
5294			pMaxWidth = b.maxHeight * this.aspectRatio;
5295			pMaxHeight = b.maxWidth / this.aspectRatio;
5296
5297			if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
5298			if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
5299			if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
5300			if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
5301		}
5302		this._vBoundaries = b;
5303	},
5304
5305	_updateCache: function(data) {
5306		var o = this.options;
5307		this.offset = this.helper.offset();
5308		if (isNumber(data.left)) this.position.left = data.left;
5309		if (isNumber(data.top)) this.position.top = data.top;
5310		if (isNumber(data.height)) this.size.height = data.height;
5311		if (isNumber(data.width)) this.size.width = data.width;
5312	},
5313
5314	_updateRatio: function(data, event) {
5315
5316		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
5317
5318		if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
5319		else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
5320
5321		if (a == 'sw') {
5322			data.left = cpos.left + (csize.width - data.width);
5323			data.top = null;
5324		}
5325		if (a == 'nw') {
5326			data.top = cpos.top + (csize.height - data.height);
5327			data.left = cpos.left + (csize.width - data.width);
5328		}
5329
5330		return data;
5331	},
5332
5333	_respectSize: function(data, event) {
5334
5335		var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
5336				ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
5337					isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
5338
5339		if (isminw) data.width = o.minWidth;
5340		if (isminh) data.height = o.minHeight;
5341		if (ismaxw) data.width = o.maxWidth;
5342		if (ismaxh) data.height = o.maxHeight;
5343
5344		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
5345		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
5346
5347		if (isminw && cw) data.left = dw - o.minWidth;
5348		if (ismaxw && cw) data.left = dw - o.maxWidth;
5349		if (isminh && ch)	data.top = dh - o.minHeight;
5350		if (ismaxh && ch)	data.top = dh - o.maxHeight;
5351
5352		// fixing jump error on top/left - bug #2330
5353		var isNotwh = !data.width && !data.height;
5354		if (isNotwh && !data.left && data.top) data.top = null;
5355		else if (isNotwh && !data.top && data.left) data.left = null;
5356
5357		return data;
5358	},
5359
5360	_proportionallyResize: function() {
5361
5362		var o = this.options;
5363		if (!this._proportionallyResizeElements.length) return;
5364		var element = this.helper || this.element;
5365
5366		for (var i=0; i < this._proportionallyResizeElements.length; i++) {
5367
5368			var prel = this._proportionallyResizeElements[i];
5369
5370			if (!this.borderDif) {
5371				var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
5372					p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
5373
5374				this.borderDif = $.map(b, function(v, i) {
5375					var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
5376					return border + padding;
5377				});
5378			}
5379
5380			prel.css({
5381				height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
5382				width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
5383			});
5384
5385		};
5386
5387	},
5388
5389	_renderProxy: function() {
5390
5391		var el = this.element, o = this.options;
5392		this.elementOffset = el.offset();
5393
5394		if(this._helper) {
5395
5396			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
5397
5398			// fix ie6 offset TODO: This seems broken
5399			var ie6offset = ($.ui.ie6 ? 1 : 0),
5400			pxyoffset = ( $.ui.ie6 ? 2 : -1 );
5401
5402			this.helper.addClass(this._helper).css({
5403				width: this.element.outerWidth() + pxyoffset,
5404				height: this.element.outerHeight() + pxyoffset,
5405				position: 'absolute',
5406				left: this.elementOffset.left - ie6offset +'px',
5407				top: this.elementOffset.top - ie6offset +'px',
5408				zIndex: ++o.zIndex //TODO: Don't modify option
5409			});
5410
5411			this.helper
5412				.appendTo("body")
5413				.disableSelection();
5414
5415		} else {
5416			this.helper = this.element;
5417		}
5418
5419	},
5420
5421	_change: {
5422		e: function(event, dx, dy) {
5423			return { width: this.originalSize.width + dx };
5424		},
5425		w: function(event, dx, dy) {
5426			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
5427			return { left: sp.left + dx, width: cs.width - dx };
5428		},
5429		n: function(event, dx, dy) {
5430			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
5431			return { top: sp.top + dy, height: cs.height - dy };
5432		},
5433		s: function(event, dx, dy) {
5434			return { height: this.originalSize.height + dy };
5435		},
5436		se: function(event, dx, dy) {
5437			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
5438		},
5439		sw: function(event, dx, dy) {
5440			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
5441		},
5442		ne: function(event, dx, dy) {
5443			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
5444		},
5445		nw: function(event, dx, dy) {
5446			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
5447		}
5448	},
5449
5450	_propagate: function(n, event) {
5451		$.ui.plugin.call(this, n, [event, this.ui()]);
5452		(n != "resize" && this._trigger(n, event, this.ui()));
5453	},
5454
5455	plugins: {},
5456
5457	ui: function() {
5458		return {
5459			originalElement: this.originalElement,
5460			element: this.element,
5461			helper: this.helper,
5462			position: this.position,
5463			size: this.size,
5464			originalSize: this.originalSize,
5465			originalPosition: this.originalPosition
5466		};
5467	}
5468
5469});
5470
5471/*
5472 * Resizable Extensions
5473 */
5474
5475$.ui.plugin.add("resizable", "alsoResize", {
5476
5477	start: function (event, ui) {
5478		var that = $(this).data("resizable"), o = that.options;
5479
5480		var _store = function (exp) {
5481			$(exp).each(function() {
5482				var el = $(this);
5483				el.data("resizable-alsoresize", {
5484					width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
5485					left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
5486				});
5487			});
5488		};
5489
5490		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
5491			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
5492			else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
5493		}else{
5494			_store(o.alsoResize);
5495		}
5496	},
5497
5498	resize: function (event, ui) {
5499		var that = $(this).data("resizable"), o = that.options, os = that.originalSize, op = that.originalPosition;
5500
5501		var delta = {
5502			height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
5503			top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
5504		},
5505
5506		_alsoResize = function (exp, c) {
5507			$(exp).each(function() {
5508				var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
5509					css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
5510
5511				$.each(css, function (i, prop) {
5512					var sum = (start[prop]||0) + (delta[prop]||0);
5513					if (sum && sum >= 0)
5514						style[prop] = sum || null;
5515				});
5516
5517				el.css(style);
5518			});
5519		};
5520
5521		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
5522			$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
5523		}else{
5524			_alsoResize(o.alsoResize);
5525		}
5526	},
5527
5528	stop: function (event, ui) {
5529		$(this).removeData("resizable-alsoresize");
5530	}
5531});
5532
5533$.ui.plugin.add("resizable", "animate", {
5534
5535	stop: function(event, ui) {
5536		var that = $(this).data("resizable"), o = that.options;
5537
5538		var pr = that._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
5539					soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : that.sizeDiff.height,
5540						soffsetw = ista ? 0 : that.sizeDiff.width;
5541
5542		var style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
5543					left = (parseInt(that.element.css('left'), 10) + (that.position.left - that.originalPosition.left)) || null,
5544						top = (parseInt(that.element.css('top'), 10) + (that.position.top - that.originalPosition.top)) || null;
5545
5546		that.element.animate(
5547			$.extend(style, top && left ? { top: top, left: left } : {}), {
5548				duration: o.animateDuration,
5549				easing: o.animateEasing,
5550				step: function() {
5551
5552					var data = {
5553						width: parseInt(that.element.css('width'), 10),
5554						height: parseInt(that.element.css('height'), 10),
5555						top: parseInt(that.element.css('top'), 10),
5556						left: parseInt(that.element.css('left'), 10)
5557					};
5558
5559					if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
5560
5561					// propagating resize, and updating values for each animation step
5562					that._updateCache(data);
5563					that._propagate("resize", event);
5564
5565				}
5566			}
5567		);
5568	}
5569
5570});
5571
5572$.ui.plugin.add("resizable", "containment", {
5573
5574	start: function(event, ui) {
5575		var that = $(this).data("resizable"), o = that.options, el = that.element;
5576		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
5577		if (!ce) return;
5578
5579		that.containerElement = $(ce);
5580
5581		if (/document/.test(oc) || oc == document) {
5582			that.containerOffset = { left: 0, top: 0 };
5583			that.containerPosition = { left: 0, top: 0 };
5584
5585			that.parentData = {
5586				element: $(document), left: 0, top: 0,
5587				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
5588			};
5589		}
5590
5591		// i'm a node, so compute top, left, right, bottom
5592		else {
5593			var element = $(ce), p = [];
5594			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
5595
5596			that.containerOffset = element.offset();
5597			that.containerPosition = element.position();
5598			that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
5599
5600			var co = that.containerOffset, ch = that.containerSize.height,	cw = that.containerSize.width,
5601						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
5602
5603			that.parentData = {
5604				element: ce, left: co.left, top: co.top, width: width, height: height
5605			};
5606		}
5607	},
5608
5609	resize: function(event, ui) {
5610		var that = $(this).data("resizable"), o = that.options,
5611				ps = that.containerSize, co = that.containerOffset, cs = that.size, cp = that.position,
5612				pRatio = that._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = that.containerElement;
5613
5614		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
5615
5616		if (cp.left < (that._helper ? co.left : 0)) {
5617			that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
5618			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
5619			that.position.left = o.helper ? co.left : 0;
5620		}
5621
5622		if (cp.top < (that._helper ? co.top : 0)) {
5623			that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
5624			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
5625			that.position.top = that._helper ? co.top : 0;
5626		}
5627
5628		that.offset.left = that.parentData.left+that.position.left;
5629		that.offset.top = that.parentData.top+that.position.top;
5630
5631		var woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ),
5632					hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
5633
5634		var isParent = that.containerElement.get(0) == that.element.parent().get(0),
5635			isOffsetRelative = /relative|absolute/.test(that.containerElement.css('position'));
5636
5637		if(isParent && isOffsetRelative) woset -= that.parentData.left;
5638
5639		if (woset + that.size.width >= that.parentData.width) {
5640			that.size.width = that.parentData.width - woset;
5641			if (pRatio) that.size.height = that.size.width / that.aspectRatio;
5642		}
5643
5644		if (hoset + that.size.height >= that.parentData.height) {
5645			that.size.height = that.parentData.height - hoset;
5646			if (pRatio) that.size.width = that.size.height * that.aspectRatio;
5647		}
5648	},
5649
5650	stop: function(event, ui){
5651		var that = $(this).data("resizable"), o = that.options, cp = that.position,
5652				co = that.containerOffset, cop = that.containerPosition, ce = that.containerElement;
5653
5654		var helper = $(that.helper), ho = helper.offset(), w = helper.outerWidth() - that.sizeDiff.width, h = helper.outerHeight() - that.sizeDiff.height;
5655
5656		if (that._helper && !o.animate && (/relative/).test(ce.css('position')))
5657			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
5658
5659		if (that._helper && !o.animate && (/static/).test(ce.css('position')))
5660			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
5661
5662	}
5663});
5664
5665$.ui.plugin.add("resizable", "ghost", {
5666
5667	start: function(event, ui) {
5668
5669		var that = $(this).data("resizable"), o = that.options, cs = that.size;
5670
5671		that.ghost = that.originalElement.clone();
5672		that.ghost
5673			.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
5674			.addClass('ui-resizable-ghost')
5675			.addClass(typeof o.ghost == 'string' ? o.ghost : '');
5676
5677		that.ghost.appendTo(that.helper);
5678
5679	},
5680
5681	resize: function(event, ui){
5682		var that = $(this).data("resizable"), o = that.options;
5683		if (that.ghost) that.ghost.css({ position: 'relative', height: that.size.height, width: that.size.width });
5684	},
5685
5686	stop: function(event, ui){
5687		var that = $(this).data("resizable"), o = that.options;
5688		if (that.ghost && that.helper) that.helper.get(0).removeChild(that.ghost.get(0));
5689	}
5690
5691});
5692
5693$.ui.plugin.add("resizable", "grid", {
5694
5695	resize: function(event, ui) {
5696		var that = $(this).data("resizable"), o = that.options, cs = that.size, os = that.originalSize, op = that.originalPosition, a = that.axis, ratio = o._aspectRatio || event.shiftKey;
5697		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
5698		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
5699
5700		if (/^(se|s|e)$/.test(a)) {
5701			that.size.width = os.width + ox;
5702			that.size.height = os.height + oy;
5703		}
5704		else if (/^(ne)$/.test(a)) {
5705			that.size.width = os.width + ox;
5706			that.size.height = os.height + oy;
5707			that.position.top = op.top - oy;
5708		}
5709		else if (/^(sw)$/.test(a)) {
5710			that.size.width = os.width + ox;
5711			that.size.height = os.height + oy;
5712			that.position.left = op.left - ox;
5713		}
5714		else {
5715			that.size.width = os.width + ox;
5716			that.size.height = os.height + oy;
5717			that.position.top = op.top - oy;
5718			that.position.left = op.left - ox;
5719		}
5720	}
5721
5722});
5723
5724var num = function(v) {
5725	return parseInt(v, 10) || 0;
5726};
5727
5728var isNumber = function(value) {
5729	return !isNaN(parseInt(value, 10));
5730};
5731
5732})(jQuery);
5733
5734(function( $, undefined ) {
5735
5736$.widget("ui.selectable", $.ui.mouse, {
5737	version: "1.9.1",
5738	options: {
5739		appendTo: 'body',
5740		autoRefresh: true,
5741		distance: 0,
5742		filter: '*',
5743		tolerance: 'touch'
5744	},
5745	_create: function() {
5746		var that = this;
5747
5748		this.element.addClass("ui-selectable");
5749
5750		this.dragged = false;
5751
5752		// cache selectee children based on filter
5753		var selectees;
5754		this.refresh = function() {
5755			selectees = $(that.options.filter, that.element[0]);
5756			selectees.addClass("ui-selectee");
5757			selectees.each(function() {
5758				var $this = $(this);
5759				var pos = $this.offset();
5760				$.data(this, "selectable-item", {
5761					element: this,
5762					$element: $this,
5763					left: pos.left,
5764					top: pos.top,
5765					right: pos.left + $this.outerWidth(),
5766					bottom: pos.top + $this.outerHeight(),
5767					startselected: false,
5768					selected: $this.hasClass('ui-selected'),
5769					selecting: $this.hasClass('ui-selecting'),
5770					unselecting: $this.hasClass('ui-unselecting')
5771				});
5772			});
5773		};
5774		this.refresh();
5775
5776		this.selectees = selectees.addClass("ui-selectee");
5777
5778		this._mouseInit();
5779
5780		this.helper = $("<div class='ui-selectable-helper'></div>");
5781	},
5782
5783	_destroy: function() {
5784		this.selectees
5785			.removeClass("ui-selectee")
5786			.removeData("selectable-item");
5787		this.element
5788			.removeClass("ui-selectable ui-selectable-disabled");
5789		this._mouseDestroy();
5790	},
5791
5792	_mouseStart: function(event) {
5793		var that = this;
5794
5795		this.opos = [event.pageX, event.pageY];
5796
5797		if (this.options.disabled)
5798			return;
5799
5800		var options = this.options;
5801
5802		this.selectees = $(options.filter, this.element[0]);
5803
5804		this._trigger("start", event);
5805
5806		$(options.appendTo).append(this.helper);
5807		// position helper (lasso)
5808		this.helper.css({
5809			"left": event.clientX,
5810			"top": event.clientY,
5811			"width": 0,
5812			"height": 0
5813		});
5814
5815		if (options.autoRefresh) {
5816			this.refresh();
5817		}
5818
5819		this.selectees.filter('.ui-selected').each(function() {
5820			var selectee = $.data(this, "selectable-item");
5821			selectee.startselected = true;
5822			if (!event.metaKey && !event.ctrlKey) {
5823				selectee.$element.removeClass('ui-selected');
5824				selectee.selected = false;
5825				selectee.$element.addClass('ui-unselecting');
5826				selectee.unselecting = true;
5827				// selectable UNSELECTING callback
5828				that._trigger("unselecting", event, {
5829					unselecting: selectee.element
5830				});
5831			}
5832		});
5833
5834		$(event.target).parents().andSelf().each(function() {
5835			var selectee = $.data(this, "selectable-item");
5836			if (selectee) {
5837				var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
5838				selectee.$element
5839					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
5840					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
5841				selectee.unselecting = !doSelect;
5842				selectee.selecting = doSelect;
5843				selectee.selected = doSelect;
5844				// selectable (UN)SELECTING callback
5845				if (doSelect) {
5846					that._trigger("selecting", event, {
5847						selecting: selectee.element
5848					});
5849				} else {
5850					that._trigger("unselecting", event, {
5851						unselecting: selectee.element
5852					});
5853				}
5854				return false;
5855			}
5856		});
5857
5858	},
5859
5860	_mouseDrag: function(event) {
5861		var that = this;
5862		this.dragged = true;
5863
5864		if (this.options.disabled)
5865			return;
5866
5867		var options = this.options;
5868
5869		var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
5870		if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
5871		if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
5872		this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
5873
5874		this.selectees.each(function() {
5875			var selectee = $.data(this, "selectable-item");
5876			//prevent helper from being selected if appendTo: selectable
5877			if (!selectee || selectee.element == that.element[0])
5878				return;
5879			var hit = false;
5880			if (options.tolerance == 'touch') {
5881				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
5882			} else if (options.tolerance == 'fit') {
5883				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
5884			}
5885
5886			if (hit) {
5887				// SELECT
5888				if (selectee.selected) {
5889					selectee.$element.removeClass('ui-selected');
5890					selectee.selected = false;
5891				}
5892				if (selectee.unselecting) {
5893					selectee.$element.removeClass('ui-unselecting');
5894					selectee.unselecting = false;
5895				}
5896				if (!selectee.selecting) {
5897					selectee.$element.addClass('ui-selecting');
5898					selectee.selecting = true;
5899					// selectable SELECTING callback
5900					that._trigger("selecting", event, {
5901						selecting: selectee.element
5902					});
5903				}
5904			} else {
5905				// UNSELECT
5906				if (selectee.selecting) {
5907					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
5908						selectee.$element.removeClass('ui-selecting');
5909						selectee.selecting = false;
5910						selectee.$element.addClass('ui-selected');
5911						selectee.selected = true;
5912					} else {
5913						selectee.$element.removeClass('ui-selecting');
5914						selectee.selecting = false;
5915						if (selectee.startselected) {
5916							selectee.$element.addClass('ui-unselecting');
5917							selectee.unselecting = true;
5918						}
5919						// selectable UNSELECTING callback
5920						that._trigger("unselecting", event, {
5921							unselecting: selectee.element
5922						});
5923					}
5924				}
5925				if (selectee.selected) {
5926					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
5927						selectee.$element.removeClass('ui-selected');
5928						selectee.selected = false;
5929
5930						selectee.$element.addClass('ui-unselecting');
5931						selectee.unselecting = true;
5932						// selectable UNSELECTING callback
5933						that._trigger("unselecting", event, {
5934							unselecting: selectee.element
5935						});
5936					}
5937				}
5938			}
5939		});
5940
5941		return false;
5942	},
5943
5944	_mouseStop: function(event) {
5945		var that = this;
5946
5947		this.dragged = false;
5948
5949		var options = this.options;
5950
5951		$('.ui-unselecting', this.element[0]).each(function() {
5952			var selectee = $.data(this, "selectable-item");
5953			selectee.$element.removeClass('ui-unselecting');
5954			selectee.unselecting = false;
5955			selectee.startselected = false;
5956			that._trigger("unselected", event, {
5957				unselected: selectee.element
5958			});
5959		});
5960		$('.ui-selecting', this.element[0]).each(function() {
5961			var selectee = $.data(this, "selectable-item");
5962			selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
5963			selectee.selecting = false;
5964			selectee.selected = true;
5965			selectee.startselected = true;
5966			that._trigger("selected", event, {
5967				selected: selectee.element
5968			});
5969		});
5970		this._trigger("stop", event);
5971
5972		this.helper.remove();
5973
5974		return false;
5975	}
5976
5977});
5978
5979})(jQuery);
5980
5981(function( $, undefined ) {
5982
5983$.widget("ui.sortable", $.ui.mouse, {
5984	version: "1.9.1",
5985	widgetEventPrefix: "sort",
5986	ready: false,
5987	options: {
5988		appendTo: "parent",
5989		axis: false,
5990		connectWith: false,
5991		containment: false,
5992		cursor: 'auto',
5993		cursorAt: false,
5994		dropOnEmpty: true,
5995		forcePlaceholderSize: false,
5996		forceHelperSize: false,
5997		grid: false,
5998		handle: false,
5999		helper: "original",
6000		items: '> *',
6001		opacity: false,
6002		placeholder: false,
6003		revert: false,
6004		scroll: true,
6005		scrollSensitivity: 20,
6006		scrollSpeed: 20,
6007		scope: "default",
6008		tolerance: "intersect",
6009		zIndex: 1000
6010	},
6011	_create: function() {
6012
6013		var o = this.options;
6014		this.containerCache = {};
6015		this.element.addClass("ui-sortable");
6016
6017		//Get the items
6018		this.refresh();
6019
6020		//Let's determine if the items are being displayed horizontally
6021		this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
6022
6023		//Let's determine the parent's offset
6024		this.offset = this.element.offset();
6025
6026		//Initialize mouse events for interaction
6027		this._mouseInit();
6028
6029		//We're ready to go
6030		this.ready = true
6031
6032	},
6033
6034	_destroy: function() {
6035		this.element
6036			.removeClass("ui-sortable ui-sortable-disabled");
6037		this._mouseDestroy();
6038
6039		for ( var i = this.items.length - 1; i >= 0; i-- )
6040			this.items[i].item.removeData(this.widgetName + "-item");
6041
6042		return this;
6043	},
6044
6045	_setOption: function(key, value){
6046		if ( key === "disabled" ) {
6047			this.options[ key ] = value;
6048
6049			this.widget().toggleClass( "ui-sortable-disabled", !!value );
6050		} else {
6051			// Don't call widget base _setOption for disable as it adds ui-state-disabled class
6052			$.Widget.prototype._setOption.apply(this, arguments);
6053		}
6054	},
6055
6056	_mouseCapture: function(event, overrideHandle) {
6057		var that = this;
6058
6059		if (this.reverting) {
6060			return false;
6061		}
6062
6063		if(this.options.disabled || this.options.type == 'static') return false;
6064
6065		//We have to refresh the items data once first
6066		this._refreshItems(event);
6067
6068		//Find out if the clicked node (or one of its parents) is a actual item in this.items
6069		var currentItem = null, nodes = $(event.target).parents().each(function() {
6070			if($.data(this, that.widgetName + '-item') == that) {
6071				currentItem = $(this);
6072				return false;
6073			}
6074		});
6075		if($.data(event.target, that.widgetName + '-item') == that) currentItem = $(event.target);
6076
6077		if(!currentItem) return false;
6078		if(this.options.handle && !overrideHandle) {
6079			var validHandle = false;
6080
6081			$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
6082			if(!validHandle) return false;
6083		}
6084
6085		this.currentItem = currentItem;
6086		this._removeCurrentsFromItems();
6087		return true;
6088
6089	},
6090
6091	_mouseStart: function(event, overrideHandle, noActivation) {
6092
6093		var o = this.options;
6094		this.currentContainer = this;
6095
6096		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
6097		this.refreshPositions();
6098
6099		//Create and append the visible helper
6100		this.helper = this._createHelper(event);
6101
6102		//Cache the helper size
6103		this._cacheHelperProportions();
6104
6105		/*
6106		 * - Position generation -
6107		 * This block generates everything position related - it's the core of draggables.
6108		 */
6109
6110		//Cache the margins of the original element
6111		this._cacheMargins();
6112
6113		//Get the next scrolling parent
6114		this.scrollParent = this.helper.scrollParent();
6115
6116		//The element's absolute position on the page minus margins
6117		this.offset = this.currentItem.offset();
6118		this.offset = {
6119			top: this.offset.top - this.margins.top,
6120			left: this.offset.left - this.margins.left
6121		};
6122
6123		$.extend(this.offset, {
6124			click: { //Where the click happened, relative to the element
6125				left: event.pageX - this.offset.left,
6126				top: event.pageY - this.offset.top
6127			},
6128			parent: this._getParentOffset(),
6129			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
6130		});
6131
6132		// Only after we got the offset, we can change the helper's position to absolute
6133		// TODO: Still need to figure out a way to make relative sorting possible
6134		this.helper.css("position", "absolute");
6135		this.cssPosition = this.helper.css("position");
6136
6137		//Generate the original position
6138		this.originalPosition = this._generatePosition(event);
6139		this.originalPageX = event.pageX;
6140		this.originalPageY = event.pageY;
6141
6142		//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
6143		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6144
6145		//Cache the former DOM position
6146		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
6147
6148		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
6149		if(this.helper[0] != this.currentItem[0]) {
6150			this.currentItem.hide();
6151		}
6152
6153		//Create the placeholder
6154		this._createPlaceholder();
6155
6156		//Set a containment if given in the options
6157		if(o.containment)
6158			this._setContainment();
6159
6160		if(o.cursor) { // cursor option
6161			if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
6162			$('body').css("cursor", o.cursor);
6163		}
6164
6165		if(o.opacity) { // opacity option
6166			if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
6167			this.helper.css("opacity", o.opacity);
6168		}
6169
6170		if(o.zIndex) { // zIndex option
6171			if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
6172			this.helper.css("zIndex", o.zIndex);
6173		}
6174
6175		//Prepare scrolling
6176		if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
6177			this.overflowOffset = this.scrollParent.offset();
6178
6179		//Call callbacks
6180		this._trigger("start", event, this._uiHash());
6181
6182		//Recache the helper size
6183		if(!this._preserveHelperProportions)
6184			this._cacheHelperProportions();
6185
6186
6187		//Post 'activate' events to possible containers
6188		if(!noActivation) {
6189			 for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, this._uiHash(this)); }
6190		}
6191
6192		//Prepare possible droppables
6193		if($.ui.ddmanager)
6194			$.ui.ddmanager.current = this;
6195
6196		if ($.ui.ddmanager && !o.dropBehaviour)
6197			$.ui.ddmanager.prepareOffsets(this, event);
6198
6199		this.dragging = true;
6200
6201		this.helper.addClass("ui-sortable-helper");
6202		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6203		return true;
6204
6205	},
6206
6207	_mouseDrag: function(event) {
6208
6209		//Compute the helpers position
6210		this.position = this._generatePosition(event);
6211		this.positionAbs = this._convertPositionTo("absolute");
6212
6213		if (!this.lastPositionAbs) {
6214			this.lastPositionAbs = this.positionAbs;
6215		}
6216
6217		//Do scrolling
6218		if(this.options.scroll) {
6219			var o = this.options, scrolled = false;
6220			if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
6221
6222				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
6223					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
6224				else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
6225					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
6226
6227				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
6228					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
6229				else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
6230					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
6231
6232			} else {
6233
6234				if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
6235					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6236				else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
6237					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6238
6239				if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
6240					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6241				else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
6242					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6243
6244			}
6245
6246			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
6247				$.ui.ddmanager.prepareOffsets(this, event);
6248		}
6249
6250		//Regenerate the absolute position used for position checks
6251		this.positionAbs = this._convertPositionTo("absolute");
6252
6253		//Set the helper position
6254		if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
6255		if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
6256
6257		//Rearrange
6258		for (var i = this.items.length - 1; i >= 0; i--) {
6259
6260			//Cache variables and intersection, continue if no intersection
6261			var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
6262			if (!intersection) continue;
6263
6264			// Only put the placeholder inside the current Container, skip all
6265			// items form other containers. This works because when moving
6266			// an item from one container to another the
6267			// currentContainer is switched before the placeholder is moved.
6268			//
6269			// Without this moving items in "sub-sortables" can cause the placeholder to jitter
6270			// beetween the outer and inner container.
6271			if (item.instance !== this.currentContainer) continue;
6272
6273			if (itemElement != this.currentItem[0] //cannot intersect with itself
6274				&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
6275				&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
6276				&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
6277				//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
6278			) {
6279
6280				this.direction = intersection == 1 ? "down" : "up";
6281
6282				if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
6283					this._rearrange(event, item);
6284				} else {
6285					break;
6286				}
6287
6288				this._trigger("change", event, this._uiHash());
6289				break;
6290			}
6291		}
6292
6293		//Post events to containers
6294		this._contactContainers(event);
6295
6296		//Interconnect with droppables
6297		if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
6298
6299		//Call callbacks
6300		this._trigger('sort', event, this._uiHash());
6301
6302		this.lastPositionAbs = this.positionAbs;
6303		return false;
6304
6305	},
6306
6307	_mouseStop: function(event, noPropagation) {
6308
6309		if(!event) return;
6310
6311		//If we are using droppables, inform the manager about the drop
6312		if ($.ui.ddmanager && !this.options.dropBehaviour)
6313			$.ui.ddmanager.drop(this, event);
6314
6315		if(this.options.revert) {
6316			var that = this;
6317			var cur = this.placeholder.offset();
6318
6319			this.reverting = true;
6320
6321			$(this.helper).animate({
6322				left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
6323				top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
6324			}, parseInt(this.options.revert, 10) || 500, function() {
6325				that._clear(event);
6326			});
6327		} else {
6328			this._clear(event, noPropagation);
6329		}
6330
6331		return false;
6332
6333	},
6334
6335	cancel: function() {
6336
6337		if(this.dragging) {
6338
6339			this._mouseUp({ target: null });
6340
6341			if(this.options.helper == "original")
6342				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
6343			else
6344				this.currentItem.show();
6345
6346			//Post deactivating events to containers
6347			for (var i = this.containers.length - 1; i >= 0; i--){
6348				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
6349				if(this.containers[i].containerCache.over) {
6350					this.containers[i]._trigger("out", null, this._uiHash(this));
6351					this.containers[i].containerCache.over = 0;
6352				}
6353			}
6354
6355		}
6356
6357		if (this.placeholder) {
6358			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
6359			if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
6360			if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
6361
6362			$.extend(this, {
6363				helper: null,
6364				dragging: false,
6365				reverting: false,
6366				_noFinalSort: null
6367			});
6368
6369			if(this.domPosition.prev) {
6370				$(this.domPosition.prev).after(this.currentItem);
6371			} else {
6372				$(this.domPosition.parent).prepend(this.currentItem);
6373			}
6374		}
6375
6376		return this;
6377
6378	},
6379
6380	serialize: function(o) {
6381
6382		var items = this._getItemsAsjQuery(o && o.connected);
6383		var str = []; o = o || {};
6384
6385		$(items).each(function() {
6386			var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
6387			if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
6388		});
6389
6390		if(!str.length && o.key) {
6391			str.push(o.key + '=');
6392		}
6393
6394		return str.join('&');
6395
6396	},
6397
6398	toArray: function(o) {
6399
6400		var items = this._getItemsAsjQuery(o && o.connected);
6401		var ret = []; o = o || {};
6402
6403		items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
6404		return ret;
6405
6406	},
6407
6408	/* Be careful with the following core functions */
6409	_intersectsWith: function(item) {
6410
6411		var x1 = this.positionAbs.left,
6412			x2 = x1 + this.helperProportions.width,
6413			y1 = this.positionAbs.top,
6414			y2 = y1 + this.helperProportions.height;
6415
6416		var l = item.left,
6417			r = l + item.width,
6418			t = item.top,
6419			b = t + item.height;
6420
6421		var dyClick = this.offset.click.top,
6422			dxClick = this.offset.click.left;
6423
6424		var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
6425
6426		if(	   this.options.tolerance == "pointer"
6427			|| this.options.forcePointerForContainers
6428			|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
6429		) {
6430			return isOverElement;
6431		} else {
6432
6433			return (l < x1 + (this.helperProportions.width / 2) // Right Half
6434				&& x2 - (this.helperProportions.width / 2) < r // Left Half
6435				&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
6436				&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
6437
6438		}
6439	},
6440
6441	_intersectsWithPointer: function(item) {
6442
6443		var isOverElementHeight = (this.options.axis === 'x') || $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
6444			isOverElementWidth = (this.options.axis === 'y') || $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
6445			isOverElement = isOverElementHeight && isOverElementWidth,
6446			verticalDirection = this._getDragVerticalDirection(),
6447			horizontalDirection = this._getDragHorizontalDirection();
6448
6449		if (!isOverElement)
6450			return false;
6451
6452		return this.floating ?
6453			( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
6454			: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
6455
6456	},
6457
6458	_intersectsWithSides: function(item) {
6459
6460		var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
6461			isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
6462			verticalDirection = this._getDragVerticalDirection(),
6463			horizontalDirection = this._getDragHorizontalDirection();
6464
6465		if (this.floating && horizontalDirection) {
6466			return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
6467		} else {
6468			return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
6469		}
6470
6471	},
6472
6473	_getDragVerticalDirection: function() {
6474		var delta = this.positionAbs.top - this.lastPositionAbs.top;
6475		return delta != 0 && (delta > 0 ? "down" : "up");
6476	},
6477
6478	_getDragHorizontalDirection: function() {
6479		var delta = this.positionAbs.left - this.lastPositionAbs.left;
6480		return delta != 0 && (delta > 0 ? "right" : "left");
6481	},
6482
6483	refresh: function(event) {
6484		this._refreshItems(event);
6485		this.refreshPositions();
6486		return this;
6487	},
6488
6489	_connectWith: function() {
6490		var options = this.options;
6491		return options.connectWith.constructor == String
6492			? [options.connectWith]
6493			: options.connectWith;
6494	},
6495
6496	_getItemsAsjQuery: function(connected) {
6497
6498		var items = [];
6499		var queries = [];
6500		var connectWith = this._connectWith();
6501
6502		if(connectWith && connected) {
6503			for (var i = connectWith.length - 1; i >= 0; i--){
6504				var cur = $(connectWith[i]);
6505				for (var j = cur.length - 1; j >= 0; j--){
6506					var inst = $.data(cur[j], this.widgetName);
6507					if(inst && inst != this && !inst.options.disabled) {
6508						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
6509					}
6510				};
6511			};
6512		}
6513
6514		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
6515
6516		for (var i = queries.length - 1; i >= 0; i--){
6517			queries[i][0].each(function() {
6518				items.push(this);
6519			});
6520		};
6521
6522		return $(items);
6523
6524	},
6525
6526	_removeCurrentsFromItems: function() {
6527
6528		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
6529
6530		this.items = $.grep(this.items, function (item) {
6531			for (var j=0; j < list.length; j++) {
6532				if(list[j] == item.item[0])
6533					return false;
6534			};
6535			return true;
6536		});
6537
6538	},
6539
6540	_refreshItems: function(event) {
6541
6542		this.items = [];
6543		this.containers = [this];
6544		var items = this.items;
6545		var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
6546		var connectWith = this._connectWith();
6547
6548		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
6549			for (var i = connectWith.length - 1; i >= 0; i--){
6550				var cur = $(connectWith[i]);
6551				for (var j = cur.length - 1; j >= 0; j--){
6552					var inst = $.data(cur[j], this.widgetName);
6553					if(inst && inst != this && !inst.options.disabled) {
6554						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
6555						this.containers.push(inst);
6556					}
6557				};
6558			};
6559		}
6560
6561		for (var i = queries.length - 1; i >= 0; i--) {
6562			var targetData = queries[i][1];
6563			var _queries = queries[i][0];
6564
6565			for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
6566				var item = $(_queries[j]);
6567
6568				item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
6569
6570				items.push({
6571					item: item,
6572					instance: targetData,
6573					width: 0, height: 0,
6574					left: 0, top: 0
6575				});
6576			};
6577		};
6578
6579	},
6580
6581	refreshPositions: function(fast) {
6582
6583		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
6584		if(this.offsetParent && this.helper) {
6585			this.offset.parent = this._getParentOffset();
6586		}
6587
6588		for (var i = this.items.length - 1; i >= 0; i--){
6589			var item = this.items[i];
6590
6591			//We ignore calculating positions of all connected containers when we're not over them
6592			if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
6593				continue;
6594
6595			var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
6596
6597			if (!fast) {
6598				item.width = t.outerWidth();
6599				item.height = t.outerHeight();
6600			}
6601
6602			var p = t.offset();
6603			item.left = p.left;
6604			item.top = p.top;
6605		};
6606
6607		if(this.options.custom && this.options.custom.refreshContainers
6607) {
6608			this.options.custom.refreshContainers.call(this);
6609		} else {
6610			for (var i = this.containers.length - 1; i >= 0; i--){
6611				var p = this.containers[i].element.offset();
6612				this.containers[i].containerCache.left = p.left;
6613				this.containers[i].containerCache.top = p.top;
6614				this.containers[i].containerCache.width	= this.containers[i].element.outerWidth();
6615				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
6616			};
6617		}
6618
6619		return this;
6620	},
6621
6622	_createPlaceholder: function(that) {
6623		that = that || this;
6624		var o = that.options;
6625
6626		if(!o.placeholder || o.placeholder.constructor == String) {
6627			var className = o.placeholder;
6628			o.placeholder = {
6629				element: function() {
6630
6631					var el = $(document.createElement(that.currentItem[0].nodeName))
6632						.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
6633						.removeClass("ui-sortable-helper")[0];
6634
6635					if(!className)
6636						el.style.visibility = "hidden";
6637
6638					return el;
6639				},
6640				update: function(container, p) {
6641
6642					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
6643					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
6644					if(className && !o.forcePlaceholderSize) return;
6645
6646					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
6647					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css('paddingTop')||0, 10) - parseInt(that.currentItem.css('paddingBottom')||0, 10)); };
6648					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css('paddingLeft')||0, 10) - parseInt(that.currentItem.css('paddingRight')||0, 10)); };
6649				}
6650			};
6651		}
6652
6653		//Create the placeholder
6654		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
6655
6656		//Append it after the actual current item
6657		that.currentItem.after(that.placeholder);
6658
6659		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
6660		o.placeholder.update(that, that.placeholder);
6661
6662	},
6663
6664	_contactContainers: function(event) {
6665
6666		// get innermost container that intersects with item
6667		var innermostContainer = null, innermostIndex = null;
6668
6669
6670		for (var i = this.containers.length - 1; i >= 0; i--){
6671
6672			// never consider a container that's located within the item itself
6673			if($.contains(this.currentItem[0], this.containers[i].element[0]))
6674				continue;
6675
6676			if(this._intersectsWith(this.containers[i].containerCache)) {
6677
6678				// if we've already found a container and it's more "inner" than this, then continue
6679				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0]))
6680					continue;
6681
6682				innermostContainer = this.containers[i];
6683				innermostIndex = i;
6684
6685			} else {
6686				// container doesn't intersect. trigger "out" event if necessary
6687				if(this.containers[i].containerCache.over) {
6688					this.containers[i]._trigger("out", event, this._uiHash(this));
6689					this.containers[i].containerCache.over = 0;
6690				}
6691			}
6692
6693		}
6694
6695		// if no intersecting containers found, return
6696		if(!innermostContainer) return;
6697
6698		// move the item into the container if it's not there already
6699		if(this.containers.length === 1) {
6700			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
6701			this.containers[innermostIndex].containerCache.over = 1;
6702		} else {
6703
6704			//When entering a new container, we will find the item with the least distance and append our item near it
6705			var dist = 10000; var itemWithLeastDistance = null;
6706			var posProperty = this.containers[innermostIndex].floating ? 'left' : 'top';
6707			var sizeProperty = this.containers[innermostIndex].floating ? 'width' : 'height';
6708			var base = this.positionAbs[posProperty] + this.offset.click[posProperty];
6709			for (var j = this.items.length - 1; j >= 0; j--) {
6710				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
6711				if(this.items[j].item[0] == this.currentItem[0]) continue;
6712				var cur = this.items[j].item.offset()[posProperty];
6713				var nearBottom = false;
6714				if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
6715					nearBottom = true;
6716					cur += this.items[j][sizeProperty];
6717				}
6718
6719				if(Math.abs(cur - base) < dist) {
6720					dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
6721					this.direction = nearBottom ? "up": "down";
6722				}
6723			}
6724
6725			if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
6726				return;
6727
6728			this.currentContainer = this.containers[innermostIndex];
6729			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
6730			this._trigger("change", event, this._uiHash());
6731			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
6732
6733			//Update the placeholder
6734			this.options.placeholder.update(this.currentContainer, this.placeholder);
6735
6736			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
6737			this.containers[innermostIndex].containerCache.over = 1;
6738		}
6739
6740
6741	},
6742
6743	_createHelper: function(event) {
6744
6745		var o = this.options;
6746		var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
6747
6748		if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
6749			$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
6750
6751		if(helper[0] == this.currentItem[0])
6752			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left
6752: this.currentItem.css("left") };
6753
6754		if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
6755		if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
6756
6757		return helper;
6758
6759	},
6760
6761	_adjustOffsetFromHelper: function(obj) {
6762		if (typeof obj == 'string') {
6763			obj = obj.split(' ');
6764		}
6765		if ($.isArray(obj)) {
6766			obj = {left: +obj[0], top: +obj[1] || 0};
6767		}
6768		if ('left' in obj) {
6769			this.offset.click.left = obj.left + this.margins.left;
6770		}
6771		if ('right' in obj) {
6772			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6773		}
6774		if ('top' in obj) {
6775			this.offset.click.top = obj.top + this.margins.top;
6776		}
6777		if ('bottom' in obj) {
6778			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6779		}
6780	},
6781
6782	_getParentOffset: function() {
6783
6784
6785		//Get the offsetParent and cache its position
6786		this.offsetParent = this.helper.offsetParent();
6787		var po = this.offsetParent.offset();
6788
6789		// This is a special case where we need to modify a offset calculated on start, since the following happened:
6790		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6791		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6792		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6793		if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6794			po.left += this.scrollParent.scrollLeft();
6795			po.top += this.scrollParent.scrollTop();
6796		}
6797
6798		if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
6799		|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.ui.ie)) //Ugly IE fix
6800			po = { top: 0, left: 0 };
6801
6802		return {
6803			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
6804			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
6805		};
6806
6807	},
6808
6809	_getRelativeOffset: function() {
6810
6811		if(this.cssPosition == "relative") {
6812			var p = this.currentItem.position();
6813			return {
6814				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
6815				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
6816			};
6817		} else {
6818			return { top: 0, left: 0 };
6819		}
6820
6821	},
6822
6823	_cacheMargins: function() {
6824		this.margins = {
6825			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
6826			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
6827		};
6828	},
6829
6830	_cacheHelperProportions: function() {
6831		this.helperProportions = {
6832			width: this.helper.outerWidth(),
6833			height: this.helper.outerHeight()
6834		};
6835	},
6836
6837	_setContainment: function() {
6838
6839		var o = this.options;
6840		if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
6841		if(o.containment == 'document' || o.containment == 'window') this.containment = [
6842			0 - this.offset.relative.left - this.offset.parent.left,
6843			0 - this.offset.relative.top - this.offset.parent.top,
6844			$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
6845			($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
6846		];
6847
6848		if(!(/^(document|window|parent)$/).test(o.containment)) {
6849			var ce = $(o.containment)[0];
6850			var co = $(o.containment).offset();
6851			var over = ($(ce).css("overflow") != 'hidden');
6852
6853			this.containment = [
6854				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
6855				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
6856				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
6857				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),
685710) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
6858			];
6859		}
6860
6861	},
6862
6863	_convertPositionTo: function(d, pos) {
6864
6865		if(!pos) pos = this.position;
6866		var mod = d == "absolute" ? 1 : -1;
6867		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
6868
6869		return {
6870			top: (
6871				pos.top																	// The absolute mouse position
6872				+ this.offset.relative.top * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
6873				+ this.offset.parent.top * mod											// The offsetParent's offset without borders (offset + border)
6874				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
6875			),
6876			left: (
6877				pos.left																// The absolute mouse position
6878				+ this.offset.relative.left * mod										// Only for relative positioned nodes: Relative offset from element to offset parent
6879				+ this.offset.parent.left * mod											// The offsetParent's offset without borders (offset + border)
6880				- ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
6881			)
6882		};
6883
6884	},
6885
6886	_generatePosition: function(event) {
6887
6888		var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
6889
6890		// This is another very weird special case that only happens for relative elements:
6891		// 1. If the css position is relative
6892		// 2. and the scroll parent is the document or similar to the offset parent
6893		// we have to refresh the relative offset during the scroll so there are no jumps
6894		if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
6895			this.offset.relative = this._getRelativeOffset();
6896		}
6897
6898		var pageX = event.pageX;
6899		var pageY = event.pageY;
6900
6901		/*
6902		 * - Position constraining -
6903		 * Constrain the position to a mix of grid, containment.
6904		 */
6905
6906		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
6907
6908			if(this.containment) {
6909				if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
6910				if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
6911				if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
6912				if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
6913			}
6914
6915			if(o.grid) {
6916				var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
6917				pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
6918
6919				var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
6920				pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
6921			}
6922
6923		}
6924
6925		return {
6926			top: (
6927				pageY																// The absolute mouse position
6928				- this.offset.click.top													// Click offset (relative to the element)
6929				- this.offset.relative.top												// Only for relative positioned nodes: Relative offset from element to offset parent
6930				- this.offset.parent.top												// The offsetParent's offset without borders (offset + border)
6931				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
6932			),
6933			left: (
6934				pageX																// The absolute mouse position
6935				- this.offset.click.left												// Click offset (relative to the element)
6936				- this.offset.relative.left												// Only for relative positioned nodes: Relative offset from element to offset parent
6937				- this.offset.parent.left												// The offsetParent's offset without borders (offset + border)
6938				+ ( ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
6939			)
6940		};
6941
6942	},
6943
6944	_rearrange: function(event, i, a, hardRefresh) {
6945
6946		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
6947
6948		//Various things done here to improve the performance:
6949		// 1. we create a setTimeout, that calls refreshPositions
6950		// 2. on the instance, we have a counter variable, that get's higher after every append
6951		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
6952		// 4. this lets only the last addition to the timeout stack through
6953		this.counter = this.counter ? ++this.counter : 1;
6954		var counter = this.counter;
6955
6956		this._delay(function() {
6957			if(counter == this.counter) this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
6958		});
6959
6960	},
6961
6962	_clear: function(event, noPropagation) {
6963
6964		this.reverting = false;
6965		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
6966		// everything else normalized again
6967		var delayedTriggers = [];
6968
6969		// We first have to update the dom position of the actual currentItem
6970		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
6971		if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
6972		this._noFinalSort = null;
6973
6974		if(this.helper[0] == this.currentItem[0]) {
6975			for(var i in this._storedCSS) {
6976				if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
6977			}
6978			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
6979		} else {
6980			this.currentItem.show();
6981		}
6982
6983		if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
6984		if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
6985
6986		// Check if the items Container has Changed and trigger appropriate
6987		// events.
6988		if (this !== this.currentContainer) {
6989			if(!noPropagation) {
6990				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
6991				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
6992				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
6993			}
6994		}
6995
6996
6997		//Post events to containers
6998		for (var i = this.containers.length - 1; i >= 0; i--){
6999			if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
7000			if(this.containers[i].containerCache.over) {
7001				delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
7002				this.containers[i].containerCache.over = 0;
7003			}
7004		}
7005
7006		//Do what was originally in plugins
7007		if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
7008		if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
7009		if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
7010
7011		this.dragging = false;
7012		if(this.cancelHelperRemoval) {
7013			if(!noPropagation) {
7014				this._trigger("beforeStop", event, this._uiHash());
7015				for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
7016				this._trigger("stop", event, this._uiHash());
7017			}
7018
7019			this.fromOutside = false;
7020			return false;
7021		}
7022
7023		if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
7024
7025		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
7026		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
7027
7028		if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
7029
7030		if(!noPropagation) {
7031			for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
7032			this._trigger("stop", event, this._uiHash());
7033		}
7034
7035		this.fromOutside = false;
7036		return true;
7037
7038	},
7039
7040	_trigger: function() {
7041		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
7042			this.cancel();
7043		}
7044	},
7045
7046	_uiHash: function(_inst) {
7047		var inst = _inst || this;
7048		return {
7049			helper: inst.helper,
7050			placeholder: inst.placeholder || $([]),
7051			position: inst.position,
7052			originalPosition: inst.originalPosition,
7053			offset: inst.positionAbs,
7054			item: inst.currentItem,
7055			sender: _inst ? _inst.element : null
7056		};
7057	}
7058
7059});
7060
7061})(jQuery);
7062
7063;(jQuery.effects || (function($, undefined) {
7064
7065var backCompat = $.uiBackCompat !== false,
7066	// prefix used for storing data on .data()
7067	dataSpace = "ui-effects-";
7068
7069$.effects = {
7070	effect: {}
7071};
7072
7073/*!
7074 * jQuery Color Animations v2.0.0
7075 * http://jquery.com/
7076 *
7077 * Copyright 2012 jQuery Foundation and other contributors
7078 * Released under the MIT license.
7079 * http://jquery.org/license
7080 *
7081 * Date: Mon Aug 13 13:41:02 2012 -0500
7082 */
7083(function( jQuery, undefined ) {
7084
7085	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "),
7086
7087	// plusequals test for += 100 -= 100
7088	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
7089	// a set of RE's that can match strings and generate color tuples.
7090	stringParsers = [{
7091			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7092			parse: function( execResult ) {
7093				return [
7094					execResult[ 1 ],
7095					execResult[ 2 ],
7096					execResult[ 3 ],
7097					execResult[ 4 ]
7098				];
7099			}
7100		}, {
7101			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7102			parse: function( execResult ) {
7103				return [
7104					execResult[ 1 ] * 2.55,
7105					execResult[ 2 ] * 2.55,
7106					execResult[ 3 ] * 2.55,
7107					execResult[ 4 ]
7108				];
7109			}
7110		}, {
7111			// this regex ignores A-F because it's compared against an already lowercased string
7112			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
7113			parse: function( execResult ) {
7114				return [
7115					parseInt( execResult[ 1 ], 16 ),
7116					parseInt( execResult[ 2 ], 16 ),
7117					parseInt( execResult[ 3 ], 16 )
7118				];
7119			}
7120		}, {
7121			// this regex ignores A-F because it's compared against an already lowercased string
7122			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
7123			parse: function( execResult ) {
7124				return [
7125					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
7126					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
7127					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
7128				];
7129			}
7130		}, {
7131			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
7132			space: "hsla",
7133			parse: function( execResult ) {
7134				return [
7135					execResult[ 1 ],
7136					execResult[ 2 ] / 100,
7137					execResult[ 3 ] / 100,
7138					execResult[ 4 ]
7139				];
7140			}
7141		}],
7142
7143	// jQuery.Color( )
7144	color = jQuery.Color = function( color, green, blue, alpha ) {
7145		return new jQuery.Color.fn.parse( color, green, blue, alpha );
7146	},
7147	spaces = {
7148		rgba: {
7149			props: {
7150				red: {
7151					idx: 0,
7152					type: "byte"
7153				},
7154				green: {
7155					idx: 1,
7156					type: "byte"
7157				},
7158				blue: {
7159					idx: 2,
7160					type: "byte"
7161				}
7162			}
7163		},
7164
7165		hsla: {
7166			props: {
7167				hue: {
7168					idx: 0,
7169					type: "degrees"
7170				},
7171				saturation: {
7172					idx: 1,
7173					type: "percent"
7174				},
7175				lightness: {
7176					idx: 2,
7177					type: "percent"
7178				}
7179			}
7180		}
7181	},
7182	propTypes = {
7183		"byte": {
7184			floor: true,
7185			max: 255
7186		},
7187		"percent": {
7188			max: 1
7189		},
7190		"degrees": {
7191			mod: 360,
7192			floor: true
7193		}
7194	},
7195	support = color.support = {},
7196
7197	// element for support tests
7198	supportElem = jQuery( "<p>" )[ 0 ],
7199
7200	// colors = jQuery.Color.names
7201	colors,
7202
7203	// local aliases of functions called often
7204	each = jQuery.each;
7205
vendor: 23,788 bytes, lines 7206-8157
7206// determine rgba support immediately
7207supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
7208support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
7209
7210// define cache name and alpha properties
7211// for rgba and hsla spaces
7212each( spaces, function( spaceName, space ) {
7213	space.cache = "_" + spaceName;
7214	space.props.alpha = {
7215		idx: 3,
7216		type: "percent",
7217		def: 1
7218	};
7219});
7220
7221function clamp( value, prop, allowEmpty ) {
7222	var type = propTypes[ prop.type ] || {};
7223
7224	if ( value == null ) {
7225		return (allowEmpty || !prop.def) ? null : prop.def;
7226	}
7227
7228	// ~~ is an short way of doing floor for positive numbers
7229	value = type.floor ? ~~value : parseFloat( value );
7230
7231	// IE will pass in empty strings as value for alpha,
7232	// which will hit this case
7233	if ( isNaN( value ) ) {
7234		return prop.def;
7235	}
7236
7237	if ( type.mod ) {
7238		// we add mod before modding to make sure that negatives values
7239		// get converted properly: -10 -> 350
7240		return (value + type.mod) % type.mod;
7241	}
7242
7243	// for now all property types without mod have min and max
7244	return 0 > value ? 0 : type.max < value ? type.max : value;
7245}
7246
7247function stringParse( string ) {
7248	var inst = color(),
7249		rgba = inst._rgba = [];
7250
7251	string = string.toLowerCase();
7252
7253	each( stringParsers, function( i, parser ) {
7254		var parsed,
7255			match = parser.re.exec( string ),
7256			values = match && parser.parse( match ),
7257			spaceName = parser.space || "rgba";
7258
7259		if ( values ) {
7260			parsed = inst[ spaceName ]( values );
7261
7262			// if this was an rgba parse the assignment might happen twice
7263			// oh well....
7264			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
7265			rgba = inst._rgba = parsed._rgba;
7266
7267			// exit each( stringParsers ) here because we matched
7268			return false;
7269		}
7270	});
7271
7272	// Found a stringParser that handled it
7273	if ( rgba.length ) {
7274
7275		// if this came from a parsed string, force "transparent" when alpha is 0
7276		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
7277		if ( rgba.join() === "0,0,0,0" ) {
7278			jQuery.extend( rgba, colors.transparent );
7279		}
7280		return inst;
7281	}
7282
7283	// named colors
7284	return colors[ string ];
7285}
7286
7287color.fn = jQuery.extend( color.prototype, {
7288	parse: function( red, green, blue, alpha ) {
7289		if ( red === undefined ) {
7290			this._rgba = [ null, null, null, null ];
7291			return this;
7292		}
7293		if ( red.jquery || red.nodeType ) {
7294			red = jQuery( red ).css( green );
7295			green = undefined;
7296		}
7297
7298		var inst = this,
7299			type = jQuery.type( red ),
7300			rgba = this._rgba = [];
7301
7302		// more than 1 argument specified - assume ( red, green, blue, alpha )
7303		if ( green !== undefined ) {
7304			red = [ red, green, blue, alpha ];
7305			type = "array";
7306		}
7307
7308		if ( type === "string" ) {
7309			return this.parse( stringParse( red ) || colors._default );
7310		}
7311
7312		if ( type === "array" ) {
7313			each( spaces.rgba.props, function( key, prop ) {
7314				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
7315			});
7316			return this;
7317		}
7318
7319		if ( type === "object" ) {
7320			if ( red instanceof color ) {
7321				each( spaces, function( spaceName, space ) {
7322					if ( red[ space.cache ] ) {
7323						inst[ space.cache ] = red[ space.cache ].slice();
7324					}
7325				});
7326			} else {
7327				each( spaces, function( spaceName, space ) {
7328					var cache = space.cache;
7329					each( space.props, function( key, prop ) {
7330
7331						// if the cache doesn't exist, and we know how to convert
7332						if ( !inst[ cache ] && space.to ) {
7333
7334							// if the value was null, we don't need to copy it
7335							// if the key was alpha, we don't need to copy it either
7336							if ( key === "alpha" || red[ key ] == null ) {
7337								return;
7338							}
7339							inst[ cache ] = space.to( inst._rgba );
7340						}
7341
7342						// this is the only case where we allow nulls for ALL properties.
7343						// call clamp with alwaysAllowEmpty
7344						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
7345					});
7346
7347					// everything defined but alpha?
7348					if ( inst[ cache ] && $.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
7349						// use the default of 1
7350						inst[ cache ][ 3 ] = 1;
7351						if ( space.from ) {
7352							inst._rgba = space.from( inst[ cache ] );
7353						}
7354					}
7355				});
7356			}
7357			return this;
7358		}
7359	},
7360	is: function( compare ) {
7361		var is = color( compare ),
7362			same = true,
7363			inst = this;
7364
7365		each( spaces, function( _, space ) {
7366			var localCache,
7367				isCache = is[ space.cache ];
7368			if (isCache) {
7369				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
7370				each( space.props, function( _, prop ) {
7371					if ( isCache[ prop.idx ] != null ) {
7372						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
7373						return same;
7374					}
7375				});
7376			}
7377			return same;
7378		});
7379		return same;
7380	},
7381	_space: function() {
7382		var used = [],
7383			inst = this;
7384		each( spaces, function( spaceName, space ) {
7385			if ( inst[ space.cache ] ) {
7386				used.push( spaceName );
7387			}
7388		});
7389		return used.pop();
7390	},
7391	transition: function( other, distance ) {
7392		var end = color( other ),
7393			spaceName = end._space(),
7394			space = spaces[ spaceName ],
7395			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
7396			start = startColor[ space.cache ] || space.to( startColor._rgba ),
7397			result = start.slice();
7398
7399		end = end[ space.cache ];
7400		each( space.props, function( key, prop ) {
7401			var index = prop.idx,
7402				startValue = start[ index ],
7403				endValue = end[ index ],
7404				type = propTypes[ prop.type ] || {};
7405
7406			// if null, don't override start value
7407			if ( endValue === null ) {
7408				return;
7409			}
7410			// if null - use end
7411			if ( startValue === null ) {
7412				result[ index ] = endValue;
7413			} else {
7414				if ( type.mod ) {
7415					if ( endValue - startValue > type.mod / 2 ) {
7416						startValue += type.mod;
7417					} else if ( startValue - endValue > type.mod / 2 ) {
7418						startValue -= type.mod;
7419					}
7420				}
7421				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
7422			}
7423		});
7424		return this[ spaceName ]( result );
7425	},
7426	blend: function( opaque ) {
7427		// if we are already opaque - return ourself
7428		if ( this._rgba[ 3 ] === 1 ) {
7429			return this;
7430		}
7431
7432		var rgb = this._rgba.slice(),
7433			a = rgb.pop(),
7434			blend = color( opaque )._rgba;
7435
7436		return color( jQuery.map( rgb, function( v, i ) {
7437			return ( 1 - a ) * blend[ i ] + a * v;
7438		}));
7439	},
7440	toRgbaString: function() {
7441		var prefix = "rgba(",
7442			rgba = jQuery.map( this._rgba, function( v, i ) {
7443				return v == null ? ( i > 2 ? 1 : 0 ) : v;
7444			});
7445
7446		if ( rgba[ 3 ] === 1 ) {
7447			rgba.pop();
7448			prefix = "rgb(";
7449		}
7450
7451		return prefix + rgba.join() + ")";
7452	},
7453	toHslaString: function() {
7454		var prefix = "hsla(",
7455			hsla = jQuery.map( this.hsla(), function( v, i ) {
7456				if ( v == null ) {
7457					v = i > 2 ? 1 : 0;
7458				}
7459
7460				// catch 1 and 2
7461				if ( i && i < 3 ) {
7462					v = Math.round( v * 100 ) + "%";
7463				}
7464				return v;
7465			});
7466
7467		if ( hsla[ 3 ] === 1 ) {
7468			hsla.pop();
7469			prefix = "hsl(";
7470		}
7471		return prefix + hsla.join() + ")";
7472	},
7473	toHexString: function( includeAlpha ) {
7474		var rgba = this._rgba.slice(),
7475			alpha = rgba.pop();
7476
7477		if ( includeAlpha ) {
7478			rgba.push( ~~( alpha * 255 ) );
7479		}
7480
7481		return "#" + jQuery.map( rgba, function( v ) {
7482
7483			// default to 0 when nulls exist
7484			v = ( v || 0 ).toString( 16 );
7485			return v.length === 1 ? "0" + v : v;
7486		}).join("");
7487	},
7488	toString: function() {
7489		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
7490	}
7491});
7492color.fn.parse.prototype = color.fn;
7493
7494// hsla conversions adapted from:
7495// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
7496
7497function hue2rgb( p, q, h ) {
7498	h = ( h + 1 ) % 1;
7499	if ( h * 6 < 1 ) {
7500		return p + (q - p) * h * 6;
7501	}
7502	if ( h * 2 < 1) {
7503		return q;
7504	}
7505	if ( h * 3 < 2 ) {
7506		return p + (q - p) * ((2/3) - h) * 6;
7507	}
7508	return p;
7509}
7510
7511spaces.hsla.to = function ( rgba ) {
7512	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
7513		return [ null, null, null, rgba[ 3 ] ];
7514	}
7515	var r = rgba[ 0 ] / 255,
7516		g = rgba[ 1 ] / 255,
7517		b = rgba[ 2 ] / 255,
7518		a = rgba[ 3 ],
7519		max = Math.max( r, g, b ),
7520		min = Math.min( r, g, b ),
7521		diff = max - min,
7522		add = max + min,
7523		l = add * 0.5,
7524		h, s;
7525
7526	if ( min === max ) {
7527		h = 0;
7528	} else if ( r === max ) {
7529		h = ( 60 * ( g - b ) / diff ) + 360;
7530	} else if ( g === max ) {
7531		h = ( 60 * ( b - r ) / diff ) + 120;
7532	} else {
7533		h = ( 60 * ( r - g ) / diff ) + 240;
7534	}
7535
7536	if ( l === 0 || l === 1 ) {
7537		s = l;
7538	} else if ( l <= 0.5 ) {
7539		s = diff / add;
7540	} else {
7541		s = diff / ( 2 - add );
7542	}
7543	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
7544};
7545
7546spaces.hsla.from = function ( hsla ) {
7547	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
7548		return [ null, null, null, hsla[ 3 ] ];
7549	}
7550	var h = hsla[ 0 ] / 360,
7551		s = hsla[ 1 ],
7552		l = hsla[ 2 ],
7553		a = hsla[ 3 ],
7554		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
7555		p = 2 * l - q;
7556
7557	return [
7558		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
7559		Math.round( hue2rgb( p, q, h ) * 255 ),
7560		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
7561		a
7562	];
7563};
7564
7565
7566each( spaces, function( spaceName, space ) {
7567	var props = space.props,
7568		cache = space.cache,
7569		to = space.to,
7570		from = space.from;
7571
7572	// makes rgba() and hsla()
7573	color.fn[ spaceName ] = function( value ) {
7574
7575		// generate a cache for this space if it doesn't exist
7576		if ( to && !this[ cache ] ) {
7577			this[ cache ] = to( this._rgba );
7578		}
7579		if ( value === undefined ) {
7580			return this[ cache ].slice();
7581		}
7582
7583		var ret,
7584			type = jQuery.type( value ),
7585			arr = ( type === "array" || type === "object" ) ? value : arguments,
7586			local = this[ cache ].slice();
7587
7588		each( props, function( key, prop ) {
7589			var val = arr[ type === "object" ? key : prop.idx ];
7590			if ( val == null ) {
7591				val = local[ prop.idx ];
7592			}
7593			local[ prop.idx ] = clamp( val, prop );
7594		});
7595
7596		if ( from ) {
7597			ret = color( from( local ) );
7598			ret[ cache ] = local;
7599			return ret;
7600		} else {
7601			return color( local );
7602		}
7603	};
7604
7605	// makes red() green() blue() alpha() hue() saturation() lightness()
7606	each( props, function( key, prop ) {
7607		// alpha is included in more than one space
7608		if ( color.fn[ key ] ) {
7609			return;
7610		}
7611		color.fn[ key ] = function( value ) {
7612			var vtype = jQuery.type( value ),
7613				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
7614				local = this[ fn ](),
7615				cur = local[ prop.idx ],
7616				match;
7617
7618			if ( vtype === "undefined" ) {
7619				return cur;
7620			}
7621
7622			if ( vtype === "function" ) {
7623				value = value.call( this, cur );
7624				vtype = jQuery.type( value );
7625			}
7626			if ( value == null && prop.empty ) {
7627				return this;
7628			}
7629			if ( vtype === "string" ) {
7630				match = rplusequals.exec( value );
7631				if ( match ) {
7632					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
7633				}
7634			}
7635			local[ prop.idx ] = value;
7636			return this[ fn ]( local );
7637		};
7638	});
7639});
7640
7641// add .fx.step functions
7642each( stepHooks, function( i, hook ) {
7643	jQuery.cssHooks[ hook ] = {
7644		set: function( elem, value ) {
7645			var parsed, curElem,
7646				backgroundColor = "";
7647
7648			if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) {
7649				value = color( parsed || value );
7650				if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
7651					curElem = hook === "backgroundColor" ? elem.parentNode : elem;
7652					while (
7653						(backgroundColor === "" || backgroundColor === "transparent") &&
7654						curElem && curElem.style
7655					) {
7656						try {
7657							backgroundColor = jQuery.css( curElem, "backgroundColor" );
7658							curElem = curElem.parentNode;
7659						} catch ( e ) {
7660						}
7661					}
7662
7663					value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
7664						backgroundColor :
7665						"_default" );
7666				}
7667
7668				value = value.toRgbaString();
7669			}
7670			try {
7671				elem.style[ hook ] = value;
7672			} catch( error ) {
7673				// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
7674			}
7675		}
7676	};
7677	jQuery.fx.step[ hook ] = function( fx ) {
7678		if ( !fx.colorInit ) {
7679			fx.start = color( fx.elem, hook );
7680			fx.end = color( fx.end );
7681			fx.colorInit = true;
7682		}
7683		jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
7684	};
7685});
7686
7687jQuery.cssHooks.borderColor = {
7688	expand: function( value ) {
7689		var expanded = {};
7690
7691		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
7692			expanded[ "border" + part + "Color" ] = value;
7693		});
7694		return expanded;
7695	}
7696};
7697
7698// Basic color names only.
7699// Usage of any of the other color names requires adding yourself or including
7700// jquery.color.svg-names.js.
7701colors = jQuery.Color.names = {
7702	// 4.1. Basic color keywords
7703	aqua: "#00ffff",
7704	black: "#000000",
7705	blue: "#0000ff",
7706	fuchsia: "#ff00ff",
7707	gray: "#808080",
7708	green: "#008000",
7709	lime: "#00ff00",
7710	maroon: "#800000",
7711	navy: "#000080",
7712	olive: "#808000",
7713	purple: "#800080",
7714	red: "#ff0000",
7715	silver: "#c0c0c0",
7716	teal: "#008080",
7717	white: "#ffffff",
7718	yellow: "#ffff00",
7719
7720	// 4.2.3. "transparent" color keyword
7721	transparent: [ null, null, null, 0 ],
7722
7723	_default: "#ffffff"
7724};
7725
7726})( jQuery );
7727
7728
7729
7730/******************************************************************************/
7731/****************************** CLASS ANIMATIONS ******************************/
7732/******************************************************************************/
7733(function() {
7734
7735var classAnimationActions = [ "add", "remove", "toggle" ],
7736	shorthandStyles = {
7737		border: 1,
7738		borderBottom: 1,
7739		borderColor: 1,
7740		borderLeft: 1,
7741		borderRight: 1,
7742		borderTop: 1,
7743		borderWidth: 1,
7744		margin: 1,
7745		padding: 1
7746	};
7747
7748$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
7749	$.fx.step[ prop ] = function( fx ) {
7750		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
7751			jQuery.style( fx.elem, prop, fx.end );
7752			fx.setAttr = true;
7753		}
7754	};
7755});
7756
7757function getElementStyles() {
7758	var style = this.ownerDocument.defaultView ?
7759			this.ownerDocument.defaultView.getComputedStyle( this, null ) :
7760			this.currentStyle,
7761		newStyle = {},
7762		key,
7763		len;
7764
7765	// webkit enumerates style porperties
7766	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
7767		len = style.length;
7768		while ( len-- ) {
7769			key = style[ len ];
7770			if ( typeof style[ key ] === "string" ) {
7771				newStyle[ $.camelCase( key ) ] = style[ key ];
7772			}
7773		}
7774	} else {
7775		for ( key in style ) {
7776			if ( typeof style[ key ] === "string" ) {
7777				newStyle[ key ] = style[ key ];
7778			}
7779		}
7780	}
7781
7782	return newStyle;
7783}
7784
7785
7786function styleDifference( oldStyle, newStyle ) {
7787	var diff = {},
7788		name, value;
7789
7790	for ( name in newStyle ) {
7791		value = newStyle[ name ];
7792		if ( oldStyle[ name ] !== value ) {
7793			if ( !shorthandStyles[ name ] ) {
7794				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
7795					diff[ name ] = value;
7796				}
7797			}
7798		}
7799	}
7800
7801	return diff;
7802}
7803
7804$.effects.animateClass = function( value, duration, easing, callback ) {
7805	var o = $.speed( duration, easing, callback );
7806
7807	return this.queue( function() {
7808		var animated = $( this ),
7809			baseClass = animated.attr( "class" ) || "",
7810			applyClassChange,
7811			allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;
7812
7813		// map the animated objects to store the original styles.
7814		allAnimations = allAnimations.map(function() {
7815			var el = $( this );
7816			return {
7817				el: el,
7818				start: getElementStyles.call( this )
7819			};
7820		});
7821
7822		// apply class change
7823		applyClassChange = function() {
7824			$.each( classAnimationActions, function(i, action) {
7825				if ( value[ action ] ) {
7826					animated[ action + "Class" ]( value[ action ] );
7827				}
7828			});
7829		};
7830		applyClassChange();
7831
7832		// map all animated objects again - calculate new styles and diff
7833		allAnimations = allAnimations.map(function() {
7834			this.end = getElementStyles.call( this.el[ 0 ] );
7835			this.diff = styleDifference( this.start, this.end );
7836			return this;
7837		});
7838
7839		// apply original class
7840		animated.attr( "class", baseClass );
7841
7842		// map all animated objects again - this time collecting a promise
7843		allAnimations = allAnimations.map(function() {
7844			var styleInfo = this,
7845				dfd = $.Deferred(),
7846				opts = jQuery.extend({}, o, {
7847					queue: false,
7848					complete: function() {
7849						dfd.resolve( styleInfo );
7850					}
7851				});
7852
7853			this.el.animate( this.diff, opts );
7854			return dfd.promise();
7855		});
7856
7857		// once all animations have completed:
7858		$.when.apply( $, allAnimations.get() ).done(function() {
7859
7860			// set the final class
7861			applyClassChange();
7862
7863			// for each animated element,
7864			// clear all css properties that were animated
7865			$.each( arguments, function() {
7866				var el = this.el;
7867				$.each( this.diff, function(key) {
7868					el.css( key, '' );
7869				});
7870			});
7871
7872			// this is guarnteed to be there if you use jQuery.speed()
7873			// it also handles dequeuing the next anim...
7874			o.complete.call( animated[ 0 ] );
7875		});
7876	});
7877};
7878
7879$.fn.extend({
7880	_addClass: $.fn.addClass,
7881	addClass: function( classNames, speed, easing, callback ) {
7882		return speed ?
7883			$.effects.animateClass.call( this,
7884				{ add: classNames }, speed, easing, callback ) :
7885			this._addClass( classNames );
7886	},
7887
7888	_removeClass: $.fn.removeClass,
7889	removeClass: function( classNames, speed, easing, callback ) {
7890		return speed ?
7891			$.effects.animateClass.call( this,
7892				{ remove: classNames }, speed, easing, callback ) :
7893			this._removeClass( classNames );
7894	},
7895
7896	_toggleClass: $.fn.toggleClass,
7897	toggleClass: function( classNames, force, speed, easing, callback ) {
7898		if ( typeof force === "boolean" || force === undefined ) {
7899			if ( !speed ) {
7900				// without speed parameter
7901				return this._toggleClass( classNames, force );
7902			} else {
7903				return $.effects.animateClass.call( this,
7904					(force ? { add: classNames } : { remove: classNames }),
7905					speed, easing, callback );
7906			}
7907		} else {
7908			// without force parameter
7909			return $.effects.animateClass.call( this,
7910				{ toggle: classNames }, force, speed, easing );
7911		}
7912	},
7913
7914	switchClass: function( remove, add, speed, easing, callback) {
7915		return $.effects.animateClass.call( this, {
7916			add: add,
7917			remove: remove
7918		}, speed, easing, callback );
7919	}
7920});
7921
7922})();
7923
7924/******************************************************************************/
7925/*********************************** EFFECTS **********************************/
7926/******************************************************************************/
7927
7928(function() {
7929
7930$.extend( $.effects, {
7931	version: "1.9.1",
7932
7933	// Saves a set of properties in a data storage
7934	save: function( element, set ) {
7935		for( var i=0; i < set.length; i++ ) {
7936			if ( set[ i ] !== null ) {
7937				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
7938			}
7939		}
7940	},
7941
7942	// Restores a set of previously saved properties from a data storage
7943	restore: function( element, set ) {
7944		var val, i;
7945		for( i=0; i < set.length; i++ ) {
7946			if ( set[ i ] !== null ) {
7947				val = element.data( dataSpace + set[ i ] );
7948				// support: jQuery 1.6.2
7949				// http://bugs.jquery.com/ticket/9917
7950				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
7951				// We can't differentiate between "" and 0 here, so we just assume
7952				// empty string since it's likely to be a more common value...
7953				if ( val === undefined ) {
7954					val = "";
7955				}
7956				element.css( set[ i ], val );
7957			}
7958		}
7959	},
7960
7961	setMode: function( el, mode ) {
7962		if (mode === "toggle") {
7963			mode = el.is( ":hidden" ) ? "show" : "hide";
7964		}
7965		return mode;
7966	},
7967
7968	// Translates a [top,left] array into a baseline value
7969	// this should be a little more flexible in the future to handle a string & hash
7970	getBaseline: function( origin, original ) {
7971		var y, x;
7972		switch ( origin[ 0 ] ) {
7973			case "top": y = 0; break;
7974			case "middle": y = 0.5; break;
7975			case "bottom": y = 1; break;
7976			default: y = origin[ 0 ] / original.height;
7977		}
7978		switch ( origin[ 1 ] ) {
7979			case "left": x = 0; break;
7980			case "center": x = 0.5; break;
7981			case "right": x = 1; break;
7982			default: x = origin[ 1 ] / original.width;
7983		}
7984		return {
7985			x: x,
7986			y: y
7987		};
7988	},
7989
7990	// Wraps the element around a wrapper that copies position properties
7991	createWrapper: function( element ) {
7992
7993		// if the element is already wrapped, return it
7994		if ( element.parent().is( ".ui-effects-wrapper" )) {
7995			return element.parent();
7996		}
7997
7998		// wrap the element
7999		var props = {
8000				width: element.outerWidth(true),
8001				height: element.outerHeight(true),
8002				"float": element.css( "float" )
8003			},
8004			wrapper = $( "<div></div>" )
8005				.addClass( "ui-effects-wrapper" )
8006				.css({
8007					fontSize: "100%",
8008					background: "transparent",
8009					border: "none",
8010					margin: 0,
8011					padding: 0
8012				}),
8013			// Store the size in case width/height are defined in % - Fixes #5245
8014			size = {
8015				width: element.width(),
8016				height: element.height()
8017			},
8018			active = document.activeElement;
8019
8020		// support: Firefox
8021		// Firefox incorrectly exposes anonymous content
8022		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
8023		try {
8024			active.id;
8025		} catch( e ) {
8026			active = document.body;
8027		}
8028
8029		element.wrap( wrapper );
8030
8031		// Fixes #7595 - Elements lose focus when wrapped.
8032		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
8033			$( active ).focus();
8034		}
8035
8036		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
8037
8038		// transfer positioning properties to the wrapper
8039		if ( element.css( "position" ) === "static" ) {
8040			wrapper.css({ position: "relative" });
8041			element.css({ position: "relative" });
8042		} else {
8043			$.extend( props, {
8044				position: element.css( "position" ),
8045				zIndex: element.css( "z-index" )
8046			});
8047			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
8048				props[ pos ] = element.css( pos );
8049				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
8050					props[ pos ] = "auto";
8051				}
8052			});
8053			element.css({
8054				position: "relative",
8055				top: 0,
8056				left: 0,
8057				right: "auto",
8058				bottom: "auto"
8059			});
8060		}
8061		element.css(size);
8062
8063		return wrapper.css( props ).show();
8064	},
8065
8066	removeWrapper: function( element ) {
8067		var active = document.activeElement;
8068
8069		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
8070			element.parent().replaceWith( element );
8071
8072			// Fixes #7595 - Elements lose focus when wrapped.
8073			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
8074				$( active ).focus();
8075			}
8076		}
8077
8078
8079		return element;
8080	},
8081
8082	setTransition: function( element, list, factor, value ) {
8083		value = value || {};
8084		$.each( list, function( i, x ) {
8085			var unit = element.cssUnit( x );
8086			if ( unit[ 0 ] > 0 ) {
8087				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
8088			}
8089		});
8090		return value;
8091	}
8092});
8093
8094// return an effect options object for the given parameters:
8095function _normalizeArguments( effect, options, speed, callback ) {
8096
8097	// allow passing all options as the first parameter
8098	if ( $.isPlainObject( effect ) ) {
8099		options = effect;
8100		effect = effect.effect;
8101	}
8102
8103	// convert to an object
8104	effect = { effect: effect };
8105
8106	// catch (effect, null, ...)
8107	if ( options == null ) {
8108		options = {};
8109	}
8110
8111	// catch (effect, callback)
8112	if ( $.isFunction( options ) ) {
8113		callback = options;
8114		speed = null;
8115		options = {};
8116	}
8117
8118	// catch (effect, speed, ?)
8119	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
8120		callback = speed;
8121		speed = options;
8122		options = {};
8123	}
8124
8125	// catch (effect, options, callback)
8126	if ( $.isFunction( speed ) ) {
8127		callback = speed;
8128		speed = null;
8129	}
8130
8131	// add options to effect
8132	if ( options ) {
8133		$.extend( effect, options );
8134	}
8135
8136	speed = speed || options.duration;
8137	effect.duration = $.fx.off ? 0 :
8138		typeof speed === "number" ? speed :
8139		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
8140		$.fx.speeds._default;
8141
8142	effect.complete = callback || options.complete;
8143
8144	return effect;
8145}
8146
8147function standardSpeed( speed ) {
8148	// valid standard speeds
8149	if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
8150		return true;
8151	}
8152
8153	// invalid strings - treat as "normal" speed
8154	if ( typeof speed === "string" && !$.effects.effect[ speed ] ) {
8155		// TODO: remove in 2.0 (#7115)
8156		if ( backCompat && $.effects[ speed ] ) {
8157			return false;
8158		}
8159		return true;
8160	}
8161
8162	return false;
8163}
8164
8165$.fn.extend({
8166	effect: function( /* effect, options, speed, callback */ ) {
8167		var args = _normalizeArguments.apply( this, arguments ),
8168			mode = args.mode,
8169			queue = args.queue,
8170			effectMethod = $.effects.effect[ args.effect ],
8171
8172			// DEPRECATED: remove in 2.0 (#7115)
8173			oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ];
8174
8175		if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) {
8176			// delegate to the original method (e.g., .show()) if possible
8177			if ( mode ) {
8178				return this[ mode ]( args.duration, args.complete );
8179			} else {
8180				return this.each( function() {
8181					if ( args.complete ) {
8182						args.complete.call( this );
8183					}
8184				});
8185			}
8186		}
8187
8188		function run( next ) {
8189			var elem = $( this ),
8190				complete = args.complete,
8191				mode = args.mode;
8192
8193			function done() {
8194				if ( $.isFunction( complete ) ) {
8195					complete.call( elem[0] );
8196				}
8197				if ( $.isFunction( next ) ) {
8198					next();
8199				}
8200			}
8201
8202			// if the element is hiddden and mode is hide,
8203			// or element is visible and mode is show
8204			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
8205				done();
8206			} else {
8207				effectMethod.call( elem[0], args, done );
8208			}
8209		}
8210
8211		// TODO: remove this check in 2.0, effectMethod will always be true
8212		if ( effectMethod ) {
8213			return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
8214		} else {
8215			// DEPRECATED: remove in 2.0 (#7115)
8216			return oldEffectMethod.call(this, {
8217				options: args,
8218				duration: args.duration,
8219				callback: args.complete,
8220				mode: args.mode
8221			});
8222		}
8223	},
8224
8225	_show: $.fn.show,
8226	show: function( speed ) {
8227		if ( standardSpeed( speed ) ) {
8228			return this._show.apply( this, arguments );
8229		} else {
8230			var args = _normalizeArguments.apply( this, arguments );
8231			args.mode = "show";
8232			return this.effect.call( this, args );
8233		}
8234	},
8235
8236	_hide: $.fn.hide,
8237	hide: function( speed ) {
8238		if ( standardSpeed( speed ) ) {
8239			return this._hide.apply( this, arguments );
8240		} else {
8241			var args = _normalizeArguments.apply( this, arguments );
8242			args.mode = "hide";
8243			return this.effect.call( this, args );
8244		}
8245	},
8246
8247	// jQuery core overloads toggle and creates _toggle
8248	__toggle: $.fn.toggle,
8249	toggle: function( speed ) {
8250		if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
8251			return this.__toggle.apply( this, arguments );
8252		} else {
8253			var args = _normalizeArguments.apply( this, arguments );
8254			args.mode = "toggle";
8255			return this.effect.call( this, args );
8256		}
8257	},
8258
8259	// helper functions
8260	cssUnit: function(key) {
8261		var style = this.css( key ),
8262			val = [];
8263
8264		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
8265			if ( style.indexOf( unit ) > 0 ) {
8266				val = [ parseFloat( style ), unit ];
8267			}
8268		});
8269		return val;
8270	}
8271});
8272
8273})();
8274
8275/******************************************************************************/
8276/*********************************** EASING ***********************************/
8277/******************************************************************************/
8278
8279(function() {
8280
8281// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
8282
8283var baseEasings = {};
8284
8285$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
8286	baseEasings[ name ] = function( p ) {
8287		return Math.pow( p, i + 2 );
8288	};
8289});
8290
8291$.extend( baseEasings, {
8292	Sine: function ( p ) {
8293		return 1 - Math.cos( p * Math.PI / 2 );
8294	},
8295	Circ: function ( p ) {
8296		return 1 - Math.sqrt( 1 - p * p );
8297	},
8298	Elastic: function( p ) {
8299		return p === 0 || p === 1 ? p :
8300			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
8301	},
8302	Back: function( p ) {
8303		return p * p * ( 3 * p - 2 );
8304	},
8305	Bounce: function ( p ) {
8306		var pow2,
8307			bounce = 4;
8308
8309		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
8310		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
8311	}
8312});
8313
8314$.each( baseEasings, function( name, easeIn ) {
8315	$.easing[ "easeIn" + name ] = easeIn;
8316	$.easing[ "easeOut" + name ] = function( p ) {
8317		return 1 - easeIn( 1 - p );
8318	};
8319	$.easing[ "easeInOut" + name ] = function( p ) {
8320		return p < 0.5 ?
8321			easeIn( p * 2 ) / 2 :
8322			1 - easeIn( p * -2 + 2 ) / 2;
8323	};
8324});
8325
8326})();
8327
8328})(jQuery));
8329
8330(function( $, undefined ) {
8331
8332var uid = 0,
8333	hideProps = {},
8334	showProps = {};
8335
8336hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
8337	hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
8338showProps.height = showProps.paddingTop = showProps.paddingBottom =
8339	showProps.borderTopWidth = showProps.borderBottomWidth = "show";
8340
8341$.widget( "ui.accordion", {
8342	version: "1.9.1",
8343	options: {
8344		active: 0,
8345		animate: {},
8346		collapsible: false,
8347		event: "click",
8348		header: "> li > :first-child,> :not(li):even",
8349		heightStyle: "auto",
8350		icons: {
8351			activeHeader: "ui-icon-triangle-1-s",
8352			header: "ui-icon-triangle-1-e"
8353		},
8354
8355		// callbacks
8356		activate: null,
8357		beforeActivate: null
8358	},
8359
8360	_create: function() {
8361		var accordionId = this.accordionId = "ui-accordion-" +
8362				(this.element.attr( "id" ) || ++uid),
8363			options = this.options;
8364
8365		this.prevShow = this.prevHide = $();
8366		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" );
8367
8368		this.headers = this.element.find( options.header )
8369			.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
8370		this._hoverable( this.headers );
8371		this._focusable( this.headers );
8372
8373		this.headers.next()
8374			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
8375			.hide();
8376
8377		// don't allow collapsible: false and active: false / null
8378		if ( !options.collapsible && (options.active === false || options.active == null) ) {
8379			options.active = 0;
8380		}
8381		// handle negative values
8382		if ( options.active < 0 ) {
8383			options.active += this.headers.length;
8384		}
8385		this.active = this._findActive( options.active )
8386			.addClass( "ui-accordion-header-active ui-state-active" )
8387			.toggleClass( "ui-corner-all ui-corner-top" );
8388		this.active.next()
8389			.addClass( "ui-accordion-content-active" )
8390			.show();
8391
8392		this._createIcons();
8393		this.refresh();
8394
8395		// ARIA
8396		this.element.attr( "role", "tablist" );
8397
8398		this.headers
8399			.attr( "role", "tab" )
8400			.each(function( i ) {
8401				var header = $( this ),
8402					headerId = header.attr( "id" ),
8403					panel = header.next(),
8404					panelId = panel.attr( "id" );
8405				if ( !headerId ) {
8406					headerId = accordionId + "-header-" + i;
8407					header.attr( "id", headerId );
8408				}
8409				if ( !panelId ) {
8410					panelId = accordionId + "-panel-" + i;
8411					panel.attr( "id", panelId );
8412				}
8413				header.attr( "aria-controls", panelId );
8414				panel.attr( "aria-labelledby", headerId );
8415			})
8416			.next()
8417				.attr( "role", "tabpanel" );
8418
8419		this.headers
8420			.not( this.active )
8421			.attr({
8422				"aria-selected": "false",
8423				tabIndex: -1
8424			})
8425			.next()
8426				.attr({
8427					"aria-expanded": "false",
8428					"aria-hidden": "true"
8429				})
8430				.hide();
8431
8432		// make sure at least one header is in the tab order
8433		if ( !this.active.length ) {
8434			this.headers.eq( 0 ).attr( "tabIndex", 0 );
8435		} else {
8436			this.active.attr({
8437				"aria-selected": "true",
8438				tabIndex: 0
8439			})
8440			.next()
8441				.attr({
8442					"aria-expanded": "true",
8443					"aria-hidden": "false"
8444				});
8445		}
8446
8447		this._on( this.headers, { keydown: "_keydown" });
8448		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
8449		this._setupEvents( options.event );
8450	},
8451
8452	_getCreateEventData: function() {
8453		return {
8454			header: this.active,
8455			content: !this.active.length ? $() : this.active.next()
8456		};
8457	},
8458
8459	_createIcons: function() {
8460		var icons = this.options.icons;
8461		if ( icons ) {
8462			$( "<span>" )
8463				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
8464				.prependTo( this.headers );
8465			this.active.children( ".ui-accordion-header-icon" )
8466				.removeClass( icons.header )
8467				.addClass( icons.activeHeader );
8468			this.headers.addClass( "ui-accordion-icons" );
8469		}
8470	},
8471
8472	_destroyIcons: function() {
8473		this.headers
8474			.removeClass( "ui-accordion-icons" )
8475			.children( ".ui-accordion-header-icon" )
8476				.remove();
8477	},
8478
8479	_destroy: function() {
8480		var contents;
8481
8482		// clean up main element
8483		this.element
8484			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
8485			.removeAttr( "role" );
8486
8487		// clean up headers
8488		this.headers
8489			.removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
8490			.removeAttr( "role" )
8491			.removeAttr( "aria-selected" )
8492			.removeAttr( "aria-controls" )
8493			.removeAttr( "tabIndex" )
8494			.each(function() {
8495				if ( /^ui-accordion/.test( this.id ) ) {
8496					this.removeAttribute( "id" );
8497				}
8498			});
8499		this._destroyIcons();
8500
8501		// clean up content panels
8502		contents = this.headers.next()
8503			.css( "display", "" )
8504			.removeAttr( "role" )
8505			.removeAttr( "aria-expanded" )
8506			.removeAttr( "aria-hidden" )
8507			.removeAttr( "aria-labelledby" )
8508			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
8509			.each(function() {
8510				if ( /^ui-accordion/.test( this.id ) ) {
8511					this.removeAttribute( "id" );
8512				}
8513			});
8514		if ( this.options.heightStyle !== "content" ) {
8515			contents.css( "height", "" );
8516		}
8517	},
8518
8519	_setOption: function( key, value ) {
8520		if ( key === "active" ) {
8521			// _activate() will handle invalid values and update this.options
8522			this._activate( value );
8523			return;
8524		}
8525
8526		if ( key === "event" ) {
8527			if ( this.options.event ) {
8528				this._off( this.headers, this.options.event );
8529			}
8530			this._setupEvents( value );
8531		}
8532
8533		this._super( key, value );
8534
8535		// setting collapsible: false while collapsed; open first panel
8536		if ( key === "collapsible" && !value && this.options.active === false ) {
8537			this._activate( 0 );
8538		}
8539
8540		if ( key === "icons" ) {
8541			this._destroyIcons();
8542			if ( value ) {
8543				this._createIcons();
8544			}
8545		}
8546
8547		// #5332 - opacity doesn't cascade to positioned elements in IE
8548		// so we need to add the disabled class to the headers and panels
8549		if ( key === "disabled" ) {
8550			this.headers.add( this.headers.next() )
8551				.toggleClass( "ui-state-disabled", !!value );
8552		}
8553	},
8554
8555	_keydown: function( event ) {
8556		if ( event.altKey || event.ctrlKey ) {
8557			return;
8558		}
8559
8560		var keyCode = $.ui.keyCode,
8561			length = this.headers.length,
8562			currentIndex = this.headers.index( event.target ),
8563			toFocus = false;
vendor: 4,217 bytes, lines 8564-8719
8564
8565		switch ( event.keyCode ) {
8566			case keyCode.RIGHT:
8567			case keyCode.DOWN:
8568				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
8569				break;
8570			case keyCode.LEFT:
8571			case keyCode.UP:
8572				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
8573				break;
8574			case keyCode.SPACE:
8575			case keyCode.ENTER:
8576				this._eventHandler( event );
8577				break;
8578			case keyCode.HOME:
8579				toFocus = this.headers[ 0 ];
8580				break;
8581			case keyCode.END:
8582				toFocus = this.headers[ length - 1 ];
8583				break;
8584		}
8585
8586		if ( toFocus ) {
8587			$( event.target ).attr( "tabIndex", -1 );
8588			$( toFocus ).attr( "tabIndex", 0 );
8589			toFocus.focus();
8590			event.preventDefault();
8591		}
8592	},
8593
8594	_panelKeyDown : function( event ) {
8595		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
8596			$( event.currentTarget ).prev().focus();
8597		}
8598	},
8599
8600	refresh: function() {
8601		var maxHeight, overflow,
8602			heightStyle = this.options.heightStyle,
8603			parent = this.element.parent();
8604
8605
8606		if ( heightStyle === "fill" ) {
8607			// IE 6 treats height like minHeight, so we need to turn off overflow
8608			// in order to get a reliable height
8609			// we use the minHeight support test because we assume that only
8610			// browsers that don't support minHeight will treat height as minHeight
8611			if ( !$.support.minHeight ) {
8612				overflow = parent.css( "overflow" );
8613				parent.css( "overflow", "hidden");
8614			}
8615			maxHeight = parent.height();
8616			this.element.siblings( ":visible" ).each(function() {
8617				var elem = $( this ),
8618					position = elem.css( "position" );
8619
8620				if ( position === "absolute" || position === "fixed" ) {
8621					return;
8622				}
8623				maxHeight -= elem.outerHeight( true );
8624			});
8625			if ( overflow ) {
8626				parent.css( "overflow", overflow );
8627			}
8628
8629			this.headers.each(function() {
8630				maxHeight -= $( this ).outerHeight( true );
8631			});
8632
8633			this.headers.next()
8634				.each(function() {
8635					$( this ).height( Math.max( 0, maxHeight -
8636						$( this ).innerHeight() + $( this ).height() ) );
8637				})
8638				.css( "overflow", "auto" );
8639		} else if ( heightStyle === "auto" ) {
8640			maxHeight = 0;
8641			this.headers.next()
8642				.each(function() {
8643					maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
8644				})
8645				.height( maxHeight );
8646		}
8647	},
8648
8649	_activate: function( index ) {
8650		var active = this._findActive( index )[ 0 ];
8651
8652		// trying to activate the already active panel
8653		if ( active === this.active[ 0 ] ) {
8654			return;
8655		}
8656
8657		// trying to collapse, simulate a click on the currently active header
8658		active = active || this.active[ 0 ];
8659
8660		this._eventHandler({
8661			target: active,
8662			currentTarget: active,
8663			preventDefault: $.noop
8664		});
8665	},
8666
8667	_findActive: function( selector ) {
8668		return typeof selector === "number" ? this.headers.eq( selector ) : $();
8669	},
8670
8671	_setupEvents: function( event ) {
8672		var events = {};
8673		if ( !event ) {
8674			return;
8675		}
8676		$.each( event.split(" "), function( index, eventName ) {
8677			events[ eventName ] = "_eventHandler";
8678		});
8679		this._on( this.headers, events );
8680	},
8681
8682	_eventHandler: function( event ) {
8683		var options = this.options,
8684			active = this.active,
8685			clicked = $( event.currentTarget ),
8686			clickedIsActive = clicked[ 0 ] === active[ 0 ],
8687			collapsing = clickedIsActive && options.collapsible,
8688			toShow = collapsing ? $() : clicked.next(),
8689			toHide = active.next(),
8690			eventData = {
8691				oldHeader: active,
8692				oldPanel: toHide,
8693				newHeader: collapsing ? $() : clicked,
8694				newPanel: toShow
8695			};
8696
8697		event.preventDefault();
8698
8699		if (
8700				// click on active header, but not collapsible
8701				( clickedIsActive && !options.collapsible ) ||
8702				// allow canceling activation
8703				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
8704			return;
8705		}
8706
8707		options.active = collapsing ? false : this.headers.index( clicked );
8708
8709		// when the call to ._toggle() comes after the class changes
8710		// it causes a very odd bug in IE 8 (see #6720)
8711		this.active = clickedIsActive ? $() : clicked;
8712		this._toggle( eventData );
8713
8714		// switch classes
8715		// corner classes on the previously active header stay after the animation
8716		active.removeClass( "ui-accordion-header-active ui-state-active" );
8717		if ( options.icons ) {
8718			active.children( ".ui-accordion-header-icon" )
8719				.removeClass( options.icons.activeHeader )
8720				.addClass( options.icons.header );
8721		}
8722
8723		if ( !clickedIsActive ) {
8724			clicked
8725				.removeClass( "ui-corner-all" )
8726				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
8727			if ( options.icons ) {
8728				clicked.children( ".ui-accordion-header-icon" )
8729					.removeClass( options.icons.header )
8730					.addClass( options.icons.activeHeader );
8731			}
8732
8733			clicked
8734				.next()
8735				.addClass( "ui-accordion-content-active" );
8736		}
8737	},
8738
8739	_toggle: function( data ) {
8740		var toShow = data.newPanel,
8741			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
8742
8743		// handle activating a panel during the animation for another activation
8744		this.prevShow.add( this.prevHide ).stop( true, true );
8745		this.prevShow = toShow;
8746		this.prevHide = toHide;
8747
8748		if ( this.options.animate ) {
8749			this._animate( toShow, toHide, data );
8750		} else {
8751			toHide.hide();
8752			toShow.show();
8753			this._toggleComplete( data );
8754		}
8755
8756		toHide.attr({
8757			"aria-expanded": "false",
8758			"aria-hidden": "true"
8759		});
8760		toHide.prev().attr( "aria-selected", "false" );
8761		// if we're switching panels, remove the old header from the tab order
8762		// if we're opening from collapsed state, remove the previous header from the tab order
8763		// if we're collapsing, then keep the collapsing header in the tab order
8764		if ( toShow.length && toHide.length ) {
8765			toHide.prev().attr( "tabIndex", -1 );
8766		} else if ( toShow.length ) {
8767			this.headers.filter(function() {
8768				return $( this ).attr( "tabIndex" ) === 0;
8769			})
8770			.attr( "tabIndex", -1 );
8771		}
8772
8773		toShow
8774			.attr({
8775				"aria-expanded": "true",
8776				"aria-hidden": "false"
8777			})
8778			.prev()
8779				.attr({
8780					"aria-selected": "true",
8781					tabIndex: 0
8782				});
8783	},
8784
8785	_animate: function( toShow, toHide, data ) {
8786		var total, easing, duration,
8787			that = this,
8788			adjust = 0,
8789			down = toShow.length &&
8790				( !toHide.length || ( toShow.index() < toHide.index() ) ),
8791			animate = this.options.animate || {},
8792			options = down && animate.down || animate,
8793			complete = function() {
8794				that._toggleComplete( data );
8795			};
8796
8797		if ( typeof options === "number" ) {
8798			duration = options;
8799		}
8800		if ( typeof options === "string" ) {
8801			easing = options;
8802		}
8803		// fall back from options to animation in case of partial down settings
8804		easing = easing || options.easing || animate.easing;
8805		duration = duration || options.duration || animate.duration;
8806
8807		if ( !toHide.length ) {
8808			return toShow.animate( showProps, duration, easing, complete );
8809		}
8810		if ( !toShow.length ) {
8811			return toHide.animate( hideProps, duration, easing, complete );
8812		}
8813
8814		total = toShow.show().outerHeight();
8815		toHide.animate( hideProps, {
8816			duration: duration,
8817			easing: easing,
8818			step: function( now, fx ) {
8819				fx.now = Math.round( now );
8820			}
8821		});
8822		toShow
8823			.hide()
8824			.animate( showProps, {
8825				duration: duration,
8826				easing: easing,
8827				complete: complete,
8828				step: function( now, fx ) {
8829					fx.now = Math.round( now );
8830					if ( fx.prop !== "height" ) {
8831						adjust += fx.now;
8832					} else if ( that.options.heightStyle !== "content" ) {
8833						fx.now = Math.round( total - toHide.outerHeight() - adjust );
8834						adjust = 0;
8835					}
8836				}
8837			});
8838	},
8839
8840	_toggleComplete: function( data ) {
8841		var toHide = data.oldPanel;
8842
8843		toHide
8844			.removeClass( "ui-accordion-content-active" )
8845			.prev()
8846				.removeClass( "ui-corner-top" )
8847				.addClass( "ui-corner-all" );
8848
8849		// Work around for rendering bug in IE (#5421)
8850		if ( toHide.length ) {
8851			toHide.parent()[0].className = toHide.parent()[0].className;
8852		}
8853
8854		this._trigger( "activate", null, data );
8855	}
8856});
8857
8858
8859
8860// DEPRECATED
8861if ( $.uiBackCompat !== false ) {
8862	// navigation options
8863	(function( $, prototype ) {
8864		$.extend( prototype.options, {
8865			navigation: false,
8866			navigationFilter: function() {
8867				return this.href.toLowerCase() === location.href.toLowerCase();
8868			}
8869		});
8870
8871		var _create = prototype._create;
8872		prototype._create = function() {
8873			if ( this.options.navigation ) {
8874				var that = this,
8875					headers = this.element.find( this.options.header ),
8876					content = headers.next(),
8877					current = headers.add( content )
8878						.find( "a" )
8879						.filter( this.options.navigationFilter )
8880						[ 0 ];
8881				if ( current ) {
8882					headers.add( content ).each( function( index ) {
8883						if ( $.contains( this, current ) ) {
8884							that.options.active = Math.floor( index / 2 );
8885							return false;
8886						}
8887					});
8888				}
8889			}
8890			_create.call( this );
8891		};
8892	}( jQuery, jQuery.ui.accordion.prototype ) );
8893
8894	// height options
8895	(function( $, prototype ) {
8896		$.extend( prototype.options, {
8897			heightStyle: null, // remove default so we fall back to old values
8898			autoHeight: true, // use heightStyle: "auto"
8899			clearStyle: false, // use heightStyle: "content"
8900			fillSpace: false // use heightStyle: "fill"
8901		});
8902
8903		var _create = prototype._create,
8904			_setOption = prototype._setOption;
8905
8906		$.extend( prototype, {
8907			_create: function() {
8908				this.options.heightStyle = this.options.heightStyle ||
8909					this._mergeHeightStyle();
8910
8911				_create.call( this );
8912			},
8913
8914			_setOption: function( key ) {
8915				if ( key === "autoHeight" || key === "clearStyle" || key === "fillSpace" ) {
8916					this.options.heightStyle = this._mergeHeightStyle();
8917				}
8918				_setOption.apply( this, arguments );
8919			},
8920
8921			_mergeHeightStyle: function() {
8922				var options = this.options;
8923
8924				if ( options.fillSpace ) {
8925					return "fill";
8926				}
8927
8928				if ( options.clearStyle ) {
8929					return "content";
8930				}
8931
8932				if ( options.autoHeight ) {
8933					return "auto";
8934				}
8935			}
8936		});
8937	}( jQuery, jQuery.ui.accordion.prototype ) );
8938
8939	// icon options
8940	(function( $, prototype ) {
8941		$.extend( prototype.options.icons, {
8942			activeHeader: null, // remove default so we fall back to old values
8943			headerSelected: "ui-icon-triangle-1-s"
8944		});
8945
8946		var _createIcons = prototype._createIcons;
8947		prototype._createIcons = function() {
8948			if ( this.options.icons ) {
8949				this.options.icons.activeHeader = this.options.icons.activeHeader ||
8950					this.options.icons.headerSelected;
8951			}
8952			_createIcons.call( this );
8953		};
8954	}( jQuery, jQuery.ui.accordion.prototype ) );
8955
8956	// expanded active option, activate method
8957	(function( $, prototype ) {
8958		prototype.activate = prototype._activate;
8959
8960		var _findActive = prototype._findActive;
8961		prototype._findActive = function( index ) {
8962			if ( index === -1 ) {
8963				index = false;
8964			}
8965			if ( index && typeof index !== "number" ) {
8966				index = this.headers.index( this.headers.filter( index ) );
8967				if ( index === -1 ) {
8968					index = false;
8969				}
8970			}
8971			return _findActive.call( this, index );
8972		};
8973	}( jQuery, jQuery.ui.accordion.prototype ) );
8974
8975	// resize method
8976	jQuery.ui.accordion.prototype.resize = jQuery.ui.accordion.prototype.refresh;
8977
8978	// change events
8979	(function( $, prototype ) {
8980		$.extend( prototype.options, {
8981			change: null,
8982			changestart: null
8983		});
8984
8985		var _trigger = prototype._trigger;
8986		prototype._trigger = function( type, event, data ) {
8987			var ret = _trigger.apply( this, arguments );
8988			if ( !ret ) {
8989				return false;
8990			}
8991
8992			if ( type === "beforeActivate" ) {
8993				ret = _trigger.call( this, "changestart", event, {
8994					oldHeader: data.oldHeader,
8995					oldContent: data.oldPanel,
8996					newHeader: data.newHeader,
8997					newContent: data.newPanel
8998				});
8999			} else if ( type === "activate" ) {
9000				ret = _trigger.call( this, "change", event, {
9001					oldHeader: data.oldHeader,
9002					oldContent: data.oldPanel,
9003					newHeader: data.newHeader,
9004					newContent: data.newPanel
9005				});
9006			}
9007			return ret;
9008		};
9009	}( jQuery, jQuery.ui.accordion.prototype ) );
9010
9011	// animated option
9012	// NOTE: this only provides support for "slide", "bounceslide", and easings
9013	// not the full $.ui.accordion.animations API
9014	(function( $, prototype ) {
9015		$.extend( prototype.options, {
9016			animate: null,
9017			animated: "slide"
9018		});
9019
9020		var _create = prototype._create;
9021		prototype._create = function() {
9022			var options = this.options;
9023			if ( options.animate === null ) {
9024				if ( !options.animated ) {
9025					options.animate = false;
9026				} else if ( options.animated === "slide" ) {
9027					options.animate = 300;
9028				} else if ( options.animated === "bounceslide" ) {
9029					options.animate = {
9030						duration: 200,
9031						down: {
9032							easing: "easeOutBounce",
9033							duration: 1000
9034						}
9035					};
9036				} else {
9037					options.animate = options.animated;
9038				}
9039			}
9040
9041			_create.call( this );
9042		};
9043	}( jQuery, jQuery.ui.accordion.prototype ) );
9044}
9045
9046})( jQuery );
9047
9048(function( $, undefined ) {
9049
9050// used to prevent race conditions with remote data sources
9051var requestIndex = 0;
9052
9053$.widget( "ui.autocomplete", {
9054	version: "1.9.1",
9055	defaultElement: "<input>",
9056	options: {
9057		appendTo: "body",
9058		autoFocus: false,
9059		delay: 300,
9060		minLength: 1,
9061		position: {
9062			my: "left top",
9063			at: "left bottom",
9064			collision: "none"
9065		},
9066		source: null,
9067
9068		// callbacks
9069		change: null,
9070		close: null,
9071		focus: null,
9072		open: null,
9073		response: null,
9074		search: null,
9075		select: null
9076	},
9077
9078	pending: 0,
9079
9080	_create: function() {
9081		// Some browsers only repeat keydown events, not keypress events,
9082		// so we use the suppressKeyPress flag to determine if we've already
9083		// handled the keydown event. #7269
9084		// Unfortunately the code for & in keypress is the same as the up arrow,
9085		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
9086		// events when we know the keydown event was used to modify the
9087		// search term. #7799
9088		var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
9089
9090		this.isMultiLine = this._isMultiLine();
9091		this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ];
9092		this.isNewMenu = true;
9093
9094		this.element
9095			.addClass( "ui-autocomplete-input" )
9096			.attr( "autocomplete", "off" );
9097
9098		this._on( this.element, {
9099			keydown: function( event ) {
9100				if ( this.element.prop( "readOnly" ) ) {
9101					suppressKeyPress = true;
9102					suppressInput = true;
9103					suppressKeyPressRepeat = true;
9104					return;
9105				}
9106
9107				suppressKeyPress = false;
vendor: 4,280 bytes, lines 9108-9259
9108				suppressInput = false;
9109				suppressKeyPressRepeat = false;
9110				var keyCode = $.ui.keyCode;
9111				switch( event.keyCode ) {
9112				case keyCode.PAGE_UP:
9113					suppressKeyPress = true;
9114					this._move( "previousPage", event );
9115					break;
9116				case keyCode.PAGE_DOWN:
9117					suppressKeyPress = true;
9118					this._move( "nextPage", event );
9119					break;
9120				case keyCode.UP:
9121					suppressKeyPress = true;
9122					this._keyEvent( "previous", event );
9123					break;
9124				case keyCode.DOWN:
9125					suppressKeyPress = true;
9126					this._keyEvent( "next", event );
9127					break;
9128				case keyCode.ENTER:
9129				case keyCode.NUMPAD_ENTER:
9130					// when menu is open and has focus
9131					if ( this.menu.active ) {
9132						// #6055 - Opera still allows the keypress to occur
9133						// which causes forms to submit
9134						suppressKeyPress = true;
9135						event.preventDefault();
9136						this.menu.select( event );
9137					}
9138					break;
9139				case keyCode.TAB:
9140					if ( this.menu.active ) {
9141						this.menu.select( event );
9142					}
9143					break;
9144				case keyCode.ESCAPE:
9145					if ( this.menu.element.is( ":visible" ) ) {
9146						this._value( this.term );
9147						this.close( event );
9148						// Different browsers have different default behavior for escape
9149						// Single press can mean undo or clear
9150						// Double press in IE means clear the whole form
9151						event.preventDefault();
9152					}
9153					break;
9154				default:
9155					suppressKeyPressRepeat = true;
9156					// search timeout should be triggered before the input value is changed
9157					this._searchTimeout( event );
9158					break;
9159				}
9160			},
9161			keypress: function( event ) {
9162				if ( suppressKeyPress ) {
9163					suppressKeyPress = false;
9164					event.preventDefault();
9165					return;
9166				}
9167				if ( suppressKeyPressRepeat ) {
9168					return;
9169				}
9170
9171				// replicate some key handlers to allow them to repeat in Firefox and Opera
9172				var keyCode = $.ui.keyCode;
9173				switch( event.keyCode ) {
9174				case keyCode.PAGE_UP:
9175					this._move( "previousPage", event );
9176					break;
9177				case keyCode.PAGE_DOWN:
9178					this._move( "nextPage", event );
9179					break;
9180				case keyCode.UP:
9181					this._keyEvent( "previous", event );
9182					break;
9183				case keyCode.DOWN:
9184					this._keyEvent( "next", event );
9185					break;
9186				}
9187			},
9188			input: function( event ) {
9189				if ( suppressInput ) {
9190					suppressInput = false;
9191					event.preventDefault();
9192					return;
9193				}
9194				this._searchTimeout( event );
9195			},
9196			focus: function() {
9197				this.selectedItem = null;
9198				this.previous = this._value();
9199			},
9200			blur: function( event ) {
9201				if ( this.cancelBlur ) {
9202					delete this.cancelBlur;
9203					return;
9204				}
9205
9206				clearTimeout( this.searching );
9207				this.close( event );
9208				this._change( event );
9209			}
9210		});
9211
9212		this._initSource();
9213		this.menu = $( "<ul>" )
9214			.addClass( "ui-autocomplete" )
9215			.appendTo( this.document.find( this.options.appendTo || "body" )[ 0 ] )
9216			.menu({
9217				// custom key handling for now
9218				input: $(),
9219				// disable ARIA support, the live region takes care of that
9220				role: null
9221			})
9222			.zIndex( this.element.zIndex() + 1 )
9223			.hide()
9224			.data( "menu" );
9225
9226		this._on( this.menu.element, {
9227			mousedown: function( event ) {
9228				// prevent moving focus out of the text field
9229				event.preventDefault();
9230
9231				// IE doesn't prevent moving focus even with event.preventDefault()
9232				// so we set a flag to know when we should ignore the blur event
9233				this.cancelBlur = true;
9234				this._delay(function() {
9235					delete this.cancelBlur;
9236				});
9237
9238				// clicking on the scrollbar causes focus to shift to the body
9239				// but we can't detect a mouseup or a click immediately afterward
9240				// so we have to track the next mousedown and close the menu if
9241				// the user clicks somewhere outside of the autocomplete
9242				var menuElement = this.menu.element[ 0 ];
9243				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
9244					this._delay(function() {
9245						var that = this;
9246						this.document.one( "mousedown", function( event ) {
9247							if ( event.target !== that.element[ 0 ] &&
9248									event.target !== menuElement &&
9249									!$.contains( menuElement, event.target ) ) {
9250								that.close();
9251							}
9252						});
9253					});
9254				}
9255			},
9256			menufocus: function( event, ui ) {
9257				// #7024 - Prevent accidental activation of menu items in Firefox
9258				if ( this.isNewMenu ) {
9259					this.isNewMenu = false;
9260					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
9261						this.menu.blur();
9262
9263						this.document.one( "mousemove", function() {
9264							$( event.target ).trigger( event.originalEvent );
9265						});
9266
9267						return;
9268					}
9269				}
9270
9271				// back compat for _renderItem using item.autocomplete, via #7810
9272				// TODO remove the fallback, see #8156
9273				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" );
9274				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
9275					// use value to match what will end up in the input, if it was a key event
9276					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
9277						this._value( item.value );
9278					}
9279				} else {
9280					// Normally the input is populated with the item's value as the
9281					// menu is navigated, causing screen readers to notice a change and
9282					// announce the item. Since the focus event was canceled, this doesn't
9283					// happen, so we update the live region so that screen readers can
9284					// still notice the change and announce it.
9285					this.liveRegion.text( item.value );
9286				}
9287			},
9288			menuselect: function( event, ui ) {
9289				// back compat for _renderItem using item.autocomplete, via #7810
9290				// TODO remove the fallback, see #8156
9291				var item = ui.item.data( "ui-autocomplete-item" ) || ui.item.data( "item.autocomplete" ),
9292					previous = this.previous;
9293
9294				// only trigger when focus was lost (click on menu)
9295				if ( this.element[0] !== this.document[0].activeElement ) {
9296					this.element.focus();
9297					this.previous = previous;
9298					// #6109 - IE triggers two focus events and the second
9299					// is asynchronous, so we need to reset the previous
9300					// term synchronously and asynchronously :-(
9301					this._delay(function() {
9302						this.previous = previous;
9303						this.selectedItem = item;
9304					});
9305				}
9306
9307				if ( false !== this._trigger( "select", event, { item: item } ) ) {
9308					this._value( item.value );
9309				}
9310				// reset the term after the select event
9311				// this allows custom select handling to work properly
9312				this.term = this._value();
9313
9314				this.close( event );
9315				this.selectedItem = item;
9316			}
9317		});
9318
9319		this.liveRegion = $( "<span>", {
9320				role: "status",
9321				"aria-live": "polite"
9322			})
9323			.addClass( "ui-helper-hidden-accessible" )
9324			.insertAfter( this.element );
9325
9326		if ( $.fn.bgiframe ) {
9327			this.menu.element.bgiframe();
9328		}
9329
9330		// turning off autocomplete prevents the browser from remembering the
9331		// value when navigating through history, so we re-enable autocomplete
9332		// if the page is unloaded before the widget is destroyed. #7790
9333		this._on( this.window, {
9334			beforeunload: function() {
9335				this.element.removeAttr( "autocomplete" );
9336			}
9337		});
9338	},
9339
9340	_destroy: function() {
9341		clearTimeout( this.searching );
9342		this.element
9343			.removeClass( "ui-autocomplete-input" )
9344			.removeAttr( "autocomplete" );
9345		this.menu.element.remove();
9346		this.liveRegion.remove();
9347	},
9348
9349	_setOption: function( key, value ) {
9350		this._super( key, value );
9351		if ( key === "source" ) {
9352			this._initSource();
9353		}
9354		if ( key === "appendTo" ) {
9355			this.menu.element.appendTo( this.document.find( value || "body" )[0] );
9356		}
9357		if ( key === "disabled" && value && this.xhr ) {
9358			this.xhr.abort();
9359		}
9360	},
9361
9362	_isMultiLine: function() {
9363		// Textareas are always multi-line
9364		if ( this.element.is( "textarea" ) ) {
9365			return true;
9366		}
9367		// Inputs are always single-line, even if inside a contentEditable element
9368		// IE also treats inputs as contentEditable
9369		if ( this.element.is( "input" ) ) {
9370			return false;
9371		}
9372		// All other element types are determined by whether or not they're contentEditable
9373		return this.element.prop( "isContentEditable" );
9374	},
9375
9376	_initSource: function() {
9377		var array, url,
9378			that = this;
9379		if ( $.isArray(this.options.source) ) {
9380			array = this.options.source;
9381			this.source = function( request, response ) {
9382				response( $.ui.autocomplete.filter( array, request.term ) );
9383			};
9384		} else if ( typeof this.options.source === "string" ) {
9385			url = this.options.source;
9386			this.source = function( request, response ) {
9387				if ( that.xhr ) {
9388					that.xhr.abort();
9389				}
9390				that.xhr = $.ajax({
9391					url: url,
9392					data: request,
9393					dataType: "json",
9394					success: function( data ) {
9395						response( data );
9396					},
9397					error: function() {
9398						response( [] );
9399					}
9400				});
9401			};
9402		} else {
9403			this.source = this.options.source;
9404		}
9405	},
9406
9407	_searchTimeout: function( event ) {
9408		clearTimeout( this.searching );
9409		this.searching = this._delay(function() {
9410			// only search if the value has changed
vendor: 12,812 bytes, lines 9411-9886
9411			if ( this.term !== this._value() ) {
9412				this.selectedItem = null;
9413				this.search( null, event );
9414			}
9415		}, this.options.delay );
9416	},
9417
9418	search: function( value, event ) {
9419		value = value != null ? value : this._value();
9420
9421		// always save the actual value, not the one passed as an argument
9422		this.term = this._value();
9423
9424		if ( value.length < this.options.minLength ) {
9425			return this.close( event );
9426		}
9427
9428		if ( this._trigger( "search", event ) === false ) {
9429			return;
9430		}
9431
9432		return this._search( value );
9433	},
9434
9435	_search: function( value ) {
9436		this.pending++;
9437		this.element.addClass( "ui-autocomplete-loading" );
9438		this.cancelSearch = false;
9439
9440		this.source( { term: value }, this._response() );
9441	},
9442
9443	_response: function() {
9444		var that = this,
9445			index = ++requestIndex;
9446
9447		return function( content ) {
9448			if ( index === requestIndex ) {
9449				that.__response( content );
9450			}
9451
9452			that.pending--;
9453			if ( !that.pending ) {
9454				that.element.removeClass( "ui-autocomplete-loading" );
9455			}
9456		};
9457	},
9458
9459	__response: function( content ) {
9460		if ( content ) {
9461			content = this._normalize( content );
9462		}
9463		this._trigger( "response", null, { content: content } );
9464		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
9465			this._suggest( content );
9466			this._trigger( "open" );
9467		} else {
9468			// use ._close() instead of .close() so we don't cancel future searches
9469			this._close();
9470		}
9471	},
9472
9473	close: function( event ) {
9474		this.cancelSearch = true;
9475		this._close( event );
9476	},
9477
9478	_close: function( event ) {
9479		if ( this.menu.element.is( ":visible" ) ) {
9480			this.menu.element.hide();
9481			this.menu.blur();
9482			this.isNewMenu = true;
9483			this._trigger( "close", event );
9484		}
9485	},
9486
9487	_change: function( event ) {
9488		if ( this.previous !== this._value() ) {
9489			this._trigger( "change", event, { item: this.selectedItem } );
9490		}
9491	},
9492
9493	_normalize: function( items ) {
9494		// assume all items have the right format when the first item is complete
9495		if ( items.length && items[0].label && items[0].value ) {
9496			return items;
9497		}
9498		return $.map( items, function( item ) {
9499			if ( typeof item === "string" ) {
9500				return {
9501					label: item,
9502					value: item
9503				};
9504			}
9505			return $.extend({
9506				label: item.label || item.value,
9507				value: item.value || item.label
9508			}, item );
9509		});
9510	},
9511
9512	_suggest: function( items ) {
9513		var ul = this.menu.element
9514			.empty()
9515			.zIndex( this.element.zIndex() + 1 );
9516		this._renderMenu( ul, items );
9517		this.menu.refresh();
9518
9519		// size and position menu
9520		ul.show();
9521		this._resizeMenu();
9522		ul.position( $.extend({
9523			of: this.element
9524		}, this.options.position ));
9525
9526		if ( this.options.autoFocus ) {
9527			this.menu.next();
9528		}
9529	},
9530
9531	_resizeMenu: function() {
9532		var ul = this.menu.element;
9533		ul.outerWidth( Math.max(
9534			// Firefox wraps long text (possibly a rounding bug)
9535			// so we add 1px to avoid the wrapping (#7513)
9536			ul.width( "" ).outerWidth() + 1,
9537			this.element.outerWidth()
9538		) );
9539	},
9540
9541	_renderMenu: function( ul, items ) {
9542		var that = this;
9543		$.each( items, function( index, item ) {
9544			that._renderItemData( ul, item );
9545		});
9546	},
9547
9548	_renderItemData: function( ul, item ) {
9549		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
9550	},
9551
9552	_renderItem: function( ul, item ) {
9553		return $( "<li>" )
9554			.append( $( "<a>" ).text( item.label ) )
9555			.appendTo( ul );
9556	},
9557
9558	_move: function( direction, event ) {
9559		if ( !this.menu.element.is( ":visible" ) ) {
9560			this.search( null, event );
9561			return;
9562		}
9563		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
9564				this.menu.isLastItem() && /^next/.test( direction ) ) {
9565			this._value( this.term );
9566			this.menu.blur();
9567			return;
9568		}
9569		this.menu[ direction ]( event );
9570	},
9571
9572	widget: function() {
9573		return this.menu.element;
9574	},
9575
9576	_value: function() {
9577		return this.valueMethod.apply( this.element, arguments );
9578	},
9579
9580	_keyEvent: function( keyEvent, event ) {
9581		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
9582			this._move( keyEvent, event );
9583
9584			// prevents moving cursor to beginning/end of the text field in some browsers
9585			event.preventDefault();
9586		}
9587	}
9588});
9589
9590$.extend( $.ui.autocomplete, {
9591	escapeRegex: function( value ) {
9592		return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
9593	},
9594	filter: function(array, term) {
9595		var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
9596		return $.grep( array, function(value) {
9597			return matcher.test( value.label || value.value || value );
9598		});
9599	}
9600});
9601
9602
9603// live region extension, adding a `messages` option
9604// NOTE: This is an experimental API. We are still investigating
9605// a full solution for string manipulation and internationalization.
9606$.widget( "ui.autocomplete", $.ui.autocomplete, {
9607	options: {
9608		messages: {
9609			noResults: "No search results.",
9610			results: function( amount ) {
9611				return amount + ( amount > 1 ? " results are" : " result is" ) +
9612					" available, use up and down arrow keys to navigate.";
9613			}
9614		}
9615	},
9616
9617	__response: function( content ) {
9618		var message;
9619		this._superApply( arguments );
9620		if ( this.options.disabled || this.cancelSearch ) {
9621			return;
9622		}
9623		if ( content && content.length ) {
9624			message = this.options.messages.results( content.length );
9625		} else {
9626			message = this.options.messages.noResults;
9627		}
9628		this.liveRegion.text( message );
9629	}
9630});
9631
9632
9633}( jQuery ));
9634
9635(function( $, undefined ) {
9636
9637var lastActive, startXPos, startYPos, clickDragged,
9638	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
9639	stateClasses = "ui-state-hover ui-state-active ",
9640	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
9641	formResetHandler = function() {
9642		var buttons = $( this ).find( ":ui-button" );
9643		setTimeout(function() {
9644			buttons.button( "refresh" );
9645		}, 1 );
9646	},
9647	radioGroup = function( radio ) {
9648		var name = radio.name,
9649			form = radio.form,
9650			radios = $( [] );
9651		if ( name ) {
9652			if ( form ) {
9653				radios = $( form ).find( "[name='" + name + "']" );
9654			} else {
9655				radios = $( "[name='" + name + "']", radio.ownerDocument )
9656					.filter(function() {
9657						return !this.form;
9658					});
9659			}
9660		}
9661		return radios;
9662	};
9663
9664$.widget( "ui.button", {
9665	version: "1.9.1",
9666	defaultElement: "<button>",
9667	options: {
9668		disabled: null,
9669		text: true,
9670		label: null,
9671		icons: {
9672			primary: null,
9673			secondary: null
9674		}
9675	},
9676	_create: function() {
9677		this.element.closest( "form" )
9678			.unbind( "reset" + this.eventNamespace )
9679			.bind( "reset" + this.eventNamespace, formResetHandler );
9680
9681		if ( typeof this.options.disabled !== "boolean" ) {
9682			this.options.disabled = !!this.element.prop( "disabled" );
9683		} else {
9684			this.element.prop( "disabled", this.options.disabled );
9685		}
9686
9687		this._determineButtonType();
9688		this.hasTitle = !!this.buttonElement.attr( "title" );
9689
9690		var that = this,
9691			options = this.options,
9692			toggleButton = this.type === "checkbox" || this.type === "radio",
9693			hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
9694			focusClass = "ui-state-focus";
9695
9696		if ( options.label === null ) {
9697			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
9698		}
9699
9700		this.buttonElement
9701			.addClass( baseClasses )
9702			.attr( "role", "button" )
9703			.bind( "mouseenter" + this.eventNamespace, function() {
9704				if ( options.disabled ) {
9705					return;
9706				}
9707				$( this ).addClass( "ui-state-hover" );
9708				if ( this === lastActive ) {
9709					$( this ).addClass( "ui-state-active" );
9710				}
9711			})
9712			.bind( "mouseleave" + this.eventNamespace, function() {
9713				if ( options.disabled ) {
9714					return;
9715				}
9716				$( this ).removeClass( hoverClass );
9717			})
9718			.bind( "click" + this.eventNamespace, function( event ) {
9719				if ( options.disabled ) {
9720					event.preventDefault();
9721					event.stopImmediatePropagation();
9722				}
9723			});
9724
9725		this.element
9726			.bind( "focus" + this.eventNamespace, function() {
9727				// no need to check disabled, focus won't be triggered anyway
9728				that.buttonElement.addClass( focusClass );
9729			})
9730			.bind( "blur" + this.eventNamespace, function() {
9731				that.buttonElement.removeClass( focusClass );
9732			});
9733
9734		if ( toggleButton ) {
9735			this.element.bind( "change" + this.eventNamespace, function() {
9736				if ( clickDragged ) {
9737					return;
9738				}
9739				that.refresh();
9740			});
9741			// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
9742			// prevents issue where button state changes but checkbox/radio checked state
9743			// does not in Firefox (see ticket #6970)
9744			this.buttonElement
9745				.bind( "mousedown" + this.eventNamespace, function( event ) {
9746					if ( options.disabled ) {
9747						return;
9748					}
9749					clickDragged = false;
9750					startXPos = event.pageX;
9751					startYPos = event.pageY;
9752				})
9753				.bind( "mouseup" + this.eventNamespace, function( event ) {
9754					if ( options.disabled ) {
9755						return;
9756					}
9757					if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
9758						clickDragged = true;
9759					}
9760			});
9761		}
9762
9763		if ( this.type === "checkbox" ) {
9764			this.buttonElement.bind( "click" + this.eventNamespace, function() {
9765				if ( options.disabled || clickDragged ) {
9766					return false;
9767				}
9768				$( this ).toggleClass( "ui-state-active" );
9769				that.buttonElement.attr( "aria-pressed", that.element[0].checked );
9770			});
9771		} else if ( this.type === "radio" ) {
9772			this.buttonElement.bind( "click" + this.eventNamespace, function() {
9773				if ( options.disabled || clickDragged ) {
9774					return false;
9775				}
9776				$( this ).addClass( "ui-state-active" );
9777				that.buttonElement.attr( "aria-pressed", "true" );
9778
9779				var radio = that.element[ 0 ];
9780				radioGroup( radio )
9781					.not( radio )
9782					.map(function() {
9783						return $( this ).button( "widget" )[ 0 ];
9784					})
9785					.removeClass( "ui-state-active" )
9786					.attr( "aria-pressed", "false" );
9787			});
9788		} else {
9789			this.buttonElement
9790				.bind( "mousedown" + this.eventNamespace, function() {
9791					if ( options.disabled ) {
9792						return false;
9793					}
9794					$( this ).addClass( "ui-state-active" );
9795					lastActive = this;
9796					that.document.one( "mouseup", function() {
9797						lastActive = null;
9798					});
9799				})
9800				.bind( "mouseup" + this.eventNamespace, function() {
9801					if ( options.disabled ) {
9802						return false;
9803					}
9804					$( this ).removeClass( "ui-state-active" );
9805				})
9806				.bind( "keydown" + this.eventNamespace, function(event) {
9807					if ( options.disabled ) {
9808						return false;
9809					}
9810					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
9811						$( this ).addClass( "ui-state-active" );
9812					}
9813				})
9814				.bind( "keyup" + this.eventNamespace, function() {
9815					$( this ).removeClass( "ui-state-active" );
9816				});
9817
9818			if ( this.buttonElement.is("a") ) {
9819				this.buttonElement.keyup(function(event) {
9820					if ( event.keyCode === $.ui.keyCode.SPACE ) {
9821						// TODO pass through original event correctly (just as 2nd argument doesn't work)
9822						$( this ).click();
9823					}
9824				});
9825			}
9826		}
9827
9828		// TODO: pull out $.Widget's handling for the disabled option into
9829		// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
9830		// be overridden by individual plugins
9831		this._setOption( "disabled", options.disabled );
9832		this._resetButton();
9833	},
9834
9835	_determineButtonType: function() {
9836		var ancestor, labelSelector, checked;
9837
9838		if ( this.element.is("[type=checkbox]") ) {
9839			this.type = "checkbox";
9840		} else if ( this.element.is("[type=radio]") ) {
9841			this.type = "radio";
9842		} else if ( this.element.is("input") ) {
9843			this.type = "input";
9844		} else {
9845			this.type = "button";
9846		}
9847
9848		if ( this.type === "checkbox" || this.type === "radio" ) {
9849			// we don't search against the document in case the element
9850			// is disconnected from the DOM
9851			ancestor = this.element.parents().last();
9852			labelSelector = "label[for='" + this.element.attr("id") + "']";
9853			this.buttonElement = ancestor.find( labelSelector );
9854			if ( !this.buttonElement.length ) {
9855				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
9856				this.buttonElement = ancestor.filter( labelSelector );
9857				if ( !this.buttonElement.length ) {
9858					this.buttonElement = ancestor.find( labelSelector );
9859				}
9860			}
9861			this.element.addClass( "ui-helper-hidden-accessible" );
9862
9863			checked = this.element.is( ":checked" );
9864			if ( checked ) {
9865				this.buttonElement.addClass( "ui-state-active" );
9866			}
9867			this.buttonElement.prop( "aria-pressed", checked );
9868		} else {
9869			this.buttonElement = this.element;
9870		}
9871	},
9872
9873	widget: function() {
9874		return this.buttonElement;
9875	},
9876
9877	_destroy: function() {
9878		this.element
9879			.removeClass( "ui-helper-hidden-accessible" );
9880		this.buttonElement
9881			.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
9882			.removeAttr( "role" )
9883			.removeAttr( "aria-pressed" )
9884			.html( this.buttonElement.find(".ui-button-text").html() );
9885
9886		if ( !this.hasTitle ) {
vendor: 6,439 bytes, lines 9887-10076
9887			this.buttonElement.removeAttr( "title" );
9888		}
9889	},
9890
9891	_setOption: function( key, value ) {
9892		this._super( key, value );
9893		if ( key === "disabled" ) {
9894			if ( value ) {
9895				this.element.prop( "disabled", true );
9896			} else {
9897				this.element.prop( "disabled", false );
9898			}
9899			return;
9900		}
9901		this._resetButton();
9902	},
9903
9904	refresh: function() {
9905		var isDisabled = this.element.is( ":disabled" ) || this.element.hasClass( "ui-button-disabled" );
9906		if ( isDisabled !== this.options.disabled ) {
9907			this._setOption( "disabled", isDisabled );
9908		}
9909		if ( this.type === "radio" ) {
9910			radioGroup( this.element[0] ).each(function() {
9911				if ( $( this ).is( ":checked" ) ) {
9912					$( this ).button( "widget" )
9913						.addClass( "ui-state-active" )
9914						.attr( "aria-pressed", "true" );
9915				} else {
9916					$( this ).button( "widget" )
9917						.removeClass( "ui-state-active" )
9918						.attr( "aria-pressed", "false" );
9919				}
9920			});
9921		} else if ( this.type === "checkbox" ) {
9922			if ( this.element.is( ":checked" ) ) {
9923				this.buttonElement
9924					.addClass( "ui-state-active" )
9925					.attr( "aria-pressed", "true" );
9926			} else {
9927				this.buttonElement
9928					.removeClass( "ui-state-active" )
9929					.attr( "aria-pressed", "false" );
9930			}
9931		}
9932	},
9933
9934	_resetButton: function() {
9935		if ( this.type === "input" ) {
9936			if ( this.options.label ) {
9937				this.element.val( this.options.label );
9938			}
9939			return;
9940		}
9941		var buttonElement = this.buttonElement.removeClass( typeClasses ),
9942			buttonText = $( "<span></span>", this.document[0] )
9943				.addClass( "ui-button-text" )
9944				.html( this.options.label )
9945				.appendTo( buttonElement.empty() )
9946				.text(),
9947			icons = this.options.icons,
9948			multipleIcons = icons.primary && icons.secondary,
9949			buttonClasses = [];
9950
9951		if ( icons.primary || icons.secondary ) {
9952			if ( this.options.text ) {
9953				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
9954			}
9955
9956			if ( icons.primary ) {
9957				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
9958			}
9959
9960			if ( icons.secondary ) {
9961				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
9962			}
9963
9964			if ( !this.options.text ) {
9965				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
9966
9967				if ( !this.hasTitle ) {
9968					buttonElement.attr( "title", $.trim( buttonText ) );
9969				}
9970			}
9971		} else {
9972			buttonClasses.push( "ui-button-text-only" );
9973		}
9974		buttonElement.addClass( buttonClasses.join( " " ) );
9975	}
9976});
9977
9978$.widget( "ui.buttonset", {
9979	version: "1.9.1",
9980	options: {
9981		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(button)"
9982	},
9983
9984	_create: function() {
9985		this.element.addClass( "ui-buttonset" );
9986	},
9987
9988	_init: function() {
9989		this.refresh();
9990	},
9991
9992	_setOption: function( key, value ) {
9993		if ( key === "disabled" ) {
9994			this.buttons.button( "option", key, value );
9995		}
9996
9997		this._super( key, value );
9998	},
9999
10000	refresh: function() {
10001		var rtl = this.element.css( "direction" ) === "rtl";
10002
10003		this.buttons = this.element.find( this.options.items )
10004			.filter( ":ui-button" )
10005				.button( "refresh" )
10006			.end()
10007			.not( ":ui-button" )
10008				.button()
10009			.end()
10010			.map(function() {
10011				return $( this ).button( "widget" )[ 0 ];
10012			})
10013				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
10014				.filter( ":first" )
10015					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
10016				.end()
10017				.filter( ":last" )
10018					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
10019				.end()
10020			.end();
10021	},
10022
10023	_destroy: function() {
10024		this.element.removeClass( "ui-buttonset" );
10025		this.buttons
10026			.map(function() {
10027				return $( this ).button( "widget" )[ 0 ];
10028			})
10029				.removeClass( "ui-corner-left ui-corner-right" )
10030			.end()
10031			.button( "destroy" );
10032	}
10033});
10034
10035}( jQuery ) );
10036
10037(function( $, undefined ) {
10038
10039$.extend($.ui, { datepicker: { version: "1.9.1" } });
10040
10041var PROP_NAME = 'datepicker';
10042var dpuuid = new Date().getTime();
10043var instActive;
10044
10045/* Date picker manager.
10046   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
10047   Settings for (groups of) date pickers are maintained in an instance object,
10048   allowing multiple different settings on the same page. */
10049
10050function Datepicker() {
10051	this.debug = false; // Change this to true to start debugging
10052	this._curInst = null; // The current instance in use
10053	this._keyEvent = false; // If the last event was a key event
10054	this._disabledInputs = []; // List of date picker inputs that have been disabled
10055	this._datepickerShowing = false; // True if the popup picker is showing , false if not
10056	this._inDialog = false; // True if showing within a "dialog", false if not
10057	this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
10058	this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
10059	this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
10060	this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
10061	this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
10062	this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
10063	this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
10064	this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
10065	this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
10066	this.regional = []; // Available regional settings, indexed by language code
10067	this.regional[''] = { // Default regional settings
10068		closeText: 'Done', // Display text for close link
10069		prevText: 'Prev', // Display text for previous month link
10070		nextText: 'Next', // Display text for next month link
10071		currentText: 'Today', // Display text for current month link
10072		monthNames: ['January','February','March','April','May','June',
10073			'July','August','September','October','November','December'], // Names of months for drop-down and formatting
10074		monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
10075		dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
10076		dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
10077		dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
10078		weekHeader: 'Wk', // Column header for week of the year
10079		dateFormat: 'mm/dd/yy', // See format options on parseDate
10080		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
10081		isRTL: false, // True if right-to-left language, false if left-to-right
10082		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
10083		yearSuffix: '' // Additional text to append to the year in the month headers
10084	};
10085	this._defaults = { // Global defaults for all the date picker instances
10086		showOn: 'focus', // 'focus' for popup on focus,
10087			// 'button' for trigger button, or 'both' for either
10088		showAnim: 'fadeIn', // Name of jQuery animation for popup
10089		showOptions: {}, // Options for enhanced animations
10090		defaultDate: null, // Used when field is blank: actual date,
10091			// +/-number for offset from today, null for today
10092		appendText: '', // Display text following the input box, e.g. showing the format
10093		buttonText: '...', // Text for trigger button
10094		buttonImage: '', // URL for trigger button image
10095		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
10096		hideIfNoPrevNext: false, // True to hide next/previous month links
10097			// if not applicable, false to just disable them
10098		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
10099		gotoCurrent: false, // True if today link goes back to current selection instead
10100		changeMonth: false, // True if month can be selected directly, false if only prev/next
10101		changeYear: false, // True if year can be selected directly, false if only prev/next
10102		yearRange: 'c-10:c+10', // Range of years to display in drop-down,
10103			// either relative to today's year (-nn:+nn), relative to currently displayed year
10104			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
10105		showOtherMonths: false, // True to show dates in other months, false to leave blank
10106		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
10107		showWeek: false, // True to show week of the year, false to not show it
10108		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
10109			// takes a Date and returns the number of the week for it
10110		shortYearCutoff: '+10', // Short year values < this are in the current century,
10111			// > this are in the previous century,
10112			// string value starting with '+' for current year + value
10113		minDate: null, // The earliest selectable date, or null for no limit
10114		maxDate: null, // The latest selectable date, or null for no limit
10115		duration: 'fast', // Duration of display/closure
10116		beforeShowDay: null, // Function that takes a date and returns an array with
10117			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
10118			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
10119		beforeShow: null, // Function that takes an input field and
10120			// returns a set of custom settings for the date picker
10121		onSelect: null, // Define a callback function when a date is selected
10122		onChangeMonthYear: null, // Define a callback function when the month or year is changed
10123		onClose: null, // Define a callback function when the datepicker is closed
10124		numberOfMonths: 1, // Number of months to show at a time
10125		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
10126		stepMonths: 1, // Number of months to step back/forward
10127		stepBigMonths: 12, // Number of months to step back/forward for the big links
10128		altField: '', // Selector for an alternate field to store selected dates into
10129		altFormat: '', // The date format to use for the alternate field
10130		constrainInput: true, // The input is constrained by the current date format
10131		showButtonPanel: false, // True to show button panel, false to not show it
10132		autoSize: false, // True to size the input for the date format, false to leave as is
10133		disabled: false // The initial disabled state
10134	};
10135	$.extend(this._defaults, this.regional['']);
10136	this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
10137}
10138
10139$.extend(Datepicker.prototype, {
10140	/* Class name added to elements to indicate already configured with a date picker. */
10141	markerClassName: 'hasDatepicker',
10142
10143	//Keep track of the maximum number of rows displayed (see #7043)
10144	maxRows: 4,
10145
10146	/* Debug logging (if enabled). */
10147	log: function () {
10148		if (this.debug)
10149			console.log.apply('', arguments);
10150	},
10151
10152	// TODO rename to "widget" when switching to widget factory
10153	_widgetDatepicker: function() {
10154		return this.dpDiv;
10155	},
10156
10157	/* Override the default settings for all instances of the date picker.
10158	   @param  settings  object - the new settings to use as defaults (anonymous object)
10159	   @return the manager object */
10160	setDefaults: function(settings) {
10161		extendRemove(this._defaults, settings || {});
10162		return this;
10163	},
10164
10165	/* Attach the date picker to a jQuery selection.
10166	   @param  target    element - the target input field or division or span
10167	   @param  settings  object - the new settings to use for this date picker instance (anonymous) */
10168	_attachDatepicker: function(target, settings) {
10169		// check for settings on the control itself - in namespace 'date:'
10170		var inlineSettings = null;
10171		for (var attrName in this._defaults) {
10172			var attrValue = target.getAttribute('date:' + attrName);
10173			if (attrValue) {
10174				inlineSettings = inlineSettings || {};
10175				try {
10176					inlineSettings[attrName] = eval(attrValue);
10177				} catch (err) {
10178					inlineSettings[attrName] = attrValue;
10179				}
10180			}
10181		}
10182		var nodeName = target.nodeName.toLowerCase();
10183		var inline = (nodeName == 'div' || nodeName == 'span');
10184		if (!target.id) {
10185			this.uuid += 1;
10186			target.id = 'dp' + this.uuid;
10187		}
10188		var inst = this._newInst($(target), inline);
10189		inst.settings = $.extend({}, settings || {}, inlineSettings || {});
10190		if (nodeName == 'input') {
10191			this._connectDatepicker(target, inst);
10192		} else if (inline) {
10193			this._inlineDatepicker(target, inst);
10194		}
10195	},
10196
10197	/* Create a new instance object. */
10198	_newInst: function(target, inline) {
10199		var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
10200		return {id: id, input: target, // associated target
10201			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
10202			drawMonth: 0, drawYear: 0, // month being drawn
10203			inline: inline, // is datepicker inline or not
10204			dpDiv: (!inline ? this.dpDiv : // presentation div
10205			bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
10206	},
10207
10208	/* Attach the date picker to an input field. */
10209	_connectDatepicker: function(target, inst) {
10210		var input = $(target);
10211		inst.append = $([]);
10212		inst.trigger = $([]);
10213		if (input.hasClass(this.markerClassName))
10214			return;
10215		this._attachments(input, inst);
10216		input.addClass(this.markerClassName).keydown(this._doKeyDown).
10217			keypress(this._doKeyPress).keyup(this._doKeyUp).
10218			bind("setData.datepicker", function(event, key, value) {
10219				inst.settings[key] = value;
10220			}).bind("getData.datepicker", function(event, key) {
10221				return this._get(inst, key);
10222			});
10223		this._autoSize(inst);
10224		$.data(target, PROP_NAME, inst);
10225		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
10226		if( inst.settings.disabled ) {
10227			this._disableDatepicker( target );
10228		}
10229	},
10230
10231	/* Make attachments based on settings. */
10232	_attachments: function(input, inst) {
10233		var appendText = this._get(inst, 'appendText');
10234		var isRTL = this._get(inst, 'isRTL');
10235		if (inst.append)
10236			inst.append.remove();
10237		if (appendText) {
10238			inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
10239			input[isRTL ? 'before' : 'after'](inst.append);
10240		}
10241		input.unbind('focus', this._showDatepicker);
10242		if (inst.trigger)
10243			inst.trigger.remove();
10244		var showOn = this._get(inst, 'showOn');
10245		if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
10246			input.focus(this._showDatepicker);
10247		if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
10248			var buttonText = this._get(inst, 'buttonText');
10249			var buttonImage = this._get(inst, 'buttonImage');
10250			inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
10251				$('<img/>').addClass(this._triggerClass).
10252					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
10253				$('<button type="button"></button>').addClass(this._triggerClass).
10254					html(buttonImage == '' ? buttonText : $('<img/>').attr(
10255					{ src:buttonImage, alt:buttonText, title:buttonText })));
10256			input[isRTL ? 'before' : 'after'](inst.trigger);
10257			inst.trigger.click(function() {
10258				if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
10259					$.datepicker._hideDatepicker();
10260				else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
10261					$.datepicker._hideDatepicker();
10262					$.datepicker._showDatepicker(input[0]);
10263				} else
10264					$.datepicker._showDatepicker(input[0]);
10265				return false;
10266			});
10267		}
10268	},
10269
10270	/* Apply the maximum length for the date format. */
10271	_autoSize: function(inst) {
10272		if (this._get(inst, 'autoSize') && !inst.inline) {
10273			var date = new Date(2009, 12 - 1, 20); // Ensure double digits
10274			var dateFormat = this._get(inst, 'dateFormat');
10275			if (dateFormat.match(/[DM]/)) {
10276				var findMax = function(names) {
10277					var max = 0;
10278					var maxI = 0;
10279					for (var i = 0; i < names.length; i++) {
10280						if (names[i].length > max) {
10281							max = names[i].length;
10282							maxI = i;
10283						}
10284					}
10285					return maxI;
10286				};
10287				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
10288					'monthNames' : 'monthNamesShort'))));
10289				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
10290					'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
10291			}
10292			inst.input.attr('size', this._formatDate(inst, date).length);
10293		}
10294	},
10295
10296	/* Attach an inline date picker to a div. */
10297	_inlineDatepicker: function(target, inst) {
10298		var divSpan = $(target);
10299		if (divSpan.hasClass(this.markerClassName))
10300			return;
10301		divSpan.addClass(this.markerClassName).append(inst.dpDiv).
10302			bind("setData.datepicker", function(event, key, value){
10303				inst.settings[key] = value;
10304			}).bind("getData.datepicker", function(event, key){
10305				return this._get(inst, key);
10306			});
10307		$.data(target, PROP_NAME, inst);
10308		this._setDate(inst, this._getDefaultDate(inst), true);
10309		this._updateDatepicker(inst);
10310		this._updateAlternate(inst);
10311		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
10312		if( inst.settings.disabled ) {
10313			this._disableDatepicker( target );
10314		}
10315		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
10316		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
10317		inst.dpDiv.css( "display", "block" );
10318	},
10319
10320	/* Pop-up the date picker in a "dialog" box.
10321	   @param  input     element - ignored
10322	   @param  date      string or Date - the initial date to display
10323	   @param  onSelect  function - the function to call when a date is selected
10324	   @param  settings  object - update the dialog date picker instance's settings (anonymous object)
10325	   @param  pos       int[2] - coordinates for the dialog's position within the screen or
10326	                     event - with x/y coordinates or
10327	                     leave empty for default (screen centre)
10328	   @return the manager object */
10329	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
10330		var inst = this._dialogInst; // internal instance
10331		if (!inst) {
10332			this.uuid += 1;
10333			var id = 'dp' + this.uuid;
10334			this._dialogInput = $('<input type="text" id="' + id +
10335				'" style="position: absolute; top: -100px; width: 0px;"/>');
10336			this._dialogInput.keydown(this._doKeyDown);
10337			$('body').append(this._dialogInput);
10338			inst = this._dialogInst = this._newInst(this._dialogInput, false);
10339			inst.settings = {};
10340			$.data(this._dialogInput[0], PROP_NAME, inst);
10341		}
10342		extendRemove(inst.settings, settings || {});
10343		date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
10344		this._dialogInput.val(date);
10345
10346		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
10347		if (!this._pos) {
10348			var browserWidth = document.documentElement.clientWidth;
10349			var browserHeight = document.documentElement.clientHeight;
10350			var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
10351			var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
10352			this._pos = // should use actual width/height below
10353				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
10354		}
10355
10356		// move input on screen for focus, but hidden behind dialog
10357		this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
10358		inst.settings.onSelect = onSelect;
10359		this._inDialog = true;
10360		this.dpDiv.addClass(this._dialogClass);
10361		this._showDatepicker(this._dialogInput[0]);
10362		if ($.blockUI)
10363			$.blockUI(this.dpDiv);
10364		$.data(this._dialogInput[0], PROP_NAME, inst);
10365		return this;
10366	},
10367
10368	/* Detach a datepicker from its control.
10369	   @param  target    element - the target input field or division or span */
10370	_destroyDatepicker: function(target) {
10371		var $target = $(target);
10372		var inst = $.data(target, PROP_NAME);
10373		if (!$target.hasClass(this.markerClassName)) {
10374			return;
10375		}
10376		var nodeName = target.nodeName.toLowerCase();
10377		$.removeData(target, PROP_NAME);
10378		if (nodeName == 'input') {
10379			inst.append.remove();
10380			inst.trigger.remove();
10381			$target.removeClass(this.markerClassName).
10382				unbind('focus', this._showDatepicker).
10383				unbind('keydown', this._doKeyDown).
10384				unbind('keypress', this._doKeyPress).
10385				unbind('keyup', this._doKeyUp);
10386		} else if (nodeName == 'div' || nodeName == 'span')
10387			$target.removeClass(this.markerClassName).empty();
10388	},
10389
10390	/* Enable the date picker to a jQuery selection.
10391	   @param  target    element - the target input field or division or span */
10392	_enableDatepicker: function(target) {
10393		var $target = $(target);
10394		var inst = $.data(target, PROP_NAME);
10395		if (!$target.hasClass(this.markerClassName)) {
10396			return;
10397		}
10398		var nodeName = target.nodeName.toLowerCase();
10399		if (nodeName == 'input') {
10400			target.disabled = false;
10401			inst.trigger.filter('button').
10402				each(function() { this.disabled = false; }).end().
10403				filter('img').css({opacity: '1.0', cursor: ''});
10404		}
10405		else if (nodeName == 'div' || nodeName == 'span') {
10406			var inline = $target.children('.' + this._inlineClass);
10407			inline.children().removeClass('ui-state-disabled');
10408			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
10409				prop("disabled", false);
10410		}
10411		this._disabledInputs = $.map(this._disabledInputs,
10412			function(value) { return (value == target ? null : value); }); // delete entry
10413	},
10414
10415	/* Disable the date picker to a jQuery selection.
10416	   @param  target    element - the target input field or division or span */
10417	_disableDatepicker: function(target) {
10418		var $target = $(target);
10419		var inst = $.data(target, PROP_NAME);
10420		if (!$target.hasClass(this.markerClassName)) {
10421			return;
10422		}
10423		var nodeName = target.nodeName.toLowerCase();
10424		if (nodeName == 'input') {
10425			target.disabled = true;
10426			inst.trigger.filter('button').
10427				each(function() { this.disabled = true; }).end().
10428				filter('img').css({opacity: '0.5', cursor: 'default'});
10429		}
10430		else if (nodeName == 'div' || nodeName == 'span') {
10431			var inline = $target.children('.' + this._inlineClass);
10432			inline.children().addClass('ui-state-disabled');
10433			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
10434				prop("disabled", true);
10435		}
10436		this._disabledInputs = $.map(this._disabledInputs,
10437			function(value) { return (value == target ? null : value); }); // delete entry
10438		this._disabledInputs[this._disabledInputs.length] = target;
10439	},
10440
10441	/* Is the first field in a jQuery collection disabled as a datepicker?
10442	   @param  target    element - the target input field or division or span
10443	   @return boolean - true if disabled, false if enabled */
10444	_isDisabledDatepicker: function(target) {
10445		if (!target) {
10446			return false;
10447		}
10448		for (var i = 0; i < this._disabledInputs.length; i++) {
10449			if (this._disabledInputs[i] == target)
10450				return true;
10451		}
10452		return false;
10453	},
10454
10455	/* Retrieve the instance data for the target control.
10456	   @param  target  element - the target input field or division or span
10457	   @return  object - the associated instance data
10458	   @throws  error if a jQuery problem getting data */
10459	_getInst: function(target) {
10460		try {
10461			return $.data(target, PROP_NAME);
10462		}
10463		catch (err) {
10464			throw 'Missing instance data for this datepicker';
10465		}
10466	},
10467
10468	/* Update or retrieve the settings for a date picker attached to an input field or division.
10469	   @param  target  element - the target input field or division or span
10470	   @param  name    object - the new settings to update or
10471	                   string - the name of the setting to change or retrieve,
10472	                   when retrieving also 'all' for all instance settings or
10473	                   'defaults' for all global defaults
10474	   @param  value   any - the new value for the setting
10475	                   (omit if above is an object or to retrieve a value) */
10476	_optionDatepicker: function(target, name, value) {
10477		var inst = this._getInst(target);
10478		if (arguments.length == 2 && typeof name == 'string') {
10479			return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
10480				(inst ? (name == 'all' ? $.extend({}, inst.settings) :
10481				this._get(inst, name)) : null));
10482		}
10483		var settings = name || {};
10484		if (typeof name == 'string') {
10485			settings = {};
10486			settings[name] = value;
10487		}
10488		if (inst) {
10489			if (this._curInst == inst) {
10490				this._hideDatepicker();
10491			}
10492			var date = this._getDateDatepicker(target, true);
10493			var minDate = this._getMinMaxDate(inst, 'min');
10494			var maxDate = this._getMinMaxDate(inst, 'max');
10495			extendRemove(inst.settings, settings);
10496			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
10497			if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
10498				inst.settings.minDate = this._formatDate(inst, minDate);
10499			if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
10500				inst.settings.maxDate = this._formatDate(inst, maxDate);
10501			this._attachments($(target), inst);
10502			this._autoSize(inst);
10503			this._setDate(inst, date);
10504			this._updateAlternate(inst);
10505			this._updateDatepicker(inst);
10506		}
10507	},
10508
10509	// change method deprecated
10510	_changeDatepicker: function(target, name, value) {
10511		this._optionDatepicker(target, name, value);
10512	},
10513
10514	/* Redraw the date picker attached to an input field or division.
10515	   @param  target  element - the target input field or division or span */
10516	_refreshDatepicker: function(target) {
10517		var inst = this._getInst(target);
10518		if (inst) {
10519			this._updateDatepicker(inst);
10520		}
10521	},
10522
10523	/* Set the dates for a jQuery selection.
10524	   @param  target   element - the target input field or division or span
10525	   @param  date     Date - the new date */
10526	_setDateDatepicker: function(target, date) {
10527		var inst = this._getInst(target);
10528		if (inst) {
10529			this._setDate(inst, date);
10530			this._updateDatepicker(inst);
10531			this._updateAlternate(inst);
10532		}
10533	},
10534
10535	/* Get the date(s) for the first entry in a jQuery selection.
10536	   @param  target     element - the target input field or division or span
10537	   @param  noDefault  boolean - true if no default date is to be used
10538	   @return Date - the current date */
10539	_getDateDatepicker: function(target, noDefault) {
10540		var inst = this._getInst(target);
10541		if (inst && !inst.inline)
10542			this._setDateFromField(inst, noDefault);
10543		return (inst ? this._getDate(inst) : null);
10544	},
10545
10546	/* Handle keystrokes. */
10547	_doKeyDown: function(event) {
10548		var inst = $.datepicker._getInst(event.target);
10549		var handled = true;
10550		var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
10551		inst._keyEvent = true;
10552		if ($.datepicker._datepickerShowing)
10553			switch (event.keyCode) {
10554				case 9: $.datepicker._hideDatepicker();
10555						handled = false;
10556						break; // hide on tab out
10557				case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
10558									$.datepicker._currentClass + ')', inst.dpDiv);
10559						if (sel[0])
10560							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
10561							var onSelect = $.datepicker._get(inst, 'onSelect');
10562							if (onSelect) {
10563								var dateStr = $.datepicker._formatDate(inst);
10564
10565								// trigger custom callback
10566								onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
10567							}
10568						else
10569							$.datepicker._hideDatepicker();
10570						return false; // don't submit the form
10571						break; // select the value on enter
10572				case 27: $.datepicker._hideDatepicker();
10573						break; // hide on escape
10574				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10575							-$.datepicker._get(inst, 'stepBigMonths') :
10576							-$.datepicker._get(inst, 'stepMonths')), 'M');
10577						break; // previous month/year on page up/+ ctrl
10578				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10579							+$.datepicker._get(inst, 'stepBigMonths') :
10580							+$.datepicker._get(inst, 'stepMonths')), 'M');
10581						break; // next month/year on page down/+ ctrl
10582				case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
10583						handled = event.ctrlKey || event.metaKey;
10584						break; // clear on ctrl or command +end
10585				case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
10586						handled = event.ctrlKey || event.metaKey;
10587						break; // current on ctrl or command +home
10588				case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
10589						handled = event.ctrlKey || event.metaKey;
10590						// -1 day on ctrl or command +left
10591						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10592									-$.datepicker._get(inst, 'stepBigMonths') :
10593									-$.datepicker._get(inst, 'stepMonths')), 'M');
10594						// next month/year on alt +left on Mac
10595						break;
10596				case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
10597						handled = event.ctrlKey || event.metaKey;
10598						break; // -1 week on ctrl or command +up
10599				case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
10600						handled = event.ctrlKey || event.metaKey;
10601						// +1 day on ctrl or command +right
10602						if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
10603									+$.datepicker._get(inst, 'stepBigMonths') :
10604									+$.datepicker._get(inst, 'stepMonths')), 'M');
10605						// next month/year on alt +right
10606						break;
10607				case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
10608						handled = event.ctrlKey || event.metaKey;
10609						break; // +1 week on ctrl or command +down
10610				default: handled = false;
10611			}
10612		else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
10613			$.datepicker._showDatepicker(this);
10614		else {
10615			handled = false;
10616		}
10617		if (handled) {
10618			event.preventDefault();
10619			event.stopPropagation();
10620		}
10621	},
10622
10623	/* Filter entered characters - based on date format. */
10624	_doKeyPress: function(event) {
10625		var inst = $.datepicker._getInst(event.target);
10626		if ($.datepicker._get(inst, 'constrainInput')) {
10627			var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
10628			var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
10629			return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
10630		}
10631	},
10632
10633	/* Synchronise manual entry and field/alternate field. */
10634	_doKeyUp: function(event) {
10635		var inst = $.datepicker._getInst(event.target);
10636		if (inst.input.val() != inst.lastVal) {
10637			try {
10638				var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
10639					(inst.input ? inst.input.val() : null),
10640					$.datepicker._getFormatConfig(inst));
10641				if (date) { // only if valid
10642					$.datepicker._setDateFromField(inst);
10643					$.datepicker._updateAlternate(inst);
10644					$.datepicker._updateDatepicker(inst);
10645				}
10646			}
10647			catch (err) {
10648				$.datepicker.log(err);
10649			}
10650		}
10651		return true;
10652	},
10653
10654	/* Pop-up the date picker for a given input field.
10655	   If false returned from beforeShow event handler do not show.
10656	   @param  input  element - the input field attached to the date picker or
10657	                  event - if triggered by focus */
10658	_showDatepicker: function(input) {
10659		input = input.target || input;
10660		if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
10661			input = $('input', input.parentNode)[0];
10662		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
10663			return;
10664		var inst = $.datepicker._getInst(input);
10665		if ($.datepicker._curInst && $.datepicker._curInst != inst) {
10666			$.datepicker._curInst.dpDiv.stop(true, true);
10667			if ( inst && $.datepicker._datepickerShowing ) {
10668				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
10669			}
10670		}
10671		var beforeShow = $.datepicker._get(inst, 'beforeShow');
10672		var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
10673		if(beforeShowSettings === false){
10674			//false
10675			return;
10676		}
10677		extendRemove(inst.settings, beforeShowSettings);
10678		inst.lastVal = null;
10679		$.datepicker._lastInput = input;
10680		$.datepicker._setDateFromField(inst);
10681		if ($.datepicker._inDialog) // hide cursor
10682			input.value = '';
10683		if (!$.datepicker._pos) { // position below input
10684			$.datepicker._pos = $.datepicker._findPos(input);
10685			$.datepicker._pos[1] += input.offsetHeight; // add the height
10686		}
10687		var isFixed = false;
10688		$(input).parents().each(function() {
10689			isFixed |= $(this).css('position') == 'fixed';
10690			return !isFixed;
10691		});
10692		var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
10693		$.datepicker._pos = null;
10694		//to avoid flashes on Firefox
10695		inst.dpDiv.empty();
10696		// determine sizing offscreen
10697		inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
10698		$.datepicker._updateDatepicker(inst);
10699		// fix width for dynamic number of date pickers
10700		// and adjust position before showing
10701		offset = $.datepicker._checkOffset(inst, offset, isFixed);
10702		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
10703			'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
10704			left: offset.left + 'px', top: offset.top + 'px'});
10705		if (!inst.inline) {
10706			var showAnim = $.datepicker._get(inst, 'showAnim');
10707			var duration = $.datepicker._get(inst, 'duration');
10708			var postProcess = function() {
10709				var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
10710				if( !! cover.length ){
10711					var borders = $.datepicker._getBorders(inst.dpDiv);
10712					cover.css({left: -borders[0], top: -borders[1],
10713						width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
10714				}
10715			};
10716			inst.dpDiv.zIndex($(input).zIndex()+1);
10717			$.datepicker._datepickerShowing = true;
10718
10719			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10720			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
10721				inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
10722			else
10723				inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
10724			if (!showAnim || !duration)
10725				postProcess();
10726			if (inst.input.is(':visible') && !inst.input.is(':disabled'))
10727				inst.input.focus();
10728			$.datepicker._curInst = inst;
10729		}
10730	},
10731
10732	/* Generate the date picker content. */
10733	_updateDatepicker: function(inst) {
10734		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
10735		var borders = $.datepicker._getBorders(inst.dpDiv);
10736		instActive = inst; // for delegate hover events
10737		inst.dpDiv.empty().append(this._generateHTML(inst));
10738		this._attachHandlers(inst);
10739		var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
10740		if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
10741			cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
10742		}
10743		inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
10744		var numMonths = this._getNumberOfMonths(inst);
10745		var cols = numMonths[1];
10746		var width = 17;
10747		inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
10748		if (cols > 1)
10749			inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
10750		inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
10751			'Class']('ui-datepicker-multi');
10752		inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
10753			'Class']('ui-datepicker-rtl');
10754		if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
10755				// #6694 - don't focus the input if it's already focused
10756				// this breaks the change event in IE
10757				inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
10758			inst.input.focus();
10759		// deffered render of the years select (to avoid flashes on Firefox)
10760		if( inst.yearshtml ){
10761			var origyearshtml = inst.yearshtml;
10762			setTimeout(function(){
10763				//assure that inst.yearshtml didn't change.
10764				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
10765					inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
10766				}
10767				origyearshtml = inst.yearshtml = null;
10768			}, 0);
10769		}
10770	},
10771
10772	/* Retrieve the size of left and top borders for an element.
10773	   @param  elem  (jQuery object) the element of interest
10774	   @return  (number[2]) the left and top borders */
10775	_getBorders: function(elem) {
10776		var convert = function(value) {
10777			return {thin: 1, medium: 2, thick: 3}[value] || value;
10778		};
10779		return [parseFloat(convert(elem.css('border-left-width'))),
10780			parseFloat(convert(elem.css('border-top-width')))];
10781	},
10782
10783	/* Check positioning to remain on screen. */
10784	_checkOffset: function(inst, offset, isFixed) {
10785		var dpWidth = inst.dpDiv.outerWidth();
10786		var dpHeight = inst.dpDiv.outerHeight();
10787		var inputWidth = inst.input ? inst.input.outerWidth() : 0;
10788		var inputHeight = inst.input ? inst.input.outerHeight() : 0;
10789		var viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft());
10790		var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
10791
10792		offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
10793		offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
10794		offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
10795
10796		// now check if datepicker is showing outside window viewport - move to a better place if so.
10797		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
10798			Math.abs(offset.left + dpWidth - viewWidth) : 0);
10799		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
10800			Math.abs(dpHeight + inputHeight) : 0);
10801
10802		return offset;
10803	},
10804
10805	/* Find an object's position on the screen. */
10806	_findPos: function(obj) {
10807		var inst = this._getInst(obj);
10808		var isRTL = this._get(inst, 'isRTL');
10809		while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
10810			obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
10811		}
10812		var position = $(obj).offset();
10813		return [position.left, position.top];
10814	},
10815
10816	/* Hide the date picker from view.
10817	   @param  input  element - the input field attached to the date picker */
10818	_hideDatepicker: function(input) {
10819		var inst = this._curInst;
10820		if (!inst || (input && inst != $.data(input, PROP_NAME)))
10821			return;
10822		if (this._datepickerShowing) {
10823			var showAnim = this._get(inst, 'showAnim');
10824			var duration = this._get(inst, 'duration');
10825			var postProcess = function() {
10826				$.datepicker._tidyDialog(inst);
10827			};
10828
10829			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
10830			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) )
10831				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
10832			else
10833				inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
10834					(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
10835			if (!showAnim)
10836				postProcess();
10837			this._datepickerShowing = false;
10838			var onClose = this._get(inst, 'onClose');
10839			if (onClose)
10840				onClose.apply((inst.input ? inst.input[0] : null),
10841					[(inst.input ? inst.input.val() : ''), inst]);
10842			this._lastInput = null;
10843			if (this._inDialog) {
10844				this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
10845				if ($.blockUI) {
10846					$.unblockUI();
10847					$('body').append(this.dpDiv);
10848				}
10849			}
10850			this._inDialog = false;
10851		}
10852	},
10853
10854	/* Tidy up after a dialog display. */
10855	_tidyDialog: function(inst) {
10856		inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
10857	},
10858
10859	/* Close date picker if clicked elsewhere. */
10860	_checkExternalClick: function(event) {
10861		if (!$.datepicker._curInst)
10862			return;
10863
10864		var $target = $(event.target),
10865			inst = $.datepicker._getInst($target[0]);
10866
10867		if ( ( ( $target[0].id != $.datepicker._mainDivId &&
10868				$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
10869				!$target.hasClass($.datepicker.markerClassName) &&
10870				!$target.closest("." + $.datepicker._triggerClass).length &&
10871				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
10872			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
10873			$.datepicker._hideDatepicker();
10874	},
10875
10876	/* Adjust one of the date sub-fields. */
10877	_adjustDate: function(id, offset, period) {
10878		var target = $(id);
10879		var inst = this._getInst(target[0]);
10880		if (this._isDisabledDatepicker(target[0])) {
10881			return;
10882		}
10883		this._adjustInstDate(inst, offset +
10884			(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
10885			period);
10886		this._updateDatepicker(inst);
10887	},
10888
10889	/* Action for current link. */
10890	_gotoToday: function(id) {
10891		var target = $(id);
10892		var inst = this._getInst(target[0]);
10893		if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
10894			inst.selectedDay = inst.currentDay;
10895			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
10896			inst.drawYear = inst.selectedYear = inst.currentYear;
10897		}
10898		else {
10899			var date = new Date();
10900			inst.selectedDay = date.getDate();
10901			inst.drawMonth = inst.selectedMonth = date.getMonth();
10902			inst.drawYear = inst.selectedYear = date.getFullYear();
10903		}
10904		this._notifyChange(inst);
10905		this._adjustDate(target);
10906	},
10907
10908	/* Action for selecting a new month/year. */
10909	_selectMonthYear: function(id, select, period) {
10910		var target = $(id);
10911		var inst = this._getInst(target[0]);
10912		inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
10913		inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
10914			parseInt(select.options[select.selectedIndex].value,10);
10915		this._notifyChange(inst);
10916		this._adjustDate(target);
10917	},
10918
10919	/* Action for selecting a day. */
10920	_selectDay: function(id, month, year, td) {
10921		var target = $(id);
10922		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
10923			return;
10924		}
10925		var inst = this._getInst(target[0]);
10926		inst.selectedDay = inst.currentDay = $('a', td).html();
10927		inst.selectedMonth = inst.currentMonth = month;
10928		inst.selectedYear = inst.currentYear = year;
10929		this._selectDate(id, this._formatDate(inst,
10930			inst.currentDay, inst.currentMonth, inst.currentYear));
10931	},
10932
10933	/* Erase the input field and hide the date picker. */
10934	_clearDate: function(id) {
10935		var target = $(id);
10936		var inst = this._getInst(target[0]);
10937		this._selectDate(target, '');
10938	},
10939
10940	/* Update the input field with the selected date. */
10941	_selectDate: function(id, dateStr) {
10942		var target = $(id);
10943		var inst = this._getInst(target[0]);
10944		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
10945		if (inst.input)
10946			inst.input.val(dateStr);
10947		this._updateAlternate(inst);
10948		var onSelect = this._get(inst, 'onSelect');
10949		if (onSelect)
10950			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
10951		else if (inst.input)
10952			inst.input.trigger('change'); // fire the change event
10953		if (inst.inline)
10954			this._updateDatepicker(inst);
10955		else {
10956			this._hideDatepicker();
10957			this._lastInput = inst.input[0];
10958			if (typeof(inst.input[0]) != 'object')
10959				inst.input.focus(); // restore focus
10960			this._lastInput = null;
10961		}
10962	},
10963
10964	/* Update any alternate field to synchronise with the main field. */
10965	_updateAlternate: function(inst) {
10966		var altField = this._get(inst, 'altField');
10967		if (altField) { // update alternate field too
10968			var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
10969			var date = this._getDate(inst);
10970			var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
10971			$(altField).each(function() { $(this).val(dateStr); });
10972		}
10973	},
10974
10975	/* Set as beforeShowDay function to prevent selection of weekends.
10976	   @param  date  Date - the date to customise
10977	   @return [boolean, string] - is this date selectable?, what is its CSS class? */
10978	noWeekends: function(date) {
10979		var day = date.getDay();
10980		return [(day > 0 && day < 6), ''];
10981	},
10982
10983	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
10984	   @param  date  Date - the date to get the week for
10985	   @return  number - the number of the week within the year that contains this date */
10986	iso8601Week: function(date) {
10987		var checkDate = new Date(date.getTime());
10988		// Find Thursday of this week starting on Monday
10989		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
10990		var time = checkDate.getTime();
10991		checkDate.setMonth(0); // Compare with Jan 1
10992		checkDate.setDate(1);
10993		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
10994	},
10995
10996	/* Parse a string value into a date object.
10997	   See formatDate below for the possible formats.
10998
10999	   @param  format    string - the expected format of the date
11000	   @param  value     string - the date in the above format
11001	   @param  settings  Object - attributes include:
11002	                     shortYearCutoff  number - the cutoff year for determining the century (optional)
11003	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
11004	                     dayNames         string[7] - names of the days from Sunday (optional)
11005	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
11006	                     monthNames       string[12] - names of the months (optional)
11007	   @return  Date - the extracted date value or null if value is blank */
11008	parseDate: function (format, value, settings) {
11009		if (format == null || value == null)
11010			throw 'Invalid arguments';
11011		value = (typeof value == 'object' ? value.toString() : value + '');
11012		if (value == '')
11013			return null;
11014		var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
11015		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
11016				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
11017		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
11018		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
11019		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
11020		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
11021		var year = -1;
11022		var month = -1;
11023		var day = -1;
11024		var doy = -1;
11025		var literal = false;
11026		// Check whether a format character is doubled
11027		var lookAhead = function(match) {
11028			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
11029			if (matches)
11030				iFormat++;
11031			return matches;
11032		};
11033		// Extract a number from the string value
11034		var getNumber = function(match) {
11035			var isDoubled = lookAhead(match);
11036			var size = (match == '@' ? 14 : (match == '!' ? 20 :
11037				(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
11038			var digits = new RegExp('^\\d{1,' + size + '}');
11039			var num = value.substring(iValue).match(digits);
11040			if (!num)
11041				throw 'Missing number at position ' + iValue;
11042			iValue += num[0].length;
11043			return parseInt(num[0], 10);
11044		};
11045		// Extract a name from the string value and convert to an index
11046		var getName = function(match, shortNames, longNames) {
11047			var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
11048				return [ [k, v] ];
11049			}).sort(function (a, b) {
11050				return -(a[1].length - b[1].length);
11051			});
11052			var index = -1;
11053			$.each(names, function (i, pair) {
11054				var name = pair[1];
11055				if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
11056					index = pair[0];
11057					iValue += name.length;
11058					return false;
11059				}
11060			});
11061			if (index != -1)
11062				return index + 1;
11063			else
11064				throw 'Unknown name at position ' + iValue;
11065		};
11066		// Confirm that a literal character matches the string value
11067		var checkLiteral = function() {
11068			if (value.charAt(iValue) != format.charAt(iFormat))
11069				throw 'Unexpected literal at position ' + iValue;
11070			iValue++;
11071		};
11072		var iValue = 0;
11073		for (var iFormat = 0; iFormat < format.length; iFormat++) {
11074			if (literal)
11075				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
11076					literal = false;
11077				else
11078					checkLiteral();
11079			else
11080				switch (format.charAt(iFormat)) {
11081					case 'd':
11082						day = getNumber('d');
11083						break;
11084					case 'D':
11085						getName('D', dayNamesShort, dayNames);
11086						break;
11087					case 'o':
11088						doy = getNumber('o');
11089						break;
11090					case 'm':
11091						month = getNumber('m');
11092						break;
11093					case 'M':
11094						month = getName('M', monthNamesShort, monthNames);
11095						break;
11096					case 'y':
11097						year = getNumber('y');
11098						break;
11099					case '@':
11100						var date = new Date(getNumber('@'));
11101						year = date.getFullYear();
11102						month = date.getMonth() + 1;
11103						day = date.getDate();
11104						break;
11105					case '!':
11106						var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
11107						year = date.getFullYear();
11108						month = date.getMonth() + 1;
11109						day = date.getDate();
11110						break;
11111					case "'":
11112						if (lookAhead("'"))
11113							checkLiteral();
11114						else
11115							literal = true;
11116						break;
11117					default:
11118						checkLiteral();
11119				}
11120		}
11121		if (iValue < value.length){
11122			var extra = value.substr(iValue);
11123			if (!/^\s+/.test(extra)) {
11124				throw "Extra/unparsed characters found in date: " + extra;
11125			}
11126		}
11127		if (year == -1)
11128			year = new Date().getFullYear();
11129		else if (year < 100)
11130			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
11131				(year <= shortYearCutoff ? 0 : -100);
11132		if (doy > -1) {
11133			month = 1;
11134			day = doy;
11135			do {
11136				var dim = this._getDaysInMonth(year, month - 1);
11137				if (day <= dim)
11138					break;
11139				month++;
11140				day -= dim;
11141			} while (true);
11142		}
11143		var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
11144		if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
11145			throw 'Invalid date'; // E.g. 31/02/00
11146		return date;
11147	},
11148
11149	/* Standard date formats. */
11150	ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
11151	COOKIE: 'D, dd M yy',
11152	ISO_8601: 'yy-mm-dd',
11153	RFC_822: 'D, d M y',
11154	RFC_850: 'DD, dd-M-y',
11155	RFC_1036: 'D, d M y',
11156	RFC_1123: 'D, d M yy',
11157	RFC_2822: 'D, d M yy',
11158	RSS: 'D, d M y', // RFC 822
11159	TICKS: '!',
11160	TIMESTAMP: '@',
11161	W3C: 'yy-mm-dd', // ISO 8601
11162
11163	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
11164		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
11165
11166	/* Format a date object into a string value.
11167	   The format can be combinations of the following:
11168	   d  - day of month (no leading zero)
11169	   dd - day of month (two digit)
11170	   o  - day of year (no leading zeros)
11171	   oo - day of year (three digit)
11172	   D  - day name short
11173	   DD - day name long
11174	   m  - month of year (no leading zero)
11175	   mm - month of year (two digit)
11176	   M  - month name short
11177	   MM - month name long
11178	   y  - year (two digit)
11179	   yy - year (four digit)
11180	   @ - Unix timestamp (ms since 01/01/1970)
11181	   ! - Windows ticks (100ns since 01/01/0001)
11182	   '...' - literal text
11183	   '' - single quote
11184
11185	   @param  format    string - the desired format of the date
11186	   @param  date      Date - the date value to format
11187	   @param  settings  Object - attributes include:
11188	                     dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
11189	                     dayNames         string[7] - names of the days from Sunday (optional)
11190	                     monthNamesShort  string[12] - abbreviated names of the months (optional)
11191	                     monthNames       string[12] - names of the months (optional)
11192	   @return  string - the date in the above format */
11193	formatDate: function (format, date, settings) {
11194		if (!date)
11195			return '';
11196		var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
11197		var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
11198		var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
11199		var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
11200		// Check whether a format character is doubled
11201		var lookAhead = function(match) {
11202			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
11203			if (matches)
11204				iFormat++;
11205			return matches;
11206		};
11207		// Format a number, with leading zero if necessary
11208		var formatNumber = function(match, value, len) {
11209			var num = '' + value;
11210			if (lookAhead(match))
11211				while (num.length < len)
11212					num = '0' + num;
11213			return num;
11214		};
11215		// Format a name, short or long as requested
11216		var formatName = function(match, value, shortNames, longNames) {
11217			return (lookAhead(match) ? longNames[value] : shortNames[value]);
11218		};
11219		var output = '';
11220		var literal = false;
11221		if (date)
11222			for (var iFormat = 0; iFormat < format.length; iFormat++) {
11223				if (literal)
11224					if (format.charAt(iFormat) == "'" && !lookAhead("'"))
11225						literal = false;
11226					else
11227						output += format.charAt(iFormat);
11228				else
11229					switch (format.charAt(iFormat)) {
11230						case 'd':
11231							output += formatNumber('d', date.getDate(), 2);
11232							break;
11233						case 'D':
11234							output += formatName('D', date.getDay(), dayNamesShort, dayNames);
11235							break;
11236						case 'o':
11237							output += formatNumber('o',
11238								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
11239							break;
11240						case 'm':
11241							output += formatNumber('m', date.getMonth() + 1, 2);
11242							break;
11243						case 'M':
11244							output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
11245							break;
11246						case 'y':
11247							output += (lookAhead('y') ? date.getFullYear() :
11248								(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
11249							break;
11250						case '@':
11251							output += date.getTime();
11252							break;
11253						case '!':
11254							output += date.getTime() * 10000 + this._ticksTo1970;
11255							break;
11256						case "'":
11257							if (lookAhead("'"))
11258								output += "'";
11259							else
11260								literal = true;
11261							break;
11262						default:
11263							output += format.charAt(iFormat);
11264					}
11265			}
11266		return output;
11267	},
11268
11269	/* Extract all possible characters from the date format. */
11270	_possibleChars: function (format) {
11271		var chars = '';
11272		var literal = false;
11273		// Check whether a format character is doubled
11274		var lookAhead = function(match) {
11275			var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
11276			if (matches)
11277				iFormat++;
11278			return matches;
11279		};
11280		for (var iFormat = 0; iFormat < format.length; iFormat++)
11281			if (literal)
11282				if (format.charAt(iFormat) == "'" && !lookAhead("'"))
11283					literal = false;
11284				else
11285					chars += format.charAt(iFormat);
11286			else
11287				switch (format.charAt(iFormat)) {
11288					case 'd': case 'm': case 'y': case '@':
11289						chars += '0123456789';
11290						break;
11291					case 'D': case 'M':
11292						return null; // Accept anything
11293					case "'":
11294						if (lookAhead("'"))
11295							chars += "'";
11296						else
11297							literal = true;
11298						break;
11299					default:
11300						chars += format.charAt(iFormat);
11301				}
11302		return chars;
11303	},
11304
11305	/* Get a setting value, defaulting if necessary. */
11306	_get: function(inst, name) {
11307		return inst.settings[name] !== undefined ?
11308			inst.settings[name] : this._defaults[name];
11309	},
11310
11311	/* Parse existing date and initialise date picker. */
11312	_setDateFromField: function(inst, noDefault) {
11313		if (inst.input.val() == inst.lastVal) {
11314			return;
11315		}
11316		var dateFormat = this._get(inst, 'dateFormat');
11317		var dates = inst.lastVal = inst.input ? inst.input.val() : null;
11318		var date, defaultDate;
11319		date = defaultDate = this._getDefaultDate(inst);
11320		var settings = this._getFormatConfig(inst);
11321		try {
11322			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
11323		} catch (event) {
11324			this.log(event);
11325			dates = (noDefault ? '' : dates);
11326		}
11327		inst.selectedDay = date.getDate();
11328		inst.drawMonth = inst.selectedMonth = date.getMonth();
11329		inst.drawYear = inst.selectedYear = date.getFullYear();
11330		inst.currentDay = (dates ? date.getDate() : 0);
11331		inst.currentMonth = (dates ? date.getMonth() : 0);
11332		inst.currentYear = (dates ? date.getFullYear() : 0);
11333		this._adjustInstDate(inst);
11334	},
11335
11336	/* Retrieve the default date shown on opening. */
11337	_getDefaultDate: function(inst) {
11338		return this._restrictMinMax(inst,
11339			this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
11340	},
11341
11342	/* A date may be specified as an exact value or a relative one. */
11343	_determineDate: function(inst, date, defaultDate) {
11344		var offsetNumeric = function(offset) {
11345			var date = new Date();
11346			date.setDate(date.getDate() + offset);
11347			return date;
11348		};
11349		var offsetString = function(offset) {
11350			try {
11351				return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
11352					offset, $.datepicker._getFormatConfig(inst));
11353			}
11354			catch (e) {
11355				// Ignore
11356			}
11357			var date = (offset.toLowerCase().match(/^c/) ?
11358				$.datepicker._getDate(inst) : null) || new Date();
11359			var year = date.getFullYear();
11360			var month = date.getMonth();
11361			var day = date.getDate();
11362			var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
11363			var matches = pattern.exec(offset);
11364			while (matches) {
11365				switch (matches[2] || 'd') {
11366					case 'd' : case 'D' :
11367						day += parseInt(matches[1],10); break;
11368					case 'w' : case 'W' :
11369						day += parseInt(matches[1],10) * 7; break;
11370					case 'm' : case 'M' :
11371						month += parseInt(matches[1],10);
11372						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
11373						break;
11374					case 'y': case 'Y' :
11375						year += parseInt(matches[1],10);
11376						day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
11377						break;
11378				}
11379				matches = pattern.exec(offset);
11380			}
11381			return new Date(year, month, day);
11382		};
11383		var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
11384			(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
11385		newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
11386		if (newDate) {
11387			newDate.setHours(0);
11388			newDate.setMinutes(0);
11389			newDate.setSeconds(0);
11390			newDate.setMilliseconds(0);
11391		}
11392		return this._daylightSavingAdjust(newDate);
11393	},
11394
11395	/* Handle switch to/from daylight saving.
11396	   Hours may be non-zero on daylight saving cut-over:
11397	   > 12 when midnight changeover, but then cannot generate
11398	   midnight datetime, so jump to 1AM, otherwise reset.
11399	   @param  date  (Date) the date to check
11400	   @return  (Date) the corrected date */
11401	_daylightSavingAdjust: function(date) {
11402		if (!date) return null;
11403		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
11404		return date;
11405	},
11406
11407	/* Set the date(s) directly. */
11408	_setDate: function(inst, date, noChange) {
11409		var clear = !date;
11410		var origMonth = inst.selectedMonth;
11411		var origYear = inst.selectedYear;
11412		var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
11413		inst.selectedDay = inst.currentDay = newDate.getDate();
11414		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
11415		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
11416		if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
11417			this._notifyChange(inst);
11418		this._adjustInstDate(inst);
11419		if (inst.input) {
11420			inst.input.val(clear ? '' : this._formatDate(inst));
11421		}
11422	},
11423
11424	/* Retrieve the date(s) directly. */
11425	_getDate: function(inst) {
11426		var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
11427			this._daylightSavingAdjust(new Date(
11428			inst.currentYear, inst.currentMonth, inst.currentDay)));
11429			return startDate;
11430	},
11431
11432	/* Attach the onxxx handlers.  These are declared statically so
11433	 * they work with static code transformers like Caja.
11434	 */
11435	_attachHandlers: function(inst) {
11436		var stepMonths = this._get(inst, 'stepMonths');
11437		var id = '#' + inst.id.replace( /\\\\/g, "\\" );
11438		inst.dpDiv.find('[data-handler]').map(function () {
11439			var handler = {
11440				prev: function () {
11441					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, -stepMonths, 'M');
11442				},
11443				next: function () {
11444					window['DP_jQuery_' + dpuuid].datepicker._adjustDate(id, +stepMonths, 'M');
11445				},
11446				hide: function () {
11447					window['DP_jQuery_' + dpuuid].datepicker._hideDatepicker();
11448				},
11449				today: function () {
11450					window['DP_jQuery_' + dpuuid].datepicker._gotoToday(id);
11451				},
11452				selectDay: function () {
11453					window['DP_jQuery_' + dpuuid].datepicker._selectDay(id, +this.getAttribute('data-month'), +this.getAttribute('data-year'), this);
11454					return false;
11455				},
11456				selectMonth: function () {
11457					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'M');
11458					return false;
11459				},
11460				selectYear: function () {
11461					window['DP_jQuery_' + dpuuid].datepicker._selectMonthYear(id, this, 'Y');
11462					return false;
11463				}
11464			};
11465			$(this).bind(this.getAttribute('data-event'), handler[this.getAttribute('data-handler')]);
11466		});
11467	},
11468
11469	/* Generate the HTML for the current state of the date picker. */
11470	_generateHTML: function(inst) {
11471		var today = new Date();
11472		today = this._daylightSavingAdjust(
11473			new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
11474		var isRTL = this._get(inst, 'isRTL');
11475		var showButtonPanel = this._get(inst, 'showButtonPanel');
11476		var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
11477		var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
11478		var numMonths = this._getNumberOfMonths(inst);
11479		var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
11480		var stepMonths = this._get(inst, 'stepMonths');
11481		var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
11482		var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
11483			new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
11484		var minDate = this._getMinMaxDate(inst, 'min');
11485		var maxDate = this._getMinMaxDate(inst, 'max');
11486		var drawMonth = inst.drawMonth - showCurrentAtPos;
11487		var drawYear = inst.drawYear;
11488		if (drawMonth < 0) {
11489			drawMonth += 12;
11490			drawYear--;
11491		}
11492		if (maxDate) {
11493			var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
11494				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
11495			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
11496			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
11497				drawMonth--;
11498				if (drawMonth < 0) {
11499					drawMonth = 11;
11500					drawYear--;
11501				}
11502			}
11503		}
11504		inst.drawMonth = drawMonth;
11505		inst.drawYear = drawYear;
11506		var prevText = this._get(inst, 'prevText');
11507		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
11508			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
11509			this._getFormatConfig(inst)));
11510		var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
11511			'<a class="ui-datepicker-prev ui-corner-all" data-handler="prev" data-event="click"' +
11512			' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
11513			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
11514		var nextText = this._get(inst, 'nextText');
11515		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
11516			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
11517			this._getFormatConfig(inst)));
11518		var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
11519			'<a class="ui-datepicker-next ui-corner-all" data-handler="next" data-event="click"' +
11520			' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
11521			(hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
11522		var currentText = this._get(inst, 'currentText');
11523		var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
11524		currentText = (!navigationAsDateFormat ? currentText :
11525			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
11526		var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">' +
11527			this._get(inst, 'closeText') + '</button>' : '');
11528		var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
11529			(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" data-handler="today" data-event="click"' +
11530			'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
11531		var firstDay = parseInt(this._get(inst, 'firstDay'),10);
11532		firstDay = (isNaN(firstDay) ? 0 : firstDay);
11533		var showWeek = this._get(inst, 'showWeek');
11534		var dayNames = this._get(inst, 'dayNames');
11535		var dayNamesShort = this._get(inst, 'dayNamesShort');
11536		var dayNamesMin = this._get(inst, 'dayNamesMin');
11537		var monthNames = this._get(inst, 'monthNames');
11538		var monthNamesShort = this._get(inst, 'monthNamesShort');
11539		var beforeShowDay = this._get(inst, 'beforeShowDay');
11540		var showOtherMonths = this._get(inst, 'showOtherMonths');
11541		var selectOtherMonths = this._get(inst, 'selectOtherMonths');
11542		var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
11543		var defaultDate = this._getDefaultDate(inst);
11544		var html = '';
11545		for (var row = 0; row < numMonths[0]; row++) {
11546			var group = '';
11547			this.maxRows = 4;
11548			for (var col = 0; col < numMonths[1]; col++) {
11549				var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
11550				var cornerClass = ' ui-corner-all';
11551				var calender = '';
11552				if (isMultiMonth) {
11553					calender += '<div class="ui-datepicker-group';
11554					if (numMonths[1] > 1)
11555						switch (col) {
11556							case 0: calender += ' ui-datepicker-group-first';
11557								cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
11558							case numMonths[1]-1: calender += ' ui-datepicker-group-last';
11559								cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
11560							default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
11561						}
11562					calender += '">';
11563				}
11564				calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
11565					(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
11566					(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
11567					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
11568					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
11569					'</div><table class="ui-datepicker-calendar"><thead>' +
11570					'<tr>';
11571				var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
11572				for (var dow = 0; dow < 7; dow++) { // days of the week
11573					var day = (dow + firstDay) % 7;
11574					thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>
11574' +
11575						'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
11576				}
11577				calender += thead + '</tr></thead><tbody>';
11578				var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
11579				if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
11580					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
11581				var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
11582				var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
11583				var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
11584				this.maxRows = numRows;
11585				var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
11586				for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
11587					calender += '<tr>';
11588					var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
11589						this._get(inst, 'calculateWeek')(printDate) + '</td>');
11590					for (var dow = 0; dow < 7; dow++) { // create date picker days
11591						var daySettings = (beforeShowDay ?
11592							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
11593						var otherMonth = (printDate.getMonth() != drawMonth);
11594						var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
11595							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
11596						tbody += '<td class="' +
11597							((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
11598							(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
11599							((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
11600							(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
11601							// or defaultDate is current printedDate and defaultDate is selectedDate
11602							' ' + this._dayOverClass : '') + // highlight selected day
11603							(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
11604							(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
11605							(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
11606							(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
11607							((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
11608							(unselectable ? '' : ' data-handler="selectDay" data-event="click" data-month="' + printDate.getMonth() + '" data-year="' + printDate.getFullYear() + '"') + '>' + // actions
11609							(otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
11610							(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
11611							(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
11612							(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
11613							(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
11614							'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
11615						printDate.setDate(printDate.getDate() + 1);
11616						printDate = this._daylightSavingAdjust(printDate);
11617					}
11618					calender += tbody + '</tr>';
11619				}
11620				drawMonth++;
11621				if (drawMonth > 11) {
11622					drawMonth = 0;
11623					drawYear++;
11624				}
11625				calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
11626							((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
11627				group += calender;
11628			}
11629			html += group;
11630		}
11631		html += buttonPanel + ($.ui.ie6 && !inst.inline ?
11632			'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
11633		inst._keyEvent = false;
11634		return html;
11635	},
11636
11637	/* Generate the month and year header. */
11638	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
11639			secondary, monthNames, monthNamesShort) {
11640		var changeMonth = this._get(inst, 'changeMonth');
11641		var changeYear = this._get(inst, 'changeYear');
11642		var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
11643		var html = '<div class="ui-datepicker-title">';
11644		var monthHtml = '';
11645		// month selection
11646		if (secondary || !changeMonth)
11647			monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
11648		else {
11649			var inMinYear = (minDate && minDate.getFullYear() == drawYear);
11650			var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
11651			monthHtml += '<select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">';
11652			for (var month = 0; month < 12; month++) {
11653				if ((!inMinYear || month >= minDate.getMonth()) &&
11654						(!inMaxYear || month <= maxDate.getMonth()))
11655					monthHtml += '<option value="' + month + '"' +
11656						(month == drawMonth ? ' selected="selected"' : '') +
11657						'>' + monthNamesShort[month] + '</option>';
11658			}
11659			monthHtml += '</select>';
11660		}
11661		if (!showMonthAfterYear)
11662			html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
11663		// year selection
11664		if ( !inst.yearshtml ) {
11665			inst.yearshtml = '';
11666			if (secondary || !changeYear)
11667				html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
11668			else {
11669				// determine range of years to display
11670				var years = this._get(inst, 'yearRange').split(':');
11671				var thisYear = new Date().getFullYear();
11672				var determineYear = function(value) {
11673					var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
11674						(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
11675						parseInt(value, 10)));
11676					return (isNaN(year) ? thisYear : year);
11677				};
11678				var year = determineYear(years[0]);
11679				var endYear = Math.max(year, determineYear(years[1] || ''));
11680				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
11681				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
11682				inst.yearshtml += '<select class="ui-datepicker-year" data-handler="selectYear" data-event="change">';
11683				for (; year <= endYear; year++) {
11684					inst.yearshtml += '<option value="' + year + '"' +
11685						(year == drawYear ? ' selected="selected"' : '') +
11686						'>' + year + '</option>';
11687				}
11688				inst.yearshtml += '</select>';
11689
11690				html += inst.yearshtml;
11691				inst.yearshtml = null;
11692			}
11693		}
11694		html += this._get(inst, 'yearSuffix');
11695		if (showMonthAfterYear)
11696			html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
11697		html += '</div>'; // Close datepicker_header
11698		return html;
11699	},
11700
11701	/* Adjust one of the date sub-fields. */
11702	_adjustInstDate: function(inst, offset, period) {
11703		var year = inst.drawYear + (period == 'Y' ? offset : 0);
11704		var month = inst.drawMonth + (period == 'M' ? offset : 0);
11705		var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
11706			(period == 'D' ? offset : 0);
11707		var date = this._restrictMinMax(inst,
11708			this._daylightSavingAdjust(new Date(year, month, day)));
11709		inst.selectedDay = date.getDate();
11710		inst.drawMonth = inst.selectedMonth = date.getMonth();
11711		inst.drawYear = inst.selectedYear = date.getFullYear();
11712		if (period == 'M' || period == 'Y')
11713			this._notifyChange(inst);
11714	},
11715
11716	/* Ensure a date is within any min/max bounds. */
11717	_restrictMinMax: function(inst, date) {
11718		var minDate = this._getMinMaxDate(inst, 'min');
11719		var maxDate = this._getMinMaxDate(inst, 'max');
11720		var newDate = (minDate && date < minDate ? minDate : date);
11721		newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
11722		return newDate;
11723	},
11724
11725	/* Notify change of month/year. */
11726	_notifyChange: function(inst) {
11727		var onChange = this._get(inst, 'onChangeMonthYear');
11728		if (onChange)
11729			onChange.apply((inst.input ? inst.input[0] : null),
11730				[inst.selectedYear, inst.selectedMonth + 1, inst]);
11731	},
11732
11733	/* Determine the number of months to show. */
11734	_getNumberOfMonths: function(inst) {
11735		var numMonths = this._get(inst, 'numberOfMonths');
11736		return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
11737	},
11738
11739	/* Determine the current maximum date - ensure no time components are set. */
11740	_getMinMaxDate: function(inst, minMax) {
11741		return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
11742	},
11743
11744	/* Find the number of days in a given month. */
11745	_getDaysInMonth: function(year, month) {
11746		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
11747	},
11748
11749	/* Find the day of the week of the first of a month. */
11750	_getFirstDayOfMonth: function(year, month) {
11751		return new Date(year, month, 1).getDay();
11752	},
11753
11754	/* Determines if we should allow a "next/prev" month display change. */
11755	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
11756		var numMonths = this._getNumberOfMonths(inst);
11757		var date = this._daylightSavingAdjust(new Date(curYear,
11758			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
11759		if (offset < 0)
11760			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
11761		return this._isInRange(inst, date);
11762	},
11763
11764	/* Is the given date in the accepted range? */
11765	_isInRange: function(inst, date) {
11766		var minDate = this._getMinMaxDate(inst, 'min');
11767		var maxDate = this._getMinMaxDate(inst, 'max');
11768		return ((!minDate || date.getTime() >= minDate.getTime()) &&
11769			(!maxDate || date.getTime() <= maxDate.getTime()));
11770	},
11771
11772	/* Provide the configuration settings for formatting/parsing. */
11773	_getFormatConfig: function(inst) {
11774		var shortYearCutoff = this._get(inst, 'shortYearCutoff');
11775		shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
11776			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
11777		return {shortYearCutoff: shortYearCutoff,
11778			dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
11779			monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
11780	},
11781
11782	/* Format the given date for display. */
11783	_formatDate: function(inst, day, month, year) {
11784		if (!day) {
11785			inst.currentDay = inst.selectedDay;
11786			inst.currentMonth = inst.selectedMonth;
11787			inst.currentYear = inst.selectedYear;
11788		}
11789		var date = (day ? (typeof day == 'object' ? day :
11790			this._daylightSavingAdjust(new Date(year, month, day))) :
11791			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
11792		return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
11793	}
11794});
11795
11796/*
11797 * Bind hover events for datepicker elements.
11798 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
11799 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
11800 */
11801function bindHover(dpDiv) {
11802	var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
11803	return dpDiv.delegate(selector, 'mouseout', function() {
11804			$(this).removeClass('ui-state-hover');
11805			if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
11806			if (this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
11807		})
11808		.delegate(selector, 'mouseover', function(){
11809			if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
11810				$(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
11811				$(this).addClass('ui-state-hover');
11812				if (this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
11813				if (this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
11814			}
11815		});
11816}
11817
11818/* jQuery extend now ignores nulls! */
11819function extendRemove(target, props) {
11820	$.extend(target, props);
11821	for (var name in props)
11822		if (props[name] == null || props[name] == undefined)
11823			target[name] = props[name];
11824	return target;
11825};
11826
11827/* Invoke the datepicker functionality.
11828   @param  options  string - a command, optionally followed by additional parameters or
11829	                Object - settings for attaching new datepicker functionality
11830   @return  jQuery object */
11831$.fn.datepicker = function(options){
11832
11833	/* Verify an empty collection wasn't passed - Fixes #6976 */
11834	if ( !this.length ) {
11835		return this;
11836	}
11837
11838	/* Initialise the date picker. */
11839	if (!$.datepicker.initialized) {
11840		$(document).mousedown($.datepicker._checkExternalClick).
11841			find(document.body).append($.datepicker.dpDiv);
11842		$.datepicker.initialized = true;
11843	}
11844
11845	var otherArgs = Array.prototype.slice.call(arguments, 1);
11846	if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
11847		return $.datepicker['_' + options + 'Datepicker'].
11848			apply($.datepicker, [this[0]].concat(otherArgs));
11849	if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
11850		return $.datepicker['_' + options + 'Datepicker'].
11851			apply($.datepicker, [this[0]].concat(otherArgs));
11852	return this.each(function() {
11853		typeof options == 'string' ?
11854			$.datepicker['_' + options + 'Datepicker'].
11855				apply($.datepicker, [this].concat(otherArgs)) :
11856			$.datepicker._attachDatepicker(this, options);
11857	});
11858};
11859
11860$.datepicker = new Datepicker(); // singleton instance
11861$.datepicker.initialized = false;
11862$.datepicker.uuid = new Date().getTime();
11863$.datepicker.version = "1.9.1";
11864
11865// Workaround for #4055
11866// Add another global to avoid noConflict issues with inline event handlers
11867window['DP_jQuery_' + dpuuid] = $;
11868
11869})(jQuery);
11870
11871(function( $, undefined ) {
11872
11873var uiDialogClasses = "ui-dialog ui-widget ui-widget-content ui-corner-all ",
11874	sizeRelatedOptions = {
11875		buttons: true,
11876		height: true,
11877		maxHeight: true,
11878		maxWidth: true,
11879		minHeight: true,
11880		minWidth: true,
11881		width: true
11882	},
11883	resizableRelatedOptions = {
11884		maxHeight: true,
11885		maxWidth: true,
11886		minHeight: true,
11887		minWidth: true
11888	};
11889
11890$.widget("ui.dialog", {
11891	version: "1.9.1",
11892	options: {
11893		autoOpen: true,
11894		buttons: {},
11895		closeOnEscape: true,
11896		closeText: "close",
11897		dialogClass: "",
11898		draggable: true,
11899		hide: null,
11900		height: "auto",
11901		maxHeight: false,
11902		maxWidth: false,
11903		minHeight: 150,
11904		minWidth: 150,
11905		modal: false,
11906		position: {
11907			my: "center",
11908			at: "center",
11909			of: window,
11910			collision: "fit",
11911			// ensure that the titlebar is never outside the document
11912			using: function( pos ) {
11913				var topOffset = $( this ).css( pos ).offset().top;
11914				if ( topOffset < 0 ) {
11915					$( this ).css( "top", pos.top - topOffset );
11916				}
11917			}
11918		},
11919		resizable: true,
11920		show: null,
11921		stack: true,
11922		title: "",
11923		width: 300,
11924		zIndex: 1000
11925	},
11926
11927	_create: function() {
11928		this.originalTitle = this.element.attr( "title" );
11929		// #5742 - .attr() might return a DOMElement
11930		if ( typeof this.originalTitle !== "string" ) {
11931			this.originalTitle = "";
11932		}
11933		this.oldPosition = {
11934			parent: this.element.parent(),
11935			index: this.element.parent().children().index( this.element )
11936		};
11937		this.options.title = this.options.title || this.originalTitle;
11938		var that = this,
11939			options = this.options,
11940
11941			title = options.title || "&#160;",
11942			uiDialog,
11943			uiDialogTitlebar,
11944			uiDialogTitlebarClose,
11945			uiDialogTitle,
11946			uiDialogButtonPane;
11947
11948			uiDialog = ( this.uiDialog = $( "<div>" ) )
11949				.addClass( uiDialogClasses + options.dialogClass )
11950				.css({
11951					display: "none",
11952					outline: 0, // TODO: move to stylesheet
11953					zIndex: options.zIndex
11954				})
11955				// setting tabIndex makes the div focusable
11956				.attr( "tabIndex", -1)
11957				.keydown(function( event ) {
11958					if ( options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
11959							event.keyCode === $.ui.keyCode.ESCAPE ) {
11960						that.close( event );
11961						event.preventDefault();
11962					}
11963				})
11964				.mousedown(function( event ) {
11965					that.moveToTop( false, event );
11966				})
11967				.appendTo( "body" );
11968
11969			this.element
11970				.show()
11971				.removeAttr( "title" )
11972				.addClass( "ui-dialog-content ui-widget-content" )
11973				.appendTo( uiDialog );
11974
11975			uiDialogTitlebar = ( this.uiDialogTitlebar = $( "<div>" ) )
11976				.addClass( "ui-dialog-titlebar  ui-widget-header  " +
11977					"ui-corner-all  ui-helper-clearfix" )
11978				.bind( "mousedown", function() {
11979					// Dialog isn't getting focus when dragging (#8063)
11980					uiDialog.focus();
11981				})
11982				.prependTo( uiDialog );
11983
11984			uiDialogTitlebarClose = $( "<a href='#'></a>" )
11985				.addClass( "ui-dialog-titlebar-close  ui-corner-all" )
11986				.attr( "role", "button" )
11987				.click(function( event ) {
11988					event.preventDefault();
11989					that.close( event );
11990				})
11991				.appendTo( uiDialogTitlebar );
11992
11993			( this.uiDialogTitlebarCloseText = $( "<span>" ) )
11994				.addClass( "ui-icon ui-icon-closethick" )
11995				.text( options.closeText )
11996				.appendTo( uiDialogTitlebarClose );
11997
11998			uiDialogTitle = $( "<span>" )
11999				.uniqueId()
12000				.addClass( "ui-dialog-title" )
12001				.html( title )
12002				.prependTo( uiDialogTitlebar );
12003
12004			uiDialogButtonPane = ( this.uiDialogButtonPane = $( "<div>" ) )
12005				.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
12006
12007			( this.uiButtonSet = $( "<div>" ) )
12008				.addClass( "ui-dialog-buttonset" )
12009				.appendTo( uiDialogButtonPane );
12010
12011		uiDialog.attr({
12012			role: "dialog",
12013			"aria-labelledby": uiDialogTitle.attr( "id" )
12014		});
12015
12016		uiDialogTitlebar.find( "*" ).add( uiDialogTitlebar ).disableSelection();
12017		this._hoverable( uiDialogTitlebarClose );
12018		this._focusable( uiDialogTitlebarClose );
12019
12020		if ( options.draggable && $.fn.draggable ) {
12021			this._makeDraggable();
12022		}
12023		if ( options.resizable && $.fn.resizable ) {
12024			this._makeResizable();
12025		}
12026
12027		this._createButtons( options.buttons );
12028		this._isOpen = false;
12029
12030		if ( $.fn.bgiframe ) {
12031			uiDialog.bgiframe();
12032		}
12033
12034		// prevent tabbing out of modal dialogs
12035		this._on( uiDialog, { keydown: function( event ) {
12036			if ( !options.modal || event.keyCode !== $.ui.keyCode.TAB ) {
12037				return;
12038			}
12039
12040			var tabbables = $( ":tabbable", uiDialog ),
12041				first = tabbables.filter( ":first" ),
12042				last  = tabbables.filter( ":last" );
12043
12044			if ( event.target === last[0] && !event.shiftKey ) {
12045				first.focus( 1 );
12046				return false;
12047			} else if ( event.target === first[0] && event.shiftKey ) {
12048				last.focus( 1 );
12049				return false;
12050			}
12051		}});
12052	},
12053
12054	_init: function() {
12055		if ( this.options.autoOpen ) {
12056			this.open();
12057		}
12058	},
12059
12060	_destroy: function() {
12061		var next,
12062			oldPosition = this.oldPosition;
12063
12064		if ( this.overlay ) {
12065			this.overlay.destroy();
12066		}
12067		this.uiDialog.hide();
12068		this.element
12069			.removeClass( "ui-dialog-content ui-widget-content" )
12070			.hide()
12071			.appendTo( "body" );
12072		this.uiDialog.remove();
12073
12074		if ( this.originalTitle ) {
12075			this.element.attr( "title", this.originalTitle );
12076		}
12077
12078		next = oldPosition.parent.children().eq( oldPosition.index );
12079		// Don't try to place the dialog next to itself (#8613)
12080		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12081			next.before( this.element );
12082		} else {
12083			oldPosition.parent.append( this.element );
12084		}
12085	},
12086
12087	widget: function() {
12088		return this.uiDialog;
12089	},
12090
12091	close: function( event ) {
12092		var that = this,
12093			maxZ, thisZ;
12094
12095		if ( !this._isOpen ) {
12096			return;
12097		}
12098
12099		if ( false === this._trigger( "beforeClose", event ) ) {
12100			return;
12101		}
12102
12103		this._isOpen = false;
12104
12105		if ( this.overlay ) {
12106			this.overlay.destroy();
12107		}
12108
12109		if ( this.options.hide ) {
12110			this._hide( this.uiDialog, this.options.hide, function() {
12111				that._trigger( "close", event );
12112			});
12113		} else {
12114			this.uiDialog.hide();
12115			this._trigger( "close", event );
12116		}
12117
12118		$.ui.dialog.overlay.resize();
12119
12120		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
12121		if ( this.options.modal ) {
12122			maxZ = 0;
12123			$( ".ui-dialog" ).each(function() {
12124				if ( this !== that.uiDialog[0] ) {
12125					thisZ = $( this ).css( "z-index" );
12126					if ( !isNaN( thisZ ) ) {
12127						maxZ = Math.max( maxZ, thisZ );
12128					}
12129				}
12130			});
12131			$.ui.dialog.maxZ = maxZ;
12132		}
12133
12134		return this;
12135	},
12136
12137	isOpen: function() {
12138		return this._isOpen;
12139	},
12140
12141	// the force parameter allows us to move modal dialogs to their correct
12142	// position on open
12143	moveToTop: function( force, event ) {
12144		var options = this.options,
12145			saveScroll;
12146
12147		if ( ( options.modal && !force ) ||
12148				( !options.stack && !options.modal ) ) {
12149			return this._trigger( "focus", event );
12150		}
12151
12152		if ( options.zIndex > $.ui.dialog.maxZ ) {
12153			$.ui.dialog.maxZ = options.zIndex;
12154		}
12155		if ( this.overlay ) {
12156			$.ui.dialog.maxZ += 1;
12157			$.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ;
12158			this.overlay.$el.css( "z-index", $.ui.dialog.overlay.maxZ );
12159		}
12160
12161		// Save and then restore scroll
12162		// Opera 9.5+ resets when parent z-index is changed.
12163		// http://bugs.jqueryui.com/ticket/3193
12164		saveScroll = {
12165			scrollTop: this.element.scrollTop(),
12166			scrollLeft: this.element.scrollLeft()
12167		};
12168		$.ui.dialog.maxZ += 1;
12169		this.uiDialog.css( "z-index", $.ui.dialog.maxZ );
12170		this.element.attr( saveScroll );
12171		this._trigger( "focus", event );
12172
12173		return this;
12174	},
12175
12176	open: function() {
12177		if ( this._isOpen ) {
12178			return;
12179		}
12180
12181		var hasFocus,
12182			options = this.options,
12183			uiDialog = this.uiDialog;
12184
12185		this._size();
12186		this._position( options.position );
12187		uiDialog.show( options.show );
12188		this.overlay = options.modal ? new $.ui.dialog.overlay( this ) : null;
12189		this.moveToTop( true );
12190
12191		// set focus to the first tabbable element in the content area or the first button
12192		// if there are no tabbable elements, set focus on the dialog itself
12193		hasFocus = this.element.find( ":tabbable" );
12194		if ( !hasFocus.length ) {
12195			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12196			if ( !hasFocus.length ) {
12197				hasFocus = uiDialog;
12198			}
12199		}
12200		hasFocus.eq( 0 ).focus();
12201
12202		this._isOpen = true;
12203		this._trigger( "open" );
12204
12205		return this;
12206	},
12207
12208	_createButtons: function( buttons ) {
12209		var that = this,
12210			hasButtons = false;
12211
12212		// if we already have a button pane, remove it
12213		this.uiDialogButtonPane.remove();
12214		this.uiButtonSet.empty();
12215
12216		if ( typeof buttons === "object" && buttons !== null ) {
12217			$.each( buttons, function() {
12218				return !(hasButtons = true);
12219			});
12220		}
12221		if ( hasButtons ) {
12222			$.each( buttons, function( name, props ) {
12223				props = $.isFunction( props ) ?
12224					{ click: props, text: name } :
12225					props;
12226				var button = $( "<button type='button'></button>" )
12227					.attr( props, true )
12228					.unbind( "click" )
12229					.click(function() {
12230						props.click.apply( that.element[0], arguments );
12231					})
12232					.appendTo( that.uiButtonSet );
12233				if ( $.fn.button ) {
12234					button.button();
12235				}
12236			});
12237			this.uiDialog.addClass( "ui-dialog-buttons" );
12238			this.uiDialogButtonPane.appendTo( this.uiDialog );
12239		} else {
12240			this.uiDialog.removeClass( "ui-dialog-buttons" );
12241		}
12242	},
12243
12244	_makeDraggable: function() {
12245		var that = this,
12246			options = this.options;
12247
12248		function filteredUi( ui ) {
12249			return {
12250				position: ui.position,
12251				offset: ui.offset
12252			};
12253		}
12254
12255		this.uiDialog.draggable({
12256			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12257			handle: ".ui-dialog-titlebar",
12258			containment: "document",
12259			start: function( event, ui ) {
12260				$( this )
12261					.addClass( "ui-dialog-dragging" );
12262				that._trigger( "dragStart", event, filteredUi( ui ) );
12263			},
12264			drag: function( event, ui ) {
12265				that._trigger( "drag", event, filteredUi( ui ) );
12266			},
12267			stop: function( event, ui ) {
12268				options.position = [
12269					ui.position.left - that.document.scrollLeft(),
12270					ui.position.top - that.document.scrollTop()
12271				];
12272				$( this )
12273					.removeClass( "ui-dialog-dragging" );
12274				that._trigger( "dragStop", event, filteredUi( ui ) );
12275				$.ui.dialog.overlay.resize();
12276			}
12277		});
12278	},
12279
12280	_makeResizable: function( handles ) {
12281		handles = (handles === undefined ? this.options.resizable : handles);
12282		var that = this,
12283			options = this.options,
12284			// .ui-resizable has position: relative defined in the stylesheet
12285			// but dialogs have to use absolute or fixed positioning
12286			position = this.uiDialog.css( "position" ),
12287			resizeHandles = typeof handles === 'string' ?
12288				handles	:
12289				"n,e,s,w,se,sw,ne,nw";
12290
12291		function filteredUi( ui ) {
12292			return {
12293				originalPosition: ui.originalPosition,
12294				originalSize: ui.originalSize,
12295				position: ui.position,
12296				size: ui.size
12297			};
12298		}
12299
12300		this.uiDialog.resizable({
12301			cancel: ".ui-dialog-content",
12302			containment: "document",
12303			alsoResize: this.element,
12304			maxWidth: options.maxWidth,
12305			maxHeight: options.maxHeight,
12306			minWidth: options.minWidth,
12307			minHeight: this._minHeight(),
12308			handles: resizeHandles,
12309			start: function( event, ui ) {
12310				$( this ).addClass( "ui-dialog-resizing" );
12311				that._trigger( "resizeStart", event, filteredUi( ui ) );
12312			},
12313			resize: function( event, ui ) {
12314				that._trigger( "resize", event, filteredUi( ui ) );
12315			},
12316			stop: function( event, ui ) {
12317				$( this ).removeClass( "ui-dialog-resizing" );
12318				options.height = $( this ).height();
12319				options.width = $( this ).width();
12320				that._trigger( "resizeStop", event, filteredUi( ui ) );
12321				$.ui.dialog.overlay.resize();
12322			}
12323		})
12324		.css( "position", position )
12325		.find( ".ui-resizable-se" )
12326			.addClass( "ui-icon ui-icon-grip-diagonal-se" );
12327	},
12328
12329	_minHeight: function() {
12330		var options = this.options;
12331
12332		if ( options.height === "auto" ) {
12333			return options.minHeight;
12334		} else {
12335			return Math.min( options.minHeight, options.height );
12336		}
12337	},
12338
12339	_position: function( position ) {
12340		var myAt = [],
12341			offset = [ 0, 0 ],
12342			isVisible;
12343
12344		if ( position ) {
12345			// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
12346	//		if (typeof position == 'string' || $.isArray(position)) {
12347	//			myAt = $.isArray(position) ? position : position.split(' ');
12348
12349			if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
12350				myAt = position.split ? position.split( " " ) : [ position[ 0 ], position[ 1 ] ];
12351				if ( myAt.length === 1 ) {
12352					myAt[ 1 ] = myAt[ 0 ];
12353				}
12354
12355				$.each( [ "left", "top" ], function( i, offsetPosition ) {
12356					if ( +myAt[ i ] === myAt[ i ] ) {
12357						offset[ i ] = myAt[ i ];
12358						myAt[ i ] = offsetPosition;
12359					}
12360				});
12361
12362				position = {
12363					my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
12364						myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
12365					at: myAt.join( " " )
12366				};
12367			}
12368
12369			position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
12370		} else {
12371			position = $.ui.dialog.prototype.options.position;
12372		}
12373
12374		// need to show the dialog to get the actual offset in the position plugin
12375		isVisible = this.uiDialog.is( ":visible" );
12376		if ( !isVisible ) {
12377			this.uiDialog.show();
12378		}
12379		this.uiDialog.position( position );
12380		if ( !isVisible ) {
12381			this.uiDialog.hide();
12382		}
12383	},
12384
12385	_setOptions: function( options ) {
12386		var that = this,
12387			resizableOptions = {},
12388			resize = false;
12389
12390		$.each( options, function( key, value ) {
12391			that._setOption( key, value );
12392
12393			if ( key in sizeRelatedOptions ) {
12394				resize = true;
12395			}
12396			if ( key in resizableRelatedOptions ) {
12397				resizableOptions[ key ] = value;
12398			}
12399		});
12400
12401		if ( resize ) {
12402			this._size();
12403		}
12404		if ( this.uiDialog.is( ":data(resizable)" ) ) {
12405			this.uiDialog.resizable( "option", resizableOptions );
12406		}
12407	},
12408
12409	_setOption: function( key, value ) {
12410		var isDraggable, isResizable,
12411			uiDialog = this.uiDialog;
12412
12413		switch ( key ) {
12414			case "buttons":
12415				this._createButtons( value );
12416				break;
12417			case "closeText":
12418				// ensure that we always pass a string
12419				this.uiDialogTitlebarCloseText.text( "" + value );
12420				break;
12421			case "dialogClass":
12422				uiDialog
12423					.removeClass( this.options.dialogClass )
12424					.addClass( uiDialogClasses + value );
12425				break;
12426			case "disabled":
12427				if ( value ) {
12428					uiDialog.addClass( "ui-dialog-disabled" );
12429				} else {
12430					uiDialog.removeClass( "ui-dialog-disabled" );
12431				}
12432				break;
12433			case "draggable":
12434				isDraggable = uiDialog.is( ":data(draggable)" );
12435				if ( isDraggable && !value ) {
12436					uiDialog.draggable( "destroy" );
12437				}
12438
12439				if ( !isDraggable && value ) {
12440					this._makeDraggable();
12441				}
12442				break;
12443			case "position":
12444				this._position( value );
12445				break;
12446			case "resizable":
12447				// currently resizable, becoming non-resizable
12448				isResizable = uiDialog.is( ":data(resizable)" );
12449				if ( isResizable && !value ) {
12450					uiDialog.resizable( "destroy" );
12451				}
12452
12453				// currently resizable, changing handles
12454				if ( isResizable && typeof value === "string" ) {
12455					uiDialog.resizable( "option", "handles", value );
12456				}
12457
12458				// currently non-resizable, becoming resizable
12459				if ( !isResizable && value !== false ) {
12460					this._makeResizable( value );
12461				}
12462				break;
12463			case "title":
12464				// convert whatever was passed in o a string, for html() to not throw up
12465				$( ".ui-dialog-title", this.uiDialogTitlebar )
12466					.html( "" + ( value || "&#160;" ) );
12467				break;
12468		}
12469
12470		this._super( key, value );
12471	},
12472
12473	_size: function() {
12474		/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12475		 * divs will both have width and height set, so we need to reset them
12476		 */
12477		var nonContentHeight, minContentHeight, autoHeight,
12478			options = this.options,
12479			isVisible = this.uiDialog.is( ":visible" );
12480
12481		// reset content sizing
12482		this.element.show().css({
12483			width: "auto",
12484			minHeight: 0,
12485			height: 0
12486		});
12487
12488		if ( options.minWidth > options.width ) {
12489			options.width = options.minWidth;
12490		}
12491
12492		// reset wrapper sizing
12493		// determine the height of all the non-content elements
12494		nonContentHeight = this.uiDialog.css({
12495				height: "auto",
12496				width: options.width
12497			})
12498			.outerHeight();
12499		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12500
12501		if ( options.height === "auto" ) {
12502			// only needed for IE6 support
12503			if ( $.support.minHeight ) {
12504				this.element.css({
12505					minHeight: minContentHeight,
12506					height: "auto"
12507				});
12508			} else {
12509				this.uiDialog.show();
12510				autoHeight = this.element.css( "height", "auto" ).height();
12511				if ( !isVisible ) {
12512					this.uiDialog.hide();
12513				}
12514				this.element.height( Math.max( autoHeight, minContentHeight ) );
12515			}
12516		} else {
12517			this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
12518		}
12519
12520		if (this.uiDialog.is( ":data(resizable)" ) ) {
12521			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12522		}
12523	}
12524});
12525
12526$.extend($.ui.dialog, {
12527	uuid: 0,
12528	maxZ: 0,
12529
12530	getTitleId: function($el) {
12531		var id = $el.attr( "id" );
12532		if ( !id ) {
12533			this.uuid += 1;
12534			id = this.uuid;
12535		}
12536		return "ui-dialog-title-" + id;
12537	},
12538
12539	overlay: function( dialog ) {
12540		this.$el = $.ui.dialog.overlay.create( dialog );
12541	}
12542});
12543
12544$.extend( $.ui.dialog.overlay, {
12545	instances: [],
12546	// reuse old instances due to IE memory leak with alpha transparency (see #5185)
12547	oldInstances: [],
12548	maxZ: 0,
12549	events: $.map(
12550		"focus,mousedown,mouseup,keydown,keypress,click".split( "," ),
12551		function( event ) {
12552			return event + ".dialog-overlay";
12553		}
12554	).join( " " ),
12555	create: function( dialog ) {
12556		if ( this.instances.length === 0 ) {
12557			// prevent use of anchors and inputs
12558			// we use a setTimeout in case the overlay is created from an
12559			// event that we're going to be cancelling (see #2804)
12560			setTimeout(function() {
12561				// handle $(el).dialog().dialog('close') (see #4065)
12562				if ( $.ui.dialog.overlay.instances.length ) {
12563					$( document ).bind( $.ui.dialog.overlay.events, function( event ) {
12564						// stop events if the z-index of the target is < the z-index of the overlay
12565						// we cannot return true when we don't want to cancel the event (#3523)
12566						if ( $( event.target ).zIndex() < $.ui.dialog.overlay.maxZ ) {
12567							return false;
12568						}
12569					});
12570				}
12571			}, 1 );
12572
12573			// handle window resize
12574			$( window ).bind( "resize.dialog-overlay", $.ui.dialog.overlay.resize );
12575		}
12576
12577		var $el = ( this.oldInstances.pop() || $( "<div>" ).addClass( "ui-widget-overlay" ) );
12578
12579		// allow closing by pressing the escape key
12580		$( document ).bind( "keydown.dialog-overlay", function( event ) {
12581			var instances = $.ui.dialog.overlay.instances;
12582			// only react to the event if we're the top overlay
12583			if ( instances.length !== 0 && instances[ instances.length - 1 ] === $el &&
12584				dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12585				event.keyCode === $.ui.keyCode.ESCAPE ) {
12586
12587				dialog.close( event );
12588				event.preventDefault();
12589			}
12590		});
12591
12592		$el.appendTo( document.body ).css({
12593			width: this.width(),
12594			height: this.height()
12595		});
12596
12597		if ( $.fn.bgiframe ) {
12598			$el.bgiframe();
12599		}
12600
12601		this.instances.push( $el );
12602		return $el;
12603	},
12604
12605	destroy: function( $el ) {
12606		var indexOf = $.inArray( $el, this.instances ),
12607			maxZ = 0;
12608
12609		if ( indexOf !== -1 ) {
12610			this.oldInstances.push( this.instances.splice( indexOf, 1 )[ 0 ] );
12611		}
12612
12613		if ( this.instances.length === 0 ) {
12614			$( [ document, window ] ).unbind( ".dialog-overlay" );
12615		}
12616
12617		$el.height( 0 ).width( 0 ).remove();
12618
12619		// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
12620		$.each( this.instances, function() {
12621			maxZ = Math.max( maxZ, this.css( "z-index" ) );
12622		});
12623		this.maxZ = maxZ;
12624	},
12625
12626	height: function() {
12627		var scrollHeight,
12628			offsetHeight;
12629		// handle IE
12630		if ( $.ui.ie ) {
12631			scrollHeight = Math.max(
12632				document.documentElement.scrollHeight,
12633				document.body.scrollHeight
12634			);
12635			offsetHeight = Math.max(
12636				document.documentElement.offsetHeight,
12637				document.body.offsetHeight
12638			);
12639
12640			if ( scrollHeight < offsetHeight ) {
12641				return $( window ).height() + "px";
12642			} else {
12643				return scrollHeight + "px";
12644			}
12645		// handle "good" browsers
12646		} else {
12647			return $( document ).height() + "px";
12648		}
12649	},
12650
12651	width: function() {
12652		var scrollWidth,
12653			offsetWidth;
12654		// handle IE
12655		if ( $.ui.ie ) {
12656			scrollWidth = Math.max(
12657				document.documentElement.scrollWidth,
12658				document.body.scrollWidth
12659			);
12660			offsetWidth = Math.max(
12661				document.documentElement.offsetWidth,
12662				document.body.offsetWidth
12663			);
12664
12665			if ( scrollWidth < offsetWidth ) {
12666				return $( window ).width() + "px";
12667			} else {
12668				return scrollWidth + "px";
12669			}
12670		// handle "good" browsers
12671		} else {
12672			return $( document ).width() + "px";
12673		}
12674	},
12675
12676	resize: function() {
12677		/* If the dialog is draggable and the user drags it past the
12678		 * right edge of the window, the document becomes wider so we
12679		 * need to stretch the overlay. If the user then drags the
12680		 * dialog back to the left, the document will become narrower,
12681		 * so we need to shrink the overlay to the appropriate size.
12682		 * This is handled by shrinking the overlay before setting it
12683		 * to the full document size.
12684		 */
12685		var $overlays = $( [] );
12686		$.each( $.ui.dialog.overlay.instances, function() {
12687			$overlays = $overlays.add( this );
12688		});
12689
12690		$overlays.css({
12691			width: 0,
12692			height: 0
12693		}).css({
12694			width: $.ui.dialog.overlay.width(),
12695			height: $.ui.dialog.overlay.height()
12696		});
12697	}
12698});
12699
12700$.extend( $.ui.dialog.overlay.prototype, {
12701	destroy: function() {
12702		$.ui.dialog.overlay.destroy( this.$el );
12703	}
12704});
12705
12706}( jQuery ) );
12707
12708(function( $, undefined ) {
12709
12710var rvertical = /up|down|vertical/,
12711	rpositivemotion = /up|left|vertical|horizontal/;
12712
12713$.effects.effect.blind = function( o, done ) {
12714	// Create element
12715	var el = $( this ),
12716		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
12717		mode = $.effects.setMode( el, o.mode || "hide" ),
12718		direction = o.direction || "up",
12719		vertical = rvertical.test( direction ),
12720		ref = vertical ? "height" : "width",
12721		ref2 = vertical ? "top" : "left",
12722		motion = rpositivemotion.test( direction ),
12723		animation = {},
12724		show = mode === "show",
12725		wrapper, distance, margin;
12726
12727	// if already wrapped, the wrapper's properties are my property. #6245
12728	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
12729		$.effects.save( el.parent(), props );
12730	} else {
12731		$.effects.save( el, props );
12732	}
12733	el.show();
12734	wrapper = $.effects.createWrapper( el ).css({
12735		overflow: "hidden"
12736	});
12737
12738	distance = wrapper[ ref ]();
12739	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
12740
12741	animation[ ref ] = show ? distance : 0;
12742	if ( !motion ) {
12743		el
12744			.css( vertical ? "bottom" : "right", 0 )
12745			.css( vertical ? "top" : "left", "auto" )
12746			.css({ position: "absolute" });
12747
12748		animation[ ref2 ] = show ? margin : distance + margin;
12749	}
12750
12751	// start at 0 if we are showing
12752	if ( show ) {
12753		wrapper.css( ref, 0 );
12754		if ( ! motion ) {
12755			wrapper.css( ref2, margin + distance );
12756		}
12757	}
12758
12759	// Animate
12760	wrapper.animate( animation, {
12761		duration: o.duration,
12762		easing: o.easing,
12763		queue: false,
12764		complete: function() {
12765			if ( mode === "hide" ) {
12766				el.hide();
12767			}
12768			$.effects.restore( el, props );
12769			$.effects.removeWrapper( el );
12770			done();
12771		}
12772	});
12773
12774};
12775
12776})(jQuery);
12777
12778(function( $, undefined ) {
12779
12780$.effects.effect.bounce = function( o, done ) {
12781	var el = $( this ),
12782		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
12783
12784		// defaults:
12785		mode = $.effects.setMode( el, o.mode || "effect" ),
12786		hide = mode === "hide",
12787		show = mode === "show",
12788		direction = o.direction || "up",
12789		distance = o.distance,
12790		times = o.times || 5,
12791
12792		// number of internal animations
12793		anims = times * 2 + ( show || hide ? 1 : 0 ),
12794		speed = o.duration / anims,
12795		easing = o.easing,
12796
12797		// utility:
12798		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
12799		motion = ( direction === "up" || direction === "left" ),
12800		i,
12801		upAnim,
12802		downAnim,
12803
12804		// we will need to re-assemble the queue to stack our animations in place
12805		queue = el.queue(),
12806		queuelen = queue.length;
12807
12808	// Avoid touching opacity to prevent clearType and PNG issues in IE
12809	if ( show || hide ) {
12810		props.push( "opacity" );
12811	}
12812
12813	$.effects.save( el, props );
12814	el.show();
12815	$.effects.createWrapper( el ); // Create Wrapper
12816
12817	// default distance for the BIGGEST bounce is the outer Distance / 3
12818	if ( !distance ) {
12819		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
12820	}
12821
12822	if ( show ) {
12823		downAnim = { opacity: 1 };
12824		downAnim[ ref ] = 0;
12825
12826		// if we are showing, force opacity 0 and set the initial position
12827		// then do the "first" animation
12828		el.css( "opacity", 0 )
12829			.css( ref, motion ? -distance * 2 : distance * 2 )
12830			.animate( downAnim, speed, easing );
12831	}
12832
12833	// start at the smallest distance if we are hiding
12834	if ( hide ) {
12835		distance = distance / Math.pow( 2, times - 1 );
12836	}
12837
12838	downAnim = {};
12839	downAnim[ ref ] = 0;
12840	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
12841	for ( i = 0; i < times; i++ ) {
12842		upAnim = {};
12843		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
12844
12845		el.animate( upAnim, speed, easing )
12846			.animate( downAnim, speed, easing );
12847
12848		distance = hide ? distance * 2 : distance / 2;
12849	}
12850
12851	// Last Bounce when Hiding
12852	if ( hide ) {
12853		upAnim = { opacity: 0 };
12854		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
12855
12856		el.animate( upAnim, speed, easing );
12857	}
12858
12859	el.queue(function() {
12860		if ( hide ) {
12861			el.hide();
12862		}
12863		$.effects.restore( el, props );
12864		$.effects.removeWrapper( el );
12865		done();
12866	});
12867
12868	// inject all the animations we just queued to be first in line (after "inprogress")
12869	if ( queuelen > 1) {
12870		queue.splice.apply( queue,
12871			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
12872	}
12873	el.dequeue();
12874
12875};
12876
12877})(jQuery);
12878
12879(function( $, undefined ) {
12880
12881$.effects.effect.clip = function( o, done ) {
12882	// Create element
12883	var el = $( this ),
12884		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
12885		mode = $.effects.setMode( el, o.mode || "hide" ),
12886		show = mode === "show",
12887		direction = o.direction || "vertical",
12888		vert = direction === "vertical",
12889		size = vert ? "height" : "width",
12890		position = vert ? "top" : "left",
12891		animation = {},
12892		wrapper, animate, distance;
12893
12894	// Save & Show
12895	$.effects.save( el, props );
12896	el.show();
12897
12898	// Create Wrapper
12899	wrapper = $.effects.createWrapper( el ).css({
12900		overflow: "hidden"
12901	});
12902	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
12903	distance = animate[ size ]();
12904
12905	// Shift
12906	if ( show ) {
12907		animate.css( size, 0 );
12908		animate.css( position, distance / 2 );
12909	}
12910
12911	// Create Animation Object:
12912	animation[ size ] = show ? distance : 0;
12913	animation[ position ] = show ? 0 : distance / 2;
12914
12915	// Animate
12916	animate.animate( animation, {
12917		queue: false,
12918		duration: o.duration,
12919		easing: o.easing,
vendor: 17,802 bytes, lines 12920-13658
12920		complete: function() {
12921			if ( !show ) {
12922				el.hide();
12923			}
12924			$.effects.restore( el, props );
12925			$.effects.removeWrapper( el );
12926			done();
12927		}
12928	});
12929
12930};
12931
12932})(jQuery);
12933
12934(function( $, undefined ) {
12935
12936$.effects.effect.drop = function( o, done ) {
12937
12938	var el = $( this ),
12939		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
12940		mode = $.effects.setMode( el, o.mode || "hide" ),
12941		show = mode === "show",
12942		direction = o.direction || "left",
12943		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
12944		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
12945		animation = {
12946			opacity: show ? 1 : 0
12947		},
12948		distance;
12949
12950	// Adjust
12951	$.effects.save( el, props );
12952	el.show();
12953	$.effects.createWrapper( el );
12954
12955	distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
12956
12957	if ( show ) {
12958		el
12959			.css( "opacity", 0 )
12960			.css( ref, motion === "pos" ? -distance : distance );
12961	}
12962
12963	// Animation
12964	animation[ ref ] = ( show ?
12965		( motion === "pos" ? "+=" : "-=" ) :
12966		( motion === "pos" ? "-=" : "+=" ) ) +
12967		distance;
12968
12969	// Animate
12970	el.animate( animation, {
12971		queue: false,
12972		duration: o.duration,
12973		easing: o.easing,
12974		complete: function() {
12975			if ( mode === "hide" ) {
12976				el.hide();
12977			}
12978			$.effects.restore( el, props );
12979			$.effects.removeWrapper( el );
12980			done();
12981		}
12982	});
12983};
12984
12985})(jQuery);
12986
12987(function( $, undefined ) {
12988
12989$.effects.effect.explode = function( o, done ) {
12990
12991	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
12992		cells = rows,
12993		el = $( this ),
12994		mode = $.effects.setMode( el, o.mode || "hide" ),
12995		show = mode === "show",
12996
12997		// show and then visibility:hidden the element before calculating offset
12998		offset = el.show().css( "visibility", "hidden" ).offset(),
12999
13000		// width and height of a piece
13001		width = Math.ceil( el.outerWidth() / cells ),
13002		height = Math.ceil( el.outerHeight() / rows ),
13003		pieces = [],
13004
13005		// loop
13006		i, j, left, top, mx, my;
13007
13008	// children animate complete:
13009	function childComplete() {
13010		pieces.push( this );
13011		if ( pieces.length === rows * cells ) {
13012			animComplete();
13013		}
13014	}
13015
13016	// clone the element for each row and cell.
13017	for( i = 0; i < rows ; i++ ) { // ===>
13018		top = offset.top + i * height;
13019		my = i - ( rows - 1 ) / 2 ;
13020
13021		for( j = 0; j < cells ; j++ ) { // |||
13022			left = offset.left + j * width;
13023			mx = j - ( cells - 1 ) / 2 ;
13024
13025			// Create a clone of the now hidden main element that will be absolute positioned
13026			// within a wrapper div off the -left and -top equal to size of our pieces
13027			el
13028				.clone()
13029				.appendTo( "body" )
13030				.wrap( "<div></div>" )
13031				.css({
13032					position: "absolute",
13033					visibility: "visible",
13034					left: -j * width,
13035					top: -i * height
13036				})
13037
13038			// select the wrapper - make it overflow: hidden and absolute positioned based on
13039			// where the original was located +left and +top equal to the size of pieces
13040				.parent()
13041				.addClass( "ui-effects-explode" )
13042				.css({
13043					position: "absolute",
13044					overflow: "hidden",
13045					width: width,
13046					height: height,
13047					left: left + ( show ? mx * width : 0 ),
13048					top: top + ( show ? my * height : 0 ),
13049					opacity: show ? 0 : 1
13050				}).animate({
13051					left: left + ( show ? 0 : mx * width ),
13052					top: top + ( show ? 0 : my * height ),
13053					opacity: show ? 1 : 0
13054				}, o.duration || 500, o.easing, childComplete );
13055		}
13056	}
13057
13058	function animComplete() {
13059		el.css({
13060			visibility: "visible"
13061		});
13062		$( pieces ).remove();
13063		if ( !show ) {
13064			el.hide();
13065		}
13066		done();
13067	}
13068};
13069
13070})(jQuery);
13071
13072(function( $, undefined ) {
13073
13074$.effects.effect.fade = function( o, done ) {
13075	var el = $( this ),
13076		mode = $.effects.setMode( el, o.mode || "toggle" );
13077
13078	el.animate({
13079		opacity: mode
13080	}, {
13081		queue: false,
13082		duration: o.duration,
13083		easing: o.easing,
13084		complete: done
13085	});
13086};
13087
13088})( jQuery );
13089
13090(function( $, undefined ) {
13091
13092$.effects.effect.fold = function( o, done ) {
13093
13094	// Create element
13095	var el = $( this ),
13096		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13097		mode = $.effects.setMode( el, o.mode || "hide" ),
13098		show = mode === "show",
13099		hide = mode === "hide",
13100		size = o.size || 15,
13101		percent = /([0-9]+)%/.exec( size ),
13102		horizFirst = !!o.horizFirst,
13103		widthFirst = show !== horizFirst,
13104		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
13105		duration = o.duration / 2,
13106		wrapper, distance,
13107		animation1 = {},
13108		animation2 = {};
13109
13110	$.effects.save( el, props );
13111	el.show();
13112
13113	// Create Wrapper
13114	wrapper = $.effects.createWrapper( el ).css({
13115		overflow: "hidden"
13116	});
13117	distance = widthFirst ?
13118		[ wrapper.width(), wrapper.height() ] :
13119		[ wrapper.height(), wrapper.width() ];
13120
13121	if ( percent ) {
13122		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
13123	}
13124	if ( show ) {
13125		wrapper.css( horizFirst ? {
13126			height: 0,
13127			width: size
13128		} : {
13129			height: size,
13130			width: 0
13131		});
13132	}
13133
13134	// Animation
13135	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
13136	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
13137
13138	// Animate
13139	wrapper
13140		.animate( animation1, duration, o.easing )
13141		.animate( animation2, duration, o.easing, function() {
13142			if ( hide ) {
13143				el.hide();
13144			}
13145			$.effects.restore( el, props );
13146			$.effects.removeWrapper( el );
13147			done();
13148		});
13149
13150};
13151
13152})(jQuery);
13153
13154(function( $, undefined ) {
13155
13156$.effects.effect.highlight = function( o, done ) {
13157	var elem = $( this ),
13158		props = [ "backgroundImage", "backgroundColor", "opacity" ],
13159		mode = $.effects.setMode( elem, o.mode || "show" ),
13160		animation = {
13161			backgroundColor: elem.css( "backgroundColor" )
13162		};
13163
13164	if (mode === "hide") {
13165		animation.opacity = 0;
13166	}
13167
13168	$.effects.save( elem, props );
13169
13170	elem
13171		.show()
13172		.css({
13173			backgroundImage: "none",
13174			backgroundColor: o.color || "#ffff99"
13175		})
13176		.animate( animation, {
13177			queue: false,
13178			duration: o.duration,
13179			easing: o.easing,
13180			complete: function() {
13181				if ( mode === "hide" ) {
13182					elem.hide();
13183				}
13184				$.effects.restore( elem, props );
13185				done();
13186			}
13187		});
13188};
13189
13190})(jQuery);
13191
13192(function( $, undefined ) {
13193
13194$.effects.effect.pulsate = function( o, done ) {
13195	var elem = $( this ),
13196		mode = $.effects.setMode( elem, o.mode || "show" ),
13197		show = mode === "show",
13198		hide = mode === "hide",
13199		showhide = ( show || mode === "hide" ),
13200
13201		// showing or hiding leaves of the "last" animation
13202		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
13203		duration = o.duration / anims,
13204		animateTo = 0,
13205		queue = elem.queue(),
13206		queuelen = queue.length,
13207		i;
13208
13209	if ( show || !elem.is(":visible")) {
13210		elem.css( "opacity", 0 ).show();
13211		animateTo = 1;
13212	}
13213
13214	// anims - 1 opacity "toggles"
13215	for ( i = 1; i < anims; i++ ) {
13216		elem.animate({
13217			opacity: animateTo
13218		}, duration, o.easing );
13219		animateTo = 1 - animateTo;
13220	}
13221
13222	elem.animate({
13223		opacity: animateTo
13224	}, duration, o.easing);
13225
13226	elem.queue(function() {
13227		if ( hide ) {
13228			elem.hide();
13229		}
13230		done();
13231	});
13232
13233	// We just queued up "anims" animations, we need to put them next in the queue
13234	if ( queuelen > 1 ) {
13235		queue.splice.apply( queue,
13236			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
13237	}
13238	elem.dequeue();
13239};
13240
13241})(jQuery);
13242
13243(function( $, undefined ) {
13244
13245$.effects.effect.puff = function( o, done ) {
13246	var elem = $( this ),
13247		mode = $.effects.setMode( elem, o.mode || "hide" ),
13248		hide = mode === "hide",
13249		percent = parseInt( o.percent, 10 ) || 150,
13250		factor = percent / 100,
13251		original = {
13252			height: elem.height(),
13253			width: elem.width()
13254		};
13255
13256	$.extend( o, {
13257		effect: "scale",
13258		queue: false,
13259		fade: true,
13260		mode: mode,
13261		complete: done,
13262		percent: hide ? percent : 100,
13263		from: hide ?
13264			original :
13265			{
13266				height: original.height * factor,
13267				width: original.width * factor
13268			}
13269	});
13270
13271	elem.effect( o );
13272};
13273
13274$.effects.effect.scale = function( o, done ) {
13275
13276	// Create element
13277	var el = $( this ),
13278		options = $.extend( true, {}, o ),
13279		mode = $.effects.setMode( el, o.mode || "effect" ),
13280		percent = parseInt( o.percent, 10 ) ||
13281			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
13282		direction = o.direction || "both",
13283		origin = o.origin,
13284		original = {
13285			height: el.height(),
13286			width: el.width(),
13287			outerHeight: el.outerHeight(),
13288			outerWidth: el.outerWidth()
13289		},
13290		factor = {
13291			y: direction !== "horizontal" ? (percent / 100) : 1,
13292			x: direction !== "vertical" ? (percent / 100) : 1
13293		};
13294
13295	// We are going to pass this effect to the size effect:
13296	options.effect = "size";
13297	options.queue = false;
13298	options.complete = done;
13299
13300	// Set default origin and restore for show/hide
13301	if ( mode !== "effect" ) {
13302		options.origin = origin || ["middle","center"];
13303		options.restore = true;
13304	}
13305
13306	options.from = o.from || ( mode === "show" ? { height: 0, width: 0 } : original );
13307	options.to = {
13308		height: original.height * factor.y,
13309		width: original.width * factor.x,
13310		outerHeight: original.outerHeight * factor.y,
13311		outerWidth: original.outerWidth * factor.x
13312	};
13313
13314	// Fade option to support puff
13315	if ( options.fade ) {
13316		if ( mode === "show" ) {
13317			options.from.opacity = 0;
13318			options.to.opacity = 1;
13319		}
13320		if ( mode === "hide" ) {
13321			options.from.opacity = 1;
13322			options.to.opacity = 0;
13323		}
13324	}
13325
13326	// Animate
13327	el.effect( options );
13328
13329};
13330
13331$.effects.effect.size = function( o, done ) {
13332
13333	// Create element
13334	var original, baseline, factor,
13335		el = $( this ),
13336		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
13337
13338		// Always restore
13339		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
13340
13341		// Copy for children
13342		props2 = [ "width", "height", "overflow" ],
13343		cProps = [ "fontSize" ],
13344		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
13345		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
13346
13347		// Set options
13348		mode = $.effects.setMode( el, o.mode || "effect" ),
13349		restore = o.restore || mode !== "effect",
13350		scale = o.scale || "both",
13351		origin = o.origin || [ "middle", "center" ],
13352		position = el.css( "position" ),
13353		props = restore ? props0 : props1,
13354		zero = {
13355			height: 0,
13356			width: 0
13357		};
13358
13359	if ( mode === "show" ) {
13360		el.show();
13361	}
13362	original = {
13363		height: el.height(),
13364		width: el.width(),
13365		outerHeight: el.outerHeight(),
13366		outerWidth: el.outerWidth()
13367	};
13368
13369	if ( o.mode === "toggle" && mode === "show" ) {
13370		el.from = o.to || zero;
13371		el.to = o.from || original;
13372	} else {
13373		el.from = o.from || ( mode === "show" ? zero : original );
13374		el.to = o.to || ( mode === "hide" ? zero : original );
13375	}
13376
13377	// Set scaling factor
13378	factor = {
13379		from: {
13380			y: el.from.height / original.height,
13381			x: el.from.width / original.width
13382		},
13383		to: {
13384			y: el.to.height / original.height,
13385			x: el.to.width / original.width
13386		}
13387	};
13388
13389	// Scale the css box
13390	if ( scale === "box" || scale === "both" ) {
13391
13392		// Vertical props scaling
13393		if ( factor.from.y !== factor.to.y ) {
13394			props = props.concat( vProps );
13395			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
13396			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
13397		}
13398
13399		// Horizontal props scaling
13400		if ( factor.from.x !== factor.to.x ) {
13401			props = props.concat( hProps );
13402			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
13403			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
13404		}
13405	}
13406
13407	// Scale the content
13408	if ( scale === "content" || scale === "both" ) {
13409
13410		// Vertical props scaling
13411		if ( factor.from.y !== factor.to.y ) {
13412			props = props.concat( cProps ).concat( props2 );
13413			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
13414			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
13415		}
13416	}
13417
13418	$.effects.save( el, props );
13419	el.show();
13420	$.effects.createWrapper( el );
13421	el.css( "overflow", "hidden" ).css( el.from );
13422
13423	// Adjust
13424	if (origin) { // Calculate baseline shifts
13425		baseline = $.effects.getBaseline( origin, original );
13426		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
13427		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
13428		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
13429		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
13430	}
13431	el.css( el.from ); // set top & left
13432
13433	// Animate
13434	if ( scale === "content" || scale === "both" ) { // Scale the children
13435
13436		// Add margins/font-size
13437		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
13438		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
13439		props2 = props0.concat(vProps).concat(hProps);
13440
13441		el.find( "*[width]" ).each( function(){
13442			var child = $( this ),
13443				c_original = {
13444					height: child.height(),
13445					width: child.width()
13446				};
13447			if (restore) {
13448				$.effects.save(child, props2);
13449			}
13450
13451			child.from = {
13452				height: c_original.height * factor.from.y,
13453				width: c_original.width * factor.from.x
13454			};
13455			child.to = {
13456				height: c_original.height * factor.to.y,
13457				width: c_original.width * factor.to.x
13458			};
13459
13460			// Vertical props scaling
13461			if ( factor.from.y !== factor.to.y ) {
13462				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
13463				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
13464			}
13465
13466			// Horizontal props scaling
13467			if ( factor.from.x !== factor.to.x ) {
13468				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
13469				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
13470			}
13471
13472			// Animate children
13473			child.css( child.from );
13474			child.animate( child.to, o.duration, o.easing, function() {
13475
13476				// Restore children
13477				if ( restore ) {
13478					$.effects.restore( child, props2 );
13479				}
13480			});
13481		});
13482	}
13483
13484	// Animate
13485	el.animate( el.to, {
13486		queue: false,
13487		duration: o.duration,
13488		easing: o.easing,
13489		complete: function() {
13490			if ( el.to.opacity === 0 ) {
13491				el.css( "opacity", el.from.opacity );
13492			}
13493			if( mode === "hide" ) {
13494				el.hide();
13495			}
13496			$.effects.restore( el, props );
13497			if ( !restore ) {
13498
13499				// we need to calculate our new positioning based on the scaling
13500				if ( position === "static" ) {
13501					el.css({
13502						position: "relative",
13503						top: el.to.top,
13504						left: el.to.left
13505					});
13506				} else {
13507					$.each([ "top", "left" ], function( idx, pos ) {
13508						el.css( pos, function( _, str ) {
13509							var val = parseInt( str, 10 ),
13510								toRef = idx ? el.to.left : el.to.top;
13511
13512							// if original was "auto", recalculate the new value from wrapper
13513							if ( str === "auto" ) {
13514								return toRef + "px";
13515							}
13516
13517							return val + toRef + "px";
13518						});
13519					});
13520				}
13521			}
13522
13523			$.effects.removeWrapper( el );
13524			done();
13525		}
13526	});
13527
13528};
13529
13530})(jQuery);
13531
13532(function( $, undefined ) {
13533
13534$.effects.effect.shake = function( o, done ) {
13535
13536	var el = $( this ),
13537		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
13538		mode = $.effects.setMode( el, o.mode || "effect" ),
13539		direction = o.direction || "left",
13540		distance = o.distance || 20,
13541		times = o.times || 3,
13542		anims = times * 2 + 1,
13543		speed = Math.round(o.duration/anims),
13544		ref = (direction === "up" || direction === "down") ? "top" : "left",
13545		positiveMotion = (direction === "up" || direction === "left"),
13546		animation = {},
13547		animation1 = {},
13548		animation2 = {},
13549		i,
13550
13551		// we will need to re-assemble the queue to stack our animations in place
13552		queue = el.queue(),
13553		queuelen = queue.length;
13554
13555	$.effects.save( el, props );
13556	el.show();
13557	$.effects.createWrapper( el );
13558
13559	// Animation
13560	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
13561	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
13562	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
13563
13564	// Animate
13565	el.animate( animation, speed, o.easing );
13566
13567	// Shakes
13568	for ( i = 1; i < times; i++ ) {
13569		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
13570	}
13571	el
13572		.animate( animation1, speed, o.easing )
13573		.animate( animation, speed / 2, o.easing )
13574		.queue(function() {
13575			if ( mode === "hide" ) {
13576				el.hide();
13577			}
13578			$.effects.restore( el, props );
13579			$.effects.removeWrapper( el );
13580			done();
13581		});
13582
13583	// inject all the animations we just queued to be first in line (after "inprogress")
13584	if ( queuelen > 1) {
13585		queue.splice.apply( queue,
13586			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
13587	}
13588	el.dequeue();
13589
13590};
13591
13592})(jQuery);
13593
13594(function( $, undefined ) {
13595
13596$.effects.effect.slide = function( o, done ) {
13597
13598	// Create element
13599	var el = $( this ),
13600		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
13601		mode = $.effects.setMode( el, o.mode || "show" ),
13602		show = mode === "show",
13603		direction = o.direction || "left",
13604		ref = (direction === "up" || direction === "down") ? "top" : "left",
13605		positiveMotion = (direction === "up" || direction === "left"),
13606		distance,
13607		animation = {};
13608
13609	// Adjust
13610	$.effects.save( el, props );
13611	el.show();
13612	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
13613
13614	$.effects.createWrapper( el ).css({
13615		overflow: "hidden"
13616	});
13617
13618	if ( show ) {
13619		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
13620	}
13621
13622	// Animation
13623	animation[ ref ] = ( show ?
13624		( positiveMotion ? "+=" : "-=") :
13625		( positiveMotion ? "-=" : "+=")) +
13626		distance;
13627
13628	// Animate
13629	el.animate( animation, {
13630		queue: false,
13631		duration: o.duration,
13632		easing: o.easing,
13633		complete: function() {
13634			if ( mode === "hide" ) {
13635				el.hide();
13636			}
13637			$.effects.restore( el, props );
13638			$.effects.removeWrapper( el );
13639			done();
13640		}
13641	});
13642};
13643
13644})(jQuery);
13645
13646(function( $, undefined ) {
13647
13648$.effects.effect.transfer = function( o, done ) {
13649	var elem = $( this ),
13650		target = $( o.to ),
13651		targetFixed = target.css( "position" ) === "fixed",
13652		body = $("body"),
13653		fixTop = targetFixed ? body.scrollTop() : 0,
13654		fixLeft = targetFixed ? body.scrollLeft() : 0,
13655		endPosition = target.offset(),
13656		animation = {
13657			top: endPosition.top - fixTop ,
13658			left: endPosition.left - fixLeft ,
13659			height: target.innerHeight(),
13660			width: target.innerWidth()
13661		},
13662		startPosition = elem.offset(),
13663		transfer = $( '<div class="ui-effects-transfer"></div>' )
13664			.appendTo( document.body )
13665			.addClass( o.className )
13666			.css({
13667				top: startPosition.top - fixTop ,
13668				left: startPosition.left - fixLeft ,
13669				height: elem.innerHeight(),
13670				width: elem.innerWidth(),
13671				position: targetFixed ? "fixed" : "absolute"
13672			})
13673			.animate( animation, o.duration, o.easing, function() {
13674				transfer.remove();
13675				done();
13676			});
13677};
13678
13679})(jQuery);
13680
13681(function( $, undefined ) {
13682
13683var mouseHandled = false;
13684
13685$.widget( "ui.menu", {
13686	version: "1.9.1",
13687	defaultElement: "<ul>",
13688	delay: 300,
13689	options: {
13690		icons: {
13691			submenu: "ui-icon-carat-1-e"
13692		},
13693		menus: "ul",
13694		position: {
13695			my: "left top",
13696			at: "right top"
13697		},
13698		role: "menu",
13699
13700		// callbacks
13701		blur: null,
13702		focus: null,
13703		select: null
13704	},
13705
13706	_create: function() {
13707		this.activeMenu = this.element;
13708		this.element
13709			.uniqueId()
13710			.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
13711			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
13712			.attr({
13713				role: this.options.role,
13714				tabIndex: 0
13715			})
13716			// need to catch all clicks on disabled menu
13717			// not possible through _on
13718			.bind( "click" + this.eventNamespace, $.proxy(function( event ) {
13719				if ( this.options.disabled ) {
13720					event.preventDefault();
13721				}
13722			}, this ));
13723
13724		if ( this.options.disabled ) {
13725			this.element
13726				.addClass( "ui-state-disabled" )
13727				.attr( "aria-disabled", "true" );
13728		}
13729
13730		this._on({
13731			// Prevent focus from sticking to links inside menu after clicking
13732			// them (focus should always stay on UL during navigation).
13733			"mousedown .ui-menu-item > a": function( event ) {
13734				event.preventDefault();
13735			},
13736			"click .ui-state-disabled > a": function( event ) {
13737				event.preventDefault();
13738			},
13739			"click .ui-menu-item:has(a)": function( event ) {
13740				var target = $( event.target ).closest( ".ui-menu-item" );
13741				if ( !mouseHandled && target.not( ".ui-state-disabled" ).length ) {
13742					mouseHandled = true;
13743
13744					this.select( event );
13745					// Open submenu on click
13746					if ( target.has( ".ui-menu" ).length ) {
13747						this.expand( event );
13748					} else if ( !this.element.is( ":focus" ) ) {
13749						// Redirect focus to the menu
13750						this.element.trigger( "focus", [ true ] );
13751
13752						// If the active item is on the top level, let it stay active.
13753						// Otherwise, blur the active item since it is no longer visible.
13754						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
13755							clearTimeout( this.timer );
13756						}
13757					}
13758				}
13759			},
13760			"mouseenter .ui-menu-item": function( event ) {
13761				var target = $( event.currentTarget );
13762				// Remove ui-state-active class from siblings of the newly focused menu item
13763				// to avoid a jump caused by adjacent elements both having a class with a border
13764				target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
13765				this.focus( event, target );
13766			},
13767			mouseleave: "collapseAll",
13768			"mouseleave .ui-menu": "collapseAll",
13769			focus: function( event, keepActiveItem ) {
13770				// If there's already an active item, keep it active
13771				// If not, activate the first item
13772				var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
13773
13774				if ( !keepActiveItem ) {
13775					this.focus( event, item );
13776				}
13777			},
13778			blur: function( event ) {
13779				this._delay(function() {
13780					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
13781						this.collapseAll( event );
13782					}
13783				});
13784			},
13785			keydown: "_keydown"
13786		});
13787
13788		this.refresh();
13789
vendor: 29,387 bytes, lines 13790-14801
13790		// Clicks outside of a menu collapse any open menus
13791		this._on( this.document, {
13792			click: function( event ) {
13793				if ( !$( event.target ).closest( ".ui-menu" ).length ) {
13794					this.collapseAll( event );
13795				}
13796
13797				// Reset the mouseHandled flag
13798				mouseHandled = false;
13799			}
13800		});
13801	},
13802
13803	_destroy: function() {
13804		// Destroy (sub)menus
13805		this.element
13806			.removeAttr( "aria-activedescendant" )
13807			.find( ".ui-menu" ).andSelf()
13808				.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
13809				.removeAttr( "role" )
13810				.removeAttr( "tabIndex" )
13811				.removeAttr( "aria-labelledby" )
13812				.removeAttr( "aria-expanded" )
13813				.removeAttr( "aria-hidden" )
13814				.removeAttr( "aria-disabled" )
13815				.removeUniqueId()
13816				.show();
13817
13818		// Destroy menu items
13819		this.element.find( ".ui-menu-item" )
13820			.removeClass( "ui-menu-item" )
13821			.removeAttr( "role" )
13822			.removeAttr( "aria-disabled" )
13823			.children( "a" )
13824				.removeUniqueId()
13825				.removeClass( "ui-corner-all ui-state-hover" )
13826				.removeAttr( "tabIndex" )
13827				.removeAttr( "role" )
13828				.removeAttr( "aria-haspopup" )
13829				.children().each( function() {
13830					var elem = $( this );
13831					if ( elem.data( "ui-menu-submenu-carat" ) ) {
13832						elem.remove();
13833					}
13834				});
13835
13836		// Destroy menu dividers
13837		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
13838	},
13839
13840	_keydown: function( event ) {
13841		var match, prev, character, skip, regex,
13842			preventDefault = true;
13843
13844		function escape( value ) {
13845			return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
13846		}
13847
13848		switch ( event.keyCode ) {
13849		case $.ui.keyCode.PAGE_UP:
13850			this.previousPage( event );
13851			break;
13852		case $.ui.keyCode.PAGE_DOWN:
13853			this.nextPage( event );
13854			break;
13855		case $.ui.keyCode.HOME:
13856			this._move( "first", "first", event );
13857			break;
13858		case $.ui.keyCode.END:
13859			this._move( "last", "last", event );
13860			break;
13861		case $.ui.keyCode.UP:
13862			this.previous( event );
13863			break;
13864		case $.ui.keyCode.DOWN:
13865			this.next( event );
13866			break;
13867		case $.ui.keyCode.LEFT:
13868			this.collapse( event );
13869			break;
13870		case $.ui.keyCode.RIGHT:
13871			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
13872				this.expand( event );
13873			}
13874			break;
13875		case $.ui.keyCode.ENTER:
13876		case $.ui.keyCode.SPACE:
13877			this._activate( event );
13878			break;
13879		case $.ui.keyCode.ESCAPE:
13880			this.collapse( event );
13881			break;
13882		default:
13883			preventDefault = false;
13884			prev = this.previousFilter || "";
13885			character = String.fromCharCode( event.keyCode );
13886			skip = false;
13887
13888			clearTimeout( this.filterTimer );
13889
13890			if ( character === prev ) {
13891				skip = true;
13892			} else {
13893				character = prev + character;
13894			}
13895
13896			regex = new RegExp( "^" + escape( character ), "i" );
13897			match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
13898				return regex.test( $( this ).children( "a" ).text() );
13899			});
13900			match = skip && match.index( this.active.next() ) !== -1 ?
13901				this.active.nextAll( ".ui-menu-item" ) :
13902				match;
13903
13904			// If no matches on the current filter, reset to the last character pressed
13905			// to move down the menu to the first item that starts with that character
13906			if ( !match.length ) {
13907				character = String.fromCharCode( event.keyCode );
13908				regex = new RegExp( "^" + escape( character ), "i" );
13909				match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
13910					return regex.test( $( this ).children( "a" ).text() );
13911				});
13912			}
13913
13914			if ( match.length ) {
13915				this.focus( event, match );
13916				if ( match.length > 1 ) {
13917					this.previousFilter = character;
13918					this.filterTimer = this._delay(function() {
13919						delete this.previousFilter;
13920					}, 1000 );
13921				} else {
13922					delete this.previousFilter;
13923				}
13924			} else {
13925				delete this.previousFilter;
13926			}
13927		}
13928
13929		if ( preventDefault ) {
13930			event.preventDefault();
13931		}
13932	},
13933
13934	_activate: function( event ) {
13935		if ( !this.active.is( ".ui-state-disabled" ) ) {
13936			if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
13937				this.expand( event );
13938			} else {
13939				this.select( event );
13940			}
13941		}
13942	},
13943
13944	refresh: function() {
13945		// Initialize nested menus
13946		var menus,
13947			icon = this.options.icons.submenu,
13948			submenus = this.element.find( this.options.menus + ":not(.ui-menu)" )
13949				.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
13950				.hide()
13951				.attr({
13952					role: this.options.role,
13953					"aria-hidden": "true",
13954					"aria-expanded": "false"
13955				});
13956
13957		// Don't refresh list items that are already adapted
13958		menus = submenus.add( this.element );
13959
13960		menus.children( ":not(.ui-menu-item):has(a)" )
13961			.addClass( "ui-menu-item" )
13962			.attr( "role", "presentation" )
13963			.children( "a" )
13964				.uniqueId()
13965				.addClass( "ui-corner-all" )
13966				.attr({
13967					tabIndex: -1,
13968					role: this._itemRole()
13969				});
13970
13971		// Initialize unlinked menu-items containing spaces and/or dashes only as dividers
13972		menus.children( ":not(.ui-menu-item)" ).each(function() {
13973			var item = $( this );
13974			// hyphen, em dash, en dash
13975			if ( !/[^\-—–\s]/.test( item.text() ) ) {
13976				item.addClass( "ui-widget-content ui-menu-divider" );
13977			}
13978		});
13979
13980		// Add aria-disabled attribute to any disabled menu item
13981		menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
13982
13983		submenus.each(function() {
13984			var menu = $( this ),
13985				item = menu.prev( "a" ),
13986				submenuCarat = $( "<span>" )
13987					.addClass( "ui-menu-icon ui-icon " + icon )
13988					.data( "ui-menu-submenu-carat", true );
13989
13990			item
13991				.attr( "aria-haspopup", "true" )
13992				.prepend( submenuCarat );
13993			menu.attr( "aria-labelledby", item.attr( "id" ) );
13994		});
13995
13996		// If the active item has been removed, blur the menu
13997		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
13998			this.blur();
13999		}
14000	},
14001
14002	_itemRole: function() {
14003		return {
14004			menu: "menuitem",
14005			listbox: "option"
14006		}[ this.options.role ];
14007	},
14008
14009	focus: function( event, item ) {
14010		var nested, focused;
14011		this.blur( event, event && event.type === "focus" );
14012
14013		this._scrollIntoView( item );
14014
14015		this.active = item.first();
14016		focused = this.active.children( "a" ).addClass( "ui-state-focus" );
14017		// Only update aria-activedescendant if there's a role
14018		// otherwise we assume focus is managed elsewhere
14019		if ( this.options.role ) {
14020			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
14021		}
14022
14023		// Highlight active parent menu item, if any
14024		this.active
14025			.parent()
14026			.closest( ".ui-menu-item" )
14027			.children( "a:first" )
14028			.addClass( "ui-state-active" );
14029
14030		if ( event && event.type === "keydown" ) {
14031			this._close();
14032		} else {
14033			this.timer = this._delay(function() {
14034				this._close();
14035			}, this.delay );
14036		}
14037
14038		nested = item.children( ".ui-menu" );
14039		if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
14040			this._startOpening(nested);
14041		}
14042		this.activeMenu = item.parent();
14043
14044		this._trigger( "focus", event, { item: item } );
14045	},
14046
14047	_scrollIntoView: function( item ) {
14048		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
14049		if ( this._hasScroll() ) {
14050			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
14051			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
14052			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
14053			scroll = this.activeMenu.scrollTop();
14054			elementHeight = this.activeMenu.height();
14055			itemHeight = item.height();
14056
14057			if ( offset < 0 ) {
14058				this.activeMenu.scrollTop( scroll + offset );
14059			} else if ( offset + itemHeight > elementHeight ) {
14060				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
14061			}
14062		}
14063	},
14064
14065	blur: function( event, fromFocus ) {
14066		if ( !fromFocus ) {
14067			clearTimeout( this.timer );
14068		}
14069
14070		if ( !this.active ) {
14071			return;
14072		}
14073
14074		this.active.children( "a" ).removeClass( "ui-state-focus" );
14075		this.active = null;
14076
14077		this._trigger( "blur", event, { item: this.active } );
14078	},
14079
14080	_startOpening: function( submenu ) {
14081		clearTimeout( this.timer );
14082
14083		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
14084		// shift in the submenu position when mousing over the carat icon
14085		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
14086			return;
14087		}
14088
14089		this.timer = this._delay(function() {
14090			this._close();
14091			this._open( submenu );
14092		}, this.delay );
14093	},
14094
14095	_open: function( submenu ) {
14096		var position = $.extend({
14097			of: this.active
14098		}, this.options.position );
14099
14100		clearTimeout( this.timer );
14101		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
14102			.hide()
14103			.attr( "aria-hidden", "true" );
14104
14105		submenu
14106			.show()
14107			.removeAttr( "aria-hidden" )
14108			.attr( "aria-expanded", "true" )
14109			.position( position );
14110	},
14111
14112	collapseAll: function( event, all ) {
14113		clearTimeout( this.timer );
14114		this.timer = this._delay(function() {
14115			// If we were passed an event, look for the submenu that contains the event
14116			var currentMenu = all ? this.element :
14117				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
14118
14119			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
14120			if ( !currentMenu.length ) {
14121				currentMenu = this.element;
14122			}
14123
14124			this._close( currentMenu );
14125
14126			this.blur( event );
14127			this.activeMenu = currentMenu;
14128		}, this.delay );
14129	},
14130
14131	// With no arguments, closes the currently active menu - if nothing is active
14132	// it closes all menus.  If passed an argument, it will search for menus BELOW
14133	_close: function( startMenu ) {
14134		if ( !startMenu ) {
14135			startMenu = this.active ? this.active.parent() : this.element;
14136		}
14137
14138		startMenu
14139			.find( ".ui-menu" )
14140				.hide()
14141				.attr( "aria-hidden", "true" )
14142				.attr( "aria-expanded", "false" )
14143			.end()
14144			.find( "a.ui-state-active" )
14145				.removeClass( "ui-state-active" );
14146	},
14147
14148	collapse: function( event ) {
14149		var newItem = this.active &&
14150			this.active.parent().closest( ".ui-menu-item", this.element );
14151		if ( newItem && newItem.length ) {
14152			this._close();
14153			this.focus( event, newItem );
14154		}
14155	},
14156
14157	expand: function( event ) {
14158		var newItem = this.active &&
14159			this.active
14160				.children( ".ui-menu " )
14161				.children( ".ui-menu-item" )
14162				.first();
14163
14164		if ( newItem && newItem.length ) {
14165			this._open( newItem.parent() );
14166
14167			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
14168			this._delay(function() {
14169				this.focus( event, newItem );
14170			});
14171		}
14172	},
14173
14174	next: function( event ) {
14175		this._move( "next", "first", event );
14176	},
14177
14178	previous: function( event ) {
14179		this._move( "prev", "last", event );
14180	},
14181
14182	isFirstItem: function() {
14183		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
14184	},
14185
14186	isLastItem: function() {
14187		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
14188	},
14189
14190	_move: function( direction, filter, event ) {
14191		var next;
14192		if ( this.active ) {
14193			if ( direction === "first" || direction === "last" ) {
14194				next = this.active
14195					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
14196					.eq( -1 );
14197			} else {
14198				next = this.active
14199					[ direction + "All" ]( ".ui-menu-item" )
14200					.eq( 0 );
14201			}
14202		}
14203		if ( !next || !next.length || !this.active ) {
14204			next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
14205		}
14206
14207		this.focus( event, next );
14208	},
14209
14210	nextPage: function( event ) {
14211		var item, base, height;
14212
14213		if ( !this.active ) {
14214			this.next( event );
14215			return;
14216		}
14217		if ( this.isLastItem() ) {
14218			return;
14219		}
14220		if ( this._hasScroll() ) {
14221			base = this.active.offset().top;
14222			height = this.element.height();
14223			this.active.nextAll( ".ui-menu-item" ).each(function() {
14224				item = $( this );
14225				return item.offset().top - base - height < 0;
14226			});
14227
14228			this.focus( event, item );
14229		} else {
14230			this.focus( event, this.activeMenu.children( ".ui-menu-item" )
14231				[ !this.active ? "first" : "last" ]() );
14232		}
14233	},
14234
14235	previousPage: function( event ) {
14236		var item, base, height;
14237		if ( !this.active ) {
14238			this.next( event );
14239			return;
14240		}
14241		if ( this.isFirstItem() ) {
14242			return;
14243		}
14244		if ( this._hasScroll() ) {
14245			base = this.active.offset().top;
14246			height = this.element.height();
14247			this.active.prevAll( ".ui-menu-item" ).each(function() {
14248				item = $( this );
14249				return item.offset().top - base + height > 0;
14250			});
14251
14252			this.focus( event, item );
14253		} else {
14254			this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
14255		}
14256	},
14257
14258	_hasScroll: function() {
14259		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
14260	},
14261
14262	select: function( event ) {
14263		// TODO: It should never be possible to not have an active item at this
14264		// point, but the tests don't trigger mouseenter before click.
14265		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
14266		var ui = { item: this.active };
14267		if ( !this.active.has( ".ui-menu" ).length ) {
14268			this.collapseAll( event, true );
14269		}
14270		this._trigger( "select", event, ui );
14271	}
14272});
14273
14274}( jQuery ));
14275
14276(function( $, undefined ) {
14277
14278$.ui = $.ui || {};
14279
14280var cachedScrollbarWidth,
14281	max = Math.max,
14282	abs = Math.abs,
14283	round = Math.round,
14284	rhorizontal = /left|center|right/,
14285	rvertical = /top|center|bottom/,
14286	roffset = /[\+\-]\d+%?/,
14287	rposition = /^\w+/,
14288	rpercent = /%$/,
14289	_position = $.fn.position;
14290
14291function getOffsets( offsets, width, height ) {
14292	return [
14293		parseInt( offsets[ 0 ], 10 ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
14294		parseInt( offsets[ 1 ], 10 ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
14295	];
14296}
14297function parseCss( element, property ) {
14298	return parseInt( $.css( element, property ), 10 ) || 0;
14299}
14300
14301$.position = {
14302	scrollbarWidth: function() {
14303		if ( cachedScrollbarWidth !== undefined ) {
14304			return cachedScrollbarWidth;
14305		}
14306		var w1, w2,
14307			div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
14308			innerDiv = div.children()[0];
14309
14310		$( "body" ).append( div );
14311		w1 = innerDiv.offsetWidth;
14312		div.css( "overflow", "scroll" );
14313
14314		w2 = innerDiv.offsetWidth;
14315
14316		if ( w1 === w2 ) {
14317			w2 = div[0].clientWidth;
14318		}
14319
14320		div.remove();
14321
14322		return (cachedScrollbarWidth = w1 - w2);
14323	},
14324	getScrollInfo: function( within ) {
14325		var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
14326			overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
14327			hasOverflowX = overflowX === "scroll" ||
14328				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
14329			hasOverflowY = overflowY === "scroll" ||
14330				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
14331		return {
14332			width: hasOverflowX ? $.position.scrollbarWidth() : 0,
14333			height: hasOverflowY ? $.position.scrollbarWidth() : 0
14334		};
14335	},
14336	getWithinInfo: function( element ) {
14337		var withinElement = $( element || window ),
14338			isWindow = $.isWindow( withinElement[0] );
14339		return {
14340			element: withinElement,
14341			isWindow: isWindow,
14342			offset: withinElement.offset() || { left: 0, top: 0 },
14343			scrollLeft: withinElement.scrollLeft(),
14344			scrollTop: withinElement.scrollTop(),
14345			width: isWindow ? withinElement.width() : withinElement.outerWidth(),
14346			height: isWindow ? withinElement.height() : withinElement.outerHeight()
14347		};
14348	}
14349};
14350
14351$.fn.position = function( options ) {
14352	if ( !options || !options.of ) {
14353		return _position.apply( this, arguments );
14354	}
14355
14356	// make a copy, we don't want to modify arguments
14357	options = $.extend( {}, options );
14358
14359	var atOffset, targetWidth, targetHeight, targetOffset, basePosition,
14360		target = $( options.of ),
14361		within = $.position.getWithinInfo( options.within ),
14362		scrollInfo = $.position.getScrollInfo( within ),
14363		targetElem = target[0],
14364		collision = ( options.collision || "flip" ).split( " " ),
14365		offsets = {};
14366
14367	if ( targetElem.nodeType === 9 ) {
14368		targetWidth = target.width();
14369		targetHeight = target.height();
14370		targetOffset = { top: 0, left: 0 };
14371	} else if ( $.isWindow( targetElem ) ) {
14372		targetWidth = target.width();
14373		targetHeight = target.height();
14374		targetOffset = { top: target.scrollTop(), left: target.scrollLeft() };
14375	} else if ( targetElem.preventDefault ) {
14376		// force left top to allow flipping
14377		options.at = "left top";
14378		targetWidth = targetHeight = 0;
14379		targetOffset = { top: targetElem.pageY, left: targetElem.pageX };
14380	} else {
14381		targetWidth = target.outerWidth();
14382		targetHeight = target.outerHeight();
14383		targetOffset = target.offset();
14384	}
14385	// clone to reuse original targetOffset later
14386	basePosition = $.extend( {}, targetOffset );
14387
14388	// force my and at to have valid horizontal and vertical positions
14389	// if a value is missing or invalid, it will be converted to center
14390	$.each( [ "my", "at" ], function() {
14391		var pos = ( options[ this ] || "" ).split( " " ),
14392			horizontalOffset,
14393			verticalOffset;
14394
14395		if ( pos.length === 1) {
14396			pos = rhorizontal.test( pos[ 0 ] ) ?
14397				pos.concat( [ "center" ] ) :
14398				rvertical.test( pos[ 0 ] ) ?
14399					[ "center" ].concat( pos ) :
14400					[ "center", "center" ];
14401		}
14402		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
14403		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
14404
14405		// calculate offsets
14406		horizontalOffset = roffset.exec( pos[ 0 ] );
14407		verticalOffset = roffset.exec( pos[ 1 ] );
14408		offsets[ this ] = [
14409			horizontalOffset ? horizontalOffset[ 0 ] : 0,
14410			verticalOffset ? verticalOffset[ 0 ] : 0
14411		];
14412
14413		// reduce to just the positions without the offsets
14414		options[ this ] = [
14415			rposition.exec( pos[ 0 ] )[ 0 ],
14416			rposition.exec( pos[ 1 ] )[ 0 ]
14417		];
14418	});
14419
14420	// normalize collision option
14421	if ( collision.length === 1 ) {
14422		collision[ 1 ] = collision[ 0 ];
14423	}
14424
14425	if ( options.at[ 0 ] === "right" ) {
14426		basePosition.left += targetWidth;
14427	} else if ( options.at[ 0 ] === "center" ) {
14428		basePosition.left += targetWidth / 2;
14429	}
14430
14431	if ( options.at[ 1 ] === "bottom" ) {
14432		basePosition.top += targetHeight;
14433	} else if ( options.at[ 1 ] === "center" ) {
14434		basePosition.top += targetHeight / 2;
14435	}
14436
14437	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
14438	basePosition.left += atOffset[ 0 ];
14439	basePosition.top += atOffset[ 1 ];
14440
14441	return this.each(function() {
14442		var collisionPosition, using,
14443			elem = $( this ),
14444			elemWidth = elem.outerWidth(),
14445			elemHeight = elem.outerHeight(),
14446			marginLeft = parseCss( this, "marginLeft" ),
14447			marginTop = parseCss( this, "marginTop" ),
14448			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
14449			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
14450			position = $.extend( {}, basePosition ),
14451			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
14452
14453		if ( options.my[ 0 ] === "right" ) {
14454			position.left -= elemWidth;
14455		} else if ( options.my[ 0 ] === "center" ) {
14456			position.left -= elemWidth / 2;
14457		}
14458
14459		if ( options.my[ 1 ] === "bottom" ) {
14460			position.top -= elemHeight;
14461		} else if ( options.my[ 1 ] === "center" ) {
14462			position.top -= elemHeight / 2;
14463		}
14464
14465		position.left += myOffset[ 0 ];
14466		position.top += myOffset[ 1 ];
14467
14468		// if the browser doesn't support fractions, then round for consistent results
14469		if ( !$.support.offsetFractions ) {
14470			position.left = round( position.left );
14471			position.top = round( position.top );
14472		}
14473
14474		collisionPosition = {
14475			marginLeft: marginLeft,
14476			marginTop: marginTop
14477		};
14478
14479		$.each( [ "left", "top" ], function( i, dir ) {
14480			if ( $.ui.position[ collision[ i ] ] ) {
14481				$.ui.position[ collision[ i ] ][ dir ]( position, {
14482					targetWidth: targetWidth,
14483					targetHeight: targetHeight,
14484					elemWidth: elemWidth,
14485					elemHeight: elemHeight,
14486					collisionPosition: collisionPosition,
14487					collisionWidth: collisionWidth,
14488					collisionHeight: collisionHeight,
14489					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
14490					my: options.my,
14491					at: options.at,
14492					within: within,
14493					elem : elem
14494				});
14495			}
14496		});
14497
14498		if ( $.fn.bgiframe ) {
14499			elem.bgiframe();
14500		}
14501
14502		if ( options.using ) {
14503			// adds feedback as second argument to using callback, if present
14504			using = function( props ) {
14505				var left = targetOffset.left - position.left,
14506					right = left + targetWidth - elemWidth,
14507					top = targetOffset.top - position.top,
14508					bottom = top + targetHeight - elemHeight,
14509					feedback = {
14510						target: {
14511							element: target,
14512							left: targetOffset.left,
14513							top: targetOffset.top,
14514							width: targetWidth,
14515							height: targetHeight
14516						},
14517						element: {
14518							element: elem,
14519							left: position.left,
14520							top: position.top,
14521							width: elemWidth,
14522							height: elemHeight
14523						},
14524						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
14525						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
14526					};
14527				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
14528					feedback.horizontal = "center";
14529				}
14530				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
14531					feedback.vertical = "middle";
14532				}
14533				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
14534					feedback.important = "horizontal";
14535				} else {
14536					feedback.important = "vertical";
14537				}
14538				options.using.call( this, props, feedback );
14539			};
14540		}
14541
14542		elem.offset( $.extend( position, { using: using } ) );
14543	});
14544};
14545
14546$.ui.position = {
14547	fit: {
14548		left: function( position, data ) {
14549			var within = data.within,
14550				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
14551				outerWidth = within.width,
14552				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
14553				overLeft = withinOffset - collisionPosLeft,
14554				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
14555				newOverRight;
14556
14557			// element is wider than within
14558			if ( data.collisionWidth > outerWidth ) {
14559				// element is initially over the left side of within
14560				if ( overLeft > 0 && overRight <= 0 ) {
14561					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
14562					position.left += overLeft - newOverRight;
14563				// element is initially over right side of within
14564				} else if ( overRight > 0 && overLeft <= 0 ) {
14565					position.left = withinOffset;
14566				// element is initially over both left and right sides of within
14567				} else {
14568					if ( overLeft > overRight ) {
14569						position.left = withinOffset + outerWidth - data.collisionWidth;
14570					} else {
14571						position.left = withinOffset;
14572					}
14573				}
14574			// too far left -> align with left edge
14575			} else if ( overLeft > 0 ) {
14576				position.left += overLeft;
14577			// too far right -> align with right edge
14578			} else if ( overRight > 0 ) {
14579				position.left -= overRight;
14580			// adjust based on position and margin
14581			} else {
14582				position.left = max( position.left - collisionPosLeft, position.left );
14583			}
14584		},
14585		top: function( position, data ) {
14586			var within = data.within,
14587				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
14588				outerHeight = data.within.height,
14589				collisionPosTop = position.top - data.collisionPosition.marginTop,
14590				overTop = withinOffset - collisionPosTop,
14591				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
14592				newOverBottom;
14593
14594			// element is taller than within
14595			if ( data.collisionHeight > outerHeight ) {
14596				// element is initially over the top of within
14597				if ( overTop > 0 && overBottom <= 0 ) {
14598					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
14599					position.top += overTop - newOverBottom;
14600				// element is initially over bottom of within
14601				} else if ( overBottom > 0 && overTop <= 0 ) {
14602					position.top = withinOffset;
14603				// element is initially over both top and bottom of within
14604				} else {
14605					if ( overTop > overBottom ) {
14606						position.top = withinOffset + outerHeight - data.collisionHeight;
14607					} else {
14608						position.top = withinOffset;
14609					}
14610				}
14611			// too far up -> align with top
14612			} else if ( overTop > 0 ) {
14613				position.top += overTop;
14614			// too far down -> align with bottom edge
14615			} else if ( overBottom > 0 ) {
14616				position.top -= overBottom;
14617			// adjust based on position and margin
14618			} else {
14619				position.top = max( position.top - collisionPosTop, position.top );
14620			}
14621		}
14622	},
14623	flip: {
14624		left: function( position, data ) {
14625			var within = data.within,
14626				withinOffset = within.offset.left + within.scrollLeft,
14627				outerWidth = within.width,
14628				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
14629				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
14630				overLeft = collisionPosLeft - offsetLeft,
14631				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
14632				myOffset = data.my[ 0 ] === "left" ?
14633					-data.elemWidth :
14634					data.my[ 0 ] === "right" ?
14635						data.elemWidth :
14636						0,
14637				atOffset = data.at[ 0 ] === "left" ?
14638					data.targetWidth :
14639					data.at[ 0 ] === "right" ?
14640						-data.targetWidth :
14641						0,
14642				offset = -2 * data.offset[ 0 ],
14643				newOverRight,
14644				newOverLeft;
14645
14646			if ( overLeft < 0 ) {
14647				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
14648				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
14649					position.left += myOffset + atOffset + offset;
14650				}
14651			}
14652			else if ( overRight > 0 ) {
14653				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
14654				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
14655					position.left += myOffset + atOffset + offset;
14656				}
14657			}
14658		},
14659		top: function( position, data ) {
14660			var within = data.within,
14661				withinOffset = within.offset.top + within.scrollTop,
14662				outerHeight = within.height,
14663				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
14664				collisionPosTop = position.top - data.collisionPosition.marginTop,
14665				overTop = collisionPosTop - offsetTop,
14666				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
14667				top = data.my[ 1 ] === "top",
14668				myOffset = top ?
14669					-data.elemHeight :
14670					data.my[ 1 ] === "bottom" ?
14671						data.elemHeight :
14672						0,
14673				atOffset = data.at[ 1 ] === "top" ?
14674					data.targetHeight :
14675					data.at[ 1 ] === "bottom" ?
14676						-data.targetHeight :
14677						0,
14678				offset = -2 * data.offset[ 1 ],
14679				newOverTop,
14680				newOverBottom;
14681			if ( overTop < 0 ) {
14682				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
14683				if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
14684					position.top += myOffset + atOffset + offset;
14685				}
14686			}
14687			else if ( overBottom > 0 ) {
14688				newOverTop = position.top -  data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
14689				if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
14690					position.top += myOffset + atOffset + offset;
14691				}
14692			}
14693		}
14694	},
14695	flipfit: {
14696		left: function() {
14697			$.ui.position.flip.left.apply( this, arguments );
14698			$.ui.position.fit.left.apply( this, arguments );
14699		},
14700		top: function() {
14701			$.ui.position.flip.top.apply( this, arguments );
14702			$.ui.position.fit.top.apply( this, arguments );
14703		}
14704	}
14705};
14706
14707// fraction support test
14708(function () {
14709	var testElement, testElementParent, testElementStyle, offsetLeft, i,
14710		body = document.getElementsByTagName( "body" )[ 0 ],
14711		div = document.createElement( "div" );
14712
14713	//Create a "fake body" for testing based on method used in jQuery.support
14714	testElement = document.createElement( body ? "div" : "body" );
14715	testElementStyle = {
14716		visibility: "hidden",
14717		width: 0,
14718		height: 0,
14719		border: 0,
14720		margin: 0,
14721		background: "none"
14722	};
14723	if ( body ) {
14724		$.extend( testElementStyle, {
14725			position: "absolute",
14726			left: "-1000px",
14727			top: "-1000px"
14728		});
14729	}
14730	for ( i in testElementStyle ) {
14731		testElement.style[ i ] = testElementStyle[ i ];
14732	}
14733	testElement.appendChild( div );
14734	testElementParent = body || document.documentElement;
14735	testElementParent.insertBefore( testElement, testElementParent.firstChild );
14736
14737	div.style.cssText = "position: absolute; left: 10.7432222px;";
14738
14739	offsetLeft = $( div ).offset().left;
14740	$.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
14741
14742	testElement.innerHTML = "";
14743	testElementParent.removeChild( testElement );
14744})();
14745
14746// DEPRECATED
14747if ( $.uiBackCompat !== false ) {
14748	// offset option
14749	(function( $ ) {
14750		var _position = $.fn.position;
14751		$.fn.position = function( options ) {
14752			if ( !options || !options.offset ) {
14753				return _position.call( this, options );
14754			}
14755			var offset = options.offset.split( " " ),
14756				at = options.at.split( " " );
14757			if ( offset.length === 1 ) {
14758				offset[ 1 ] = offset[ 0 ];
14759			}
14760			if ( /^\d/.test( offset[ 0 ] ) ) {
14761				offset[ 0 ] = "+" + offset[ 0 ];
14762			}
14763			if ( /^\d/.test( offset[ 1 ] ) ) {
14764				offset[ 1 ] = "+" + offset[ 1 ];
14765			}
14766			if ( at.length === 1 ) {
14767				if ( /left|center|right/.test( at[ 0 ] ) ) {
14768					at[ 1 ] = "center";
14769				} else {
14770					at[ 1 ] = at[ 0 ];
14771					at[ 0 ] = "center";
14772				}
14773			}
14774			return _position.call( this, $.extend( options, {
14775				at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
14776				offset: undefined
14777			} ) );
14778		};
14779	}( jQuery ) );
14780}
14781
14782}( jQuery ) );
14783
14784(function( $, undefined ) {
14785
14786$.widget( "ui.progressbar", {
14787	version: "1.9.1",
14788	options: {
14789		value: 0,
14790		max: 100
14791	},
14792
14793	min: 0,
14794
14795	_create: function() {
14796		this.element
14797			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
14798			.attr({
14799				role: "progressbar",
14800				"aria-valuemin": this.min,
14801				"aria-valuemax": this.options.max,
14802				"aria-valuenow": this._value()
14803			});
14804
14805		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
14806			.appendTo( this.element );
14807
14808		this.oldValue = this._value();
14809		this._refreshValue();
14810	},
14811
14812	_destroy: function() {
14813		this.element
14814			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
14815			.removeAttr( "role" )
14816			.removeAttr( "aria-valuemin" )
14817			.removeAttr( "aria-valuemax" )
14818			.removeAttr( "aria-valuenow" );
14819
14820		this.valueDiv.remove();
14821	},
14822
14823	value: function( newValue ) {
14824		if ( newValue === undefined ) {
14825			return this._value();
14826		}
14827
14828		this._setOption( "value", newValue );
14829		return this;
14830	},
14831
14832	_setOption: function( key, value ) {
14833		if ( key === "value" ) {
14834			this.options.value = value;
14835			this._refreshValue();
14836			if ( this._value() === this.options.max ) {
14837				this._trigger( "complete" );
14838			}
14839		}
14840
14841		this._super( key, value );
14842	},
14843
14844	_value: function() {
14845		var val = this.options.value;
14846		// normalize invalid value
14847		if ( typeof val !== "number" ) {
14848			val = 0;
14849		}
14850		return Math.min( this.options.max, Math.max( this.min, val ) );
14851	},
14852
14853	_percentage: function() {
14854		return 100 * this._value() / this.options.max;
14855	},
14856
14857	_refreshValue: function() {
14858		var value = this.value(),
14859			percentage = this._percentage();
14860
14861		if ( this.oldValue !== value ) {
14862			this.oldValue = value;
14863			this._trigger( "change" );
14864		}
14865
14866		this.valueDiv
14867			.toggle( value > this.min )
14868			.toggleClass( "ui-corner-right", value === this.options.max )
14869			.width( percentage.toFixed(0) + "%" );
14870		this.element.attr( "aria-valuenow", value );
14871	}
14872});
14873
14874})( jQuery );
14875
14876(function( $, undefined ) {
14877
14878// number of pages in a slider
14879// (how many times can you page up/down to go through the whole range)
14880var numPages = 5;
14881
14882$.widget( "ui.slider", $.ui.mouse, {
14883	version: "1.9.1",
14884	widgetEventPrefix: "slide",
14885
14886	options: {
14887		animate: false,
14888		distance: 0,
14889		max: 100,
14890		min: 0,
14891		orientation: "horizontal",
14892		range: false,
14893		step: 1,
14894		value: 0,
14895		values: null
14896	},
14897
14898	_create: function() {
14899		var i, handleCount,
14900			o = this.options,
14901			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
14902			handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
14903			handles = [];
14904
14905		this._keySliding = false;
14906		this._mouseSliding = false;
14907		this._animateOff = true;
14908		this._handleIndex = null;
14909		this._detectOrientation();
14910		this._mouseInit();
14911
14912		this.element
14913			.addClass( "ui-slider" +
14914				" ui-slider-" + this.orientation +
14915				" ui-widget" +
14916				" ui-widget-content" +
14917				" ui-corner-all" +
14918				( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
14919
14920		this.range = $([]);
14921
14922		if ( o.range ) {
14923			if ( o.range === true ) {
14924				if ( !o.values ) {
14925					o.values = [ this._valueMin(), this._valueMin() ];
14926				}
14927				if ( o.values.length && o.values.length !== 2 ) {
14928					o.values = [ o.values[0], o.values[0] ];
14929				}
14930			}
14931
14932			this.range = $( "<div></div>" )
14933				.appendTo( this.element )
14934				.addClass( "ui-slider-range" +
14935				// note: this isn't the most fittingly semantic framework class for this element,
14936				// but worked best visually with a variety of themes
14937				" ui-widget-header" +
14938				( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
14939		}
14940
14941		handleCount = ( o.values && o.values.length ) || 1;
14942
14943		for ( i = existingHandles.length; i < handleCount; i++ ) {
14944			handles.push( handle );
14945		}
14946
14947		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14948
14949		this.handle = this.handles.eq( 0 );
14950
14951		this.handles.add( this.range ).filter( "a" )
14952			.click(function( event ) {
14953				event.preventDefault();
14954			})
14955			.mouseenter(function() {
14956				if ( !o.disabled ) {
14957					$( this ).addClass( "ui-state-hover" );
14958				}
14959			})
14960			.mouseleave(function() {
14961				$( this ).removeClass( "ui-state-hover" );
14962			})
14963			.focus(function() {
14964				if ( !o.disabled ) {
14965					$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
14966					$( this ).addClass( "ui-state-focus" );
14967				} else {
14968					$( this ).blur();
14969				}
14970			})
14971			.blur(function() {
14972				$( this ).removeClass( "ui-state-focus" );
14973			});
14974
14975		this.handles.each(function( i ) {
14976			$( this ).data( "ui-slider-handle-index", i );
14977		});
14978
14979		this._on( this.handles, {
14980			keydown: function( event ) {
14981				var allowed, curVal, newVal, step,
14982					index = $( event.target ).data( "ui-slider-handle-index" );
14983
14984				switch ( event.keyCode ) {
14985					case $.ui.keyCode.HOME:
14986					case $.ui.keyCode.END:
14987					case $.ui.keyCode.PAGE_UP:
14988					case $.ui.keyCode.PAGE_DOWN:
14989					case $.ui.keyCode.UP:
14990					case $.ui.keyCode.RIGHT:
14991					case $.ui.keyCode.DOWN:
14992					case $.ui.keyCode.LEFT:
14993						event.preventDefault();
14994						if ( !this._keySliding ) {
14995							this._keySliding = true;
14996							$( event.target ).addClass( "ui-state-active" );
14997							allowed = this._start( event, index );
14998							if ( allowed === false ) {
14999								return;
15000							}
15001						}
15002						break;
15003				}
15004
15005				step = this.options.step;
15006				if ( this.options.values && this.options.values.length ) {
15007					curVal = newVal = this.values( index );
15008				} else {
15009					curVal = newVal = this.value();
15010				}
15011
15012				switch ( event.keyCode ) {
15013					case $.ui.keyCode.HOME:
15014						newVal = this._valueMin();
15015						break;
15016					case $.ui.keyCode.END:
15017						newVal = this._valueMax();
15018						break;
15019					case $.ui.keyCode.PAGE_UP:
15020						newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
15021						break;
15022					case $.ui.keyCode.PAGE_DOWN:
15023						newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
15024						break;
15025					case $.ui.keyCode.UP:
15026					case $.ui.keyCode.RIGHT:
15027						if ( curVal === this._valueMax() ) {
15028							return;
15029						}
15030						newVal = this._trimAlignValue( curVal + step );
15031						break;
15032					case $.ui.keyCode.DOWN:
15033					case $.ui.keyCode.LEFT:
15034						if ( curVal === this._valueMin() ) {
15035							return;
15036						}
15037						newVal = this._trimAlignValue( curVal - step );
15038						break;
15039				}
15040
15041				this._slide( event, index, newVal );
15042			},
15043			keyup: function( event ) {
15044				var index = $( event.target ).data( "ui-slider-handle-index" );
15045
15046				if ( this._keySliding ) {
15047					this._keySliding = false;
vendor: 21,330 bytes, lines 15048-15844
15048					this._stop( event, index );
15049					this._change( event, index );
15050					$( event.target ).removeClass( "ui-state-active" );
15051				}
15052			}
15053		});
15054
15055		this._refreshValue();
15056
15057		this._animateOff = false;
15058	},
15059
15060	_destroy: function() {
15061		this.handles.remove();
15062		this.range.remove();
15063
15064		this.element
15065			.removeClass( "ui-slider" +
15066				" ui-slider-horizontal" +
15067				" ui-slider-vertical" +
15068				" ui-slider-disabled" +
15069				" ui-widget" +
15070				" ui-widget-content" +
15071				" ui-corner-all" );
15072
15073		this._mouseDestroy();
15074	},
15075
15076	_mouseCapture: function( event ) {
15077		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
15078			that = this,
15079			o = this.options;
15080
15081		if ( o.disabled ) {
15082			return false;
15083		}
15084
15085		this.elementSize = {
15086			width: this.element.outerWidth(),
15087			height: this.element.outerHeight()
15088		};
15089		this.elementOffset = this.element.offset();
15090
15091		position = { x: event.pageX, y: event.pageY };
15092		normValue = this._normValueFromMouse( position );
15093		distance = this._valueMax() - this._valueMin() + 1;
15094		this.handles.each(function( i ) {
15095			var thisDistance = Math.abs( normValue - that.values(i) );
15096			if ( distance > thisDistance ) {
15097				distance = thisDistance;
15098				closestHandle = $( this );
15099				index = i;
15100			}
15101		});
15102
15103		// workaround for bug #3736 (if both handles of a range are at 0,
15104		// the first is always used as the one with least distance,
15105		// and moving it is obviously prevented by preventing negative ranges)
15106		if( o.range === true && this.values(1) === o.min ) {
15107			index += 1;
15108			closestHandle = $( this.handles[index] );
15109		}
15110
15111		allowed = this._start( event, index );
15112		if ( allowed === false ) {
15113			return false;
15114		}
15115		this._mouseSliding = true;
15116
15117		this._handleIndex = index;
15118
15119		closestHandle
15120			.addClass( "ui-state-active" )
15121			.focus();
15122
15123		offset = closestHandle.offset();
15124		mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
15125		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
15126			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
15127			top: event.pageY - offset.top -
15128				( closestHandle.height() / 2 ) -
15129				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
15130				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
15131				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
15132		};
15133
15134		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
15135			this._slide( event, index, normValue );
15136		}
15137		this._animateOff = true;
15138		return true;
15139	},
15140
15141	_mouseStart: function() {
15142		return true;
15143	},
15144
15145	_mouseDrag: function( event ) {
15146		var position = { x: event.pageX, y: event.pageY },
15147			normValue = this._normValueFromMouse( position );
15148
15149		this._slide( event, this._handleIndex, normValue );
15150
15151		return false;
15152	},
15153
15154	_mouseStop: function( event ) {
15155		this.handles.removeClass( "ui-state-active" );
15156		this._mouseSliding = false;
15157
15158		this._stop( event, this._handleIndex );
15159		this._change( event, this._handleIndex );
15160
15161		this._handleIndex = null;
15162		this._clickOffset = null;
15163		this._animateOff = false;
15164
15165		return false;
15166	},
15167
15168	_detectOrientation: function() {
15169		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
15170	},
15171
15172	_normValueFromMouse: function( position ) {
15173		var pixelTotal,
15174			pixelMouse,
15175			percentMouse,
15176			valueTotal,
15177			valueMouse;
15178
15179		if ( this.orientation === "horizontal" ) {
15180			pixelTotal = this.elementSize.width;
15181			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
15182		} else {
15183			pixelTotal = this.elementSize.height;
15184			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
15185		}
15186
15187		percentMouse = ( pixelMouse / pixelTotal );
15188		if ( percentMouse > 1 ) {
15189			percentMouse = 1;
15190		}
15191		if ( percentMouse < 0 ) {
15192			percentMouse = 0;
15193		}
15194		if ( this.orientation === "vertical" ) {
15195			percentMouse = 1 - percentMouse;
15196		}
15197
15198		valueTotal = this._valueMax() - this._valueMin();
15199		valueMouse = this._valueMin() + percentMouse * valueTotal;
15200
15201		return this._trimAlignValue( valueMouse );
15202	},
15203
15204	_start: function( event, index ) {
15205		var uiHash = {
15206			handle: this.handles[ index ],
15207			value: this.value()
15208		};
15209		if ( this.options.values && this.options.values.length ) {
15210			uiHash.value = this.values( index );
15211			uiHash.values = this.values();
15212		}
15213		return this._trigger( "start", event, uiHash );
15214	},
15215
15216	_slide: function( event, index, newVal ) {
15217		var otherVal,
15218			newValues,
15219			allowed;
15220
15221		if ( this.options.values && this.options.values.length ) {
15222			otherVal = this.values( index ? 0 : 1 );
15223
15224			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
15225					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
15226				) {
15227				newVal = otherVal;
15228			}
15229
15230			if ( newVal !== this.values( index ) ) {
15231				newValues = this.values();
15232				newValues[ index ] = newVal;
15233				// A slide can be canceled by returning false from the slide callback
15234				allowed = this._trigger( "slide", event, {
15235					handle: this.handles[ index ],
15236					value: newVal,
15237					values: newValues
15238				} );
15239				otherVal = this.values( index ? 0 : 1 );
15240				if ( allowed !== false ) {
15241					this.values( index, newVal, true );
15242				}
15243			}
15244		} else {
15245			if ( newVal !== this.value() ) {
15246				// A slide can be canceled by returning false from the slide callback
15247				allowed = this._trigger( "slide", event, {
15248					handle: this.handles[ index ],
15249					value: newVal
15250				} );
15251				if ( allowed !== false ) {
15252					this.value( newVal );
15253				}
15254			}
15255		}
15256	},
15257
15258	_stop: function( event, index ) {
15259		var uiHash = {
15260			handle: this.handles[ index ],
15261			value: this.value()
15262		};
15263		if ( this.options.values && this.options.values.length ) {
15264			uiHash.value = this.values( index );
15265			uiHash.values = this.values();
15266		}
15267
15268		this._trigger( "stop", event, uiHash );
15269	},
15270
15271	_change: function( event, index ) {
15272		if ( !this._keySliding && !this._mouseSliding ) {
15273			var uiHash = {
15274				handle: this.handles[ index ],
15275				value: this.value()
15276			};
15277			if ( this.options.values && this.options.values.length ) {
15278				uiHash.value = this.values( index );
15279				uiHash.values = this.values();
15280			}
15281
15282			this._trigger( "change", event, uiHash );
15283		}
15284	},
15285
15286	value: function( newValue ) {
15287		if ( arguments.length ) {
15288			this.options.value = this._trimAlignValue( newValue );
15289			this._refreshValue();
15290			this._change( null, 0 );
15291			return;
15292		}
15293
15294		return this._value();
15295	},
15296
15297	values: function( index, newValue ) {
15298		var vals,
15299			newValues,
15300			i;
15301
15302		if ( arguments.length > 1 ) {
15303			this.options.values[ index ] = this._trimAlignValue( newValue );
15304			this._refreshValue();
15305			this._change( null, index );
15306			return;
15307		}
15308
15309		if ( arguments.length ) {
15310			if ( $.isArray( arguments[ 0 ] ) ) {
15311				vals = this.options.values;
15312				newValues = arguments[ 0 ];
15313				for ( i = 0; i < vals.length; i += 1 ) {
15314					vals[ i ] = this._trimAlignValue( newValues[ i ] );
15315					this._change( null, i );
15316				}
15317				this._refreshValue();
15318			} else {
15319				if ( this.options.values && this.options.values.length ) {
15320					return this._values( index );
15321				} else {
15322					return this.value();
15323				}
15324			}
15325		} else {
15326			return this._values();
15327		}
15328	},
15329
15330	_setOption: function( key, value ) {
15331		var i,
15332			valsLength = 0;
15333
15334		if ( $.isArray( this.options.values ) ) {
15335			valsLength = this.options.values.length;
15336		}
15337
15338		$.Widget.prototype._setOption.apply( this, arguments );
15339
15340		switch ( key ) {
15341			case "disabled":
15342				if ( value ) {
15343					this.handles.filter( ".ui-state-focus" ).blur();
15344					this.handles.removeClass( "ui-state-hover" );
15345					this.handles.prop( "disabled", true );
15346					this.element.addClass( "ui-disabled" );
15347				} else {
15348					this.handles.prop( "disabled", false );
15349					this.element.removeClass( "ui-disabled" );
15350				}
15351				break;
15352			case "orientation":
15353				this._detectOrientation();
15354				this.element
15355					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
15356					.addClass( "ui-slider-" + this.orientation );
15357				this._refreshValue();
15358				break;
15359			case "value":
15360				this._animateOff = true;
15361				this._refreshValue();
15362				this._change( null, 0 );
15363				this._animateOff = false;
15364				break;
15365			case "values":
15366				this._animateOff = true;
15367				this._refreshValue();
15368				for ( i = 0; i < valsLength; i += 1 ) {
15369					this._change( null, i );
15370				}
15371				this._animateOff = false;
15372				break;
15373			case "min":
15374			case "max":
15375				this._animateOff = true;
15376				this._refreshValue();
15377				this._animateOff = false;
15378				break;
15379		}
15380	},
15381
15382	//internal value getter
15383	// _value() returns value trimmed by min and max, aligned by step
15384	_value: function() {
15385		var val = this.options.value;
15386		val = this._trimAlignValue( val );
15387
15388		return val;
15389	},
15390
15391	//internal values getter
15392	// _values() returns array of values trimmed by min and max, aligned by step
15393	// _values( index ) returns single value trimmed by min and max, aligned by step
15394	_values: function( index ) {
15395		var val,
15396			vals,
15397			i;
15398
15399		if ( arguments.length ) {
15400			val = this.options.values[ index ];
15401			val = this._trimAlignValue( val );
15402
15403			return val;
15404		} else {
15405			// .slice() creates a copy of the array
15406			// this copy gets trimmed by min and max and then returned
15407			vals = this.options.values.slice();
15408			for ( i = 0; i < vals.length; i+= 1) {
15409				vals[ i ] = this._trimAlignValue( vals[ i ] );
15410			}
15411
15412			return vals;
15413		}
15414	},
15415
15416	// returns the step-aligned value that val is closest to, between (inclusive) min and max
15417	_trimAlignValue: function( val ) {
15418		if ( val <= this._valueMin() ) {
15419			return this._valueMin();
15420		}
15421		if ( val >= this._valueMax() ) {
15422			return this._valueMax();
15423		}
15424		var step = ( this.options.step > 0 ) ? this.options.step : 1,
15425			valModStep = (val - this._valueMin()) % step,
15426			alignValue = val - valModStep;
15427
15428		if ( Math.abs(valModStep) * 2 >= step ) {
15429			alignValue += ( valModStep > 0 ) ? step : ( -step );
15430		}
15431
15432		// Since JavaScript has problems with large floats, round
15433		// the final value to 5 digits after the decimal point (see #4124)
15434		return parseFloat( alignValue.toFixed(5) );
15435	},
15436
15437	_valueMin: function() {
15438		return this.options.min;
15439	},
15440
15441	_valueMax: function() {
15442		return this.options.max;
15443	},
15444
15445	_refreshValue: function() {
15446		var lastValPercent, valPercent, value, valueMin, valueMax,
15447			oRange = this.options.range,
15448			o = this.options,
15449			that = this,
15450			animate = ( !this._animateOff ) ? o.animate : false,
15451			_set = {};
15452
15453		if ( this.options.values && this.options.values.length ) {
15454			this.handles.each(function( i ) {
15455				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
15456				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15457				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15458				if ( that.options.range === true ) {
15459					if ( that.orientation === "horizontal" ) {
15460						if ( i === 0 ) {
15461							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
15462						}
15463						if ( i === 1 ) {
15464							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
15465						}
15466					} else {
15467						if ( i === 0 ) {
15468							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
15469						}
15470						if ( i === 1 ) {
15471							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
15472						}
15473					}
15474				}
15475				lastValPercent = valPercent;
15476			});
15477		} else {
15478			value = this.value();
15479			valueMin = this._valueMin();
15480			valueMax = this._valueMax();
15481			valPercent = ( valueMax !== valueMin ) ?
15482					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15483					0;
15484			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15485			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15486
15487			if ( oRange === "min" && this.orientation === "horizontal" ) {
15488				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
15489			}
15490			if ( oRange === "max" && this.orientation === "horizontal" ) {
15491				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
15492			}
15493			if ( oRange === "min" && this.orientation === "vertical" ) {
15494				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
15495			}
15496			if ( oRange === "max" && this.orientation === "vertical" ) {
15497				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
15498			}
15499		}
15500	}
15501
15502});
15503
15504}(jQuery));
15505
15506(function( $ ) {
15507
15508function modifier( fn ) {
15509	return function() {
15510		var previous = this.element.val();
15511		fn.apply( this, arguments );
15512		this._refresh();
15513		if ( previous !== this.element.val() ) {
15514			this._trigger( "change" );
15515		}
15516	};
15517}
15518
15519$.widget( "ui.spinner", {
15520	version: "1.9.1",
15521	defaultElement: "<input>",
15522	widgetEventPrefix: "spin",
15523	options: {
15524		culture: null,
15525		icons: {
15526			down: "ui-icon-triangle-1-s",
15527			up: "ui-icon-triangle-1-n"
15528		},
15529		incremental: true,
15530		max: null,
15531		min: null,
15532		numberFormat: null,
15533		page: 10,
15534		step: 1,
15535
15536		change: null,
15537		spin: null,
15538		start: null,
15539		stop: null
15540	},
15541
15542	_create: function() {
15543		// handle string values that need to be parsed
15544		this._setOption( "max", this.options.max );
15545		this._setOption( "min", this.options.min );
15546		this._setOption( "step", this.options.step );
15547
15548		// format the value, but don't constrain
15549		this._value( this.element.val(), true );
15550
15551		this._draw();
15552		this._on( this._events );
15553		this._refresh();
15554
15555		// turning off autocomplete prevents the browser from remembering the
15556		// value when navigating through history, so we re-enable autocomplete
15557		// if the page is unloaded before the widget is destroyed. #7790
15558		this._on( this.window, {
15559			beforeunload: function() {
15560				this.element.removeAttr( "autocomplete" );
15561			}
15562		});
15563	},
15564
15565	_getCreateOptions: function() {
15566		var options = {},
15567			element = this.element;
15568
15569		$.each( [ "min", "max", "step" ], function( i, option ) {
15570			var value = element.attr( option );
15571			if ( value !== undefined && value.length ) {
15572				options[ option ] = value;
15573			}
15574		});
15575
15576		return options;
15577	},
15578
15579	_events: {
15580		keydown: function( event ) {
15581			if ( this._start( event ) && this._keydown( event ) ) {
15582				event.preventDefault();
15583			}
15584		},
15585		keyup: "_stop",
15586		focus: function() {
15587			this.previous = this.element.val();
15588		},
15589		blur: function( event ) {
15590			if ( this.cancelBlur ) {
15591				delete this.cancelBlur;
15592				return;
15593			}
15594
15595			this._refresh();
15596			if ( this.previous !== this.element.val() ) {
15597				this._trigger( "change", event );
15598			}
15599		},
15600		mousewheel: function( event, delta ) {
15601			if ( !delta ) {
15602				return;
15603			}
15604			if ( !this.spinning && !this._start( event ) ) {
15605				return false;
15606			}
15607
15608			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
15609			clearTimeout( this.mousewheelTimer );
15610			this.mousewheelTimer = this._delay(function() {
15611				if ( this.spinning ) {
15612					this._stop( event );
15613				}
15614			}, 100 );
15615			event.preventDefault();
15616		},
15617		"mousedown .ui-spinner-button": function( event ) {
15618			var previous;
15619
15620			// We never want the buttons to have focus; whenever the user is
15621			// interacting with the spinner, the focus should be on the input.
15622			// If the input is focused then this.previous is properly set from
15623			// when the input first received focus. If the input is not focused
15624			// then we need to set this.previous based on the value before spinning.
15625			previous = this.element[0] === this.document[0].activeElement ?
15626				this.previous : this.element.val();
15627			function checkFocus() {
15628				var isActive = this.element[0] === this.document[0].activeElement;
15629				if ( !isActive ) {
15630					this.element.focus();
15631					this.previous = previous;
15632					// support: IE
15633					// IE sets focus asynchronously, so we need to check if focus
15634					// moved off of the input because the user clicked on the button.
15635					this._delay(function() {
15636						this.previous = previous;
15637					});
15638				}
15639			}
15640
15641			// ensure focus is on (or stays on) the text field
15642			event.preventDefault();
15643			checkFocus.call( this );
15644
15645			// support: IE
15646			// IE doesn't prevent moving focus even with event.preventDefault()
15647			// so we set a flag to know when we should ignore the blur event
15648			// and check (again) if focus moved off of the input.
15649			this.cancelBlur = true;
15650			this._delay(function() {
15651				delete this.cancelBlur;
15652				checkFocus.call( this );
15653			});
15654
15655			if ( this._start( event ) === false ) {
15656				return;
15657			}
15658
15659			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
15660		},
15661		"mouseup .ui-spinner-button": "_stop",
15662		"mouseenter .ui-spinner-button": function( event ) {
15663			// button will add ui-state-active if mouse was down while mouseleave and kept down
15664			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
15665				return;
15666			}
15667
15668			if ( this._start( event ) === false ) {
15669				return false;
15670			}
15671			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
15672		},
15673		// TODO: do we really want to consider this a stop?
15674		// shouldn't we just stop the repeater and wait until mouseup before
15675		// we trigger the stop event?
15676		"mouseleave .ui-spinner-button": "_stop"
15677	},
15678
15679	_draw: function() {
15680		var uiSpinner = this.uiSpinner = this.element
15681			.addClass( "ui-spinner-input" )
15682			.attr( "autocomplete", "off" )
15683			.wrap( this._uiSpinnerHtml() )
15684			.parent()
15685				// add buttons
15686				.append( this._buttonHtml() );
15687
15688		this.element.attr( "role", "spinbutton" );
15689
15690		// button bindings
15691		this.buttons = uiSpinner.find( ".ui-spinner-button" )
15692			.attr( "tabIndex", -1 )
15693			.button()
15694			.removeClass( "ui-corner-all" );
15695
15696		// IE 6 doesn't understand height: 50% for the buttons
15697		// unless the wrapper has an explicit height
15698		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
15699				uiSpinner.height() > 0 ) {
15700			uiSpinner.height( uiSpinner.height() );
15701		}
15702
15703		// disable spinner if element was already disabled
15704		if ( this.options.disabled ) {
15705			this.disable();
15706		}
15707	},
15708
15709	_keydown: function( event ) {
15710		var options = this.options,
15711			keyCode = $.ui.keyCode;
15712
15713		switch ( event.keyCode ) {
15714		case keyCode.UP:
15715			this._repeat( null, 1, event );
15716			return true;
15717		case keyCode.DOWN:
15718			this._repeat( null, -1, event );
15719			return true;
15720		case keyCode.PAGE_UP:
15721			this._repeat( null, options.page, event );
15722			return true;
15723		case keyCode.PAGE_DOWN:
15724			this._repeat( null, -options.page, event );
15725			return true;
15726		}
15727
15728		return false;
15729	},
15730
15731	_uiSpinnerHtml: function() {
15732		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15733	},
15734
15735	_buttonHtml: function() {
15736		return "" +
15737			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15738				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15739			"</a>" +
15740			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15741				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15742			"</a>";
15743	},
15744
15745	_start: function( event ) {
15746		if ( !this.spinning && this._trigger( "start", event ) === false ) {
15747			return false;
15748		}
15749
15750		if ( !this.counter ) {
15751			this.counter = 1;
15752		}
15753		this.spinning = true;
15754		return true;
15755	},
15756
15757	_repeat: function( i, steps, event ) {
15758		i = i || 500;
15759
15760		clearTimeout( this.timer );
15761		this.timer = this._delay(function() {
15762			this._repeat( 40, steps, event );
15763		}, i );
15764
15765		this._spin( steps * this.options.step, event );
15766	},
15767
15768	_spin: function( step, event ) {
15769		var value = this.value() || 0;
15770
15771		if ( !this.counter ) {
15772			this.counter = 1;
15773		}
15774
15775		value = this._adjustValue( value + step * this._increment( this.counter ) );
15776
15777		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15778			this._value( value );
15779			this.counter++;
15780		}
15781	},
15782
15783	_increment: function( i ) {
15784		var incremental = this.options.incremental;
15785
15786		if ( incremental ) {
15787			return $.isFunction( incremental ) ?
15788				incremental( i ) :
15789				Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
15790		}
15791
15792		return 1;
15793	},
15794
15795	_precision: function() {
15796		var precision = this._precisionOf( this.options.step );
15797		if ( this.options.min !== null ) {
15798			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15799		}
15800		return precision;
15801	},
15802
15803	_precisionOf: function( num ) {
15804		var str = num.toString(),
15805			decimal = str.indexOf( "." );
15806		return decimal === -1 ? 0 : str.length - decimal - 1;
15807	},
15808
15809	_adjustValue: function( value ) {
15810		var base, aboveMin,
15811			options = this.options;
15812
15813		// make sure we're at a valid step
15814		// - find out where we are relative to the base (min or 0)
15815		base = options.min !== null ? options.min : 0;
15816		aboveMin = value - base;
15817		// - round to the nearest step
15818		aboveMin = Math.round(aboveMin / options.step) * options.step;
15819		// - rounding is based on 0, so adjust back to our base
15820		value = base + aboveMin;
15821
15822		// fix precision from bad JS floating point math
15823		value = parseFloat( value.toFixed( this._precision() ) );
15824
15825		// clamp the value
15826		if ( options.max !== null && value > options.max) {
15827			return options.max;
15828		}
15829		if ( options.min !== null && value < options.min ) {
15830			return options.min;
15831		}
15832
15833		return value;
15834	},
15835
15836	_stop: function( event ) {
15837		if ( !this.spinning ) {
15838			return;
15839		}
15840
15841		clearTimeout( this.timer );
15842		clearTimeout( this.mousewheelTimer );
15843		this.counter = 0;
15844		this.spinning = false;
15845		this._trigger( "stop", event );
15846	},
15847
15848	_setOption: function( key, value ) {
15849		if ( key === "culture" || key === "numberFormat" ) {
15850			var prevValue = this._parse( this.element.val() );
15851			this.options[ key ] = value;
15852			this.element.val( this._format( prevValue ) );
15853			return;
15854		}
15855
15856		if ( key === "max" || key === "min" || key === "step" ) {
15857			if ( typeof value === "string" ) {
15858				value = this._parse( value );
15859			}
15860		}
15861
15862		this._super( key, value );
15863
15864		if ( key === "disabled" ) {
15865			if ( value ) {
15866				this.element.prop( "disabled", true );
15867				this.buttons.button( "disable" );
15868			} else {
15869				this.element.prop( "disabled", false );
15870				this.buttons.button( "enable" );
15871			}
15872		}
15873	},
15874
15875	_setOptions: modifier(function( options ) {
15876		this._super( options );
15877		this._value( this.element.val() );
15878	}),
15879
15880	_parse: function( val ) {
15881		if ( typeof val === "string" && val !== "" ) {
15882			val = window.Globalize && this.options.numberFormat ?
15883				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15884		}
15885		return val === "" || isNaN( val ) ? null : val;
15886	},
15887
15888	_format: function( value ) {
15889		if ( value === "" ) {
15890			return "";
15891		}
15892		return window.Globalize && this.options.numberFormat ?
15893			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15894			value;
15895	},
15896
15897	_refresh: function() {
15898		this.element.attr({
15899			"aria-valuemin": this.options.min,
15900			"aria-valuemax": this.options.max,
15901			// TODO: what should we do with values that can't be parsed?
15902			"aria-valuenow": this._parse( this.element.val() )
15903		});
15904	},
15905
15906	// update the value without triggering change
15907	_value: function( value, allowAny ) {
15908		var parsed;
15909		if ( value !== "" ) {
15910			parsed = this._parse( value );
15911			if ( parsed !== null ) {
15912				if ( !allowAny ) {
15913					parsed = this._adjustValue( parsed );
15914				}
15915				value = this._format( parsed );
15916			}
15917		}
15918		this.element.val( value );
15919		this._refresh();
15920	},
15921
15922	_destroy: function() {
15923		this.element
15924			.removeClass( "ui-spinner-input" )
15925			.prop( "disabled", false )
15926			.removeAttr( "autocomplete" )
15927			.removeAttr( "role" )
15928			.removeAttr( "aria-valuemin" )
15929			.removeAttr( "aria-valuemax" )
15930			.removeAttr( "aria-valuenow" );
15931		this.uiSpinner.replaceWith( this.element );
15932	},
15933
15934	stepUp: modifier(function( steps ) {
15935		this._stepUp( steps );
15936	}),
15937	_stepUp: function( steps ) {
15938		this._spin( (steps || 1) * this.options.step );
15939	},
15940
15941	stepDown: modifier(function( steps ) {
15942		this._stepDown( steps );
15943	}),
15944	_stepDown: function( steps ) {
15945		this._spin( (steps || 1) * -this.options.step );
15946	},
15947
15948	pageUp: modifier(function( pages ) {
15949		this._stepUp( (pages || 1) * this.options.page );
15950	}),
15951
15952	pageDown: modifier(function( pages ) {
15953		this._stepDown( (pages || 1) * this.options.page );
15954	}),
15955
15956	value: function( newVal ) {
15957		if ( !arguments.length ) {
15958			return this._parse( this.element.val() );
15959		}
15960		modifier( this._value ).call( this, newVal );
15961	},
15962
15963	widget: function() {
15964		return this.uiSpinner;
15965	}
15966});
15967
15968}( jQuery ) );
15969
15970(function( $, undefined ) {
15971
15972var tabId = 0,
15973	rhash = /#.*$/;
15974
15975function getNextTabId() {
15976	return ++tabId;
15977}
15978
15979function isLocal( anchor ) {
15980	return anchor.hash.length > 1 &&
15981		anchor.href.replace( rhash, "" ) === location.href.replace( rhash, "" );
15982}
15983
15984$.widget( "ui.tabs", {
15985	version: "1.9.1",
15986	delay: 300,
15987	options: {
15988		active: null,
15989		collapsible: false,
15990		event: "click",
15991		heightStyle: "content",
15992		hide: null,
15993		show: null,
15994
15995		// callbacks
15996		activate: null,
15997		beforeActivate: null,
15998		beforeLoad: null,
15999		load: null
16000	},
16001
16002	_create: function() {
16003		var that = this,
16004			options = this.options,
16005			active = options.active,
16006			locationHash = location.hash.substring( 1 );
16007
16008		this.running = false;
16009
16010		this.element
16011			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
16012			.toggleClass( "ui-tabs-collapsible", options.collapsible )
16013			// Prevent users from focusing disabled tabs via click
16014			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
16015				if ( $( this ).is( ".ui-state-disabled" ) ) {
16016					event.preventDefault();
16017				}
16018			})
16019			// support: IE <9
16020			// Preventing the default action in mousedown doesn't prevent IE
vendor: 18,126 bytes, lines 16021-16692
16021			// from focusing the element, so if the anchor gets focused, blur.
16022			// We don't have to worry about focusing the previously focused
16023			// element since clicking on a non-focusable element should focus
16024			// the body anyway.
16025			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
16026				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
16027					this.blur();
16028				}
16029			});
16030
16031		this._processTabs();
16032
16033		if ( active === null ) {
16034			// check the fragment identifier in the URL
16035			if ( locationHash ) {
16036				this.tabs.each(function( i, tab ) {
16037					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
16038						active = i;
16039						return false;
16040					}
16041				});
16042			}
16043
16044			// check for a tab marked active via a class
16045			if ( active === null ) {
16046				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
16047			}
16048
16049			// no active tab, set to false
16050			if ( active === null || active === -1 ) {
16051				active = this.tabs.length ? 0 : false;
16052			}
16053		}
16054
16055		// handle numbers: negative, out of range
16056		if ( active !== false ) {
16057			active = this.tabs.index( this.tabs.eq( active ) );
16058			if ( active === -1 ) {
16059				active = options.collapsible ? false : 0;
16060			}
16061		}
16062		options.active = active;
16063
16064		// don't allow collapsible: false and active: false
16065		if ( !options.collapsible && options.active === false && this.anchors.length ) {
16066			options.active = 0;
16067		}
16068
16069		// Take disabling tabs via class attribute from HTML
16070		// into account and update option properly.
16071		if ( $.isArray( options.disabled ) ) {
16072			options.disabled = $.unique( options.disabled.concat(
16073				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
16074					return that.tabs.index( li );
16075				})
16076			) ).sort();
16077		}
16078
16079		// check for length avoids error when initializing empty list
16080		if ( this.options.active !== false && this.anchors.length ) {
16081			this.active = this._findActive( this.options.active );
16082		} else {
16083			this.active = $();
16084		}
16085
16086		this._refresh();
16087
16088		if ( this.active.length ) {
16089			this.load( options.active );
16090		}
16091	},
16092
16093	_getCreateEventData: function() {
16094		return {
16095			tab: this.active,
16096			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
16097		};
16098	},
16099
16100	_tabKeydown: function( event ) {
16101		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
16102			selectedIndex = this.tabs.index( focusedTab ),
16103			goingForward = true;
16104
16105		if ( this._handlePageNav( event ) ) {
16106			return;
16107		}
16108
16109		switch ( event.keyCode ) {
16110			case $.ui.keyCode.RIGHT:
16111			case $.ui.keyCode.DOWN:
16112				selectedIndex++;
16113				break;
16114			case $.ui.keyCode.UP:
16115			case $.ui.keyCode.LEFT:
16116				goingForward = false;
16117				selectedIndex--;
16118				break;
16119			case $.ui.keyCode.END:
16120				selectedIndex = this.anchors.length - 1;
16121				break;
16122			case $.ui.keyCode.HOME:
16123				selectedIndex = 0;
16124				break;
16125			case $.ui.keyCode.SPACE:
16126				// Activate only, no collapsing
16127				event.preventDefault();
16128				clearTimeout( this.activating );
16129				this._activate( selectedIndex );
16130				return;
16131			case $.ui.keyCode.ENTER:
16132				// Toggle (cancel delayed activation, allow collapsing)
16133				event.preventDefault();
16134				clearTimeout( this.activating );
16135				// Determine if we should collapse or activate
16136				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
16137				return;
16138			default:
16139				return;
16140		}
16141
16142		// Focus the appropriate tab, based on which key was pressed
16143		event.preventDefault();
16144		clearTimeout( this.activating );
16145		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
16146
16147		// Navigating with control key will prevent automatic activation
16148		if ( !event.ctrlKey ) {
16149			// Update aria-selected immediately so that AT think the tab is already selected.
16150			// Otherwise AT may confuse the user by stating that they need to activate the tab,
16151			// but the tab will already be activated by the time the announcement finishes.
16152			focusedTab.attr( "aria-selected", "false" );
16153			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
16154
16155			this.activating = this._delay(function() {
16156				this.option( "active", selectedIndex );
16157			}, this.delay );
16158		}
16159	},
16160
16161	_panelKeydown: function( event ) {
16162		if ( this._handlePageNav( event ) ) {
16163			return;
16164		}
16165
16166		// Ctrl+up moves focus to the current tab
16167		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
16168			event.preventDefault();
16169			this.active.focus();
16170		}
16171	},
16172
16173	// Alt+page up/down moves focus to the previous/next tab (and activates)
16174	_handlePageNav: function( event ) {
16175		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
16176			this._activate( this._focusNextTab( this.options.active - 1, false ) );
16177			return true;
16178		}
16179		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
16180			this._activate( this._focusNextTab( this.options.active + 1, true ) );
16181			return true;
16182		}
16183	},
16184
16185	_findNextTab: function( index, goingForward ) {
16186		var lastTabIndex = this.tabs.length - 1;
16187
16188		function constrain() {
16189			if ( index > lastTabIndex ) {
16190				index = 0;
16191			}
16192			if ( index < 0 ) {
16193				index = lastTabIndex;
16194			}
16195			return index;
16196		}
16197
16198		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
16199			index = goingForward ? index + 1 : index - 1;
16200		}
16201
16202		return index;
16203	},
16204
16205	_focusNextTab: function( index, goingForward ) {
16206		index = this._findNextTab( index, goingForward );
16207		this.tabs.eq( index ).focus();
16208		return index;
16209	},
16210
16211	_setOption: function( key, value ) {
16212		if ( key === "active" ) {
16213			// _activate() will handle invalid values and update this.options
16214			this._activate( value );
16215			return;
16216		}
16217
16218		if ( key === "disabled" ) {
16219			// don't use the widget factory's disabled handling
16220			this._setupDisabled( value );
16221			return;
16222		}
16223
16224		this._super( key, value);
16225
16226		if ( key === "collapsible" ) {
16227			this.element.toggleClass( "ui-tabs-collapsible", value );
16228			// Setting collapsible: false while collapsed; open first panel
16229			if ( !value && this.options.active === false ) {
16230				this._activate( 0 );
16231			}
16232		}
16233
16234		if ( key === "event" ) {
16235			this._setupEvents( value );
16236		}
16237
16238		if ( key === "heightStyle" ) {
16239			this._setupHeightStyle( value );
16240		}
16241	},
16242
16243	_tabId: function( tab ) {
16244		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
16245	},
16246
16247	_sanitizeSelector: function( hash ) {
16248		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
16249	},
16250
16251	refresh: function() {
16252		var options = this.options,
16253			lis = this.tablist.children( ":has(a[href])" );
16254
16255		// get disabled tabs from class attribute from HTML
16256		// this will get converted to a boolean if needed in _refresh()
16257		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
16258			return lis.index( tab );
16259		});
16260
16261		this._processTabs();
16262
16263		// was collapsed or no tabs
16264		if ( options.active === false || !this.anchors.length ) {
16265			options.active = false;
16266			this.active = $();
16267		// was active, but active tab is gone
16268		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
16269			// all remaining tabs are disabled
16270			if ( this.tabs.length === options.disabled.length ) {
16271				options.active = false;
16272				this.active = $();
16273			// activate previous tab
16274			} else {
16275				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
16276			}
16277		// was active, active tab still exists
16278		} else {
16279			// make sure active index is correct
16280			options.active = this.tabs.index( this.active );
16281		}
16282
16283		this._refresh();
16284	},
16285
16286	_refresh: function() {
16287		this._setupDisabled( this.options.disabled );
16288		this._setupEvents( this.options.event );
16289		this._setupHeightStyle( this.options.heightStyle );
16290
16291		this.tabs.not( this.active ).attr({
16292			"aria-selected": "false",
16293			tabIndex: -1
16294		});
16295		this.panels.not( this._getPanelForTab( this.active ) )
16296			.hide()
16297			.attr({
16298				"aria-expanded": "false",
16299				"aria-hidden": "true"
16300			});
16301
16302		// Make sure one tab is in the tab order
16303		if ( !this.active.length ) {
16304			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
16305		} else {
16306			this.active
16307				.addClass( "ui-tabs-active ui-state-active" )
16308				.attr({
16309					"aria-selected": "true",
16310					tabIndex: 0
16311				});
16312			this._getPanelForTab( this.active )
16313				.show()
16314				.attr({
16315					"aria-expanded": "true",
16316					"aria-hidden": "false"
16317				});
16318		}
16319	},
16320
16321	_processTabs: function() {
16322		var that = this;
16323
16324		this.tablist = this._getList()
16325			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
16326			.attr( "role", "tablist" );
16327
16328		this.tabs = this.tablist.find( "> li:has(a[href])" )
16329			.addClass( "ui-state-default ui-corner-top" )
16330			.attr({
16331				role: "tab",
16332				tabIndex: -1
16333			});
16334
16335		this.anchors = this.tabs.map(function() {
16336				return $( "a", this )[ 0 ];
16337			})
16338			.addClass( "ui-tabs-anchor" )
16339			.attr({
16340				role: "presentation",
16341				tabIndex: -1
16342			});
16343
16344		this.panels = $();
16345
16346		this.anchors.each(function( i, anchor ) {
16347			var selector, panel, panelId,
16348				anchorId = $( anchor ).uniqueId().attr( "id" ),
16349				tab = $( anchor ).closest( "li" ),
16350				originalAriaControls = tab.attr( "aria-controls" );
16351
16352			// inline tab
16353			if ( isLocal( anchor ) ) {
16354				selector = anchor.hash;
16355				panel = that.element.find( that._sanitizeSelector( selector ) );
16356			// remote tab
16357			} else {
16358				panelId = that._tabId( tab );
16359				selector = "#" + panelId;
16360				panel = that.element.find( selector );
16361				if ( !panel.length ) {
16362					panel = that._createPanel( panelId );
16363					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
16364				}
16365				panel.attr( "aria-live", "polite" );
16366			}
16367
16368			if ( panel.length) {
16369				that.panels = that.panels.add( panel );
16370			}
16371			if ( originalAriaControls ) {
16372				tab.data( "ui-tabs-aria-controls", originalAriaControls );
16373			}
16374			tab.attr({
16375				"aria-controls": selector.substring( 1 ),
16376				"aria-labelledby": anchorId
16377			});
16378			panel.attr( "aria-labelledby", anchorId );
16379		});
16380
16381		this.panels
16382			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
16383			.attr( "role", "tabpanel" );
16384	},
16385
16386	// allow overriding how to find the list for rare usage scenarios (#7715)
16387	_getList: function() {
16388		return this.element.find( "ol,ul" ).eq( 0 );
16389	},
16390
16391	_createPanel: function( id ) {
16392		return $( "<div>" )
16393			.attr( "id", id )
16394			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
16395			.data( "ui-tabs-destroy", true );
16396	},
16397
16398	_setupDisabled: function( disabled ) {
16399		if ( $.isArray( disabled ) ) {
16400			if ( !disabled.length ) {
16401				disabled = false;
16402			} else if ( disabled.length === this.anchors.length ) {
16403				disabled = true;
16404			}
16405		}
16406
16407		// disable tabs
16408		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
16409			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
16410				$( li )
16411					.addClass( "ui-state-disabled" )
16412					.attr( "aria-disabled", "true" );
16413			} else {
16414				$( li )
16415					.removeClass( "ui-state-disabled" )
16416					.removeAttr( "aria-disabled" );
16417			}
16418		}
16419
16420		this.options.disabled = disabled;
16421	},
16422
16423	_setupEvents: function( event ) {
16424		var events = {
16425			click: function( event ) {
16426				event.preventDefault();
16427			}
16428		};
16429		if ( event ) {
16430			$.each( event.split(" "), function( index, eventName ) {
16431				events[ eventName ] = "_eventHandler";
16432			});
16433		}
16434
16435		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
16436		this._on( this.anchors, events );
16437		this._on( this.tabs, { keydown: "_tabKeydown" } );
16438		this._on( this.panels, { keydown: "_panelKeydown" } );
16439
16440		this._focusable( this.tabs );
16441		this._hoverable( this.tabs );
16442	},
16443
16444	_setupHeightStyle: function( heightStyle ) {
16445		var maxHeight, overflow,
16446			parent = this.element.parent();
16447
16448		if ( heightStyle === "fill" ) {
16449			// IE 6 treats height like minHeight, so we need to turn off overflow
16450			// in order to get a reliable height
16451			// we use the minHeight support test because we assume that only
16452			// browsers that don't support minHeight will treat height as minHeight
16453			if ( !$.support.minHeight ) {
16454				overflow = parent.css( "overflow" );
16455				parent.css( "overflow", "hidden");
16456			}
16457			maxHeight = parent.height();
16458			this.element.siblings( ":visible" ).each(function() {
16459				var elem = $( this ),
16460					position = elem.css( "position" );
16461
16462				if ( position === "absolute" || position === "fixed" ) {
16463					return;
16464				}
16465				maxHeight -= elem.outerHeight( true );
16466			});
16467			if ( overflow ) {
16468				parent.css( "overflow", overflow );
16469			}
16470
16471			this.element.children().not( this.panels ).each(function() {
16472				maxHeight -= $( this ).outerHeight( true );
16473			});
16474
16475			this.panels.each(function() {
16476				$( this ).height( Math.max( 0, maxHeight -
16477					$( this ).innerHeight() + $( this ).height() ) );
16478			})
16479			.css( "overflow", "auto" );
16480		} else if ( heightStyle === "auto" ) {
16481			maxHeight = 0;
16482			this.panels.each(function() {
16483				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
16484			}).height( maxHeight );
16485		}
16486	},
16487
16488	_eventHandler: function( event ) {
16489		var options = this.options,
16490			active = this.active,
16491			anchor = $( event.currentTarget ),
16492			tab = anchor.closest( "li" ),
16493			clickedIsActive = tab[ 0 ] === active[ 0 ],
16494			collapsing = clickedIsActive && options.collapsible,
16495			toShow = collapsing ? $() : this._getPanelForTab( tab ),
16496			toHide = !active.length ? $() : this._getPanelForTab( active ),
16497			eventData = {
16498				oldTab: active,
16499				oldPanel: toHide,
16500				newTab: collapsing ? $() : tab,
16501				newPanel: toShow
16502			};
16503
16504		event.preventDefault();
16505
16506		if ( tab.hasClass( "ui-state-disabled" ) ||
16507				// tab is already loading
16508				tab.hasClass( "ui-tabs-loading" ) ||
16509				// can't switch durning an animation
16510				this.running ||
16511				// click on active header, but not collapsible
16512				( clickedIsActive && !options.collapsible ) ||
16513				// allow canceling activation
16514				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
16515			return;
16516		}
16517
16518		options.active = collapsing ? false : this.tabs.index( tab );
16519
16520		this.active = clickedIsActive ? $() : tab;
16521		if ( this.xhr ) {
16522			this.xhr.abort();
16523		}
16524
16525		if ( !toHide.length && !toShow.length ) {
16526			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
16527		}
16528
16529		if ( toShow.length ) {
16530			this.load( this.tabs.index( tab ), event );
16531		}
16532		this._toggle( event, eventData );
16533	},
16534
16535	// handles show/hide for selecting tabs
16536	_toggle: function( event, eventData ) {
16537		var that = this,
16538			toShow = eventData.newPanel,
16539			toHide = eventData.oldPanel;
16540
16541		this.running = true;
16542
16543		function complete() {
16544			that.running = false;
16545			that._trigger( "activate", event, eventData );
16546		}
16547
16548		function show() {
16549			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
16550
16551			if ( toShow.length && that.options.show ) {
16552				that._show( toShow, that.options.show, complete );
16553			} else {
16554				toShow.show();
16555				complete();
16556			}
16557		}
16558
16559		// start out by hiding, then showing, then completing
16560		if ( toHide.length && this.options.hide ) {
16561			this._hide( toHide, this.options.hide, function() {
16562				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
16563				show();
16564			});
16565		} else {
16566			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
16567			toHide.hide();
16568			show();
16569		}
16570
16571		toHide.attr({
16572			"aria-expanded": "false",
16573			"aria-hidden": "true"
16574		});
16575		eventData.oldTab.attr( "aria-selected", "false" );
16576		// If we're switching tabs, remove the old tab from the tab order.
16577		// If we're opening from collapsed state, remove the previous tab from the tab order.
16578		// If we're collapsing, then keep the collapsing tab in the tab order.
16579		if ( toShow.length && toHide.length ) {
16580			eventData.oldTab.attr( "tabIndex", -1 );
16581		} else if ( toShow.length ) {
16582			this.tabs.filter(function() {
16583				return $( this ).attr( "tabIndex" ) === 0;
16584			})
16585			.attr( "tabIndex", -1 );
16586		}
16587
16588		toShow.attr({
16589			"aria-expanded": "true",
16590			"aria-hidden": "false"
16591		});
16592		eventData.newTab.attr({
16593			"aria-selected": "true",
16594			tabIndex: 0
16595		});
16596	},
16597
16598	_activate: function( index ) {
16599		var anchor,
16600			active = this._findActive( index );
16601
16602		// trying to activate the already active panel
16603		if ( active[ 0 ] === this.active[ 0 ] ) {
16604			return;
16605		}
16606
16607		// trying to collapse, simulate a click on the current active header
16608		if ( !active.length ) {
16609			active = this.active;
16610		}
16611
16612		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
16613		this._eventHandler({
16614			target: anchor,
16615			currentTarget: anchor,
16616			preventDefault: $.noop
16617		});
16618	},
16619
16620	_findActive: function( index ) {
16621		return index === false ? $() : this.tabs.eq( index );
16622	},
16623
16624	_getIndex: function( index ) {
16625		// meta-function to give users option to provide a href string instead of a numerical index.
16626		if ( typeof index === "string" ) {
16627			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
16628		}
16629
16630		return index;
16631	},
16632
16633	_destroy: function() {
16634		if ( this.xhr ) {
16635			this.xhr.abort();
16636		}
16637
16638		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
16639
16640		this.tablist
16641			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
16642			.removeAttr( "role" );
16643
16644		this.anchors
16645			.removeClass( "ui-tabs-anchor" )
16646			.removeAttr( "role" )
16647			.removeAttr( "tabIndex" )
16648			.removeData( "href.tabs" )
16649			.removeData( "load.tabs" )
16650			.removeUniqueId();
16651
16652		this.tabs.add( this.panels ).each(function() {
16653			if ( $.data( this, "ui-tabs-destroy" ) ) {
16654				$( this ).remove();
16655			} else {
16656				$( this )
16657					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16658						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16659					.removeAttr( "tabIndex" )
16660					.removeAttr( "aria-live" )
16661					.removeAttr( "aria-busy" )
16662					.removeAttr( "aria-selected" )
16663					.removeAttr( "aria-labelledby" )
16664					.removeAttr( "aria-hidden" )
16665					.removeAttr( "aria-expanded" )
16666					.removeAttr( "role" );
16667			}
16668		});
16669
16670		this.tabs.each(function() {
16671			var li = $( this ),
16672				prev = li.data( "ui-tabs-aria-controls" );
16673			if ( prev ) {
16674				li.attr( "aria-controls", prev );
16675			} else {
16676				li.removeAttr( "aria-controls" );
16677			}
16678		});
16679
16680		if ( this.options.heightStyle !== "content" ) {
16681			this.panels.css( "height", "" );
16682		}
16683	},
16684
16685	enable: function( index ) {
16686		var disabled = this.options.disabled;
16687		if ( disabled === false ) {
16688			return;
16689		}
16690
16691		if ( index === undefined ) {
16692			disabled = false;
16693		} else {
16694			index = this._getIndex( index );
16695			if ( $.isArray( disabled ) ) {
16696				disabled = $.map( disabled, function( num ) {
16697					return num !== index ? num : null;
16698				});
16699			} else {
16700				disabled = $.map( this.tabs, function( li, num ) {
16701					return num !== index ? num : null;
16702				});
16703			}
16704		}
16705		this._setupDisabled( disabled );
16706	},
16707
16708	disable: function( index ) {
16709		var disabled = this.options.disabled;
16710		if ( disabled === true ) {
16711			return;
16712		}
16713
16714		if ( index === undefined ) {
16715			disabled = true;
16716		} else {
16717			index = this._getIndex( index );
16718			if ( $.inArray( index, disabled ) !== -1 ) {
16719				return;
16720			}
16721			if ( $.isArray( disabled ) ) {
16722				disabled = $.merge( [ index ], disabled ).sort();
16723			} else {
16724				disabled = [ index ];
16725			}
16726		}
16727		this._setupDisabled( disabled );
16728	},
16729
16730	load: function( index, event ) {
16731		index = this._getIndex( index );
16732		var that = this,
16733			tab = this.tabs.eq( index ),
16734			anchor = tab.find( ".ui-tabs-anchor" ),
16735			panel = this._getPanelForTab( tab ),
16736			eventData = {
16737				tab: tab,
16738				panel: panel
16739			};
16740
16741		// not remote
16742		if ( isLocal( anchor[ 0 ] ) ) {
16743			return;
16744		}
16745
16746		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16747
16748		// support: jQuery <1.8
16749		// jQuery <1.8 returns false if the request is canceled in beforeSend,
16750		// but as of 1.8, $.ajax() always returns a jqXHR object.
16751		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16752			tab.addClass( "ui-tabs-loading" );
16753			panel.attr( "aria-busy", "true" );
16754
16755			this.xhr
16756				.success(function( response ) {
16757					// support: jQuery <1.8
16758					// http://bugs.jquery.com/ticket/11778
16759					setTimeout(function() {
16760						panel.html( response );
16761						that._trigger( "load", event, eventData );
16762					}, 1 );
16763				})
16764				.complete(function( jqXHR, status ) {
16765					// support: jQuery <1.8
16766					// http://bugs.jquery.com/ticket/11778
16767					setTimeout(function() {
16768						if ( status === "abort" ) {
16769							that.panels.stop( false, true );
16770						}
16771
16772						tab.removeClass( "ui-tabs-loading" );
16773						panel.removeAttr( "aria-busy" );
16774
16775						if ( jqXHR === that.xhr ) {
16776							delete that.xhr;
16777						}
16778					}, 1 );
16779				});
16780		}
16781	},
16782
16783	// TODO: Remove this function in 1.10 when ajaxOptions is removed
16784	_ajaxSettings: function( anchor, event, eventData ) {
16785		var that = this;
16786		return {
16787			url: anchor.attr( "href" ),
16788			beforeSend: function( jqXHR, settings ) {
16789				return that._trigger( "beforeLoad", event,
16790					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
16791			}
16792		};
16793	},
16794
16795	_getPanelForTab: function( tab ) {
16796		var id = $( tab ).attr( "aria-controls" );
16797		return this.element.find( this._sanitizeSelector( "#" + id ) );
16798	}
16799});
16800
16801// DEPRECATED
16802if ( $.uiBackCompat !== false ) {
16803
16804	// helper method for a lot of the back compat extensions
16805	$.ui.tabs.prototype._ui = function( tab, panel ) {
16806		return {
16807			tab: tab,
16808			panel: panel,
16809			index: this.anchors.index( tab )
16810		};
16811	};
16812
16813	// url method
16814	$.widget( "ui.tabs", $.ui.tabs, {
16815		url: function( index, url ) {
16816			this.anchors.eq( index ).attr( "href", url );
16817		}
16818	});
16819
16820	// TODO: Remove _ajaxSettings() method when removing this extension
16821	// ajaxOptions and cache options
16822	$.widget( "ui.tabs", $.ui.tabs, {
16823		options: {
16824			ajaxOptions: null,
16825			cache: false
16826		},
16827
16828		_create: function() {
16829			this._super();
16830
16831			var that = this;
16832
16833			this._on({ tabsbeforeload: function( event, ui ) {
16834				// tab is already cached
16835				if ( $.data( ui.tab[ 0 ], "cache.tabs" ) ) {
16836					event.preventDefault();
16837					return;
16838				}
16839
16840				ui.jqXHR.success(function() {
16841					if ( that.options.cache ) {
16842						$.data( ui.tab[ 0 ], "cache.tabs", true );
16843					}
16844				});
16845			}});
16846		},
16847
16848		_ajaxSettings: function( anchor, event, ui ) {
16849			var ajaxOptions = this.options.ajaxOptions;
16850			return $.extend( {}, ajaxOptions, {
16851				error: function( xhr, status ) {
16852					try {
16853						// Passing index avoid a race condition when this method is
16854						// called after the user has selected another tab.
16855						// Pass the anchor that initiated this request allows
16856						// loadError to manipulate the tab content panel via $(a.hash)
16857						ajaxOptions.error(
16858							xhr, status, ui.tab.closest( "li" ).index(), ui.tab[ 0 ] );
16859					}
16860					catch ( error ) {}
16861				}
16862			}, this._superApply( arguments ) );
16863		},
16864
16865		_setOption: function( key, value ) {
16866			// reset cache if switching from cached to not cached
16867			if ( key === "cache" && value === false ) {
16868				this.anchors.removeData( "cache.tabs" );
16869			}
16870			this._super( key, value );
16871		},
16872
16873		_destroy: function() {
16874			this.anchors.removeData( "cache.tabs" );
16875			this._super();
16876		},
16877
16878		url: function( index ){
16879			this.anchors.eq( index ).removeData( "cache.tabs" );
16880			this._superApply( arguments );
16881		}
16882	});
16883
16884	// abort method
16885	$.widget( "ui.tabs", $.ui.tabs, {
16886		abort: function() {
16887			if ( this.xhr ) {
16888				this.xhr.abort();
16889			}
16890		}
16891	});
16892
16893	// spinner
16894	$.widget( "ui.tabs", $.ui.tabs, {
16895		options: {
16896			spinner: "<em>Loading&#8230;</em>"
16897		},
16898		_create: function() {
16899			this._super();
16900			this._on({
16901				tabsbeforeload: function( event, ui ) {
16902					// Don't react to nested tabs or tabs that don't use a spinner
16903					if ( event.target !== this.element[ 0 ] ||
16904							!this.options.spinner ) {
16905						return;
16906					}
16907
16908					var span = ui.tab.find( "span" ),
16909						html = span.html();
16910					span.html( this.options.spinner );
16911					ui.jqXHR.complete(function() {
16912						span.html( html );
16913					});
16914				}
16915			});
16916		}
16917	});
16918
16919	// enable/disable events
16920	$.widget( "ui.tabs", $.ui.tabs, {
16921		options: {
16922			enable: null,
16923			disable: null
16924		},
16925
16926		enable: function( index ) {
16927			var options = this.options,
16928				trigger;
16929
16930			if ( index && options.disabled === true ||
16931					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) !== -1 ) ) {
16932				trigger = true;
16933			}
16934
16935			this._superApply( arguments );
16936
16937			if ( trigger ) {
16938				this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
16939			}
16940		},
16941
16942		disable: function( index ) {
16943			var options = this.options,
16944				trigger;
16945
16946			if ( index && options.disabled === false ||
16947					( $.isArray( options.disabled ) && $.inArray( index, options.disabled ) === -1 ) ) {
16948				trigger = true;
16949			}
16950
16951			this._superApply( arguments );
16952
16953			if ( trigger ) {
16954				this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
16955			}
16956		}
16957	});
16958
16959	// add/remove methods and events
16960	$.widget( "ui.tabs", $.ui.tabs, {
16961		options: {
16962			add: null,
16963			remove: null,
16964			tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
16965		},
16966
16967		add: function( url, label, index ) {
16968			if ( index === undefined ) {
16969				index = this.anchors.length;
16970			}
16971
16972			var doInsertAfter, panel,
16973				options = this.options,
16974				li = $( options.tabTemplate
16975					.replace( /#\{href\}/g, url )
16976					.replace( /#\{label\}/g, label ) ),
16977				id = !url.indexOf( "#" ) ?
16978					url.replace( "#", "" ) :
16979					this._tabId( li );
16980
16981			li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true );
16982			li.attr( "aria-controls", id );
16983
16984			doInsertAfter = index >= this.tabs.length;
16985
16986			// try to find an existing element before creating a new one
16987			panel = this.element.find( "#" + id );
16988			if ( !panel.length ) {
16989				panel = this._createPanel( id );
16990				if ( doInsertAfter ) {
16991					if ( index > 0 ) {
16992						panel.insertAfter( this.panels.eq( -1 ) );
16993					} else {
16994						panel.appendTo( this.element );
16995					}
16996				} else {
16997					panel.insertBefore( this.panels[ index ] );
16998				}
16999			}
17000			panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide();
17001
17002			if ( doInsertAfter ) {
17003				li.appendTo( this.tablist );
17004			} else {
17005				li.insertBefore( this.tabs[ index ] );
17006			}
17007
17008			options.disabled = $.map( options.disabled, function( n ) {
17009				return n >= index ? ++n : n;
17010			});
17011
17012			this.refresh();
17013			if ( this.tabs.length === 1 && options.active === false ) {
17014				this.option( "active", 0 );
17015			}
17016
17017			this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
17018			return this;
17019		},
17020
17021		remove: function( index ) {
17022			index = this._getIndex( index );
17023			var options = this.options,
17024				tab = this.tabs.eq( index ).remove(),
17025				panel = this._getPanelForTab( tab ).remove();
17026
17027			// If selected tab was removed focus tab to the right or
17028			// in case the last tab was removed the tab to the left.
17029			// We check for more than 2 tabs, because if there are only 2,
17030			// then when we remove this tab, there will only be one tab left
17031			// so we don't need to detect which tab to activate.
17032			if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) {
17033				this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
17034			}
17035
17036			options.disabled = $.map(
17037				$.grep( options.disabled, function( n ) {
17038					return n !== index;
17039				}),
17040				function( n ) {
17041					return n >= index ? --n : n;
17042				});
17043
17044			this.refresh();
17045
17046			this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) );
17047			return this;
17048		}
17049	});
17050
17051	// length method
17052	$.widget( "ui.tabs", $.ui.tabs, {
17053		length: function() {
17054			return this.anchors.length;
17055		}
17056	});
17057
17058	// panel ids (idPrefix option + title attribute)
17059	$.widget( "ui.tabs", $.ui.tabs, {
17060		options: {
17061			idPrefix: "ui-tabs-"
17062		},
17063
17064		_tabId: function( tab ) {
17065			var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab;
17066			a = a[0];
17067			return $( a ).closest( "li" ).attr( "aria-controls" ) ||
17068				a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) ||
17069				this.options.idPrefix + getNextTabId();
17070		}
17071	});
17072
17073	// _createPanel method
17074	$.widget( "ui.tabs", $.ui.tabs, {
17075		options: {
17076			panelTemplate: "<div></div>"
17077		},
17078
17079		_createPanel: function( id ) {
17080			return $( this.options.panelTemplate )
17081				.attr( "id", id )
17082				.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
17083				.data( "ui-tabs-destroy", true );
17084		}
17085	});
17086
17087	// selected option
17088	$.widget( "ui.tabs", $.ui.tabs, {
17089		_create: function() {
17090			var options = this.options;
17091			if ( options.active === null && options.selected !== undefined ) {
17092				options.active = options.selected === -1 ? false : options.selected;
17093			}
17094			this._super();
17095			options.selected = options.active;
17096			if ( options.selected === false ) {
17097				options.selected = -1;
17098			}
17099		},
17100
17101		_setOption: function( key, value ) {
17102			if ( key !== "selected" ) {
17103				return this._super( key, value );
17104			}
17105
17106			var options = this.options;
17107			this._super( "active", value === -1 ? false : value );
17108			options.selected = options.active;
17109			if ( options.selected === false ) {
17110				options.selected = -1;
17111			}
17112		},
17113
17114		_eventHandler: function() {
17115			this._superApply( arguments );
17116			this.options.selected = this.options.active;
17117			if ( this.options.selected === false ) {
17118				this.options.selected = -1;
17119			}
17120		}
17121	});
17122
17123	// show and select event
17124	$.widget( "ui.tabs", $.ui.tabs, {
17125		options: {
17126			show: null,
17127			select: null
17128		},
17129		_create: function() {
17130			this._super();
17131			if ( this.options.active !== false ) {
17132				this._trigger( "show", null, this._ui(
17133					this.active.find( ".ui-tabs-anchor" )[ 0 ],
17134					this._getPanelForTab( this.active )[ 0 ] ) );
17135			}
17136		},
17137		_trigger: function( type, event, data ) {
17138			var ret = this._superApply( arguments );
17139			if ( !ret ) {
17140				return false;
17141			}
17142			if ( type === "beforeActivate" && data.newTab.length ) {
17143				ret = this._super( "select", event, {
17144					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0],
17145					panel: data.newPanel[ 0 ],
17146					index: data.newTab.closest( "li" ).index()
17147				});
17148			} else if ( type === "activate" && data.newTab.length ) {
17149				ret = this._super( "show", event, {
17150					tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ],
17151					panel: data.newPanel[ 0 ],
17152					index: data.newTab.closest( "li" ).index()
17153				});
17154			}
17155			return ret;
17156		}
17157	});
17158
17159	// select method
17160	$.widget( "ui.tabs", $.ui.tabs, {
17161		select: function( index ) {
17162			index = this._getIndex( index );
17163			if ( index === -1 ) {
17164				if ( this.options.collapsible && this.options.selected !== -1 ) {
17165					index = this.options.selected;
17166				} else {
17167					return;
17168				}
17169			}
17170			this.anchors.eq( index ).trigger( this.options.event + this.eventNamespace );
17171		}
17172	});
17173
17174	// cookie option
17175	(function() {
17176
17177	var listId = 0;
17178
17179	$.widget( "ui.tabs", $.ui.tabs, {
17180		options: {
17181			cookie: null // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
17182		},
17183		_create: function() {
17184			var options = this.options,
17185				active;
17186			if ( options.active == null && options.cookie ) {
17187				active = parseInt( this._cookie(), 10 );
17188				if ( active === -1 ) {
17189					active = false;
17190				}
17191				options.active = active;
17192			}
17193			this._super();
17194		},
17195		_cookie: function( active ) {
17196			var cookie = [ this.cookie ||
17197				( this.cookie = this.options.cookie.name || "ui-tabs-" + (++listId) ) ];
17198			if ( arguments.length ) {
17199				cookie.push( active === false ? -1 : active );
17200				cookie.push( this.options.cookie );
17201			}
17202			return $.cookie.apply( null, cookie );
17203		},
17204		_refresh: function() {
17205			this._super();
17206			if ( this.options.cookie ) {
17207				this._cookie( this.options.active, this.options.cookie );
17208			}
17209		},
17210		_eventHandler: function() {
17211			this._superApply( arguments );
17212			if ( this.options.cookie ) {
17213				this._cookie( this.options.active, this.options.cookie );
17214			}
17215		},
17216		_destroy: function() {
17217			this._super();
17218			if ( this.options.cookie ) {
17219				this._cookie( null, this.options.cookie );
17220			}
17221		}
17222	});
17223
17224	})();
17225
17226	// load event
17227	$.widget( "ui.tabs", $.ui.tabs, {
17228		_trigger: function( type, event, data ) {
17229			var _data = $.extend( {}, data );
17230			if ( type === "load" ) {
17231				_data.panel = _data.panel[ 0 ];
17232				_data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ];
17233			}
17234			return this._super( type, event, _data );
17235		}
17236	});
17237
17238	// fx option
17239	// The new animation options (show, hide) conflict with the old show callback.
17240	// The old fx option wins over show/hide anyway (always favor back-compat).
17241	// If a user wants to use the new animation API, they must give up the old API.
17242	$.widget( "ui.tabs", $.ui.tabs, {
17243		options: {
17244			fx: null // e.g. { height: "toggle", opacity: "toggle", duration: 200 }
17245		},
17246
17247		_getFx: function() {
17248			var hide, show,
17249				fx = this.options.fx;
17250
17251			if ( fx ) {
17252				if ( $.isArray( fx ) ) {
17253					hide = fx[ 0 ];
17254					show = fx[ 1 ];
17255				} else {
17256					hide = show = fx;
17257				}
17258			}
17259
17260			return fx ? { show: show, hide: hide } : null;
17261		},
17262
17263		_toggle: function( event, eventData ) {
17264			var that = this,
17265				toShow = eventData.newPanel,
17266				toHide = eventData.oldPanel,
17267				fx = this._getFx();
17268
17269			if ( !fx ) {
17270				return this._super( event, eventData );
17271			}
17272
17273			that.running = true;
17274
17275			function complete() {
17276				that.running = false;
17277				that._trigger( "activate", event, eventData );
17278			}
17279
17280			function show() {
17281				eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
17282
17283				if ( toShow.length && fx.show ) {
17284					toShow
17285						.animate( fx.show, fx.show.duration, function() {
17286							complete();
17287						});
17288				} else {
17289					toShow.show();
17290					complete();
17291				}
17292			}
17293
17294			// start out by hiding, then showing, then completing
17295			if ( toHide.length && fx.hide ) {
17296				toHide.animate( fx.hide, fx.hide.duration, function() {
17297					eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
17298					show();
17299				});
17300			} else {
17301				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
17302				toHide.hide();
17303				show();
17304			}
17305		}
17306	});
17307}
17308
17309})( jQuery );
17310
17311(function( $ ) {
17312
17313var increments = 0;
17314
17315function addDescribedBy( elem, id ) {
17316	var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
17317	describedby.push( id );
17318	elem
17319		.data( "ui-tooltip-id", id )
17320		.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
17321}
17322
17323function removeDescribedBy( elem ) {
17324	var id = elem.data( "ui-tooltip-id" ),
17325		describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
17326		index = $.inArray( id, describedby );
17327	if ( index !== -1 ) {
17328		describedby.splice( index, 1 );
17329	}
17330
17331	elem.removeData( "ui-tooltip-id" );
17332	describedby = $.trim( describedby.join( " " ) );
17333	if ( describedby ) {
17334		elem.attr( "aria-describedby", describedby );
17335	} else {
17336		elem.removeAttr( "aria-describedby" );
17337	}
17338}
17339
17340$.widget( "ui.tooltip", {
17341	version: "1.9.1",
17342	options: {
17343		content: function() {
17344			return $( this ).attr( "title" );
17345		},
17346		hide: true,
17347		// Disabled elements have inconsistent behavior across browsers (#8661)
17348		items: "[title]:not([disabled])",
17349		position: {
17350			my: "left top+15",
17351			at: "left bottom",
17352			collision: "flipfit flipfit"
17353		},
17354		show: true,
17355		tooltipClass: null,
17356		track: false,
17357
17358		// callbacks
17359		close: null,
17360		open: null
17361	},
17362
17363	_create: function() {
17364		this._on({
17365			mouseover: "open",
17366			focusin: "open"
17367		});
17368
17369		// IDs of generated tooltips, needed for destroy
17370		this.tooltips = {};
17371		// IDs of parent tooltips where we removed the title attribute
17372		this.parents = {};
17373
17374		if ( this.options.disabled ) {
17375			this._disable();
17376		}
17377	},
17378
17379	_setOption: function( key, value ) {
17380		var that = this;
17381
17382		if ( key === "disabled" ) {
17383			this[ value ? "_disable" : "_enable" ]();
17384			this.options[ key ] = value;
17385			// disable element style changes
17386			return;
17387		}
17388
17389		this._super( key, value );
17390
17391		if ( key === "content" ) {
17392			$.each( this.tooltips, function( id, element ) {
17393				that._updateContent( element );
17394			});
17395		}
17396	},
17397
17398	_disable: function() {
17399		var that = this;
17400
17401		// close open tooltips
17402		$.each( this.tooltips, function( id, element ) {
17403			var event = $.Event( "blur" );
17404			event.target = event.currentTarget = element[0];
17405			that.close( event, true );
17406		});
17407
17408		// remove title attributes to prevent native tooltips
17409		this.element.find( this.options.items ).andSelf().each(function() {
17410			var element = $( this );
17411			if ( element.is( "[title]" ) ) {
17412				element
17413					.data( "ui-tooltip-title", element.attr( "title" ) )
17414					.attr( "title", "" );
17415			}
17416		});
17417	},
17418
17419	_enable: function() {
17420		// restore title attributes
17421		this.element.find( this.options.items ).andSelf().each(function() {
17422			var element = $( this );
17423			if ( element.data( "ui-tooltip-title" ) ) {
17424				element.attr( "title", element.data( "ui-tooltip-title" ) );
17425			}
17426		});
17427	},
17428
17429	open: function( event ) {
17430		var that = this,
17431			target = $( event ? event.target : this.element )
17432				// we need closest here due to mouseover bubbling,
17433				// but always pointing at the same event target
17434				.closest( this.options.items );
17435
17436		// No element to show a tooltip for
17437		if ( !target.length ) {
17438			return;
17439		}
17440
17441		// If the tooltip is open and we're tracking then reposition the tooltip.
17442		// This makes sure that a tracking tooltip doesn't obscure a focused element
17443		// if the user was hovering when the element gained focused.
17444		if ( this.options.track && target.data( "ui-tooltip-id" ) ) {
17445			this._find( target ).position( $.extend({
17446				of: target
17447			}, this.options.position ) );
17448			// Stop tracking (#8622)
17449			this._off( this.document, "mousemove" );
17450			return;
17451		}
17452
17453		if ( target.attr( "title" ) ) {
17454			target.data( "ui-tooltip-title", target.attr( "title" ) );
17455		}
17456
17457		target.data( "tooltip-open", true );
17458
17459		// kill parent tooltips, custom or native, for hover
17460		if ( event && event.type === "mouseover" ) {
17461			target.parents().each(function() {
17462				var blurEvent;
17463				if ( $( this ).data( "tooltip-open" ) ) {
17464					blurEvent = $.Event( "blur" );
17465					blurEvent.target = blurEvent.currentTarget = this;
17466					that.close( blurEvent, true );
17467				}
17468				if ( this.title ) {
17469					$( this ).uniqueId();
17470					that.parents[ this.id ] = {
17471						element: this,
17472						title: this.title
17473					};
17474					this.title = "";
17475				}
17476			});
17477		}
17478
17479		this._updateContent( target, event );
17480	},
17481
17482	_updateContent: function( target, event ) {
17483		var content,
17484			contentOption = this.options.content,
17485			that = this;
17486
17487		if ( typeof contentOption === "string" ) {
17488			return this._open( event, target, contentOption );
17489		}
17490
17491		content = contentOption.call( target[0], function( response ) {
17492			// ignore async response if tooltip was closed already
17493			if ( !target.data( "tooltip-open" ) ) {
17494				return;
17495			}
17496			// IE may instantly serve a cached response for ajax requests
17497			// delay this call to _open so the other call to _open runs first
17498			that._delay(function() {
17499				this._open( event, target, response );
17500			});
17501		});
17502		if ( content ) {
17503			this._open( event, target, content );
17504		}
17505	},
17506
17507	_open: function( event, target, content ) {
17508		var tooltip, events, delayedShow,
17509			positionOption = $.extend( {}, this.options.position );
17510
17511		if ( !content ) {
17512			return;
17513		}
17514
17515		// Content can be updated multiple times. If the tooltip already
17516		// exists, then just update the content and bail.
17517		tooltip = this._find( target );
17518		if ( tooltip.length ) {
17519			tooltip.find( ".ui-tooltip-content" ).html( content );
17520			return;
17521		}
17522
17523		// if we have a title, clear it to prevent the native tooltip
17524		// we have to check first to avoid defining a title if none exists
17525		// (we don't want to cause an element to start matching [title])
17526		//
17527		// We use removeAttr only for key events, to allow IE to export the correct
17528		// accessible attributes. For mouse events, set to empty string to avoid
17529		// native tooltip showing up (happens only when removing inside mouseover).
17530		if ( target.is( "[title]" ) ) {
17531			if ( event && event.type === "mouseover" ) {
17532				target.attr( "title", "" );
17533			} else {
17534				target.removeAttr( "title" );
17535			}
17536		}
17537
17538		tooltip = this._tooltip( target );
17539		addDescribedBy( target, tooltip.attr( "id" ) );
17540		tooltip.find( ".ui-tooltip-content" ).html( content );
17541
17542		function position( event ) {
17543			positionOption.of = event;
17544			if ( tooltip.is( ":hidden" ) ) {
17545				return;
17546			}
17547			tooltip.position( positionOption );
17548		}
17549		if ( this.options.track && event && /^mouse/.test( event.originalEvent.type ) ) {
17550			this._on( this.document, {
17551				mousemove: position
17552			});
17553			// trigger once to override element-relative positioning
17554			position( event );
17555		} else {
17556			tooltip.position( $.extend({
17557				of: target
17558			}, this.options.position ) );
17559		}
17560
17561		tooltip.hide();
17562
17563		this._show( tooltip, this.options.show );
17564		// Handle tracking tooltips that are shown with a delay (#8644). As soon
17565		// as the tooltip is visible, position the tooltip using the most recent
17566		// event.
17567		if ( this.options.show && this.options.show.delay ) {
17568			delayedShow = setInterval(function() {
17569				if ( tooltip.is( ":visible" ) ) {
17570					position( positionOption.of );
17571					clearInterval( delayedShow );
17572				}
17573			}, $.fx.interval );
17574		}
17575
17576		this._trigger( "open", event, { tooltip: tooltip } );
17577
17578		events = {
17579			keyup: function( event ) {
17580				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
17581					var fakeEvent = $.Event(event);
17582					fakeEvent.currentTarget = target[0];
17583					this.close( fakeEvent, true );
17584				}
17585			},
17586			remove: function() {
17587				this._removeTooltip( tooltip );
17588			}
17589		};
17590		if ( !event || event.type === "mouseover" ) {
17591			events.mouseleave = "close";
17592		}
17593		if ( !event || event.type === "focusin" ) {
17594			events.focusout = "close";
17595		}
17596		this._on( target, events );
17597	},
17598
17599	close: function( event ) {
17600		var that = this,
17601			target = $( event ? event.currentTarget : this.element ),
17602			tooltip = this._find( target );
17603
17604		// disabling closes the tooltip, so we need to track when we're closing
17605		// to avoid an infinite loop in case the tooltip becomes disabled on close
17606		if ( this.closing ) {
17607			return;
17608		}
17609
17610		// only set title if we had one before (see comment in _open())
17611		if ( target.data( "ui-tooltip-title" ) ) {
17612			target.attr( "title", target.data( "ui-tooltip-title" ) );
17613		}
17614
17615		removeDescribedBy( target );
17616
17617		tooltip.stop( true );
17618		this._hide( tooltip, this.options.hide, function() {
17619			that._removeTooltip( $( this ) );
17620		});
17621
17622		target.removeData( "tooltip-open" );
17623		this._off( target, "mouseleave focusout keyup" );
17624		// Remove 'remove' binding only on delegated targets
17625		if ( target[0] !== this.element[0] ) {
17626			this._off( target, "remove" );
17627		}
17628		this._off( this.document, "mousemove" );
17629
17630		if ( event && event.type === "mouseleave" ) {
17631			$.each( this.parents, function( id, parent ) {
17632				parent.element.title = parent.title;
17633				delete that.parents[ id ];
17634			});
17635		}
17636
17637		this.closing = true;
17638		this._trigger( "close", event, { tooltip: tooltip } );
17639		this.closing = false;
17640	},
17641
17642	_tooltip: function( element ) {
17643		var id = "ui-tooltip-" + increments++,
17644			tooltip = $( "<div>" )
17645				.attr({
17646					id: id,
17647					role: "tooltip"
17648				})
17649				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
17650					( this.options.tooltipClass || "" ) );
17651		$( "<div>" )
17652			.addClass( "ui-tooltip-content" )
17653			.appendTo( tooltip );
17654		tooltip.appendTo( this.document[0].body );
17655		if ( $.fn.bgiframe ) {
17656			tooltip.bgiframe();
17657		}
17658		this.tooltips[ id ] = element;
17659		return tooltip;
17660	},
17661
17662	_find: function( target ) {
17663		var id = target.data( "ui-tooltip-id" );
17664		return id ? $( "#" + id ) : $();
17665	},
17666
17667	_removeTooltip: function( tooltip ) {
17668		tooltip.remove();
17669		delete this.tooltips[ tooltip.attr( "id" ) ];
17670	},
17671
17672	_destroy: function() {
17673		var that = this;
17674
17675		// close open tooltips
17676		$.each( this.tooltips, function( id, element ) {
17677			// Delegate to close method to handle common cleanup
17678			var event = $.Event( "blur" );
17679			event.target = event.currentTarget = element[0];
17680			that.close( event, true );
17681
17682			// Remove immediately; destroying an open tooltip doesn't use the
17683			// hide animation
17684			$( "#" + id ).remove();
17685
17686			// Restore the title
17687			if ( element.data( "ui-tooltip-title" ) ) {
17688				element.attr( "title", element.data( "ui-tooltip-title" ) );
17689				element.removeData( "ui-tooltip-title" );
17690			}
17691		});
17692	}
17693});
17694
17695}( jQuery ) );
17696
17697//fgnass.github.com/spin.js#v1.2.5
17698(function(a,b,c){function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;b<c;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1),g}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var d=["webkit","Moz","ms","O"],e={},f,i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},q.defaults,o)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width,h,i;a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:(c.left=="auto"?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,
176980,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p})(window,document);
17699
17700var opts = {
17701  lines: 9, // The number of lines to draw
17702  length: 13, // The length of each line
17703  width: 5, // The line thickness
17704  radius: 10, // The radius of the inner circle
17705  rotate: 31, // The rotation offset
17706  color: '#000', // #rgb or #rrggbb
17707  speed: 1.1, // Rounds per second
17708  trail: 70, // Afterglow percentage
17709  shadow: true, // Whether to render a shadow
17710  hwaccel: false, // Whether to use hardware acceleration
17711  className: 'spinner', // The CSS class to assign to the spinner
17712  zIndex: 2e9, // The z-index (defaults to 2000000000)
17713  top: 'auto', // Top position relative to parent in px
17714  left: 'auto' // Left position relative to parent in px
17715};
17716var target = document.getElementById('foo');
17717var spinner = new Spinner(opts).spin(target);
17718/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
17719 * Licensed under the MIT License (LICENSE.txt).
17720 *
17721 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
17722 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
17723 * Thanks to: Seamus Leahy for adding deltaX and deltaY
17724 *
17725 * Version: 3.0.6
17726 * 
17727 * Requires: 1.2.2+
17728 */
17729
17730(function($) {
17731
17732var types = ['DOMMouseScroll', 'mousewheel'];
17733
17734if ($.event.fixHooks) {
17735    for ( var i=types.length; i; ) {
17736        $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
17737    }
17738}
17739
17740$.event.special.mousewheel = {
17741    setup: function() {
17742        if ( this.addEventListener ) {
17743            for ( var i=types.length; i; ) {
17744                this.addEventListener( types[--i], handler, false );
17745            }
17746        } else {
17747            this.onmousewheel = handler;
17748        }
17749    },
17750    
17751    teardown: function() {
17752        if ( this.removeEventListener ) {
17753            for ( var i=types.length; i; ) {
17754                this.removeEventListener( types[--i], handler, false );
17755            }
17756        } else {
17757            this.onmousewheel = null;
17758        }
17759    }
17760};
17761
17762$.fn.extend({
17763    mousewheel: function(fn) {
17764        return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
17765    },
17766    
17767    unmousewheel: function(fn) {
17768        return this.unbind("mousewheel", fn);
17769    }
17770});
17771
17772
17773function handler(event) {
17774    var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
17775    event = $.event.fix(orgEvent);
17776    event.type = "mousewheel";
17777    
17778    // Old school scrollwheel delta
17779    if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
17780    if ( orgEvent.detail     ) { delta = -orgEvent.detail/3; }
17781    
17782    // New school multidimensional scroll (touchpads) deltas
17783    deltaY = delta;
17784    
17785    // Gecko
17786    if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
17787        deltaY = 0;
17788        deltaX = -1*delta;
17789    }
17790    
17791    // Webkit
17792    if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
17793    if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
17794    
17795    // Add event and delta to the front of the arguments
17796    args.unshift(event, delta, deltaX, deltaY);
17797    
17798    return ($.event.dispatch || $.event.handle).apply(this, args);
17799}
17800
17801})(jQuery);
17802
17803/*
17804 Smooth Zoom Pan - jQuery Image Viewer
17805 Copyright (c) 2011-12 Ramesh Kumar
17806 http://codecanyon.net/user/VF
17807 
17808 Version:	1.6.3
17809 RELEASE:	09 SEP 2011
17810 UPDATE:		18 JUL 2012
17811 
17812 Built using:
17813 jQuery 		version:1.7.1	http://jquery.com/
17814 Modernizr 	version:2.5.3	http://www.modernizr.com/
17815 MouseWheel	version:3.0.6	http://brandonaaron.net/code/mousewheel/docs
17816 
17817 */
17818
17819(function($, window, document) {
17820
17821    /*****************************************************************************
17822     Default settings:
17823     For detailed description of individual parameters, see the help document
17824     ******************************************************************************/
17825    var defaults = {
17826        width: '', //Width of the view area [480, '480px', '100%']
17827        height: '', //Height of the view area [480, '480px', '100%']
17828
17829        initial_ZOOM: '', //Initial zoom level to start with (in percentage) [100]
17830        initial_POSITION: '', //Initial location to be focused in pixel value [150,150 or 150 150]
17831
17832        animation_SMOOTHNESS: 5.5, //Ease or smoothness of all movements [Any number from 0]				
17833        animation_SPEED_ZOOM: 5.5, //Speed of zoom movements [Any number from 0] 
17834        animation_SPEED_PAN: 5.5, //Speed of pan movements [Any number from 0] 
17835
17836        zoom_MAX: 800, //Maximum limit for zooming (in percentage)
17837        zoom_MIN: '', //Minimum limit for zooming (in percentage)
17838        zoom_SINGLE_STEP: false, //To reach maximum and minimum zoom levels in single click 
17839        zoom_OUT_TO_FIT: true, //To allow image to be zoomed out with whitespace on sides
17840        zoom_BUTTONS_SHOW: true, //To enable/disable the + and - buttons
17841
17842        pan_BUTTONS_SHOW: true, //To enable/disable the arrow and reset buttons
17843        pan_LIMIT_BOUNDARY: true, //To allow/restrict moving the image beyond boundaries
17844        pan_REVERSE: false,
17845        reset_ALIGN_TO: 'center center', //Image can be aligned to desired position on reset. Example: 'Top Left'
17846
17847        button_SIZE: 18, //Button width and height (in pixels)
17848        button_SIZE_TOUCH_DEVICE: 30, //Button width and height (in pixels) on touch devices
17849        button_COLOR: '#FFFFFF', //Button color in hexadecimal
17850        button_BG_COLOR: '#000000', //Button set's background color in hexadecimal
17851        button_BG_TRANSPARENCY: 55, //Background transparency (in percentage)
17852        button_AUTO_HIDE: false, //To hide the button set when mouse moved outside the view area
17853        button_AUTO_HIDE_DELAY: 1, //Auto hide delay time in seconds
17854        button_ALIGN: 'bottom right', //Button set can be aligned to any side or center
17855        button_MARGIN: 10, //Space between button set and view port's edge
17856        button_ROUND_CORNERS: true, //To enable disable roundness of button corner
17857
17858        touch_DRAG: true, //Enable/disable the dragability of image (touch)
17859        mouse_DRAG: true, //Enable/disable the dragability of image (mouse)
17860        mouse_WHEEL: true, //Enable/disable mousewheel zoom
17861        mouse_WHEEL_CURSOR_POS: true, //Enable/disable position sensitive mousewheel zoom
17862        mouse_DOUBLE_CLICK: true, //Enable/disable zoom action with double click
17863
17864        background_COLOR: '#FFFFFF', //Background colour of image container
17865        border_SIZE: 1, //Border size of view area
17866        border_COLOR: '#000000', //Border color of view area
17867        border_TRANSPARENCY: 10, //Border transparency of view area
17868
17869        image_url: '', //Set url or image to be zoomed
17870        image_original_width: '', //Original width of main image
17871        image_original_height: '', //Original height of main image
17872        container: '', //Set container element of image (id of container)
17873
17874        on_IMAGE_LOAD: '', //To Call external function immediatly after image loaded
17875        on_ZOOM_PAN_UPDATE: '', //To Call external function for each zoom, pan animation frame
17876        on_ZOOM_PAN_COMPLETE: '', //To Call external function whenever zoom, pan animation completes
17877        on_LANDMARK_STATE_CHANGE: '', //To Call external function whenever the zoom leval crosses global "data-show-at-zoom" value
17878
17879        use_3D_Transform: true, //To enable / disable Hardware acceleration on webkit browsers
17880
17881        responsive: false, //To enable / disable Responsive / fluid layout
17882        responsive_maintain_ratio: true, //To maintain view area width/height ratio or not
17883        max_WIDTH: '', //Maximum allowed width of view area (helpful when 'width' parameter set with % and need limit)
17884        max_HEIGHT: ''								//Maximum allowed height of view area (helpful when 'height' parameter set with % and need limit)
17885    };
17886
17887    function Zoomer($elem, params) {
17888
17889        var self = this;
17890        this.$elem = $elem;
17891        var op = $.extend({}, defaults, params);
17892
17893        /**********************************************************
17894         Option values verified and formated if needed
17895         **********************************************************/
17896        this.sW = op.width;
17897        this.sH = op.height;
17898
17899        this.init_zoom = op.initial_ZOOM / 100;
17900        this.init_pos = op.initial_POSITION.replace(/,/g, ' ').replace(/\s{2,}/g, ' ').split(' ');
17901
17902        this.zoom_max = op.zoom_MAX / 100;
17903        this.zoom_min = op.zoom_MIN / 100;
17904
17905        this.zoom_single = checkBoolean(op.zoom_SINGLE_STEP);
17906        this.zoom_fit = checkBoolean(op.zoom_OUT_TO_FIT);
17907        this.zoom_speed = 1 + (((op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_ZOOM) + 1) / 20);
17908        this.zoom_show = checkBoolean(op.zoom_BUTTONS_SHOW);
17909
17910        this.pan_speed_o = (op.animation_SPEED === 0 || op.animation_SPEED ? op.animation_SPEED : op.animation_SPEED_PAN);
17911        this.pan_show = checkBoolean(op.pan_BUTTONS_SHOW);
17912        this.pan_limit = checkBoolean(op.pan_LIMIT_BOUNDARY);
17913        this.pan_rev = checkBoolean(op.pan_REVERSE);
17914
17915        this.reset_align = op.reset_ALIGN_TO.toLowerCase().split(' ');
17916
17917        if (supportsTouch) {
17918            this.bu_size = parseInt(op.button_SIZE_TOUCH_DEVICE / 2) * 2;
17919        } else {
17920            this.bu_size = parseInt(op.button_SIZE / 2) * 2;
17921        }
17922        this.bu_color = op.button_COLOR;
17923        this.bu_bg = op.button_BG_COLOR;
17924        this.bu_bg_alpha = op.button_BG_TRANSPARENCY / 100;
17925        this.bu_icon = op.button_ICON_IMAGE;
17926        this.bu_auto = checkBoolean(op.button_AUTO_HIDE);
17927
17928        this.bu_delay = op.button_AUTO_HIDE_DELAY * 1000;
17929        this.bu_align = op.button_ALIGN.toLowerCase().split(' ');
17930        this.bu_margin = op.button_MARGIN;
17931        this.bu_round = checkBoolean(op.button_ROUND_CORNERS);
17932
17933        this.touch_drag = checkBoolean(op.touch_DRAG);
17934        this.mouse_drag = checkBoolean(op.mouse_DRAG);
17935        this.mouse_wheel = checkBoolean(op.mouse_WHEEL);
17936        this.mouse_wheel_cur = checkBoolean(op.mouse_WHEEL_CURSOR_POS);
17937        this.mouse_dbl_click = checkBoolean(op.mouse_DOUBLE_CLICK);
17938
17939        this.ani_smooth = Math.max(1, (op.animation_SMOOTHNESS + 1) / 1.45);
17940
17941        this.bg_color = op.background_COLOR;
17942        this.bord_size = op.border_SIZE;
17943        this.bord_color = op.border_COLOR;
17944        this.bord_alpha = op.border_TRANSPARENCY / 100;
17945
17946        this.container = op.container;
17947        this.image_url = op.image_url;
17948        this.image_width = op.image_original_width;
17949        this.image_height = op.image_original_height;
17950
17951        this.responsive = checkBoolean(op.responsive);
17952        this.maintain_ratio = checkBoolean(op.responsive_maintain_ratio);
17953        this.w_max = op.max_WIDTH;
17954        this.h_max = op.max_HEIGHT;
17955
17956        this.onLOAD = op.on_IMAGE_LOAD;
17957        this.onUPDATE = op.on_ZOOM_PAN_UPDATE;
17958        this.onZOOM_PAN = op.on_ZOOM_PAN_COMPLETE;
17959        this.onLANDMARK = op.on_LANDMARK_STATE_CHANGE;
17960
17961        /***********************************************************
17962         Variables for inner operation.	
17963         x, y, width, height and scale value of image
17964         ***********************************************************/
17965        this._x;
17966        this._y;
17967        this._w;
17968        this._h;
17969        this._sc = 0;
17970
17971        this.rF = 1;
17972        this.rA = 1;
17973        this.iW = 0;
17974        this.iH = 0;
17975        this.tX = 0;
17976        this.tY = 0;
17977        this.oX = 0;
17978        this.oY = 0;
17979        this.fX = 0;
17980        this.fY = 0;
17981        this.dX = 0;
17982        this.dY = 0;
17983        this.cX = 0;
17984        this.cY = 0;
17985
17986        this.transOffX = 0;
17987        this.transOffY = 0;
17988        this.focusOffX = 0;
17989        this.focusOffY = 0;
17990        this.offX = 0;
17991        this.offY = 0;
17992
17993        /***********************************************************
17994         Flags that convey current states and events 
17995         ***********************************************************/
17996        this._playing = false;
17997        this._dragging = false;
17998        this._onfocus = false;
17999        this._moveCursor = false;
18000        this._wheel = false;
18001        this._recent = 'zoomOut';
18002        this._pinching = false;
18003        this._landmark = false;
18004        this._rA;
18005        this._centx;
18006        this._centy;
18007        this._onButton = false;
18008        this._onHitArea = false;
18009        this.cFlag = {
18010            _zi: false,
18011            _zo: false,
18012            _ml: false,
18013            _mr: false,
18014            _mu: false,
18015            _md: false,
18016            _rs: false,
18017            _nd: false
18018        };
18019
18020        /***********************************************************
18021         Elements and arrays that references elements
18022         ***********************************************************/
18023        this.$holder;
18024        this.$hitArea;
18025        this.$controls;
18026        this.$loc_cont;
18027        this.map_coordinates = [];
18028        this.locations = [];
18029        this.buttons = [];
18030        this.border = [];
18031
18032        /***********************************************************
18033         miscellaneous
18034         ***********************************************************/
18035        this.buttons_total = 7;
18036        this.cButtId = 0;
18037        this.pan_speed;
18038        this.auto_timer;
18039        this.ani_timer;
18040        this.ani_end;
18041        this.focusSpeed = this.reduction = .5;
18042        this.orig_style;
18043        this.mapAreas;
18044        this.icons;
18045        this.show_at_zoom;
18046        this.assetsLoaded = false;
18047        this.zStep = 0;
18048        this.sRed = 300;
18049        this.use3D = op.use_3D_Transform && supportsTrans3D;
18050
18051        if (supportsTouch) {
18052            this.event_down = 'touchstart.sz';
18053            this.event_up = 'touchend.sz';
18054            this.event_move = 'touchmove.sz';
18055        } else {
18056            this.event_down = 'mousedown.sz';
18057            this.event_up = 'mouseup.sz';
18058            this.event_move = 'mousemove.sz';
18059        }
18060
18061        //Case 1: Image specificed (possibly) through img tag:
18062        if (this.image_url == '') {
18063            this.$image = $elem;
18064            this.id = this.$image.attr('id');
18065
18066            //Case 2: Image url specificed through parameter:
18067        } else {
18068            var img = new Image();
18069            if (this.image_width) {
18070                img.width = this.image_width;
18071            }
18072            if (this.image_height) {
18073                img.height = this.image_height;
18074            }
18075            img.src = this.image_url;
18076            this.$image = $(img).appendTo($elem);
18077        }
18078
18079
18080        //Prepare container div (Basically the element that masks image with overflow hidden)
18081        this.setContainer();
18082
18083        //Get button icon image's url
18084        var testOb;
18085        if (!this.bu_icon) {
18086            var regx = /url\(["']?([^'")]+)['"]?\)/;
18087            testOb = $('<div class="smooth_zoom_icons"></div>');
18088            this.$holder.append(testOb);
18089            this.bu_icon = testOb.css("background-image").replace(regx, '$1');
18090            if (this.bu_icon == 'none') {
18091                this.bu_icon = 'zoom_assets/icons.png';
18092            }
18093            testOb.remove();
18094        }
18095
18096        //Firefox feature checkup
18097        if (this.$image.css('-moz-transform') && prop_transform) {
18098            testOb = $('<div style="-moz-transform: translate(1px, 1px)"></div>');
18099            this.$holder.append(testOb);
18100            this.fixMoz = testOb.position().left === 1 ? false : true;
18101            testOb.remove();
18102        } else {
18103            this.fixMoz = false;
18104        }
18105
18106        //Preload icons and main image.	
18107        this.$image.hide();
18108        this.imgList = [
18109            {loaded: false, src: this.bu_icon || 'zoom_assets/icons.png'}, //Icon image
18110            {loaded: false, src: this.image_url == '' ? this.$image.attr('src') : this.image_url} // Main image
18111        ];
18112
18113        $.each(this.imgList, function(i) {
18114            var _img = new Image();
18115            $(_img).bind('load', {id: i, self: self}, self.loadComplete)
18116                    .bind('error', {id: i, self: self}, self.loadComplete); //Allow initiation even if image is not there :(
18117            _img.src = self.imgList[i].src;
18118        });
18119
18120    }
18121
18122    Zoomer.prototype = {
18123        /*Preload the icon and main image
18124         *********************************************************************************************************************/
18125        loadComplete: function(e) {
18126            var self = e.data.self,
18127                    complete = true;
18128
18129            self.imgList[e.data.id].loaded = true;
18130            for (var j = 0; j < self.imgList.length; j++) {
18131                if (!self.imgList[j].loaded) {
18132                    complete = false;
18133                }
18134            }
18135            if (complete) {
18136                self.assetsLoaded = true;
18137                if (self.onLOAD !== '') {
18138                    self.onLOAD();
18139                }
18140
18141                //Assets loaded, initiate plugin
18142                self.init();
18143            }
18144       },
18145        /*Initiate after assets loaded
18146         ***********************************************************************************************************************/
18147        init: function() {
18148            var self = this,
18149                    $image = self.$image,
18150                    sW = self.sW,
18151                    sH = self.sH,
18152                    container = self.container,
18153                    cBW, cBH, pan_show = self.pan_show,
18154                    zoom_show = self.zoom_show,
18155                    $controls = self.$controls,
18156                    buttons = self.buttons,
18157                    cFlag = self.cFlag,
18158                    bu_align = self.bu_align,
18159                    bu_margin = self.bu_margin,
18160                    $holder = self.$holder;
18161            if ($image) {
18162                //Store the default image properties so that it can be reverted back when plugin needs to be destroyed
18163                self.orig_style = self.getStyle();
18164
18165                //IE 6 Image tool bar disabled
18166                $image.attr('galleryimg', 'no');
18167
18168                if (!navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad)/)) {
18169                    $image.removeAttr('width');
18170                    $image.removeAttr('height');
18171                }
18172
18173                //In case parent element's display property set to 'none', we need to first set them 'block', measure the width and height and then set them back to 'none'
18174                var temp = $image,
18175                        dispArray = [];
18176                for (var i = 0; i < 5; i++) {
18177                    if (temp && temp[0].tagName !== 'BODY' && temp[0].tagName !== 'HTML') {
18178                        if (temp.css('display') == 'none') {
18179                            temp.css('display', 'block');
18180                            dispArray.push(temp);
18181                        }
18182                        temp = temp.parent();
18183                    } else {
18184                        break;
18185                    }
18186                }
18187
18188                self.iW = $image.width();
18189                self.iH = $image.height();
18190
18191                for (var i = 0; i < dispArray.length; i++) {
18192                    dispArray[i].css('display', 'none');
18193                }
18194
18195                //Initially the image needs to be resized to fit container. To do so, first measure the scaledown ratio	
18196                self.rF = self.checkRatio(sW, sH, self.iW, self.iH, self.zoom_fit);
18197
18198                //If NO Minimum zoom value set
18199                if (self.zoom_min == 0 || self.init_zoom != 0) {
18200                    if (self.init_zoom != '') {
18201                        self.rA = self._sc = self.init_zoom;
18202                    } else {
18203                        self.rA = self._sc = self.rF;
18204                    }
18205                    if (self.zoom_min == 0) {
18206                        self.rF = self.rA;
18207                    } else {
18208                        self.rF = self.zoom_min;
18209                    }
18210
18211                    //If Minimum zoom value set
18212                } else {
18213                    self.rA = self._sc = self.rF = self.zoom_min;
18214                }
18215
18216                //Width and Height to be applied to the image
18217                self._w = self._sc * self.iW;
18218                self._h = self._sc * self.iH;
18219
18220                //Resize the image and position it centered inside the wrapper
18221                if (self.init_pos == '') {
18222                    self._x = self.tX = (sW - self._w) / 2;
18223                    self._y = self.tY = (sH - self._h) / 2;
18224                } else {
18225                    self._x = self.tX = (sW / 2) - parseInt(self.init_pos[0]) * self._sc;
18226                    self._y = self.tY = (sH / 2) - parseInt(self.init_pos[1]) * self._sc;
18227                    self.oX = (self.tX - ((sW - self._w) / 2)) / (self._w / sW);
18228                    self.oY = (self.tY - ((sH - self._h) / 2)) / (self._h / sH);
18229                }
18230
18231                if ((!self.pan_limit || self._moveCursor || self.init_zoom != self.rF) && self.mouse_drag) {
18232                    $image.css('cursor', 'move');
18233                    self.$hitArea.css('cursor', 'move');
18234                }
18235
18236                if ($.browser.mozilla && supportsTrans3D) {
18237                    $image.css('opacity', 0);
18238                }
18239
18240                if (prop_transform) {
18241                    self.$image.css(prop_origin, '0 0');
18242                }
18243                if (self.use3D) {
18244                    $image.css({
18245                        '-webkit-backface-visibility': 'hidden',
18246                        '-webkit-perspective': 1000
18247                    });
18248                }
18249
18250                //Start displaying the image		
18251                $image.css({
18252                    position: 'absolute',
18253                    'z-index': supportsTouch ? 1 : 2,
18254                    left: '0px',
18255                    top: '0px',
18256                    '-webkit-box-shadow': '1px 1px rgba(0,0,0,0)'
18257                })
18258                        .hide()
18259                        .fadeIn(500, function() {
18260                    $holder.css('background-image', 'none');
18261                    if ($.browser.mozilla && supportsTrans3D) {
18262                        $image.css('opacity', 1);
18263                    }
18264                });
18265                if (supportsTouch) {
18266                    $image.bind(self.event_down, function(e) {
18267                        e.preventDefault();
18268                    });
18269                }
18270                //Create Control buttons and events				
18271                var self = self,
18272                        bs = self.bu_size,
18273                        iSize = 50,
18274                        sDiff = 2,
18275                        bSpace = 3,
18276                        mSize = Math.ceil(self.bu_size / 4),
18277                        iconOff = bs < 16 ? 50 : 0,
18278                        bsDiff = bs - sDiff;
18279
18280                //Show all buttons		
18281                if (pan_show) {
18282                    if (zoom_show) {
18283                        cBW = parseInt(bs + (bs * .85) + (bsDiff * 3) + (bSpace * 2) + (mSize * 2));
18284                    } else {
18285                        cBW = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2));
18286                    }
18287                    cBH = parseInt((bsDiff * 3) + (bSpace * 2) + (mSize * 2));
18288
18289                    //Show zoom buttons only		
18290                } else {
18291                    if (zoom_show) {
18292                        cBW = parseInt(bs + mSize * 2);
18293                        cBH = parseInt(bs * 2 + mSize * 3);
18294                        cBW = parseInt(cBW / 2) * 2;
18295                        cBH = parseInt(cBH / 2) * 2;
18296                    } else {
18297                        cBW = 0;
18298                        cBH = 0;
18299                    }
18300                }
18301
18302                var pOff = (iSize - bs) / 2,
18303                        resetCenterX = cBW - ((bs - (pan_show ? sDiff : 0)) * 2) - mSize - bSpace,
18304                        resetCenterY = (cBH / 2) - ((bs - (pan_show ? sDiff : 0)) / 2);
18305
18306                var hProp, vProp, hVal, vVal;
18307                //Align button set as per settings
18308                if (bu_align[0] == 'top') {
18309                    vProp = 'top';
18310                    vVal = bu_margin;
18311                } else if (bu_align[0] == 'center') {
18312                    vProp = 'top';
18313                    vVal = parseInt((sH - cBH) / 2);
18314                } else {
18315                    vProp = 'bottom';
18316                    vVal = bu_margin;
18317                }
18318                if (bu_align[1] == 'right') {
18319                    hProp = 'right';
18320                    hVal = bu_margin;
18321                } else if (bu_align[1] == 'center') {
18322                    hProp = 'right';
18323                    hVal = parseInt((sW - cBW) / 2);
18324                } else {
18325                    hProp = 'left';
18326                    hVal = bu_margin;
18327                }
18328
18329                //Buttons Container		
18330                $controls = $(
18331                        '<div style="position: absolute; ' + hProp + ':' + hVal + 'px; ' + vProp + ': ' + vVal + 'px; width: ' + cBW + 'px; height: ' + cBH + 'px; z-index: 20;" class="noSel;">\
18332					<div class="noSel controlsBg" style="position: relative; width: 100%; height: 100%; z-index: 1;">\
18333					</div>\
18334				</div>'
18335                        );
18336
18337                $holder.append($controls);
18338                var $controlsBg = $controls.find('.controlsBg');
18339
18340                //Make the corners rounded
18341                if (self.bu_round) {
18342                    if (prop_radius) {
18343                        $controlsBg
18344                                .css(prop_radius, (iconOff > 0 ? 4 : 5) + 'px')
18345                                .css('background-color', self.bu_bg);
18346                    } else {
18347                        self.roundBG(
18348                                $controlsBg,
18349                                'cBg',
18350                                cBW,
18351                                cBH,
18352                                iconOff > 0 ? 4 : 5,
18353                                375,
18354                                self.bu_bg,
18355                                self.bu_icon,
18356                                1,
18357                                iconOff ? 50 : 0
18358                                );
18359                    }
18360                } else {
18361                    $controlsBg.css('background-color', self.bu_bg);
18362                }
18363
18364                $controlsBg.css('opacity', self.bu_bg_alpha);
18365
18366                //Generating Button properties	(7 buttons)			
18367                buttons[0] = {
18368                    _var: '_zi',
18369                    l: mSize,
18370                    t: pan_show ? (cBH - (bs * 2) - (bSpace * 2) + 2) / 2 : mSize,
18371                    w: bs,
18372                    h: bs,
18373                    bx: -pOff,
18374                    by: -pOff - iconOff
18375                };
18376
18377                buttons[1] = {
18378                    _var: '_zo',
18379                    l: mSize,
18380                    t: pan_show ? ((cBH - (bs * 2) - (bSpace * 2) + 2) / 2) + bs + (bSpace * 2) - 2 : cBH - bs - mSize,
18381                    w: bs,
18382                    h: bs,
18383                    bx: -iSize - pOff,
18384                    by: -pOff - iconOff
18385                };
18386
18387                buttons[2] = {
18388                    _var: self.pan_rev ? '_ml' : '_mr',
18389                    l: resetCenterX - bsDiff - bSpace,
18390                    t: resetCenterY,
18391                    w: bsDiff,
18392                    h: bsDiff,
18393                    bx: -(sDiff / 2) - iSize * 2 - pOff,
18394                    by: -(sDiff / 2) - pOff - iconOff
18395                };
18396
18397                buttons[3] = {
18398                    _var: self.pan_rev ? '_mr' : '_ml',
18399                    l: resetCenterX + bsDiff + bSpace,
18400                    t: resetCenterY,
18401                    w: bsDiff,
18402                    h: bsDiff,
18403                    bx: -(sDiff / 2) - iSize * 3 - pOff,
18404                    by: -(sDiff / 2) - pOff - iconOff
18405                };
18406
18407                buttons[4] = {
18408                    _var: self.pan_rev ? '_md' : '_mu',
18409                    l: resetCenterX,
18410                    t: resetCenterY + bsDiff + bSpace,
18411                    w: bsDiff,
18412                    h: bsDiff,
18413                    bx: -(sDiff / 2) - iSize * 4 - pOff,
18414                    by: -(sDiff / 2) - pOff - iconOff
18415                };
18416
18417                buttons[5] = {
18418                    _var: self.pan_rev ? '_mu' : '_md',
18419                    l: resetCenterX,
18420                    t: resetCenterY - bsDiff - bSpace,
18421                    w: bsDiff,
18422                    h: bsDiff,
18423                    bx: -(sDiff / 2) - iSize * 5 - pOff,
18424                    by: -(sDiff / 2) - pOff - iconOff
18425                };
18426
18427                buttons[6] = {
18428                    _var: '_rs',
18429                    l: resetCenterX,
18430                    t: resetCenterY,
18431                    w: bsDiff,
18432                    h: bsDiff,
18433                    bx: -(sDiff / 2) - iSize * 6 - pOff,
18434                    by: -(sDiff / 2) - pOff - iconOff
18435                };
18436
18437                for (var i = 0; i < 7; i++) {
18438                    buttons[i].$ob = $(
18439                            '<div style="position: absolute; display: ' + (i < 2 ? zoom_show ? 'block' : 'none' : pan_show ? 'block' : 'none') + '; left: ' + (buttons[i].l - 1) + 'px; top: ' + (buttons[i].t - 1) + 'px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px;
18439 z-index:' + (i + 1) + ';" class="noSel">\
18440						</div>'
18441                            )
18442                            .css('opacity', .7)
18443                            .bind((supportsTouch ? "" : 'mouseover.sz mouseout.sz ') + self.event_down, {
18444                        id: i
18445
18446                    }, function(e) {
18447                        self._onfocus = false;
18448                        $this = $(this);
18449
18450                        //Button over 
18451                        if (e.type == 'mouseover') {
18452                            if ($this.css('opacity') > .5) {
18453                                $this.css('opacity', 1);
18454                            }
18455
18456                            //Button out 
18457                        } else if (e.type == 'mouseout') {
18458                            if ($this.css('opacity') > .5) {
18459                                $this.css('opacity', .7);
18460                            }
18461
18462                            //Button press/down
18463                        } else if (e.type == 'mousedown' || e.type == 'touchstart') {
18464                            self.cButtId = e.data.id;
18465                            self._onButton = true;
18466                            self._wheel = false;
18467
18468                            //If NOT already down..
18469                            if ($this.css('opacity') > .5) {
18470                                $this.css('opacity', 1);
18471                                $holder.find('#' + buttons[self.cButtId]._var + 'norm').hide();
18472                                $holder.find('#' + buttons[self.cButtId]._var + 'over').show();
18473
18474                                //CASE 1: If zoomIn pressed and single step zoom enabled
18475                                if (self.cButtId <= 1 && self.zoom_single) {
18476                                    if (!cFlag[buttons[self.cButtId]._var]) {
18477                                        self.sRed = 300;
18478                                        cFlag[buttons[self.cButtId]._var] = true;
18479                                    }
18480
18481                                    //CASE 2: If any button except RESET pressed
18482                                } else if (self.cButtId < 6) {
18483                                    cFlag[buttons[self.cButtId]._var] = true;
18484
18485                                    //CASE 3: RESET pressed							
18486                                } else {
18487                                    cFlag._rs = true;
18488                                    self.rA = self.rF;
18489                                    if (self.reset_align[0] == 'top') {
18490                                        self.fY = (self.sH / 2) * (self.rA / 2);
18491                                    } else if (self.reset_align[0] == 'bottom') {
18492                                        self.fY = -(self.sH / 2) * (self.rA / 2);
18493                                    } else {
18494                                        self.fY = 0;
18495                                    }
18496                                    if (self.reset_align[1] == 'left') {
18497                                        self.fX = (self.sW / 2) * (self.rA / 2);
18498                                    } else if (self.reset_align[1] == 'right') {
18499                                        self.fX = -(self.sW / 2) * (self.rA / 2);
18500                                    } else {
18501                                        self.fX = 0;
18502                                    }
18503                                }
18504
18505                                self.focusOffX = self.focusOffY = 0;
18506                                self.changeOffset(true, true);
18507                                if (!self._playing) {
18508                                    self.Animate();
18509                                }
18510                            }
18511                            e.preventDefault();
18512                            e.stopPropagation();
18513                        }
18514                    });
18515
18516                    //Make 2 BGs for Button Normal and Over state
18517                    //Button BG normal
18518                    var tpm = $(
18519                            '<div id="' + buttons[i]._var + 'norm" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px;
18519 ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\
18520					</div>'
18521                            );
18522
18523                    //Button BG hover
18524                    var tpmo = $(
18525                            '<div id="' + buttons[i]._var + 'over" style="position: absolute; left: 0px; top: 0px; width: ' + (buttons[i].w + 2) + 'px; height: ' + (buttons[i].h + 2) + 'px; display: none; ' + (prop_radius || !self.bu_round ? 'background:' + self.bu_color : '') + '">\
18526					</div>'
18527                            );
18528
18529                    //Add the button icons
18530                    var cont = $(
18531                            '<div id="' + buttons[i]._var + '_icon" style="position: absolute; left: 1px; top: 1px; width: ' + buttons[i].w + 'px; height: ' + buttons[i].h + 'px; background: transparent url(' + self.bu_icon + ') ' + buttons[i].bx + 'px ' + buttons[i].by + 'px no-repeat;" >\
18532					</div>'
18533                            );
18534
18535                    buttons[i].$ob.append(tpm, tpmo, cont);
18536                    $controls.append(buttons[i].$ob);
18537
18538                    //Apply corner radius
18539                    if (self.bu_round) {
18540                        if (prop_radius) {
18541                            tpm.css(prop_radius, '2px');
18542                            tpmo.css(prop_radius, '2px');
18543                        } else {
18544                            self.roundBG(
18545                                    tpm,
18546                                    buttons[i]._var + "norm",
18547                                    buttons[i].w,
18548                                    buttons[i].h,
18549                                    2,
18550                                    425,
18551                                    self.bu_color,
18552                                    self.bu_icon,
18553                                    i + 1,
18554                                    iconOff ? 50 : 0
18555                                    );
18556                            self.roundBG(
18557                                    tpmo,
18558                                    buttons[i]._var + "over",
18559                                    buttons[i].w + 2,
18560                                    buttons[i].h + 2,
18561                                    2,
18562                                    425,
18563                                    self.bu_color,
18564                                    self.bu_icon,
18565                                    i + 1,
18566                                    iconOff ? 50 : 0
18567                                    );
18568                        }
18569                    }
18570                }
18571
18572                //Add Events for mouse drag / touch swipe action
18573                $(document).bind(self.event_up + self.id, {self: self}, self.mouseUp);
18574
18575                if ((self.mouse_drag && !supportsTouch) || (self.touch_drag && supportsTouch)) {
18576                    if (supportsTouch) {
18577                        self.$hitArea.bind(self.event_down, {self: self}, self.mouseDown);
18578                        $(document).bind(self.event_move + self.id, {self: self}, self.mouseDrag);
18579                    } else {
18580                        self.$holder.bind(self.event_down, {self: self}, self.mouseDown);
18581                    }
18582                }
18583
18584                //Add Double click / Double tap zoom
18585                if (self.mouse_dbl_click) {
18586                    var dClickedX,
18587                            dClickedY,
18588                            dbl_click_dir = 1;
18589
18590                    (supportsTouch ? self.$hitArea : self.$holder).bind('dblclick.sz', function(e) {
18591                        self.focusOffX = e.pageX - $holder.offset().left - (self.sW / 2);
18592                        self.focusOffY = e.pageY - $holder.offset().top - (self.sH / 2);
18593                        self.changeOffset(true, true);
18594                        self._wheel = false;
18595
18596                        if (self.rA < self.zoom_max && dbl_click_dir == -1 && dClickedX != self.focusOffX && dClickedY != self.focusOffY) {
18597                            dbl_click_dir = 1;
18598                        }
18599
18600                        dClickedX = self.focusOffX;
18601                        dClickedY = self.focusOffY;
18602
18603                        if (self.rA >= self.zoom_max && dbl_click_dir == 1) {
18604                            dbl_click_dir = -1;
18605                        }
18606                        if (self.rA <= self.rF && dbl_click_dir == -1) {
18607                            dbl_click_dir = 1;
18608                        }
18609                        if (dbl_click_dir > 0) {
18610                            self.rA *= 2;
18611                            self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
18612                            cFlag._zi = true;
18613                            clearTimeout(self.ani_timer);
18614                            self._playing = true;
18615                            self.Animate();
18616                            cFlag._zi = false;
18617
18618                        } else {
18619                            self.rA /= 2;
18620                            self.rA = self.rA < self.rF ? self.rF : self.rA;
18621                            cFlag._zo = true;
18622                            clearTimeout(self.ani_timer);
18623                            self._playing = true;
18624                            self.Animate();
18625                            cFlag._zo = false;
18626                        }
18627                        e.preventDefault();
18628                        e.stopPropagation();
18629                    });
18630                }
18631
18632                //Add mouse wheel event if enabled
18633                if (self.mouse_wheel) {
18634                    $holder.bind('mousewheel.sz', {self: this}, self.mouseWheel);
18635                }
18636
18637                //Auto Hide the control buttons if enabled
18638                if (self.bu_auto) {
18639                    $holder.bind('mouseleave.sz', {self: this}, self.autoHide);
18640                }
18641
18642                //Prevent Controls Bg from start dragging image
18643                $controls.bind(self.event_down, function(e) {
18644                    e.preventDefault();
18645                    e.stopPropagation();
18646                });
18647
18648                //Prevent Controls Bg from double click zoom
18649                if (self.mouse_dbl_click) {
18650                    $controls.bind('dblclick.sz', function(e) {
18651                        e.preventDefault();
18652                        e.stopPropagation();
18653                    });
18654                }
18655
18656                //Prevent text selection for smoother dragging and button focus
18657                $('.noSel').each(function() {
18658                    this.onselectstart = function() {
18659                        return false;
18660                    };
18661                });
18662
18663                self.$holder = $holder;
18664                self.$controls = $controls;
18665                self.sW = sW;
18666                self.sH = sH;
18667                self.cBW = cBW;
18668                self.cBH = cBH;
18669
18670                //Apply initial transformation
18671                self.Animate();
18672            }
18673
18674      },
18675        /*Prepare the container (holder) element and get landmarks if available
18676         ***********************************************************************************************************************/
18677        setContainer: function() {
18678            var self = this,
18679                    $image = self.$image,
18680                    bord_size = self.bord_size,
18681                    border = self.border,
18682                    $holder = self.$holder;
18683
18684            //Wrap a container for image or get the container if specified through options:
18685            if (self.container == '' && self.image_url == '') {
18686                $holder = self.$image.wrap(
18687                        '<div class="noSel smooth_zoom_preloader">\
18688					</div>'
18689                        ).parent();
18690
18691            } else {
18692                if (self.image_url == '') {
18693                    $holder = $('#' + self.container);
18694                } else {
18695                    $holder = self.$elem;
18696                }
18697                $holder.addClass('noSel smooth_zoom_preloader');
18698                self.locations = [];
18699                self.$loc_cont = $holder.find('.landmarks');
18700                if (self.$loc_cont[0]) {
18701                    var locs = self.$loc_cont.children('.item');
18702                    self.loc_clone = self.$loc_cont.clone();
18703                    self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100;
18704                    self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale'));
18705                    self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag'));
18706                    locs.each(function() {
18707                        self.setLocation($(this));
18708                    });
18709                }
18710            }
18711
18712            $holder.css({
18713                'position': 'relative',
18714                'overflow': 'hidden',
18715                'text-align': 'left',
18716                '-moz-user-select': 'none',
18717                '-khtml-user-select': 'none',
18718                '-webkit-user-select': 'none',
18719                'user-select': 'none',
18720                '-webkit-touch-callout': 'none',
18721                '-webkit-tap-highlight-color': 'rgba(255, 255, 255, 0)',
18722                'background-color': self.bg_color,
18723                'background-position': 'center center',
18724                'background-repeat': 'no-repeat'
18725            })
18726
18727            self.$hitArea = $('<div style="position: absolute; z-index: ' + (supportsTouch ? 2 : 1) + '; top: 0px; left: 0px; width: 100%; height: 100%;" ></div>').appendTo($holder);
18728
18729            self.getContainerSize(self.sW, self.sH, $holder, self.w_max, self.h_max);
18730
18731            if (self.responsive) {
18732                $(window).bind("orientationchange.sz" + self.id + " resize.sz" + self.id, {self: self}, self.resize);
18733            }
18734            var sW = self.sW;
18735            var sH = self.sH;
18736
18737            //Add Image container properties			
18738            $holder.css({
18739                'width': sW,
18740                'height': sH
18741            });
18742
18743            //Add border if needed
18744            if (bord_size > 0) {
18745                border[0] = $('<div style="position: absolute;	width: ' + bord_size + 'px; height: ' + sH + 'px;	top: 0px; left: 0px; z-index: 3; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha);
18746                border[1] = $('<div style="position: absolute;	width: ' + bord_size + 'px; height: ' + sH + 'px;	top: 0px; left: ' + (sW - bord_size) + 'px; z-index: 4; background-color: ' + self.bord_color + ';"></div>').css('opacity', self.bord_alpha);
18747                border[2] = $('<div style="position: absolute;	width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: 0px; left: ' + bord_size + 'px; z-index: 5; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha);
18748                border[3] = $('<div style="position: absolute;	width: ' + (sW - (bord_size * 2)) + 'px; height: ' + bord_size + 'px; top: ' + (sH - bord_size) + 'px; left: ' + bord_size + 'px; z-index: 6; background-color: ' + self.bord_color + '; line-height: 1px;"></div>').css('opacity', self.bord_alpha);
18749                $holder.append(border[0], border[1], border[2], border[3]);
18750            }
18751
18752            //Get Image maps if exists
18753            if ($image.attr('usemap') != undefined) {
18754                self.mapAreas = $("map[name='" + ($image.attr('usemap').split('#').join('')) + "']").children('area');
18755                self.mapAreas.each(function(i) {
18756                    var area = $(this);
18757                    area.css('cursor', 'pointer');
18758                    if (self.mouse_drag) {
18759                        area.bind(self.event_down, {self: self}, self.mouseDown);
18760                    }
18761                    if (self.mouse_wheel) {
18762                        area.bind('mousewheel.sz', {self: self}, self.mouseWheel);
18763                    }
18764                    self.map_coordinates.push(area.attr('coords').split(','));
18765                });
18766            }
18767
18768            self.$holder = $holder;
18769            self.sW = sW;
18770            self.sH = sH;
18771        },
18772        getContainerSize: function(sW, sH, $holder, w_max, h_max) {
18773            if (sW === '' || sW === 0) {
18774                if (this.image_url == '') {
18775                    sW = Math.max($holder.parent().width(), 100);
18776                } else {
18777                    sW = Math.max($holder.width(), 100);
18778                }
18779
18780            } else if (!isNaN(sW) || String(sW).indexOf('px') > -1) {
18781                sW = this.oW = parseInt(sW);
18782                if (this.responsive) {
18783                    sW = Math.min($holder.parent().width(), sW);
18784                }
18785            } else if (String(sW).indexOf('%') > -1) {
18786                sW = $holder.parent().width() * (sW.split('%')[0] / 100);
18787            } else {
18788                sW = 100;
18789            }
18790            if (w_max !== 0 && w_max !== '') {
18791                sW = Math.min(sW, w_max);
18792            }
18793            if (sH === '' || sH === 0) {
18794                if (this.image_url == '') {
18795                    sH = Math.max($holder.parent().height(), 100);
18796                } else {
18797                    sH = Math.max($holder.height(), 100);
18798                }
18799            } else if (!isNaN(sH) || String(sH).indexOf('px') > -1) {
18800                sH = this.oH = parseInt(sH);
18801
18802            } else if (String(sH).indexOf('%') > -1) {
18803                sH = $holder.parent().height() * (sH.split('%')[0] / 100);
18804            } else {
18805                sH = 100;
18806            }
18807            if (h_max !== 0 && h_max !== '') {
18808                sH = Math.min(sH, h_max);
18809            }
18810
18811            if (this.oW && sW !== this.oW) {
18812                if (this.oH && this.maintain_ratio) {
18813                    sH = sW / (this.oW / this.oH);
18814                }
18815            }
18816
18817            this.sW = sW;
18818            this.sH = sH;
18819      },
18820        /*Each landmark / location / lable initiated here
18821         ***********************************************************************************************************************/
18822        setLocation: function(lc) {
18823            var self = this,
18824                    ob = lc,
18825                    w2, h2, pos, sc;
18826
18827            if (prop_origin) {
18828                ob.css(prop_origin, '0 0');
18829            }
18830
18831            ob.css({
18832                'display': 'block',
18833                'z-index': 2
18834            })
18835            if (self.use3D) {
18836                ob.css({
18837                    '-webkit-backface-visibility': 'hidden',
18838                    '-webkit-perspective': 1000
18839                });
18840            }
18841
18842            w2 = ob.outerWidth() / 2;
18843            h2 = ob.outerHeight() / 2;
18844            pos = ob.data('position').split(',');
18845            sc = ob.data('allow-scale');
18846            if (sc == undefined) {
18847                sc = self.allow_scale;
18848            } else {
18849                sc = checkBoolean(sc);
18850            }
18851
18852            if (ob.hasClass('mark')) {
18853                var imgw = ob.find('img').css('vertical-align', 'bottom').width();
18854                $(ob.children()[0]).css({
18855                    'position': 'absolute',
18856                    'left': (-ob.width() / 2),
18857                    'bottom': parseInt(ob.css('padding-bottom')) * 2
18858                });
18859                var txt = ob.find('.text');
18860                self.locations.push({
18861                    ob: ob,
18862                    x: parseInt(pos[0]),
18863                    y: parseInt(pos[1]),
18864                    w2: w2,
18865                    h2: h2,
18866                    w2pad: w2 + (txt[0] ? parseInt(txt.css('padding-left')) : 0),
18867                    vis: false,
18868                    lab: false,
18869                    lpx: '0',
18870                    lpy: '0',
18871                    showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100,
18872                    scale: sc
18873                });
18874
18875            } else if (ob.hasClass('lable')) {
18876                var bg = ob.data('bg-color'),
18877                        opacity = ob.data('bg-opacity'),
18878                        cont = $(ob.eq(0).children()[0])
18879                        .css({
18880                    'position': 'absolute',
18881                    'z-index': 2,
18882                    left: -w2,
18883                    top: -h2
18884                });
18885
18886                self.locations.push({
18887                    ob: ob,
18888                    x: parseInt(pos[0]),
18889                    y: parseInt(pos[1]),
18890                    w2: w2,
18891                    h2: h2,
18892                    w2pad: w2,
18893                    vis: false,
18894                    lab: true,
18895                    lpx: '0',
18896                    lpy: '0',
18897                    showAt: isNaN(ob.data('show-at-zoom')) ? self.show_at_zoom : parseInt(ob.data('show-at-zoom'), 10) / 100,
18898                    scale: sc
18899                });
18900
18901                if (bg !== "") {
18902                    if (!bg) {
18903                        bg = "#000000";
18904                        opacity = .7;
18905                    }
18906                    var bgob = $('<div style="position: absolute; left: ' + (-w2) + 'px; top: ' + (-h2) + 'px; width: ' + ((w2 - parseInt(cont.css('padding-left'))) * 2) + 'px; height:' + ((h2 - parseInt(cont.css('padding-top'))) * 2) + 'px; background-color: ' + bg + ';"></div>').appendTo(ob);
18907                    if (opacity) {
18908                        bgob.css('opacity', opacity);
18909                    }
18910                }
18911            }
18912            ob.hide();
18913            if (prop_transform) {
18914                ob.css('opacity', 0);
18915            }
18916            if (!self.allow_drag) {
18917                ob.bind(self.event_down, function(e) {
18918                    e.preventDefault();
18919                    e.stopPropagation();
18920                });
18921            } else {
18922                ob.css('pointer-events', 'none');
18923            }
18924        },
18925        /*Storing the original style of image (needed only when destroying)
18926         ***********************************************************************************************************************/
18927        getStyle: function() {
18928            if (this.$image) {
18929                var el = this.$image;
18930                return {
18931                    prop_origin: [prop_origin, prop_origin !== false && prop_origin !== undefined ? el.css(prop_origin) : null],
18932                    prop_transform: [prop_transform, prop_transform !== false && prop_transform !== undefined ? el.css(prop_transform) : null],
18933                    'position': ['position', el.css('position')],
18934                    'z-index': ['z-index', el.css('z-index')],
18935                    'cursor': ['cursor', el.css('cursor')],
18936                    'left': ['left', el.css('left')],
18937                    'top': ['top', el.css('top')],
18938                    'width': ['width', el.css('width')],
18939                    'height': ['height', el.css('height')]
18940                };
18941            }
18942        },
18943        /*Find the scale ratios
18944         ***********************************************************************************************************************/
18945        checkRatio: function(sW, sH, iW, iH, zoom_fit) {
18946            var rF;
18947            if (iW == sW && iH == sH) {
18948                rF = 1;
18949            } else if (iW < sW && iH < sH) {
18950                rF = sW / iW;
18951                if (zoom_fit) {
18952                    if (rF * iH > sH) {
18953                        rF = sH / iH;
18954                    }
18955                } else {
18956                    if (rF * iH < sH) {
18957                        rF = sH / iH;
18958                    }
18959                    if (sW / iW !== sH / iH && this.mouse_drag) {
18960                        this._moveCursor = true;
18961                        this.$image.css('cursor', 'move');
18962                        this.$hitArea.css('cursor', 'move');
18963                    }
18964                }
18965            } else {
18966
18967                rF = sW / iW;
18968                if (zoom_fit) {
18969                    if (rF * iH > sH) {
18970                        rF = sH / iH;
18971                    }
18972                    if (rF < this.init_zoom && this.mouse_drag) {
18973                        this._moveCursor = true;
18974                        this.$image.css('cursor', 'move');
18975                        this.$hitArea.css('cursor', 'move');
18976                    }
18977                } else {
18978                    if (rF * iH < sH) {
18979                        rF = sH / iH;
18980                    }
18981                    if (sW / iW !== sH / iH && this.mouse_drag) {
18982                        this._moveCursor = true;
18983                        this.$image.css('cursor', 'move');
18984                        this.$hitArea.css('cursor', 'move');
18985                    }
18986                }
18987            }
18988            return rF;
18989      },
18990        /*Returns distance between 2 points (used for touch gesture)
18991         ***********************************************************************************************************************/
18992        getDistance: function(x1, y1, x2, y2) {
18993            return Math.sqrt(Math.abs(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))));
18994        },
18995        /*Image Events for Dragging and Mouse Wheel
18996         ***********************************************************************************************************************/
18997        mouseDown: function(e) {
18998            var self = e.data.self;
18999            self._onfocus = self._dragging = false;
19000            if (self.cFlag._nd) {
19001                if (self.fixMoz) {
19002                    self.correctTransValue();
19003                }
19004                if (e.type == 'mousedown') {
19005                    self.offX = e.pageX - self.$holder.offset().left - self.$image.position().left;
19006                    self.offY = e.pageY - self.$holder.offset().top - self.$image.position().top;
19007                    $(document).bind(self.event_move + self.id, {self: self}, self.mouseDrag);
19008                } else {
19009                    var te = e.originalEvent;
19010                    if (te.targetTouches.length > 1) {
19011                        self._pinching = true;
19012                        self._rA = self.rA;
19013                        self.dStart = self.getDistance(te.touches[0].pageX, te.touches[0].pageY, te.touches[1].pageX, te.touches[1].pageY);
19014                    } else {
19015                        self.offX = te.touches[0].pageX - self.$holder.offset().left - self.$image.position().left;
19016                        self.offY = te.touches[0].pageY - self.$holder.offset().top - self.$image.position().top;
19017                        self.setDraggedPos(te.touches[0].pageX - self.$holder.offset().left - self.offX, te.touches[0].pageY - self.$holder.offset().top - self.offY, self._sc);
19018                        self._recent = 'drag';
19019                        self._dragging = true;
19020                    }
19021                }
19022                self._onHitArea = true;
19023            }
19024            e.preventDefault();
19025            if (e.type !== 'mousedown') {
19026                e.stopPropagation();
19027            }
19028      },
19029        /*Mouse Drag / Touch swipe operations handled here
19030         ***********************************************************************************************************************/
19031        mouseDrag: function(e) {
19032            var self = e.data.self;
19033
19034            //Mouse
19035            if (e.type == 'mousemove') {
19036                self.setDraggedPos(e.pageX - self.$holder.offset().left - self.offX, e.pageY - self.$holder.offset().top - self.offY, self._sc);
19037                self._recent = 'drag';
19038                self._dragging = true;
19039                if (!self._playing) {
19040                    self.Animate();
19041                }
19042                return false;
19043
19044                //Touch				
19045            } else {
19046                if (self._dragging || self._pinching) {
19047                    e.preventDefault();
19048                }
19049                if (self._onHitArea) {
19050                    var touches = e.originalEvent.touches;
19051                    if (self._pinching || touches.length > 1) {
19052                        if (!self._pinching) {
19053                            self._pinching = true;
19054                            self._rA = self.rA;
19055                            if (touches.length > 1) {
19056                                self.dStart = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY);
19057                            }
19058                        }
19059                        if (touches.length > 1) {
19060                            self._centx = (touches[0].pageX + touches[1].pageX) / 2;
19061                            self._centy = (touches[0].pageY + touches[1].pageY) / 2;
19062                            self.focusOffX = self._centx - self.$holder.offset().left - (self.sW / 2);
19063                            self.focusOffY = self._centy - self.$holder.offset().top - (self.sH / 2);
19064                            self.changeOffset(true, true);
19065                            self._wheel = true;
19066                            self._dragging = false;
19067                            if (self.zoom_single) {
19068                                self.sRed = 300;
19069
19070                            } else {
19071                                self.dEnd = self.getDistance(touches[0].pageX, touches[0].pageY, touches[1].pageX, touches[1].pageY);
19072                                self.rA = self._rA * (self.dEnd / self.dStart);
19073                                self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
19074                                self.rA = self.rA < self.rF ? self.rF : self.rA;
19075                            }
19076                            if (self._sc < self.rA) {
19077                                self.cFlag._zo = false;
19078                                self.cFlag._zi = true;
19079                            } else {
19080                                self.cFlag._zi = false;
19081                                self.cFlag._zo = true;
19082                            }
19083                            if (!self._playing) {
19084                                self.Animate();
19085                            }
19086                        }
19087
19088                    } else if (self._dragging && touches.length < 2) {
19089                        self.setDraggedPos(touches[0].pageX - self.$holder.offset().left - self.offX, touches[0].pageY - self.$holder.offset().top - self.offY, self._sc);
19090                        self._recent = 'drag';
19091                        if (!self._playing) {
19092                            self.Animate();
19093                        }
19094                    }
19095                }
19096            }
19097      },
19098        /*Global Mouse Up / Touch End
19099         ***********************************************************************************************************************/
19100        mouseUp: function(e) {
19101            var self = e.data.self;
19102
19103            //If one of the buttons released
19104            if (self._onButton) {
19105                self.$holder.find('#' + self.buttons[self.cButtId]._var + 'norm').show();
19106                self.$holder.find('#' + self.buttons[self.cButtId]._var + 'over').hide();
19107                if (self.cButtId !== 6) {
19108                    self.cFlag[self.buttons[self.cButtId]._var] = false;
19109                }
19110                if (e.type == 'touchend' && self.buttons[self.cButtId].$ob.css('opacity') > .5) {
19111                    self.buttons[self.cButtId].$ob.css('opacity', .7);
19112                }
19113                self._onButton = false;
19114                e.stopPropagation();
19115                return false;
19116
19117                //If the mouse drag or touch swipe completed
19118            } else if (self._onHitArea) {
19119                if (self.mouse_drag || self.touch_drag) {
19120                    //Mouse					
19121                    if (e.type == 'mouseup') {
19122                        $(document).unbind(self.event_move + self.id);
19123                        self._recent = 'drag';
19124                        self._dragging = false;
19125                        if (!self._playing) {
19126                            self.Animate();
19127                        }
19128                        self._onHitArea = false;
19129
19130                        //Touch
19131                    } else {
19132                        e.preventDefault();
19133                        self._dragging = false;
19134                        if (self._pinching) {
19135                            self._pinching = false;
19136                            self._wheel = false;
19137                            self.cFlag._nd = true;
19138                            self.cFlag._zi = false;
19139                            self.cFlag._zo = false;
19140                        } else {
19141                            self._recent = 'drag';
19142                            if (!self._playing) {
19143                                self.Animate();
19144                            }
19145                        }
19146                        self._onHitArea = false;
19147                    }
19148                }
19149            }
19150      },
19151        /*Mouse wheel zoom in-out
19152         ***********************************************************************************************************************/
19153        mouseWheel: function(e, delta) {
19154            var self = e.data.self;
19155            self._onfocus = self._dragging = false;
19156            if (self.mouse_wheel_cur) {
19157                self.focusOffX = e.pageX - self.$holder.offset().left - (self.sW / 2);
19158                self.focusOffY = e.pageY - self.$holder.offset().top - (self.sH / 2);
19159                self.changeOffset(true, true);
19160            }
19161
19162            self._dragging = false;
19163            if (delta > 0) {
19164                if (self.rA != self.zoom_max) {
19165                    if (self.zoom_single) {
19166                        if (!self._wheel) {
19167                            self.sRed = 300;
19168                        }
19169                    } else {
19170                        self.rA *= delta < 1 ? 1 + (.3 * delta) : 1.3;
19171                        self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
19172                    }
19173                    self._wheel = true;
19174                    self.cFlag._zi = true;
19175                    clearTimeout(self.ani_timer);
19176                    self._playing = true;
19177                    self.Animate();
19178                    self.cFlag._zi = false;
19179                }
19180            } else {
19181                if (self.rA != self.rF) {
19182                    if (self.zoom_single) {
19183                        if (!self._wheel) {
19184                            self.sRed = 300;
19185                        }
19186                    } else {
19187                        self.rA /= delta > -1 ? 1 + (.3 * -delta) : 1.3;
19188                        self.rA = self.rA < self.rF ? self.rF : self.rA;
19189                    }
19190                    self._wheel = true;
19191                    self.cFlag._zo = true;
19192                    clearTimeout(self.ani_timer);
19193                    self._playing = true;
19194                    self.Animate();
19195                    self.cFlag._zo = false;
19196                }
19197            }
19198            return false;
19199        },
19200        /*Control buttons Auto hide
19201         ***********************************************************************************************************************/
19202        autoHide: function(e) {
19203            var self = e.data.self;
19204
19205            clearTimeout(self.auto_timer);
19206            self.auto_timer = setTimeout(function() {
19207                self.$controls.fadeOut(600);
19208            }, self.bu_delay);
19209
19210            self.$holder.bind('mouseenter.sz', function(e) {
19211                clearTimeout(self.auto_timer);
19212                self.$controls.fadeIn(300);
19213            });
19214        },
19215        /*Mozilla works differently than others when getting translated positions. So this correction needed
19216         ***********************************************************************************************************************/
19217        correctTransValue: function() {
19218            var v = this.$image.css('-moz-transform').toString().replace(')', '').split(',');
19219            this.transOffX = parseInt(v[4]);
19220            this.transOffY = parseInt(v[5]);
19221        },
19222        /*Make sure the dragged position obeying limits
19223         ***********************************************************************************************************************/
19224        setDraggedPos: function(xp, yp, s) {
19225            var self = this;
19226
19227            if (xp !== '') {
19228                self.dX = xp + self.transOffX;
19229                if (self.pan_limit) {
19230                    self.dX = self.dX + (s * self.iW) < self.sW ? self.sW - (s * self.iW) : self.dX;
19231                    self.dX = self.dX > 0 ? 0 : self.dX;
19232                    if ((s * self.iW) < self.sW) {
19233                        self.dX = (self.sW - (s * self.iW)) / 2;
19234                    }
19235                } else {
19236                    self.dX = self.dX + (s * self.iW) < self.sW / 2 ? (self.sW / 2) - (s * self.iW) : self.dX;
19237                    self.dX = self.dX > self.sW / 2 ? self.sW / 2 : self.dX;
19238                }
19239            }
19240            if (yp !== '') {
19241                self.dY = yp + self.transOffY;
19242                if (self.pan_limit) {
19243                    self.dY = self.dY + (s * self.iH) < self.sH ? self.sH - (s * self.iH) : self.dY;
19244                    self.dY = self.dY > 0 ? 0 : self.dY;
19245                    if ((s * self.iH) < self.sH) {
19246                        self.dY = (self.sH - (s * self.iH)) / 2;
19247                    }
19248                } else {
19249                    self.dY = self.dY + (s * self.iH) < self.sH / 2 ? (self.sH / 2) - (s * self.iH) : self.dY;
19250                    self.dY = self.dY > self.sH / 2 ? self.sH / 2 : self.dY;
19251                }
19252            }
19253        },
19254        /*Called to animate image transformation whenever the navigation events occur
19255         ***********************************************************************************************************************/
19256        Animate: function() {
19257
19258            var self = this;
19259            var pixTol = .5;
19260
19261            self.cFlag._nd = true;
19262            self.ani_end = false;
19263
19264            //Zoom In
19265            if (self.cFlag._zi) {
19266                if (!self._wheel && !self.zoom_single) {
19267                    self.rA *= self.zoom_speed;
19268                }
19269                if (self.rA > self.zoom_max) {
19270                    self.rA = self.zoom_max;
19271                }
19272                self.cFlag._nd = false;
19273                self.cFlag._rs = false;
19274                self._recent = 'zoomIn';
19275                self._onfocus = self._dragging = false;
19276            }
19277
19278            //Zoom Out
19279            if (self.cFlag._zo) {
19280                if (!self._wheel && !self.zoom_single) {
19281                    self.rA /= self.zoom_speed;
19282                }
19283                if (self.rA < self.rF) {
19284                    self.rA = self.rF;
19285                }
19286                self.cFlag._nd = false;
19287                self.cFlag._rs = false;
19288                self._recent = 'zoomOut';
19289                self._onfocus = self._dragging = false;
19290            }
19291
19292            //Zoom In or Out - Single Step
19293            if (self.zoom_single && !self.cFlag._rs) {
19294                if (self._recent == 'zoomIn') {
19295                    self.sRed += (10 - self.sRed) / 6;
19296                    self.rA += (self.zoom_max - self.rA) / (((1 / (self.pan_speed_o + 1)) * self.sRed) + 1);
19297
19298                } else if (self._recent == 'zoomOut') {
19299                    self.sRed += (3 - self.sRed) / 3;
19300                    self.rA += (self.rF - self.rA) / (((1 / self.pan_speed_o + 1) * self.sRed) + 1);
19301                }
19302            }
19303
19304            //Pan speed needs to adjust according to application dimension and zoom level
19305            self.pan_speed = (Math.max(1, 1 + ((self.sW + self.sH) / 500)) + (self.pan_speed_o * self.pan_speed_o / 4)) / Math.max(1, self.rA / 2);
19306
19307            //Move Left
19308            if (self.cFlag._ml) {
19309                self.oX -= self.pan_speed;
19310                self.cFlag._nd = false;
19311                self.cFlag._rs = false;
19312                self._recent = 'left';
19313                self._onfocus = self._dragging = false;
19314            }
19315
19316            //Move Right
19317            if (self.cFlag._mr) {
19318                self.oX += self.pan_speed;
19319                self.cFlag._nd = false;
19320                self.cFlag._rs = false;
19321                self._recent = 'right';
19322                self._onfocus = self._dragging = false;
19323            }
19324
19325            //Move Up
19326            if (self.cFlag._mu) {
19327                self.oY -= self.pan_speed;
19328                self.cFlag._nd = false;
19329                self.cFlag._rs = false;
19330                self._recent = 'up';
19331                self._onfocus = self._dragging = false;
19332            }
19333
19334            //Move Down
19335            if (self.cFlag._md) {
19336                self.oY += self.pan_speed;
19337                self.cFlag._nd = false;
19338                self.cFlag._rs = false;
19339                self._recent = 'down';
19340                self._onfocus = self._dragging = false;
19341            }
19342
19343            //Reset
19344            if (self.cFlag._rs) {
19345                self.oX += (self.fX - self.oX) / 8;
19346                self.oY += (self.fY - self.oY) / 8;
19347                self.cFlag._nd = false;
19348                self._recent = 'reset';
19349                self._onfocus = self._dragging = false;
19350            }
19351
19352            //Find scale value, width and height
19353            //Case 1: Single Step Zoom
19354            if (self.zoom_single && (self._recent !== 'reset')) {
19355                if (self._onfocus) {
19356                    self._sc += (self.rA - self._sc) / self.reduction;
19357                } else {
19358                    self._sc = self.rA;
19359                }
19360
19361                //Case 2: Normal Zoom
19362            } else {
19363                self._sc += (self.rA - self._sc) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
19364            }
19365
19366            self._w = self._sc * self.iW;
19367            self._h = self._sc * self.iH;
19368
19369            //Dragging
19370            if (self._dragging) {
19371                self.tX = self.dX;
19372                self.tY = self.dY;
19373                self.changeOffset(true, true);
19374            }
19375
19376            //Check if Zoom In completed
19377            if (self._recent == "zoomIn") {
19378                if (self._w > (self.rA * self.iW) - pixTol && !self.zoom_single) {
19379                    if (self.cFlag._nd) {
19380                        self.ani_end = true;
19381                    }
19382                    self._sc = self.rA;
19383                } else if (self._w > (self.zoom_max * self.iW) - pixTol && self.zoom_single) {
19384                    if (self.cFlag._nd) {
19385                        self.ani_end = true;
19386                    }
19387                    self._sc = self.rA = self.zoom_max;
19388                }
19389                if (self.ani_end) {
19390                    self._w = self._sc * self.iW;
19391                    self._h = self._sc * self.iH;
19392                }
19393
19394                //Check if Zoom Out completed
19395            } else if (self._recent == "zoomOut") {
19396                if (self._w < (self.rA * self.iW) + pixTol && !self.zoom_single) {
19397                    if (self.cFlag._nd) {
19398                        self.ani_end = true;
19399                    }
19400                    self._sc = self.rA;
19401                } else if (self._w < (self.rF * self.iW) + pixTol && self.zoom_single) {
19402                    if (self.cFlag._nd) {
19403                        self.ani_end = true;
19404                    }
19405                    self._sc = self.rA = self.rF;
19406                }
19407                if (self.ani_end) {
19408                    self._w = self._sc * self.iW;
19409                    self._h = self._sc * self.iH;
19410                }
19411            }
19412
19413            //Move image according to boundary limits
19414            self.limitX = (((self._w - self.sW) / (self._w / self.sW)) / 2);
19415            self.limitY = (((self._h - self.sH) / (self._h / self.sH)) / 2);
19416
19417            if (!self._dragging) {
19418                if (self.pan_limit) {
19419                    if (self.oX < -self.limitX - self.focusOffX) {
19420                        self.oX = -self.limitX - self.focusOffX;
19421                    }
19422                    if (self.oX > self.limitX - self.focusOffX) {
19423                        self.oX = self.limitX - self.focusOffX;
19424                    }
19425                    if (self._w < self.sW) {
19426                        self.tX = (self.sW - self._w) / 2;
19427                        self.changeOffset(true, false);
19428                    }
19429                    if (self.oY < -self.limitY - self.focusOffY) {
19430                        self.oY = -self.limitY - self.focusOffY;
19431                    }
19432                    if (self.oY > self.limitY - self.focusOffY) {
19433                        self.oY = self.limitY - self.focusOffY;
19434                    }
19435                    if (self._h < self.sH) {
19436                        self.tY = (self.sH - self._h) / 2;
19437                        self.changeOffset(false, true);
19438                    }
19439                } else {
19440                    if (self.oX < -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW))) {
19441                        self.oX = -self.limitX - (self.focusOffX / self._w * self.sW) - ((self.sW / 2) / (self._w / self.sW));
19442                    }
19443
19444                    if (self.oX > self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW))) {
19445                        self.oX = self.limitX - (self.focusOffX / self._w * self.sW) + ((self.sW / 2) / (self._w / self.sW));
19446                    }
19447
19448                    if (self.oY < -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2))) {
19449                        self.oY = -self.limitY - (self.focusOffY / self._h * self.sH) - (self.sH / (self._h / self.sH * 2));
19450                    }
19451
19452                    if (self.oY > self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2))) {
19453                        self.oY = self.limitY - (self.focusOffY / self._h * self.sH) + (self.sH / (self._h / self.sH * 2));
19454                    }
19455                }
19456            }
19457            if (!self._dragging && self._recent != "drag") {
19458                self.tX = ((self.sW - self._w) / 2) + self.focusOffX + (self.oX * (self._w / self.sW));
19459                self.tY = ((self.sH - self._h) / 2) + self.focusOffY + (self.oY * (self._h / self.sH));
19460                if (self.ani_smooth === 1) {
19461                    self.cFlag._nd = true;
19462                    self.ani_end = true;
19463                }
19464            }
19465            if (self._recent == "zoomIn" || self._recent == "zoomOut" || self.cFlag._rs) {
19466                self._x = self.tX;
19467                self._y = self.tY;
19468            } else {
19469                self._x += (self.tX - self._x) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
19470                self._y += (self.tY - self._y) / (self.ani_smooth / (self._onfocus ? self.reduction : 1));
19471            }
19472
19473            //Check if Left movement completed
19474            if (self._recent == "left") {
19475                if (self._x < self.tX + pixTol || self.ani_smooth === 1) {
19476                    self.cFlag._nd ? self.ani_end = true : "";
19477                    self._recent = '';
19478                    self._x = self.tX;
19479                }
19480
19481                //Check if Right  movement completed
19482            } else if (self._recent == "right") {
19483                if (self._x > self.tX - pixTol || self.ani_smooth === 1) {
19484                    self.cFlag._nd ? self.ani_end = true : "";
19485                    self._recent = '';
19486                    self._x = self.tX;
19487                }
19488
19489                //Check if Up movement completed
19490            } else if (self._recent == "up") {
19491                if (self._y < self.tY + pixTol || self.ani_smooth === 1) {
19492                    self.cFlag._nd ? self.ani_end = true : "";
19493                    self._recent = '';
19494                    self._y = self.tY;
19495                }
19496
19497                //Check if Down movement completed
19498            } else if (self._recent == "down") {
19499                if (self._y > self.tY - pixTol || self.ani_smooth === 1) {
19500                    self.cFlag._nd ? self.ani_end = true : "";
19501                    self._recent = '';
19502                    self._y = self.tY;
19503                }
19504
19505                //Check if Dragging completed
19506            } else if (self._recent == "drag") {
19507                if (self._x + pixTol >= self.tX && self._x - pixTol <= self.tX && self._y + pixTol >= self.tY && self._y - pixTol <= self.tY || self.ani_smooth === 1) {
19508                    if (self._onfocus) {
19509                        self._dragging = false;
19510                    }
19511                    self.cFlag._nd ? self.ani_end = true : "";
19512                    self._recent = '';
19513                    self._x = self.tX;
19514                    self._y = self.tY;
19515                }
19516            }
19517
19518            //Check if Reset completed
19519            if (self.cFlag._rs && self._w + pixTol >= (self.rA * self.iW) && self._w - pixTol <= (self.rA * self.iW) && self.oX <= self.fX + pixTol && self.oX >
19519= self.fX - pixTol && self.oY <= self.fY + pixTol && self.oY >= self.fY - pixTol) {
19520                self.ani_end = true;
19521                self._recent = '';
19522                self.cFlag._rs = false;
19523                self.cFlag._nd = true;
19524                self._x = self.tX;
19525                self._y = self.tY;
19526                self._sc = self.rA;
19527                self._w = self._sc * self.iW;
19528                self._h = self._sc * self.iH;
19529            }
19530
19531            //When the image fits exactly to container size, disable the pan, zoom out and reset buttons
19532            if (self.rA == self.rF && self.iW * self.rA <= self.sW && self.iH * self.rA <= self.sH) {
19533                if (self.buttons[1].$ob.css('opacity') > .5) {
19534                    if (self.rA >= self.rF && (self.init_zoom == '' || self.rA < self.init_zoom) && (self.zoom_min == '' || self.rA < self.zoom_min)) {
19535                        if (self.pan_limit && self._moveCursor && !self._moveCursor) {
19536                            self.$image.css('cursor', 'default');
19537                            self.$hitArea.css('cursor', 'default');
19538                        }
19539                        for (var bEn = 1; bEn < (self.pan_limit && !self._moveCursor ? self.buttons_total : 2); bEn++) {
19540                            self.buttons[bEn].$ob.css({
19541                                'opacity': .4
19542                            });
19543                            self._wheel = false;
19544                            self.$holder.find('#' + self.buttons[bEn]._var + 'norm').show();
19545                            self.$holder.find('#' + self.buttons[bEn]._var + 'over').hide();
19546                        }
19547                    }
19548                }
19549
19550            } else {
19551                if (self.buttons[1].$ob.css('opacity') < .5) {
19552                    if (self._moveCursor && self.mouse_drag) {
19553                        self.$image.css('cursor', 'move');
19554                        self.$hitArea.css('cursor', 'move');
19555                    }
19556                    for (var bEn = 1; bEn < self.buttons_total; bEn++) {
19557                        self.buttons[bEn].$ob.css('opacity', .7);
19558                    }
19559                }
19560            }
19561
19562            //When the image reaches max zoom, disable the zoom button
19563            if (self.rA == self.zoom_max) {
19564                if (self.buttons[0].$ob.css('opacity') > .5) {
19565                    self.buttons[0].$ob.css('opacity', .4);
19566                    self._wheel = false;
19567                    self.$holder.find('#' + self.buttons[0]._var + 'norm').show();
19568                    self.$holder.find('#' + self.buttons[0]._var + 'over').hide();
19569                }
19570
19571            } else {
19572                if (self.buttons[0].$ob.css('opacity') < .5) {
19573                    self.buttons[0].$ob.css('opacity', .7);
19574                }
19575            }
19576
19577            //Apply Scale and position to the image:
19578            if (prop_transform) {
19579                self.$image.css(prop_transform, 'translate(' + self._x.toFixed(14) + 'px,' + self._y.toFixed(14) + 'px) scale(' + self._sc + ')');
19580
19581            } else {
19582                self.$image.css({
19583                    left: self._x,
19584                    top: self._y,
19585                    width: self._w,
19586                    height: self._h
19587                });
19588            }
19589
19590            if (self.$loc_cont) {
19591                self.updateLocations(self._x, self._y, self._sc, self.locations);
19592            }
19593
19594            //In case image Maps used, update them
19595            if (!prop_transform && self.map_coordinates.length > 0) {
19596                self.updateMap();
19597            }
19598            //If the animation completed, stop running; else continue	
19599            if (self.ani_end && !self._dragging && self._recent != "drag") {
19600                self._playing = false;
19601                self._recent = '';
19602                self.cX = (-self._x + (self.sW / 2)) / self.rA;
19603                self.cY = (-self._y + (self.sH / 2)) / self.rA;
19604                if (self.onUPDATE) {
19605                    self.onUPDATE(self.getZoomData(), false);
19606                }
19607                if (self.onZOOM_PAN) {
19608                    self.onZOOM_PAN(self.getZoomData());
19609                }
19610                clearTimeout(self.ani_timer);
19611            } else {
19612                self._playing = true;
19613                if (self.onUPDATE) {
19614                    self.onUPDATE(self.getZoomData(), true);
19615                }
19616                self.ani_timer = setTimeout(function() {
19617                    self.Animate();
19618                }, 28);
19619            }
19620      },
19621        /*Relocate the landmarks according to main image's position
19622         ***********************************************************************************************************************/
19623        updateLocations: function(_x, _y, _sc, loc) {
19624
19625            if (this.onLANDMARK !== '') {
19626                if (_sc >= this.show_at_zoom) {
19627                    if (!this._landmark) {
19628                        this._landmark = true
19629                        this.onLANDMARK(true);
19630                    }
19631                } else {
19632                    if (this._landmark) {
19633                        this._landmark = false;
19634                        this.onLANDMARK(false);
19635                    }
19636                }
19637            }
19638
19639            for (var p = 0; p < loc.length; p++) {
19640                var wScaled,
19641                        hScaled,
19642                        lpx = (loc[p].x * _sc) + _x,
19643                        lpy = (loc[p].y * _sc) + _y;
19644
19645                if (_sc >= loc[p].showAt) {
19646                    if (loc[p].scale && prop_transform) {
19647                        wScaled = loc[p].w2pad * this._sc;
19648                        hScaled = loc[p].h2 * this._sc;
19649                    } else {
19650                        wScaled = loc[p].w2pad;
19651                        hScaled = loc[p].h2;
19652                    }
19653                    if (lpx > -wScaled && lpx < this.sW + wScaled && ((lpy > -hScaled && lpy < this.sH + hScaled && loc[p].lab) || (lpy > 0 && lpy < this.sH + (hScaled * 2) && !loc[p].lab))) {
19654                        if (!loc[p].vis) {
19655                            loc[p].vis = true;
19656                            if (prop_transform) {
19657                                loc[p].ob.stop()
19658                                        .css('display', 'block')
19659                                        .animate({
19660                                    opacity: 1
19661                                }, 300);
19662                            } else {
19663                                loc[p].ob.show();
19664                            }
19665                        }
19666                    } else {
19667                        if (loc[p].vis) {
19668                            loc[p].vis = false;
19669                            if (prop_transform) {
19670                                loc[p].ob.stop()
19671                                        .animate({
19672                                    opacity: 0
19673                                }, 200, function() {
19674                                    $(this).hide();
19675                                });
19676                            } else {
19677                                loc[p].ob.hide();
19678                            }
19679                        }
19680                    }
19681                } else {
19682                    if (loc[p].vis) {
19683                        loc[p].vis = false;
19684                        if (prop_transform) {
19685                            loc[p].ob.stop()
19686                                    .animate({
19687                                opacity: 0
19688                            }, 200, function() {
19689                                $(this).hide();
19690                            });
19691                        } else {
19692                            loc[p].ob.hide();
19693                        }
19694                    }
19695                }
19696                if (lpx !== loc[p].lpx || lpy !== loc[p].lpy && loc[p].vis) {
19697                    if (prop_transform) {
19698                        loc[p].ob.css(prop_transform, 'translate(' + lpx.toFixed(14) + 'px,' + lpy.toFixed(14) + 'px)' + (loc[p].scale ? ' scale(' + this._sc + ')' : ''));
19699                    } else {
19700                        loc[p].ob.css({
19701                            left: lpx,
19702                            top: lpy
19703                        });
19704                    }
19705                }
19706                loc[p].lpx = lpx;
19707                loc[p].lpy = lpy;
19708            }
19709        },
19710        /*If the broswer doesn't supports css border radius, we need to go with old school png image for roun
19710ded corner
19711         ***********************************************************************************************************************/
19712        roundBG: function(el, _name, _w, _h, _r, _p, _c, _i, _z, _yoff) {
19713            var w = 50 / 2;
19714
19715            el.append($(
19716                    '<div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-(w - _r) - _yoff) + 'px"></div>\
19717				<div class="bgh' + _name + '"></div>\
19718				<div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-(w - _r) - _yoff) + 'px; left:' + (_w - _r) + 'px"></div>\
19719				<div class="bgi' + _name + '" style="background-position:' + (-(_p - _r)) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px"></div>\
19720				<div class="bgh' + _name + '" style = "top:' + (_h - _r) + 'px; left:' + _r + 'px"></div>\
19721				<div class="bgi' + _name + '" style="background-position:' + (-_p) + 'px ' + (-w - _yoff) + 'px; top:' + (_h - _r) + 'px; left:' + (_w - _r) + 'px"></div>\
19722				<div class="bgc' + _name + '"></div>'
19723                    ));
19724            $('.bgi' + _name).css({
19725                position: 'absolute',
19726                width: _r,
19727                height: _r,
19728                'background-image': 'url(' + _i + ')',
19729                'background-repeat': 'no-repeat',
19730                '-ms-filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)',
19731                'filter': 'progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)',
19732                'zoom': 1
19733            });
19734            $('.bgh' + _name).css({
19735                position: 'absolute',
19736                width: _w - _r * 2,
19737                height: _r,
19738                'background-color': _c,
19739                left: _r
19740            });
19741            $('.bgc' + _name).css({
19742                position: 'absolute',
19743                width: _w,
19744                height: _h - _r * 2,
19745                'background-color': _c,
19746                top: _r,
19747                left: 0
19748            });
19749      },
19750        /*To calibrate position offset when navigation events supposed to be overlapped 
19751         ***********************************************************************************************************************/
19752        changeOffset: function(x, y) {
19753            if (x)
19754                this.oX = (this.tX - ((this.sW - this._w) / 2) - this.focusOffX) / (this._w / this.sW);
19755            if (y)
19756                this.oY = (this.tY - ((this.sH - this._h) / 2) - this.focusOffY) / (this._h / this.sH);
19757        },
19758        /*Transform Image Maps (hot spots) if any
19759         ***********************************************************************************************************************/
19760        updateMap: function() {
19761            var self = this,
19762                    mapId = 0;
19763
19764            self.mapAreas.each(function() {
19765                var new_vals = [];
19766                for (var i = 0; i < self.map_coordinates[mapId].length; i++) {
19767                    new_vals[i] = self.map_coordinates[mapId][i] * self._sc;
19768                }
19769                new_vals = new_vals.join(",");
19770                $(this).attr('coords', new_vals);
19771                mapId++;
19772            });
19773        },
19774        /*To stop the timer loops immediatly
19775         ***********************************************************************************************************************/
19776        haltAnimation: function() {
19777            clearTimeout(this.ani_timer);
19778            this._playing = false;
19779            this._recent = '';
19780        },
19781        /*Method to Remove the plugin instance
19782         ***********************************************************************************************************************/
19783        destroy: function() {
19784            var self = this;
19785
19786            if (self.assetsLoaded) {
19787                self.haltAnimation();
19788                for (prop in self.orig_style) {
19789                    if (self.orig_style[prop][0] !== false && self.orig_style[prop][0] !== undefined) {
19790                        if (self.orig_style[prop][0] === 'width' || self.orig_style[prop][0] === 'height') {
19791                            if (parseInt(self.orig_style[prop][1]) !== 0) {
19792                                self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]);
19793                            }
19794                        } else {
19795                            self.$image.css(self.orig_style[prop][0], self.orig_style[prop][1]);
19796                        }
19797                    }
19798                }
19799                clearTimeout(self.auto_timer);
19800                $(document).unbind('.sz' + self.id);
19801                $(window).unbind('.sz' + self.id);
19802                self.$holder.unbind('.sz');
19803                self.$controls = undefined;
19804            } else {
19805                self.$image.show();
19806            }
19807
19808            if (self.container == '') {
19809                if (self.image_url == '') {
19810                    self.$image.insertBefore(self.$holder);
19811                    if (self.$holder !== undefined) {
19812                        self.$holder.remove();
19813                    }
19814                } else {
19815                    self.$elem.empty();
19816                    if (self.$loc_cont[0]) {
19817                        self.$elem.append(self.loc_clone);
19818                    }
19819                }
19820            } else {
19821                self.$image.insertBefore(self.$holder);
19822                self.$holder.empty();
19823                self.$image.wrap(self.$holder);
19824                if (self.$loc_cont[0]) {
19825                    self.$holder.append(self.loc_clone);
19826                }
19827            }
19828            self.$elem.removeData('smoothZoom');
19829            self.$holder = undefined;
19830            self.Buttons = undefined;
19831            self.op = undefined;
19832            self.$image = undefined;
19833       },
19834        /*Method to change focus point and level
19835         ***********************************************************************************************************************/
19836        focusTo: function(params) {
19837            var self = this;
19838
19839            if (self.assetsLoaded) {
19840                if (params.zoom === undefined || params.zoom === '' || params.zoom == 0) {
19841                    params.zoom = self.rA;
19842                } else {
19843                    params.zoom /= 100;
19844                }
19845                self._onfocus = true;
19846                if (params.zoom > self.rA && self.rA != self.zoom_max) {
19847                    self.rA = params.zoom;
19848                    self.rA = self.rA > self.zoom_max ? self.zoom_max : self.rA;
19849                } else if (params.zoom < self.rA && self.rA != self.rF) {
19850                    self.rA = params.zoom;
19851                    self.rA = self.rA < self.rF ? self.rF : self.rA;
19852                }
19853                self.transOffX = self.transOffY = 0;
19854                self.setDraggedPos(params.x === undefined || params.x === '' ? "" : (-params.x * self.rA) + (self.sW / 2), params.y === undefined || params.y === '' ? "" : (-params.y * self.rA) + (self.sH / 2), self.rA);
19855                self.reduction = params.speed ? params.speed / 10 : self.focusSpeed;
19856                self._recent = 'drag';
19857                self._dragging = true;
19858                if (!self._playing) {
19859                    self.Animate();
19860                }
19861            }
19862        },
19863        zoomIn: function(params) {
19864            this.buttons[0].$ob.trigger(this.event_down, {
19865                id: 0
19866            });
19867        },
19868        zoomOut: function(params) {
19869            this.buttons[1].$ob.trigger(this.event_down, {
19870                id: 1
19871            });
19872        },
19873        moveRight: function(params) {
19874            this.buttons[2].$ob.trigger(this.event_down, {
19875                id: 2
19876            });
19877        },
19878        moveLeft: function(params) {
19879            this.buttons[3].$ob.trigger(this.event_down, {
19880                id: 3
19881            });
19882        },
19883        moveUp: function(params) {
19884            this.buttons[4].$ob.trigger(this.event_down, {
19885                id: 4
19886            });
19887        },
19888        moveDown: function(params) {
19889            this.buttons[5].$ob.trigger(this.event_down, {
19890                id: 5
19891            });
19892        },
19893        Reset: function(params) {
19894            this.buttons[6].$ob.trigger(this.event_down, {
19895                id: 6
19896            });
19897        },
19898        getZoomData: function(params) {
19899            return {
19900                //x offset (without scale ratio multiplied)
19901                normX: (-this._x / this.rA).toFixed(14),
19902                //y offset (without scale ratio multiplied)
19903                normY: (-this._y / this.rA).toFixed(14),
19904                //Original image Width
19905                normWidth: this.iW,
19906                //Original image height
19907                normHeight: this.iH,
19908                //x offset (with scale ratio multiplied)
19909                scaledX: -this._x.toFixed(14),
19910                //y offset (with scale ratio multiplied)
19911                scaledY: -this._y.toFixed(14),
19912                //Scaled image width
19913                scaledWidth: this._w,
19914                //Scaled image height
19915                scaledHeight: this._h,
19916                //The X location on image which is currently on center of canvas 
19917                centerX: (-this._x.toFixed(14) + (this.sW / 2)) / this.rA,
19918                //The Y location on image which is currently on center of canvas 
19919                centerY: (-this._y.toFixed(14) + (this.sH / 2)) / this.rA,
19920                //Scale ratio
19921                ratio: this.rA
19922            };
19923        },
19924        addLandmark: function(loc) {
19925            if (this.$loc_cont) {
19926                var total = loc.length;
19927
19928                for (var i = 0; i < total; i++) {
19929                    var $loc = $(loc[i]);
19930                    this.$loc_cont.append($loc);
19931                    this.setLocation($loc);
19932                }
19933
19934                if (total > 0) {
19935                    this.updateLocations(this._x, this._y, this._sc, this.locations);
19936                }
19937            }
19938        },
19939        attachLandmark: function(loc) {
19940            if (this.$loc_cont) {
19941                var total = loc.length;
19942                for (var i = 0; i < total; i++) {
19943                    this.setLocation(loc[i] instanceof jQuery ? loc[i] : $('#' + loc[i]));
19944                }
19945                if (total > 0) {
19946                    this.updateLocations(this._x, this._y, this._sc, this.locations);
19947                }
19948            }
19949        },
19950        removeLandmark: function(loc) {
19951            if (this.$loc_cont) {
19952                if (loc) {
19953                    var total = loc.length;
19954                    for (var i = 0; i < total; i++) {
19955                        for (var j = 0; j < this.locations.length; j++) {
19956                            if ((loc[i] instanceof jQuery && this.locations[j].ob[0] == loc[i][0]) || (!(loc[i] instanceof jQuery) && this.locations[j].ob.attr('id') == loc[i])) {
19957                                this.locations[j].ob.remove();
19958                                this.locations.splice(j, 1);
19959                                j--;
19960                            }
19961                        }
19962                    }
19963                } else {
19964                    if (this.locations.length > 0) {
19965                        this.locations[this.locations.length - 1].ob.remove();
19966                        this.locations.pop();
19967                    }
19968                }
19969                if (total > 0) {
19970                    this.updateLocations(this._x, this._y, this._sc, this.locations);
19971                }
19972            }
19973        },
19974        refreshAllLandmarks: function() {
19975            var self = this;
19976            var locs = self.$loc_cont.children('.item');
19977            self.show_at_zoom = parseInt(self.$loc_cont.data('show-at-zoom'), 10) / 100;
19978            self.allow_scale = checkBoolean(self.$loc_cont.data('allow-scale'));
19979            self.allow_drag = checkBoolean(self.$loc_cont.data('allow-drag'));
19980
19981            //Step 1: Remove records for which the elements no longer exist
19982            for (var i = 0; i < self.locations.length; i++) {
19983                var exists = false;
19984                locs.each(function() {
19985                    if (self.locations[i].ob[0] == $(this)[0]) {
19986                        exists = true;
19987                    }
19988                });
19989                if (!exists) {
19990                    self.locations.splice(i, 1);
19991                    i--;
19992                }
19993            }
19994
19995            //Step 2: Add new elements to record
19996            locs.each(function() {
19997                var exists = false;
19998                for (var i = 0; i < self.locations.length; i++) {
19999                    if (self.locations[i].ob[0] == $(this)[0]) {
20000                        exists = true;
20001                        break;
20002                    }
20003                }
20004                if (!exists) {
20005                    self.setLocation($(this));
20006                }
20007
20008            });
20009            this.updateLocations(this._x, this._y, this._sc, this.locations);
20010      },
20011        /*On windows resize, adjust some defaults
20012         ***********************************************************************************************************************/
20013        resize: function(e) {
20014            var self;
20015
20016            if (e.data) {
20017                e.preventDefault();
20018                self = e.data.self;
20019                var pw = self.$holder.parent().width();
20020                var ph = self.$holder.parent().height();
20021
20022                if (self.oW) {
20023                    pw = Math.min(pw, self.oW);
20024                }
20025                self.sW = pw;
20026
20027                if (self.oH) {
20028                    if (self.oW && self.maintain_ratio) {
20029                        self.sH = pw / (self.oW / self.oH);
20030                    }
20031                } else {
20032                    self.sH = ph;
20033                }
20034
20035
20036            } else {
20037                self = this;
20038                if (e.width) {
20039                    self.sW = e.width;
20040                }
20041                if (e.height) {
20042                    self.sH = e.height;
20043                }
20044                if (e.max_WIDTH) {
20045                    self.w_max = e.max_WIDTH;
20046                }
20047                if (e.max_HEIGHT) {
20048                    self.h_max = e.max_HEIGHT;
20049                }
20050            }
20051            if (self.w_max !== 0 && self.w_max !== '') {
20052                self.sW = Math.min(self.sW, self.w_max);
20053            }
20054            if (self.h_max !== 0 && self.h_max !== '') {
20055                self.sH = Math.min(self.sH, self.h_max);
20056            }
20057            self.$holder.css({
20058                'width': self.sW,
20059                'height': self.sH
20060            });
20061            if (self.bord_size > 0) {
20062                self.border[0].height(self.sH);
20063                self.border[1].css({
20064                    height: self.sH,
20065                    left: self.sW - self.bord_size
20066                });
20067                self.border[2].width(self.sW - (self.bord_size * 2));
20068                self.border[3].css({
20069                    width: self.sW - (self.bord_size * 2),
20070                    top: self.sH - self.bord_size
20071                });
20072            }
20073            if (self.bu_align[1] == 'center') {
20074                self.$controls.css('left', parseInt((self.sW - self.cBW) / 2));
20075            }
20076            if (self.bu_align[0] == 'center') {
20077                self.$controls.css('top', parseInt((self.sH - self.cBH) / 2));
20078            }
20079
20080            if (self.zoom_min == 0) {
20081                self.rF = self.checkRatio(self.sW, self.sH, self.iW, self.iH, self.zoom_fit);
20082                if (self.rA < self.rF) {
20083                    self.rA = self.rF;
20084                }
20085            }
20086
20087            self.focusTo({
20088                x: self.cX,
20089                y: self.cY,
20090                zoom: '',
20091                speed: 10
20092            });
20093        }
20094    }
20095
20096
20097    $.fn.smoothZoom = function(params) {
20098        var self = this;
20099        var l = self.length;
20100
20101        //For single or more than one plugin instance
20102        for (var i = 0; i < l; i++) {
20103         
20103   var $elem = $(self[i]);
20104            var instance = $elem.data('smoothZoom');
20105
20106            // Case 1: Initiate the plugin if not already have an instance
20107            if (!instance) {
20108
20109                if (typeof params === 'object' || !params) {
20110                    $elem.data('smoothZoom', new Zoomer($elem, params));
20111                }
20112
20113                // Case 2: If the instance already available - Check for method call
20114            } else {
20115
20116                // getZoomData - Returns {sourceX, sourceY, sourceWidth, sourceHeight, distX, distY, distWidth, distHeight, centerX, centerY, ratio}				
20117                if (params == "getZoomData") {
20118                    return instance[params].apply(instance, Array.prototype.slice.call(arguments, 1));
20119
20120                    // destroy | focusTo | zoomIn | zoomOut | moveRight| moveLeft | moveUp | moveDown | Reset | addLandmark | removeLandmark | attachLandmark | refreshAllLandmarks
20121                } else if (instance[params]) {
20122                    instance[params].apply(instance, Array.prototype.slice.call(arguments, 1));
20123                }
20124            }
20125        }
20126
20127        //return for chainability for possible cases
20128        if (params !== "getZoomData") {
20129            return this;
20130        }
20131    };
20132
20133    function checkBoolean(_var) {
20134        if (_var === true) {
20135            return true;
20136        } else if (_var) {
20137            _var = _var.toLowerCase();
20138            if (_var == 'yes' || _var == 'true') {
20139                return true;
20140            }
20141        }
20142        return false;
20143    }
20144
20145
20146    //...................................................................................................................
20147    //Using Modernizr to check browser capabilities and property names prefixed
20148
20149    /* Modernizr 2.5.3 (Custom Build) | MIT & BSD
20150     * Build: http://www.modernizr.com/download/#-borderradius-csstransforms-csstransforms3d-touch-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
20151     */
20152    var Modernizr = function(a, b, c) {
20153        function y(a) {
20154            i.cssText = a
20155        }
20156        function z(a, b) {
20157            return y(l.join(a + ";") + (b || ""))
20158        }
20159        function A(a, b) {
20160            return typeof a === b
20161        }
20162        function B(a, b) {
20163            return!!~("" + a).indexOf(b)
20164        }
20165        function C(a, b) {
20166            for (var d in a)
20167                if (i[a[d]] !== c)
20168                    return b == "pfx" ? a[d] : !0;
20169            return!1
20170        }
20171        function D(a, b, d) {
20172            for (var e in a) {
20173                var f = b[a[e]];
20174                if (f !== c)
20175                    return d === !1 ? a[e] : A(f, "function") ? f.bind(d || b) : f
20176            }
20177            return!1
20178        }
20179        function E(a, b, c) {
20180            var d = a.charAt(0).toUpperCase() + a.substr(1), e = (a + " " + n.join(d + " ") + d).split(" ");
20181            return A(b, "string") || A(b, "undefined") ? C(e, b) : (e = (a + " " + o.join(d + " ") + d).split(" "), D(e, b, c))
20182        }
20183        var d = "2.5.3", e = {}, f = b.documentElement, g = "modernizr", h = b.createElement(g), i = h.style, j, k = {}.toString, l = " -webkit- -moz- -o- -ms- ".split(" "), m = "Webkit Moz O ms", n = m.split(" "), o = m.toLowerCase().split(" "), p = {}, q = {}, r = {}, s = [], t = s.slice, u, v = function(a, c, d, e) {
20184            var h, i, j, k = b.createElement("div"), l = b.body, m = l ? l : b.createElement("body");
20185            if (parseInt(d, 10))
20186                while (d--)
20187                    j = b.createElement("div"), j.id = e ? e[d] : g + (d + 1), k.appendChild(j);
20188            return h = ["&#173;", "<style>", a, "</style>"].join(""), k.id = g, (l ? k : m).innerHTML += h, m.appendChild(k), l || (m.style.background = "", f.appendChild(m)), i = c(k, a), l ? k.parentNode.removeChild(k) : m.parentNode.removeChild(m), !!i
20189        }, w = {}.hasOwnProperty, x;
20190        !A(w, "undefined") && !A(w.call, "undefined") ? x = function(a, b) {
20191            return w.call(a, b)
20192        } : x = function(a, b) {
20193            return b in a && A(a.constructor.prototype[b], "undefined")
20194        }, Function.prototype.bind || (Function.prototype.bind = function(b) {
20195            var c = this;
20196            if (typeof c != "function")
20197                throw new TypeError;
20198            var d = t.call(arguments, 1), e = function() {
20199                if (this instanceof e) {
20200                    var a = function() {
20201                    };
20202                    a.prototype = c.prototype;
20203                    var f = new a, g = c.apply(f, d.concat(t.call(arguments)));
20204                    return Object(g) === g ? g : f
20205                }
20206                return c.apply(b, d.concat(t.call(arguments)))
20207            };
20208            return e
20209        });
20210        var F = function(c, d) {
20211            var f = c.join(""), g = d.length;
20212            v(f, function(c, d) {
20213                var f = b.styleSheets[b.styleSheets.length - 1], h = f ? f.cssRules && f.cssRules[0] ? f.cssRules[0].cssText : f.cssText || "" : "", i = c.childNodes, j = {};
20214                while (g--)
20215                    j[i[g].id] = i[g];
20216                e.touch = "ontouchstart"in a || a.DocumentTouch && b instanceof DocumentTouch || (j.touch && j.touch.offsetTop) === 9, e.csstransforms3d = (j.csstransforms3d && j.csstransforms3d.offsetLeft) === 9 && j.csstransforms3d.offsetHeight === 3
20217            }, g, d)
20218        }([, ["@media (", l.join("touch-enabled),("), g, ")", "{#touch{top:9px;position:absolute}}"].join(""), ["@media (", l.join("transform-3d),("), g, ")", "{#csstransforms3d{left:9px;position:absolute;height:3px;}}"].join("")], [, "touch", "csstransforms3d"]);
20219        p.touch = function() {
20220            return e.touch
20221        }
20221, p.borderradius = function() {
20222            return E("borderRadius")
20223        }, p.csstransforms = function() {
20224            return!!E("transform")
20225        }, p.csstransforms3d = function() {
20226            var a = !!E("perspective");
20227            return a && "webkitPerspective"in f.style && (a = e.csstransforms3d), a
20228        };
20229        for (var G in p)
20230            x(p, G) && (u = G.toLowerCase(), e[u] = p[G](), s.push((e[u] ? "" : "no-") + u));
20231        return y(""), h = j = null, e._version = d, e._prefixes = l, e._domPrefixes = o, e._cssomPrefixes = n, e.testProp = function(a) {
20232            return C([a])
20233        }, e.testAllProps = E, e.testStyles = v, e.prefixed = function(a, b, c) {
20234            return b ? E(a, b, c) : E(a, "pfx")
20235        }, e
20236    }(this, this.document);
20237
20238    var prop_transform = Modernizr.prefixed('transform');
20239    var prop_origin = Modernizr.prefixed('transformOrigin');
20240    var prop_radius = Modernizr.prefixed('borderRadius');
20241    var supportsTrans3D = Modernizr.csstransforms3d;
20242    var supportsTouch = Modernizr.touch;
20243
20244})(jQuery, window, document);
20245
20246//End - smoothZoom
20247
20248//...................................................................................................................
20249//For mouse wheel support
20250
20251/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
20252 * Licensed under the MIT License (LICENSE.txt).
20253 *
20254 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
20255 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
20256 * Thanks to: Seamus Leahy for adding deltaX and deltaY
20257 *
20258 * Version: 3.0.6
20259 * 
20260 * Requires: 1.2.2+
20261 */
20262//(function(a){function d(b){var c=b||window.event,d=[].slice.call(arguments,1),e=0,f=!0,g=0,h=0;return b=a.event.fix(c),b.type="mousewheel",c.wheelDelta&&(e=c.wheelDelta/120),c.detail&&(e=-c.detail/3),h=e,c.axis!==undefined&&c.axis===c.HORIZONTAL_AXIS&&(h=0,g=-1*e),c.wheelDeltaY!==undefined&&(h=c.wheelDeltaY/120),c.wheelDeltaX!==undefined&&(g=-1*c.wheelDeltaX/120),d.unshift(b,e,g,h),(a.event.dispatch||a.event.handle).apply(this,d)}var b=["DOMMouseScroll","mousewheel"];if(a.event.fixHooks)for(var c=b.length;c;)a.event.fixHooks[b[--c]]=a.event.mouseHooks;a.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=b.length;a;)this.addEventListener(b[--a],d,!1);else this.onmousewheel=d},teardown:function(){if(this.remove_eventListener)for(var a=b.length;a;)this.remove_eventListener(b[--a],d,!1);else this.onmousewheel=null}},a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery)
20263
20264//...................................................................................................................
20265/**
20266 * hoverIntent is similar to jQuery's built-in "hover" method except that
20267 * instead of firing the handlerIn function immediately, hoverIntent checks
20268 * to see if the user's mouse has slowed down (beneath the sensitivity
20269 * threshold) before firing the event. The handlerOut function is only
20270 * called after a matching handlerIn.
20271 *
20272 * hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+
20273 * http://cherne.net/brian/resources/jquery.hoverIntent.html
20274 *
20275 * You may use hoverIntent under the terms of the MIT license. Basically that
20276 * means you are free to use hoverIntent as long as this header is left intact.
20277 * Copyright 2007, 2013 Brian Cherne
20278 *
20279 * // basic usage ... just like .hover()
20280 * .hoverIntent( handlerIn, handlerOut )
20281 * .hoverIntent( handlerInOut )
20282 *
20283 * // basic usage ... with event delegation!
20284 * .hoverIntent( handlerIn, handlerOut, selector )
20285 * .hoverIntent( handlerInOut, selector )
20286 *
20287 * // using a basic configuration object
20288 * .hoverIntent( config )
20289 *
20290 * @param  handlerIn   function OR configuration object
20291 * @param  handlerOut  function OR selector for delegation OR undefined
20292 * @param  selector    selector OR undefined
20293 * @author Brian Cherne <brian(at)cherne(dot)net>
20294 **/
20295(function($) {
20296    $.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
20297
20298        // default configuration values
20299        var cfg = {
20300            interval: 100,
20301            sensitivity: 7,
20302            timeout: 0
20303        };
20304
20305        if ( typeof handlerIn === "object" ) {
20306            cfg = $.extend(cfg, handlerIn );
20307        } else if ($.isFunction(handlerOut)) {
20308            cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
20309        } else {
20310            cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
20311        }
20312
20313        // instantiate variables
20314        // cX, cY = current X and Y position of mouse, updated by mousemove event
20315        // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
20316        var cX, cY, pX, pY;
20317
20318        // A private function for getting mouse position
20319        var track = function(ev) {
20320            cX = ev.pageX;
20321            cY = ev.pageY;
20322        };
20323
20324        // A private function for comparing current and previous mouse position
20325        var compare = function(ev,ob) {
20326            ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
20327            // compare mouse positions to see if they've crossed the threshold
20328            if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
20329                $(ob).off("mousemove.hoverIntent",track);
20330                // set hoverIntent state to true (so mouseOut can be called)
20331                ob.hoverIntent_s = 1;
20332                return cfg.over.apply(ob,[ev]);
20333            } else {
20334                // set previous coordinates for next time
20335                pX = cX; pY = cY;
20336                // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
20337                ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
20338            }
20339        };
20340
20341        // A private function for delaying the mouseOut function
20342        var delay = function(ev,ob) {
20343            ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
20344            ob.hoverIntent_s = 0;
20345            return cfg.out.apply(ob,[ev]);
20346        };
20347
20348        // A private function for handling mouse 'hovering'
20349        var handleHover = function(e) {
20350            // copy objects to be passed into t (required for event object to be passed in IE)
20351            var ev = jQuery.extend({},e);
20352            var ob = this;
20353
20354            // cancel hoverIntent timer if it exists
20355            if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
20356
20357            // if e.type == "mouseenter"
20358            if (e.type == "mouseenter") {
20359                // set "previous" X and Y position based on initial entry point
20360                pX = ev.pageX; pY = ev.pageY;
20361                // update "current" X and Y position based on mousemove
20362                $(ob).on("mousemove.hoverIntent",track);
20363                // start polling interval (self-calling timeout) to compare mouse coordinates over time
20364                if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
20365
20366                // else e.type == "mouseleave"
20367            } else {
20368                // unbind expensive mousemove event
20369                $(ob).off("mousemove.hoverIntent",track);
20370                // if hoverIntent state is true, then call the mouseOut function after the specified delay
20371                if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
20372            }
20373        };
20374
20375        // listen for mouseenter and mouseleave
20376        return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
20377    };
20378})(jQuery);
20379/*
20380 * jQuery Superfish Menu Plugin
20381 * Copyright (c) 2013 Joel Birch
20382 *
20383 * Dual licensed under the MIT and GPL licenses:
20384 *	http://www.opensource.org/licenses/mit-license.php
20385 *	http://www.gnu.org/licenses/gpl.html
20386 */
20387
20388(function ($) {
20389	"use strict";
20390
20391	var methods = (function () {
20392		// private properties and methods go here
20393		var c = {
20394				bcClass: 'sf-breadcrumb',
20395				menuClass: 'sf-js-enabled',
20396				anchorClass: 'sf-with-ul',
20397				menuArrowClass: 'sf-arrows'
20398			},
20399			ios = (function () {
20400				var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent);
20401				if (ios) {
20402					// iOS clicks only bubble as far as body children
20403					$(window).load(function () {
20404						$('body').children().on('click', $.noop);
20405					});
20406				}
20407				return ios;
20408			})(),
20409			wp7 = (function () {
20410				var style = document.documentElement.style;
20411				return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent));
20412			})(),
20413			toggleMenuClasses = function ($menu, o) {
20414				var classes = c.menuClass;
20415				if (o.cssArrows) {
20416					classes += ' ' + c.menuArrowClass;
20417				}
vendor: 4,516 bytes, lines 20418-20575
20418				$menu.toggleClass(classes);
20419			},
20420			setPathToCurrent = function ($menu, o) {
20421				return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels)
20422					.addClass(o.hoverClass + ' ' + c.bcClass)
20423						.filter(function () {
20424							return ($(this).children(o.popUpSelector).hide().show().length);
20425						}).removeClass(o.pathClass);
20426			},
20427			toggleAnchorClass = function ($li) {
20428				$li.children('a').toggleClass(c.anchorClass);
20429			},
20430			toggleTouchAction = function ($menu) {
20431				var touchAction = $menu.css('ms-touch-action');
20432				touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y';
20433				$menu.css('ms-touch-action', touchAction);
20434			},
20435			applyHandlers = function ($menu, o) {
20436				var targets = 'li:has(' + o.popUpSelector + ')';
20437				if ($.fn.hoverIntent && !o.disableHI) {
20438					$menu.hoverIntent(over, out, targets);
20439				}
20440				else {
20441					$menu
20442						.on('mouseenter.superfish', targets, over)
20443						.on('mouseleave.superfish', targets, out);
20444				}
20445				var touchevent = 'MSPointerDown.superfish';
20446				if (!ios) {
20447					touchevent += ' touchend.superfish';
20448				}
20449				if (wp7) {
20450					touchevent += ' mousedown.superfish';
20451				}
20452				$menu
20453					.on('focusin.superfish', 'li', over)
20454					.on('focusout.superfish', 'li', out)
20455					.on(touchevent, 'a', o, touchHandler);
20456			},
20457			touchHandler = function (e) {
20458				var $this = $(this),
20459					$ul = $this.siblings(e.data.popUpSelector);
20460
20461				if ($ul.length > 0 && $ul.is(':hidden')) {
20462					$this.one('click.superfish', false);
20463					if (e.type === 'MSPointerDown') {
20464						$this.trigger('focus');
20465					} else {
20466						$.proxy(over, $this.parent('li'))();
20467					}
20468				}
20469			},
20470			over = function () {
20471				var $this = $(this),
20472					o = getOptions($this);
20473				clearTimeout(o.sfTimer);
20474				$this.siblings().superfish('hide').end().superfish('show');
20475			},
20476			out = function () {
20477				var $this = $(this),
20478					o = getOptions($this);
20479				if (ios) {
20480					$.proxy(close, $this, o)();
20481				}
20482				else {
20483					clearTimeout(o.sfTimer);
20484					o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay);
20485				}
20486			},
20487			close = function (o) {
20488				o.retainPath = ($.inArray(this[0], o.$path) > -1);
20489				this.superfish('hide');
20490
20491				if (!this.parents('.' + o.hoverClass).length) {
20492					o.onIdle.call(getMenu(this));
20493					if (o.$path.length) {
20494						$.proxy(over, o.$path)();
20495					}
20496				}
20497			},
20498			getMenu = function ($el) {
20499				return $el.closest('.' + c.menuClass);
20500			},
20501			getOptions = function ($el) {
20502				return getMenu($el).data('sf-options');
20503			};
20504
20505		return {
20506			// public methods
20507			hide: function (instant) {
20508				if (this.length) {
20509					var $this = this,
20510						o = getOptions($this);
20511					if (!o) {
20512						return this;
20513					}
20514					var not = (o.retainPath === true) ? o.$path : '',
20515						$ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector),
20516						speed = o.speedOut;
20517
20518					if (instant) {
20519						$ul.show();
20520						speed = 0;
20521					}
20522					o.retainPath = false;
20523					o.onBeforeHide.call($ul);
20524					$ul.stop(true, true).animate(o.animationOut, speed, function () {
20525						var $this = $(this);
20526						o.onHide.call($this);
20527					});
20528				}
20529				return this;
20530			},
20531			show: function () {
20532				var o = getOptions(this);
20533				if (!o) {
20534					return this;
20535				}
20536				var $this = this.addClass(o.hoverClass),
20537					$ul = $this.children(o.popUpSelector);
20538
20539				o.onBeforeShow.call($ul);
20540				$ul.stop(true, true).animate(o.animation, o.speed, function () {
20541					o.onShow.call($ul);
20542				});
20543				return this;
20544			},
20545			destroy: function () {
20546				return this.each(function () {
20547					var $this = $(this),
20548						o = $this.data('sf-options'),
20549						$hasPopUp;
20550					if (!o) {
20551						return false;
20552					}
20553					$hasPopUp = $this.find(o.popUpSelector).parent('li');
20554					clearTimeout(o.sfTimer);
20555					toggleMenuClasses($this, o);
20556					toggleAnchorClass($hasPopUp);
20557					toggleTouchAction($this);
20558					// remove event handlers
20559					$this.off('.superfish').off('.hoverIntent');
20560					// clear animation's inline display style
20561					$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) {
20562						return style.replace(/display[^;]+;?/g, '');
20563					});
20564					// reset 'current' path classes
20565					o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass);
20566					$this.find('.' + o.hoverClass).removeClass(o.hoverClass);
20567					o.onDestroy.call($this);
20568					$this.removeData('sf-options');
20569				});
20570			},
20571			init: function (op) {
20572				return this.each(function () {
20573					var $this = $(this);
20574					if ($this.data('sf-options')) {
20575						return false;
20576					}
20577					var o = $.extend({}, $.fn.superfish.defaults, op),
20578						$hasPopUp = $this.find(o.popUpSelector).parent('li');
20579					o.$path = setPathToCurrent($this, o);
20580
20581					$this.data('sf-options', o);
20582
20583					toggleMenuClasses($this, o);
20584					toggleAnchorClass($hasPopUp);
20585					toggleTouchAction($this);
20586					applyHandlers($this, o);
20587
20588					$hasPopUp.not('.' + c.bcClass).superfish('hide', true);
20589
20590					o.onInit.call(this);
20591				});
20592			}
20593		};
20594	})();
20595
20596	$.fn.superfish = function (method, args) {
20597		if (methods[method]) {
20598			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
20599		}
20600		else if (typeof method === 'object' || ! method) {
20601			return methods.init.apply(this, arguments);
20602		}
20603		else {
20604			return $.error('Method ' +  method + ' does not exist on jQuery.fn.superfish');
20605		}
20606	};
20607
20608	$.fn.superfish.defaults = {
20609		popUpSelector: 'ul,.sf-mega', // within menu context
20610		hoverClass: 'sfHover',
20611		pathClass: 'overrideThisToUse',
20612		pathLevels: 1,
20613		delay: 800,
20614		animation: {opacity: 'show'},
20615		animationOut: {opacity: 'hide'},
20616		speed: 'normal',
20617		speedOut: 'fast',
20618		cssArrows: true,
20619		disableHI: false,
20620		onInit: $.noop,
20621		onBeforeShow: $.noop,
20622		onShow: $.noop,
20623		onBeforeHide: $.noop,
20624		onHide: $.noop,
20625		onIdle: $.noop,
20626		onDestroy: $.noop
20627	};
20628
20629	// soon to be deprecated
20630	$.fn.extend({
20631		hideSuperfishUl: methods.hide,
20632		showSuperfishUl: methods.show
20633	});
20634
20635})(jQuery);
20636
20637
20638/*
20639 * Supersubs v0.3b - jQuery plugin
20640 * Copyright (c) 2013 Joel Birch
20641 *
20642 * Dual licensed under the MIT and GPL licenses:
20643 * 	http://www.opensource.org/licenses/mit-license.php
20644 * 	http://www.gnu.org/licenses/gpl.html
20645 *
20646 *
20647 * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
20648 * their longest list item children. If you use this, please expect bugs and report them
20649 * to the jQuery Google Group with the word 'Superfish' in the subject line.
20650 *
20651 */
20652
20653;(function($){ // $ will refer to jQuery within this closure
20654
20655	$.fn.supersubs = function(options){
20656		var opts = $.extend({}, $.fn.supersubs.defaults, options);
20657		// return original object to support chaining
20658		return this.each(function() {
20659			// cache selections
20660			var $$ = $(this);
20661			// support metadata
20662			var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
20663			// cache all ul elements and show them in preparation for measurements
20664			$ULs = $$.find('ul').show();
20665			// get the font size of menu.
20666			// .css('fontSize') returns various results cross-browser, so measure an em dash instead
20667			var fontsize = $('<li id="menu-fontsize">&#8212;</li>').css({
20668				'padding' : 0,
20669				'position' : 'absolute',
20670				'top' : '-999em',
20671				'width' : 'auto'
20672			}).appendTo($$)[0].clientWidth; //clientWidth is faster than .width()
20673			// remove em dash
20674			$('#menu-fontsize').remove();
20675			// loop through each ul in menu
20676			$ULs.each(function(i) {	
20677				// cache this ul
20678				var $ul = $(this);
20679				// get all (li) children of this ul
20680				var $LIs = $ul.children();
20681				// get all anchor grand-children
20682				var $As = $LIs.children('a');
20683				// force content to one line and save current float property
20684				var liFloat = $LIs.css('white-space','nowrap').css('float');
20685				// remove width restrictions and floats so elements remain vertically stacked
20686				$ul.add($LIs).add($As).css({
20687					'float' : 'none',
20688					'width'	: 'auto'
20689				});
20690				// this ul will now be shrink-wrapped to longest li due to position:absolute
20691				// so save its width as ems.
20692				var emWidth = $ul[0].clientWidth / fontsize;
20693				// add more width to ensure lines don't turn over at certain sizes in various browsers
20694				emWidth += o.extraWidth;
20695				// restrict to at least minWidth and at most maxWidth
20696				if (emWidth > o.maxWidth)		{ emWidth = o.maxWidth; }
20697				else if (emWidth < o.minWidth)	{ emWidth = o.minWidth; }
20698				emWidth += 'em';
20699				// set ul to width in ems
20700				$ul.css('width',emWidth);
20701				// restore li floats to avoid IE bugs
20702				// set li width to full width of this ul
20703				// revert white-space to normal
20704				$LIs.css({
20705					'float' : liFloat,
20706					'width' : '100%',
20707					'white-space' : 'normal'
20708				})
20709				// update offset position of descendant ul to reflect new width of parent.
20710				// set it to 100% in case it isn't already set to this in the CSS
20711				.each(function(){
20712					var $childUl = $(this).children('ul');
20713					var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right';
20714					$childUl.css(offsetDirection,'100%');
20715				});
20716			}).hide();
20717			
20718		});
20719	};
20720	// expose defaults
20721	$.fn.supersubs.defaults = {
20722		minWidth		: 9,		// requires em unit.
20723		maxWidth		: 25,		// requires em unit.
20724		extraWidth		: 0			// extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
20725	};
20726	
20727})(jQuery); // plugin code ends
20728
20729/*
20730 * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
20731 * http://benalman.com/projects/jquery-bbq-plugin/
20732 * 
20733 * Copyright (c) 2010 "Cowboy" Ben Alman
20734 * Dual licensed under the MIT and GPL licenses.
20735 * http://benalman.com/about/license/
20736 */
20737(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}
20737function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
20738/*
20739 * jQuery hashchange event - v1.2 - 2/11/2010
20740 * http://benalman.com/projects/jquery-hashchange-plugin/
20741 * 
20742 * Copyright (c) 2010 "Cowboy" Ben Alman
20743 * Dual licensed under the MIT and GPL licenses.
20744 * http://benalman.com/about/license/
20745 */
20746(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);
20747function md5cycle(x, k) {
20748var a = x[0], b = x[1], c = x[2], d = x[3];
20749
20750a = ff(a, b, c, d, k[0], 7, -680876936);
20751d = ff(d, a, b, c, k[1], 12, -389564586);
20752c = ff(c, d, a, b, k[2], 17,  606105819);
20753b = ff(b, c, d, a, k[3], 22, -1044525330);
20754a = ff(a, b, c, d, k[4], 7, -176418897);
20755d = ff(d, a, b, c, k[5], 12,  1200080426);
20756c = ff(c, d, a, b, k[6], 17, -1473231341);
20757b = ff(b, c, d, a, k[7], 22, -45705983);
20758a = ff(a, b, c, d, k[8], 7,  1770035416);
20759d = ff(d, a, b, c, k[9], 12, -1958414417);
20760c = ff(c, d, a, b, k[10], 17, -42063);
20761b = ff(b, c, d, a, k[11], 22, -1990404162);
20762a = ff(a, b, c, d, k[12], 7,  1804603682);
20763d = ff(d, a, b, c, k[13], 12, -40341101);
20764c = ff(c, d, a, b, k[14], 17, -1502002290);
20765b = ff(b, c, d, a, k[15], 22,  1236535329);
20766
20767a = gg(a, b, c, d, k[1], 5, -165796510);
20768d = gg(d, a, b, c, k[6], 9, -1069501632);
20769c = gg(c, d, a, b, k[11], 14,  643717713);
20770b = gg(b, c, d, a, k[0], 20, -373897302);
20771a = gg(a, b, c, d, k[5], 5, -701558691);
20772d = gg(d, a, b, c, k[10], 9,  38016083);
20773c = gg(c, d, a, b, k[15], 14, -660478335);
20774b = gg(b, c, d, a, k[4], 20, -405537848);
20775a = gg(a, b, c, d, k[9], 5,  568446438);
20776d = gg(d, a, b, c, k[14], 9, -1019803690);
20777c = gg(c, d, a, b, k[3], 14, -187363961);
20778b = gg(b, c, d, a, k[8], 20,  1163531501);
20779a = gg(a, b, c, d, k[13], 5, -1444681467);
20780d = gg(d, a, b, c, k[2], 9, -51403784);
20781c = gg(c, d, a, b, k[7], 14,  1735328473);
20782b = gg(b, c, d, a, k[12], 20, -1926607734);
20783
20784a = hh(a, b, c, d, k[5], 4, -378558);
20785d = hh(d, a, b, c, k[8], 11, -2022574463);
20786c = hh(c, d, a, b, k[11], 16,  1839030562);
20787b = hh(b, c, d, a, k[14], 23, -35309556);
20788a = hh(a, b, c, d, k[1], 4, -1530992060);
20789d = hh(d, a, b, c, k[4], 11,  1272893353);
20790c = hh(c, d, a, b, k[7], 16, -155497632);
20791b = hh(b, c, d, a, k[10], 23, -1094730640);
20792a = hh(a, b, c, d, k[13], 4,  681279174);
20793d = hh(d, a, b, c, k[0], 11, -358537222);
20794c = hh(c, d, a, b, k[3], 16, -722521979);
20795b = hh(b, c, d, a, k[6], 23,  76029189);
20796a = hh(a, b, c, d, k[9], 4, -640364487);
20797d = hh(d, a, b, c, k[12], 11, -421815835);
20798c = hh(c, d, a, b, k[15], 16,  530742520);
20799b = hh(b, c, d, a, k[2], 23, -995338651);
20800
20801a = ii(a, b, c, d, k[0], 6, -198630844);
20802d = ii(d, a, b, c, k[7], 10,  1126891415);
20803c = ii(c, d, a, b, k[14], 15, -1416354905);
20804b = ii(b, c, d, a, k[5], 21, -57434055);
20805a = ii(a, b, c, d, k[12], 6,  1700485571);
20806d = ii(d, a, b, c, k[3], 10, -1894986606);
20807c = ii(c, d, a, b, k[10], 15, -1051523);
20808b = ii(b, c, d, a, k[1], 21, -2054922799);
20809a = ii(a, b, c, d, k[8], 6,  1873313359);
20810d = ii(d, a, b, c, k[15], 10, -30611744);
20811c = ii(c, d, a, b, k[6], 15, -1560198380);
20812b = ii(b, c, d, a, k[13], 21,  1309151649);
20813a = ii(a, b, c, d, k[4], 6, -145523070);
20814d = ii(d, a, b, c, k[11], 10, -1120210379);
20815c = ii(c, d, a, b, k[2], 15,  718787259);
20816b = ii(b, c, d, a, k[9], 21, -343485551);
20817
20818x[0] = add32(a, x[0]);
20819x[1] = add32(b, x[1]);
20820x[2] = add32(c, x[2]);
20821x[3] = add32(d, x[3]);
20822
20823}
20824
20825function cmn(q, a, b, x, s, t) {
20826a = add32(add32(a, q), add32(x, t));
20827return add32((a << s) | (a >>> (32 - s)), b);
20828}
20829
20830function ff(a, b, c, d, x, s, t) {
20831return cmn((b & c) | ((~b) & d), a, b, x, s, t);
20832}
20833
20834function gg(a, b, c, d, x, s, t) {
20835return cmn((b & d) | (c & (~d)), a, b, x, s, t);
20836}
20837
20838function hh(a, b, c, d, x, s, t) {
20839return cmn(b ^ c ^ d, a, b, x, s, t);
20840}
20841
20842function ii(a, b, c, d, x, s, t) {
20843return cmn(c ^ (b | (~d)), a, b, x, s, t);
20844}
20845
20846function md51(s) {
20847txt = '';
20848var n = s.length,
20849state = [1732584193, -271733879, -1732584194, 271733878], i;
20850for (i=64; i<=s.length; i+=64) {
20851md5cycle(state, md5blk(s.substring(i-64, i)));
20852}
20853s = s.substring(i-64);
20854var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
20855for (i=0; i<s.length; i++)
20856tail[i>>
208562] |= s.charCodeAt(i) << ((i%4) << 3);
20857tail[i>>2] |= 0x80 << ((i%4) << 3);
20858if (i > 55) {
20859md5cycle(state, tail);
20860for (i=0; i<16; i++) tail[i] = 0;
20861}
20862tail[14] = n*8;
20863md5cycle(state, tail);
20864return state;
20865}
20866
20867/* there needs to be support for Unicode here,
20868 * unless we pretend that we can redefine the MD-5
20869 * algorithm for multi-byte characters (perhaps
20870 * by adding every four 16-bit characters and
20871 * shortening the sum to 32 bits). Otherwise
20872 * I suggest performing MD-5 as if every character
20873 * was two bytes--e.g., 0040 0025 = @%--but then
20874 * how will an ordinary MD-5 sum be matched?
20875 * There is no way to standardize text to something
20876 * like UTF-8 before transformation; speed cost is
20877 * utterly prohibitive. The JavaScript standard
20878 * itself needs to look at this: it should start
20879 * providing access to strings as preformed UTF-8
20880 * 8-bit unsigned value arrays.
20881 */
20882function md5blk(s) { /* I figured global was faster.   */
20883var md5blks = [], i; /* Andy King said do it this way. */
20884for (i=0; i<64; i+=4) {
20885md5blks[i>>2] = s.charCodeAt(i)
20886+ (s.charCodeAt(i+1) << 8)
20887+ (s.charCodeAt(i+2) << 16)
20888+ (s.charCodeAt(i+3) << 24);
20889}
20890return md5blks;
20891}
20892
20893var hex_chr = '0123456789abcdef'.split('');
20894
20895function rhex(n)
20896{
20897var s='', j=0;
20898for(; j<4; j++)
20899s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
20900+ hex_chr[(n >> (j * 8)) & 0x0F];
20901return s;
20902}
20903
20904function hex(x) {
20905for (var i=0; i<x.length; i++)
20906x[i] = rhex(x[i]);
20907return x.join('');
20908}
20909
20910function md5(s) {
20911return hex(md51(s));
20912}
20913
20914/* this function is much faster,
20915so if possible we use it. Some IEs
20916are the only ones I know of that
20917need the idiotic second function,
20918generated by an if clause.  */
20919
20920function add32(a, b) {
20921return (a + b) & 0xFFFFFFFF;
20922}
20923
20924if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
20925function add32(x, y) {
20926var lsw = (x & 0xFFFF) + (y & 0xFFFF),
20927msw = (x >> 16) + (y >> 16) + (lsw >> 16);
20928return (msw << 16) | (lsw & 0xFFFF);
20929}
20930}
20931
20932/*! multilevelpushmenu 05-02-2016 */
20933!function(a){a.fn.multilevelpushmenu=function(b){"use strict";var c=arguments,d=null;return this.each(function(){function e(a){a.stopPropagation&&a.preventDefault?(a.stopPropagation(),a.preventDefault()):(a.cancelBubble=!0,a.returnValue=!1)}function f(b,c){return void 0==b||void 0==c?!1:void b.on(c,function(d,e){b.hide();try{if(!d.pageX||!d.pageY)return!1;e=e||{pageX:d.pageX,pageY:d.pageY};var f=document.elementFromPoint(e.pageX,e.pageY);f=3==f.nodeType?f.parentNode:f,a(f).trigger(c,e)}catch(g){a.error("Error while propagating event: "+g.message)}finally{b.show()}})}function g(){var b=a("<nav />").prop({id:S.settings.menuID,className:S.settings.wrapperClass}).appendTo(S.settings.container);h(S.settings.menu,b)}function h(b,c){void 0==b.level&&(b.level=0),a.each(b,function(){var d=a("<div />").attr({"class":"levelHolderClass"+("rtl"==S.settings.direction?" rtl":" ltr"),"data-level":b.level,style:("rtl"==S.settings.direction?"margin-right: ":"margin-left: ")+(0!=b.level||S.settings.collapsed?"-200%":0)}).appendTo(c);y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0;d.bind(R,function(a){r(a,d)}),void 0!=this.id&&d.attr({id:this.id});var e=a("<h2 />").attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}).text(this.title).appendTo(d),f=a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft":"floatRight")+" cursorPointer "+this.icon}).prependTo(e);f.bind(Q,function(a){k(a,d,b)}),b.level>0&&l(d);a("<ul />").appendTo(d);a.each(this.items,function(){p(this,d,-1)})})}function i(){var a=S.settings.container.find("nav").length>0?S.settings.container.find("nav"):S.settings.menu;return 0==a.length?!1:(a.prop({id:S.settings.menuID,className:S.settings.wrapperClass}),void j(a))}function j(b){void 0==b.level&&(b.level=0),a.each(b,function(){var c=a("<div />").attr({"class":"levelHolderClass"+("rtl"==S.settings.direction?" rtl":" ltr"),"data-level":b.level,style:("rtl"==S.settings.direction?"margin-right: ":"margin-left: ")+(0!=b.level||S.settings.collapsed?"-200%":0)}).appendTo(b);y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0;c.bind(R,function(a){r(a,c)});var d=b.children("h2");d.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}),d.appendTo(c);var e=d.children("i");e.addClass(("rtl"==S.settings.direction?"floatLeft":"floatRight")+" cursorPointer"),e.bind(Q,function(a){k(a,c,b)}),b.level>0&&l(c);var f=b.children("ul");f.appendTo(c),a.each(f.children("li"),function(){var d=a(this);d.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")});var e=d.children("a"),f=e.children("i");f.addClass("rtl"==S.settings.direction?"floatLeft":"floatRight"),d.children("ul").length>0?(e.bind(Q,function(a){n(a,c,d)}),o(e),d.level=b.level+1,j(d)):e.bind(Q,function(a){q(a,c,d)})})})}function k(b,c,d){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onTitleItemClick.apply(this,Array.prototype.slice.call([b,c,S.settings])),e(b);var f="rtl"==S.settings.direction?parseInt(c.css("margin-right"))<0:parseInt(c.css("margin-left"))<0;if(0==d.level&&f)E();else{var g=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")>c.attr("data-level")&&parseInt(a(this).css("margin-right"))>=0:a(this).attr("data-level")>c.attr("data-level")&&parseInt(a(this).css("margin-left"))>=0;return b}),h=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")<=c.attr("data-level")&&parseInt(a(this).css("margin-right"))>=0:a(this).attr("data-level")<=c.attr("data-level")&&parseInt(a(this).css("margin-left"))>=0;return b});0==g.length&&1==h.length?C():C(parseInt(c.attr("data-level")))}c.css("visibility","visible"),c.find("."+S.settings.backItemClass).css("visibility","visible"),c.find("ul").css("visibility","visible"),c.removeClass(S.settings.menuInactiveClass)}function l(b){var c=a("<div />").attr({"class":S.settings.backItemClass}).appendTo(b),d=a("<a />").prop({href:"#"}).text(S.settings.backText).appendTo(c);a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft ":"floatRight ")+S.settings.backItemIcon}).prependTo(d);d.bind(Q,function(a){m(a,b)})}function m(b,c){return a(S).find("div.levelHolderClass").is(":animated")?!1:(S.settings.onBackItemClick.apply(this,Array.prototype.slice.call([b,c,S.settings])),e(b),void C(parseInt(c.attr("data-level")-1)))}function n(b,c,d){return a(S).find("div.levelHolderClass").is(":animated")?!1:(S.settings.onGroupItemClick.apply(this,Array.prototype.slice.call([b,c,d,S.settings])),E(d.find("div:first")),void(S.settings.preventGroupItemClick&&e(b)))}function o(b){a("<i />").attr({"class":("rtl"==S.settings.direction?" floatRight iconSpacing_rtl ":" floatLeft iconSpacing_ltr ")+S.settings.groupIcon}).prependTo(b)}function p(){var b=arguments[0],c=arguments[1],d=arguments[2],e=c.find("ul:first"),f=a("<li />");d<e.children("li").length&&d>=0?f.insertBefore(e.children("li").eq(d)):f.appendTo(e),f.attr({style:"text-align: "+("rtl"==S.settings.direction?"right":"left")}),void 0!=b.id&&f.attr({id:b.id});
20933var g=a("<a />").prop({href:b.link}).text(b.name).appendTo(f);a("<i />").prop({"class":("rtl"==S.settings.direction?"floatLeft ":"floatRight ")+b.icon}).prependTo(g);b.items?(g.bind(Q,function(a){n(a,c,f)}),o(g),b.items.level=parseInt(c.attr("data-level"),10)+1,h(b.items,f)):g.bind(Q,function(a){q(a,c,f)})}function q(a,b,c){S.settings.onItemClick.apply(this,Array.prototype.slice.call([a,b,c,S.settings])),S.settings.preventItemClick&&e(a)}function r(b,c){var d=S.settings.onMenuSwipe.apply(this,Array.prototype.slice.call([b,c,S.settings]));if(0==d)return!1;if(a(S).find("div.levelHolderClass").is(":animated"))return!1;var f=c.attr("data-level")>0?c.attr("data-level")-1:void 0;if("touchmove"==b.type&&"desktop"!=S.settings.swipe){if(e(b),b=b.touches?b:b.originalEvent,!b.touches||b.touches.length<=0)return!1;var g=b.touches[0];if(S.settings.container.unbind("touchend"),S.settings.container.bind("touchend",function(a){e(a),c.significance=0,c.swipeStart=0,S.settings.container.unbind("touchend")}),void 0==c.swipeStart||0==c.swipeStart)return c.significance=0,c.swipeStart=g.pageX,!0;c.significance=g.pageX-c.swipeStart,Math.abs(c.significance)>.3*S.settings.overlapWidth&&("rtl"==S.settings.direction&&(c.significance*=-1),c.significance>0?E(void 0==f?f:c):C(f),c.significance=0,c.swipeStart=0)}else if("touchscreen"!=S.settings.swipe){e(b);var h=0;c.unbind("mousemove"),c.bind("mousemove",function(a){return h=a.clientX-b.clientX,Math.abs(h)>.3*S.settings.overlapWidth?(c.unbind("mousemove"),"rtl"==S.settings.direction&&(h*=-1),h>0?E(void 0==f?f:c):C(f),!0):void 0}),S.settings.container.unbind("mouseup"),S.settings.container.bind("mouseup",function(a){e(a),c.unbind("mousemove"),S.settings.container.unbind("mouseup")})}}function s(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b});return b.length<1&&(b=!1),b}function t(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).position().left>S.settings.container.width()||parseInt(a(this).css("margin-right"))<0:a(this).position().left<0||parseInt(a(this).css("margin-left"))<0;return b});return b.length<1&&(b=!1),b}function u(){if(!S.redraw){S.redraw=!0;var b,c=arguments[0],d=arguments[1],e=arguments[2],f=a("#"+S.settings.menuID+" div.levelHolderClass").first().css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a("#"+S.settings.menuID+" div.levelHolderClass").first().get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,g=void 0==c?Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).width()}).get())-f:c-f,h=Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).attr("data-level")}).get()),i=y(S.settings.menuWidth)||x(S.settings.menuWidth)&&S.settings.menuWidth>0,j=y(S.settings.menuHeight)||x(S.settings.menuHeight)&&S.settings.menuHeight>0,k=void 0==e?a("#"+S.settings.menuID+" div.levelHolderClass"):e;i||void 0==S.menuWidth||(g=S.menuWidth),i&&void 0==c?k.width(S.settings.menuWidth):k.width(g),i&&((0==k.width()||y(S.settings.menuWidth)&&-1!=S.settings.menuWidth.indexOf("%"))&&void 0==c&&(k.
20933css("min-width",""),k.width(parseInt(S.settings.container.parent().width()*parseInt(S.settings.menuWidth)/100))),g=k.width()-f,k.css("min-width",k.width()-f+"px"));var l=i&&void 0==c?k.width()-f+h*(S.settings.overlapWidth+f):g+h*(S.settings.overlapWidth+f),m=void 0==d?Math.max.apply(null,a("#"+S.settings.menuID+" div.levelHolderClass").map(function(){return a(this).height()}).get()):d;S.settings.container.css("min-height",""),S.settings.container.children("nav:first").css("min-height",""),j?(S.settings.container.height(S.settings.menuHeight),S.settings.container.css("min-height",S.settings.menuHeight),S.settings.container.children("nav:first").css("min-height",S.settings.menuHeight),a("#"+S.settings.menuID).height(S.settings.menuHeight),m=S.settings.container.height()):a("#"+S.settings.menuID).height(m),S.settings.container.css("min-height",m+"px"),S.settings.container.children("nav:first").css("min-height",m+"px"),S.settings.container.width(l),S.settings.container.height(m);var n=a("#"+S.settings.menuID+" div.levelHolderClass:first"),o=s(),p=t(),q=J(),r=1==q.length?q.attr("data-level"):0;o&&o.each(function(){"overlap"==S.settings.mode&&a(this).width(a(this).width()+(parseInt(r,10)-parseInt(a(this).attr("data-level"),10))*(S.settings.overlapWidth+f))}),p&&p.each(function(){"rtl"==S.settings.direction?a(this).css("margin-right",a(this).attr("data-level")!=n.attr("data-level")||S.settings.fullCollapse?-2*a(this).width():-1*a(this).width()+S.settings.overlapWidth):a(this).css("margin-left",a(this).attr("data-level")!=n.attr("data-level")||S.settings.fullCollapse?-2*a(this).width():-1*a(this).width()+S.settings.overlapWidth)}),b=n.width()+parseInt(n.css("rtl"==S.settings.direction?"margin-right":"margin-left"),10),v(S.settings.container,b),S.menuWidth=g,S.menuHeight=m,S.redraw=!1}}function v(a,b){return void 0==a||void 0==b?!1:(a.css("min-width",""),a.css("min-width",b+"px"),a.children("nav:first").css("min-width",""),a.children("nav:first").css("min-width",b+"px"),void a.width(b))}function w(){var b=a("#"+S.settings.menuID+" div.levelHolderClass:first"),c=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var c="rtl"==S.settings.direction?(a(this).position().left>S.settings.container.width()||parseInt(a(this).css("margin-right"))<0)&&a(this).attr("data-level")>b.attr("data-level"):(a(this).position().left<0||parseInt(a(this).css("margin-left"))<0)&&a(this).attr("data-level")>b.attr("data-level");return c});c.each(function(){"rtl"==S.settings.direction?a(this).css("margin-right",a(this).attr("data-level")!=b.attr("data-level")||S.settings.collapsed?-2*a(this).width():0):a(this).css("margin-left",a(this).attr("data-level")!=b.attr("data-level")||S.settings.collapsed?-2*a(this).width():0)}),"rtl"==S.settings.direction?b.css("margin-right",S.settings.collapsed?-2*b.width():0):b.css("margin-left",S.settings.collapsed?-2*b.width():0)}function x(a){return"number"==typeof a&&parseFloat(a)==parseInt(a,10)&&!isNaN(a)}function y(a){return"string"==typeof a&&(-1!=a.indexOf("%")||-1!=a.indexOf("px")||-1!=a.indexOf("em"))}function z(){b&&void 0!=b.menu?g():i();return f(S.settings.container,Q),u(),w(),A(S.settings.collapsed),S.settings.onMenuReady.apply(this,Array.prototype.slice.call([S.settings])),T}function A(b){if(b){var c=a("#"+S.settings.menuID+" div.levelHolderClass:first");c.find("ul").hide(),c.addClass(S.settings.menuInactiveClass),"rtl"==S.settings.direction?c.stop().animate({marginRight:-1*c.width()+(S.settings.fullCollapse?0:S.settings.overlapWidth)},S.settings.durationSlideOut):c.stop().animate({marginLeft:-1*c.width()+(S.settings.fullCollapse?0:S.settings.overlapWidth)},S.settings.durationSlideOut)}}function B(b){return null==S.settings.containersToPush?!1:void a.each(S.settings.containersToPush,function(){var c=parseInt(a(this).css("margin-left")),d=x(c)?c:0,e=parseInt(a(this).css("margin-right")),f=x(e)?e:0;a(this).stop().animate({marginLeft:d+("rtl"==S.settings.direction?-1:1)*b,marginRight:f+("rtl"==S.settings.direction?1:-1)*b},S.settings.durationSlideOut)})}function C(){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onCollapseMenuStart.apply(this,Array.prototype.slice.call([S.settings]));var b,c,d,e,f=arguments[0],g=arguments[1],h={},i=a("#"+S.settings.menuID+" div.levelHolderClass:first"),j=void 0==f?!0:!1;if(h.collapsingEnded=!1,"object"==typeof f)f=f.attr("data-level");else if("string"==typeof f){var k=F(f);f=k&&1==k.length?k.attr("data-level"):i.attr("data-level")}else(void 0==f||!x(f)||0>f)&&(f=i.attr("data-level"));void 0==g&&"object"!=typeof g?g=[{method:S.settings.onCollapseMenuEnd,args:[S.settings]}]:a.merge(g,[{method:S.settings.onCollapseMenuEnd,args:[S.settings]}]);var l=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")>f&&parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:a(this).attr("data-level")>f&&parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b}),m=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?a(this).attr("data-level")<=f&&parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:a(this).attr("data-level")<=f&&parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b});return m.length>0&&(h.prevAnimEnded=!1,l.each(function(d,e){b=a(e).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(e).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,c="overlap"==S.settings.mode?a(e).width()-(l.length+m.length-a(e).attr("data-level")-1)*(S.settings.overlapWidth+b)-b:a(e).width()-b,"rtl"==S.settings.direction?a(e).stop().animate({marginRight:-1*c,width:c},S.settings.durationTransition):a(e).stop().animate({marginLeft:-1*c,width:c},S.settings.durationTransition)}),h.nextAnimEnded=l.length>0?!1:!0,l.last().queue(function(){h.nextAnimEnded=!0,N(h,g)}),m.each(function(g,h){b=a(h).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(h).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0;var k=m.filter(function(){return a(this).attr("data-level")==f});if(k.css("visibility","visible"),k.find("."+S.settings.backItemClass).css("visibility","visible"),k.find("ul").css("visibility","visible"),k.removeClass(S.settings.menuInactiveClass),c="overlap"==S.settings.mode?a(h).width()-l.length*(S.settings.overlapWidth+b)-b:a(h).width()-b,"rtl"==S.settings.direction?a(h).stop().animate({width:c,marginRight:a(h).attr("data-level")==i.attr("data-level")&&j?S.settings.fullCollapse?-1*a(h).width():-1*a(h).width()+("overlap"==S.settings.mode?l.length+1:1)*S.settings.overlapWidth:0},S.settings.durationSlideOut,function(){a(h).attr("data-level")==i.attr("data-level")&&j&&i.children("ul").first().hide(S.settings.durationSlideDown,function(){i.addClass(S.settings.menuInactiveClass)}),e=i.width()+parseInt(i.css("margin-right"),10),v(S.settings.container,e)}):a(h).stop().animate({width:c,marginLeft:a(h).attr("data-level")==i.attr("data-level")&&j?S.settings.fullCollapse?-1*a(h).width():-1*a(h).width()+("overlap"==S.settings.mode?l.length+1:1)*S.settings.overlapWidth:0},S.settings.durationSlideOut,function(){a(h).attr("data-level")==i.attr("data-level")&&j&&i.children("ul").first().hide(S.settings.durationSlideDown,function(){i.addClass(S.settings.menuInactiveClass)}),e=i.width()+parseInt(i.css("margin-left"),10),v(S.settings.container,e)}),d="overlap"==S.settings.mode?-1*(l.length*(S.settings.overlapWidth+b)):0,a(h).attr("data-level")==i.attr("data-level")&&j){var n=S.settings.fullCollapse?-1*(i.width()-b):-1*(i.width()-b)+S.settings.overlapWidth;B(n)}else B(d)}),m.last().queue(function(){h.prevAnimEnded=!0,N(h,g)})),h.collapsingEnded=!0,N(h,g),T}function D(){if(a(S).find("div.levelHolderClass").is(":animated"))return!1;S.settings.onExpandMenuStart.apply(this,Array.prototype.slice.call([S.settings]));var b,c,d,e,f,g=arguments[0],h=arguments[1],i={},j=a("#"+S.settings.menuID+" div.levelHolderClass:first"),k=void 0==g?!0:!1,l="rtl"==S.settings.direction?parseInt(j.css("margin-right"),10)<0||j.position().left>=S.settings.container.width()-S.settings.overlapWidth:parseInt(j.css("margin-left"),10)<0||j.position().left<0;if(i.expandingEnded=!1,void 0==h&&"object"!=typeof h?h=[{method:S.settings.onExpandMenuEnd,args:[S.settings]}]:a.merge(h,[{method:S.settings.onExpandMenuEnd,args:[S.settings]}]),k){i.baseAnimEnded=!1,j.removeClass(S.settings.menuInactiveClass),f=j.width(),v(S.settings.container,f),"rtl"==S.settings.direction?j.stop().animate({marginRight:0},S.settings.durationSlideOut,function(){j.children("ul").first().show(S.settings.durationSlideDown,function(){i.baseAnimEnded=!0,N(i,h)})}):j.stop().animate({marginLeft:0},S.settings.durationSlideOut,function(){j.children("ul").first().show(S.settings.durationSlideDown,function(){i.baseAnimEnded=!0,N(i,h)})}),e=S.settings.fullCollapse?j.width():j.width()-S.settings.overlapWidth;K(j)?null:B(e)}else{var m;if("object"==typeof g?m=g:"string"==typeof g?m=F(g):(m=null,a.error("Provided menu selector is not val
20933id")),m&&1==m.length){var n=J(),o=1==n.length?n.attr("data-level"):0,p=m.width(),q=H(m);if(i.setToOpenAnimEnded=!1,q){var r=a(q).length-1;j.find("ul").each(function(){a(this).show(0)}),a(q).find("ul").css("visibility","hidden"),a(q).find("div").css("visibility","visible"),a(q).find("."+S.settings.backItemClass).css("visibility","hidden"),a(q).each(function(d,e){b=a(e).css("filter").match(/DXImageTransform\.Microsoft\.Shadow/)?a(e).get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength:0,c=p-b+(r-a(e).attr("data-level"))*(S.settings.overlapWidth+b),S.settings.container.width()<c&&"overlap"==S.settings.mode&&v(S.settings.container,c),"rtl"==S.settings.direction?a(e).stop().animate({marginRight:0,width:"overlap"==S.settings.mode?c:p-b},S.settings.durationTransition,function(){a(e).addClass(S.settings.menuInactiveClass)}):a(e).stop().animate({marginLeft:0,width:"overlap"==S.settings.mode?c:p-b},S.settings.durationTransition,function(){a(e).addClass(S.settings.menuInactiveClass)})}),a(q).last().queue(function(){a(this).removeClass(S.settings.menuInactiveClass),i.setToOpenAnimEnded=!0,N(i,h)}),l&&(e=S.settings.fullCollapse?j.width():j.width()-S.settings.overlapWidth,B(e)),"overlap"==S.settings.mode&&(d=l?p+(r-(S.settings.fullCollapse?0:1))*(S.settings.overlapWidth+b):(r-o)*(S.settings.overlapWidth+b),B(d)),m.css("visibility","visible"),m.find("."+S.settings.backItemClass).css("visibility","visible"),m.find("ul").css("visibility","visible"),m.removeClass(S.settings.menuInactiveClass)}else a.error("Invalid menu object provided")}else a.error("No or too many menus named "+g)}i.expandingEnded=!0,N(i,h)}function E(){var b,c,d,e,f=arguments[0],g=J();return"object"==typeof f?b=f:"string"==typeof f?(e=F(f),e?b=e.eq(0):a.error(f+" menu level does not exist!")):b=a("#"+S.settings.menuID+" div.levelHolderClass:first"),c=I(b,g,!0),d=c.length>0?Math.max.apply(null,c.map(function(){return a(this).attr("data-level")}).get()):0,d<g.attr("data-level")?C(d,[{method:D,args:arguments}]):D.apply(this,Array.prototype.slice.call(arguments)),T}function F(){var b,c=arguments[0],e=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){return a(this).children("h2").text()==c});return e.length>0?(d=e,b=d):(d=!1,b=d),b}function G(){var b,c=arguments[0],e=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass li").filter(function(){return a(this).children("a").text()==c});return e.length>0?(d=e,b=d):(d=!1,b=d),b}function H(){var b,c,e=arguments[0];return void 0==e||1!=e.length?d=!1:(b=e.parents("div.levelHolderClass"),c=a.merge(b.get().reverse(),e.get()),d=c)}function I(){var b,c,e,f,g,h,i,j=arguments[0],k=arguments[1],l=void 0!=arguments[2]?arguments[2]:!1;return void 0==j||void 0==k?d=!1:(b=1==j.length?j.parents("div.levelHolderClass"):null,c=1==k.length?k.parents("div.levelHolderClass"):null,e=null!=b?a.merge(b.get().reverse(),j.get()):[],f=null!=c?a.merge(c.get().reverse(),k.get()):[],g=e.length>=f.length?e:f,h=g===e?f:e,i=a(g).filter(function(){return l?-1!=a.inArray(this,h):-1==a.inArray(this,h)}),d=i)}function J(){var b=S.settings.container.find("#"+S.settings.menuID+" div.levelHolderClass").filter(function(){var b="rtl"==S.settings.direction?parseInt(a(this).css("margin-right"))>=0&&a(this).position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a(this).css("margin-left"))>=0&&a(this).position().left>=0;return b}),c=Math.max.apply(null,b.map(function(){return a(this).attr("data-level")}).get()),e=b.filter(function(){return a(this).attr("data-level")==c});return d=e}function K(){var a=arguments[0],b=!1;if(void 0==a)return b;var c="rtl"==S.settings.direction?parseInt(a.css("margin-right"))>=0&&a.position().left<S.settings.container.width()-S.settings.overlapWidth:parseInt(a.css("margin-left"))>=0&&a.position().left>=0;return c}function L(){var b=arguments[0],c=arguments[1],d=arguments[2];if(void 0==c||"object"!=typeof b||!c)return!1;void 0==b.level&&(b.level=parseInt(c.attr("data-level"),10)),void 0==d&&(d=0);c.find("ul:first");return a.each(b,function(){void 0!=this.name&&p(this,c,d)}),u(S.menuWidth),T}function M(){var b=arguments[0];if(void 0==b||"object"!=typeof b||0==b.length)return!1;b.remove();var c=J();if(1==c.length){c.css("visibility","visible"),c.find("."+S.settings.backItemClass).css("visibility","visible"),c.find("ul").css("visibility","visible"),c.removeClass(S.settings.menuInactiveClass);var d=c.width()-S.menuWidth;if(0!=d){var e=s();e&&e.each(function(){a(this).width(a(this).width()-d)})}}return u(S.menuWidth),T}function N(b,c){var d=!0;a.each(b,function(a,b){d=d&&b}),d&&window.setTimeout(function(){a.each(c,function(a,b){b.method.apply(this,Array.prototype.slice.call(b.args))})},1)}function O(){var b=!1;return void 0!=S.settings[arguments[0]]?(void 0!=arguments[1]&&(S.settings[arguments[0]]=arguments[1]),b=S.settings[arguments[0]]):a.error("No option "+arguments[0]+" found in jQuery.multilevelpushmenu"),b}function P(){var a=!1;return function(b){(/(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(b)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
20933sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(b.substr(0,4)))&&(a=!0)}(navigator.userAgent||navigator.vendor||window.opera),a}var Q,R,S=this,T=a(this),U=void 0!=T.context?T:a("body"),V=b&&void 0!=b.menu?b.menu:T.find("nav"),W=a.extend({container:U,containersToPush:null,menuID:(void 0!=U.prop("id")&&""!=U.prop("id")?U.prop("id"):this.nodeName.toLowerCase())+"_multilevelpushmenu",wrapperClass:"multilevelpushmenu_wrapper",menuInactiveClass:"multilevelpushmenu_inactive",menu:V,menuWidth:0,menuHeight:0,collapsed:!1,fullCollapse:!1,direction:"ltr",backText:"Back",backItemClass:"backItemClass",backItemIcon:"fa fa-angle-right",groupIcon:"fa fa-angle-left",mode:"overlap",overlapWidth:40,preventItemClick:!0,preventGroupItemClick:!0,swipe:"both",durationSlideOut:400,durationSlideDown:500,durationTransition:400,onCollapseMenuStart:function(){},onCollapseMenuEnd:function(){},onExpandMenuStart:function(){},onExpandMenuEnd:function(){},onGroupItemClick:function(){},onItemClick:function(){},onTitleItemClick:function(){},onBackItemClick:function(){},onMenuReady:function(){},onMenuSwipe:function(){}},b);a.data(S,"plugin_multilevelpushmenu")||(a.data(S,"plugin_multilevelpushmenu",W),S.settings=a.data(S,"plugin_multilevelpushmenu"));var X={init:function(){return z.apply(this,Array.prototype.slice.call(arguments))},collapse:function(){return C.apply(this,Array.prototype.slice.call(arguments))},expand:function(){return E.apply(this,Array.prototype.slice.call(arguments))},menuexpanded:function(){return K.apply(this,Array.prototype.slice.call(arguments))},activemenu:function(){return J.apply(this,Array.prototype.slice.call(arguments))},findmenusbytitle:function(){return F.apply(this,Array.prototype.slice.call(arguments))},finditemsbyname:function(){return G.apply(this,Array.prototype.slice.call(arguments))},pathtoroot:function(){return H.apply(this,Array.prototype.slice.call(arguments))},comparepaths:function(){return I.apply(this,Array.prototype.slice.call(arguments))},option:function(){return O.apply(this,Array.prototype.slice.call(arguments))},additems:function(){return L.apply(this,Array.prototype.slice.call(arguments))},removeitems:function(){return M.apply(this,Array.prototype.slice.call(arguments))},redraw:function(){return u.apply(this,Array.prototype.slice.call(arguments))},visiblemenus:function(){return s.apply(this,Array.prototype.slice.call(arguments))},hiddenmenus:function(){return t.apply(this,Array.prototype.slice.call(arguments))},propagateevent:function(){return f.apply(this,Array.prototype.slice.call(arguments))}};return P()?(Q="touchend",R="touchmove"):(Q="click",R="mousedown"),X[b]?d=X[b].apply(this,Array.prototype.slice.call(c,1)):"object"!=typeof b&&b?(a.error("No "+b+" method found in jQuery.multilevelpushmenu"),void(d||(d=this))):d=X.init.apply(this,arguments)}),d}}(jQuery);
20934!function(e){var t={};function o(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,o),i.l=!0,i.exports}o.m=e,o.c=t,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)o.d(n,i,function(t){return e[t]}.bind(null,i));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=11)}([function(e,t){e.exports='{{message}} <a aria-label="learn more about cookies" role=button tabindex=0 class=cc-link href={{href}} rel="noopener noreferrer nofollow" target={{target}}> {{link}} </a> '},function(e,t){e.exports='<div class="cc-revoke dp--revoke {{classes}}"> <i class=dp--icon-fingerprint></i> <span class=dp--hover>{{policy}}</span> </div> '},function(e,t,o){(function(e,o){function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var i=/^\[object .+?Constructor\]$/,s=/^(?:0|[1-9]\d*)$/,r={};
vendor: 11,313 bytes, line 20934
20934r["[object Float32Array]"]=r["[object Float64Array]"]=r["[object Int8Array]"]=r["[object Int16Array]"]=r["[object Int32Array]"]=r["[object Uint8Array]"]=r["[object Uint8ClampedArray]"]=r["[object Uint16Array]"]=r["[object Uint32Array]"]=!0,r["[object Arguments]"]=r["[object Array]"]=r["[object ArrayBuffer]"]=r["[object Boolean]"]=r["[object DataView]"]=r["[object Date]"]=r["[object Error]"]=r["[object Function]"]=r["[object Map]"]=r["[object Number]"]=r["[object Object]"]=r["[object RegExp]"]=r["[object Set]"]=r["[object String]"]=r["[object WeakMap]"]=!1;var c="object"==(void 0===e?"undefined":n(e))&&e&&e.Object===Object&&e,a="object"==("undefined"==typeof self?"undefined":n(self))&&self&&self.Object===Object&&self,l=c||a||Function("return this")(),u="object"==n(t)&&t&&!t.nodeType&&t,d=u&&"object"==n(o)&&o&&!o.nodeType&&o,p=d&&d.exports===u,h=p&&c.process,f=function(){try{var e=d&&d.require&&d.require("util").types;return e||h&&h.binding&&h.binding("util")}catch(e){}}(),v=f&&f.isTypedArray;function k(e,t,o){switch(o.length){case 0:return e.call(t);case 1:return e.call(t,o[0]);case 2:return e.call(t,o[0],o[1]);case 3:return e.call(t,o[0],o[1],o[2])}return e.apply(t,o)}var b,y,m,w=Array.prototype,g=Function.prototype,C=Object.prototype,x=l["__core-js_shared__"],_=g.toString,S=C.hasOwnProperty,O=(b=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+b:"",E=C.toString,P=_.call(Object),j=RegExp("^"+_.call(S).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=p?l.Buffer:void 0,A=l.Symbol,L=l.Uint8Array,D=T?T.allocUnsafe:void 0,N=(y=Object.getPrototypeOf,m=Object,function(e){return y(m(e))}),B=Object.create,M=C.propertyIsEnumerable,R=w.splice,I=A?A.toStringTag:void 0,F=function(){try{var e=ue(Object,"defineProperty");return e({},"",{}),e}catch(e){}}(),H=T?T.isBuffer:void 0,z=Math.max,U=Date.now,W=ue(l,"Map"),q=ue(Object,"create"),J=function(){function e(){}return function(t){if(!Ce(t))return{};if(B)return B(t);e.prototype=t;var o=new e;return e.prototype=void 0,o}}();function $(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function K(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function G(e){var t=-1,o=null==e?0:e.length;for(this.clear();++t<o;){var n=e[t];this.set(n[0],n[1])}}function Y(e){var t=this.__data__=new K(e);this.size=t.size}function X(e,t){var o=be(e),n=!o&&ke(e),i=!o&&!n&&me(e),s=!o&&!n&&!i&&_e(e),r=o||n||i||s,c=r?function(e,t){for(var o=-1,n=Array(e);++o<e;)n[o]=t(o);return n}(e.length,String):[],a=c.length;for(var l in e)!t&&!S.call(e,l)||r&&("length"==l||i&&("offset"==l||"parent"==l)||s&&("buffer"==l||"byteLength"==l||"byteOffset"==l)||de(l,a))||c.push(l);return c}function V(e,t,o){(void 0===o||ve(e[t],o))&&(void 0!==o||t in e)||ee(e,t,o)}function Z(e,t,o){var n=e[t];S.call(e,t)&&ve(n,o)&&(void 0!==o||t in e)||ee(e,t,o)}function Q(e,t){for(var o=e.length;o--;)if(ve(e[o][0],t))return o;return-1}function ee(e,t,o){"__proto__"==t&&F?F(e,t,{configurable:!0,enumerable:!0,value:o,writable:!0}):e[t]=o}$.prototype.clear=function(){this.__data__=q?q(null):{},this.size=0},$.prototype.delete=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t},$.prototype.get=function(e){var t=this.__data__;if(q){var o=t[e];return"__lodash_hash_undefined__"===o?void 0:o}return S.call(t,e)?t[e]:void 0},$.prototype.has=function(e){var t=this.__data__;return q?void 0!==t[e]:S.call(t,e)},$.prototype.set=function(e,t){var o=this.__data__;return this.size+=this.has(e)?0:1,o[e]=q&&void 0===t?"__lodash_hash_undefined__":t,this},K.prototype.clear=function(){this.__data__=[],this.size=0},K.prototype.delete=function(e){var t=this.__data__,o=Q(t,e);return!(o<0)&&(o==t.length-1?t.pop():R.call(t,o,1),--this.size,!0)},K.prototype.get=function(e){var t=this.__data__,o=Q(t,e);return o<0?void 0:t[o][1]},K.prototype.has=function(e){return Q(this.__data__,e)>-1},K.prototype.set=function(e,t){var o=this.__data__,n=Q(o,e);return n<0?(++this.size,o.push([e,t])):o[n][1]=t,this},G.prototype.clear=function(){this.size=0,this.__data__={hash:new $,map:new(W||K),string:new $}},G.prototype.delete=function(e){var t=le(this,e).delete(e);return this.size-=t?1:0,t},G.prototype.get=function(e){return le(this,e).get(e)},G.prototype.has=function(e){return le(this,e).has(e)},G.prototype.set=function(e,t){var o=le(this,e),n=o.size;return o.set(e,t),this.size+=o.size==n?0:1,this},Y.prototype.clear=function(){this.__data__=new K,this.size=0},Y.prototype.delete=function(e){var t=this.__data__,o=t.delete(e);return this.size=t.size,o},Y.prototype.get=function(e){return this.__data__.get(e)},Y.prototype.has=function(e){return this.__data__.has(e)},Y.prototype.set=function(e,t){var o=this.__data__;if(o instanceof K){var n=o.__data__;if(!W||n.length<199)return n.push([e,t]),this.size=++o.size,this;o=this.__data__=new G(n)}return o.set(e,t),this.size=o.size,this};var te,oe=function(e,t,o){for(var n=-1,i=Object(e),s=o(e),r=s.length;r--;){var c=s[te?r:++n];if(!1===t(i[c],c,i))break}return e};function ne(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":I&&I in Object(e)?function(e){var t=S.call(e,I),o=e[I];try{e[I]=void 0;var n=!0}catch(e){}var i=E.call(e);n&&(t?e[I]=o:delete e[I]);return i}(e):function(e){return E.call(e)}(e)}function ie(e){return xe(e)&&"[object Arguments]"==ne(e)}function se(e){return!(!Ce(e)||function(e){return!!O&&O in e}(e))&&(we(e)?j:i).test(function(e){if(null!=e){try{return _.call(e)}catch(e){}try{return e+""}catch(e){}}return""}(e))}function re(e){if(!Ce(e))return function(e){var t=[];if(null!=e)for(var o in Object(e))t.push(o);return t}(e);var t=pe(e),o=[];for(var n in e)("constructor"!=n||!t&&S.call(e,n))&&o.push(n);return o}function ce(e,t,o,n,i){e!==t&&oe(t,(function(s,r){if(i||(i=new Y),Ce(s))!function(e,t,o,n,i,s,r){var c=he(e,o),a=he(t,o),l=r.get(a);if(l)return void V(e,o,l);var u=s?s(c,a,o+"",e,t,r):void 0,d=void 0===u;if(d){var p=be(a),h=!p&&me(a),f=!p&&!h&&_e(a);u=a,p||h||f?be(c)?u=c:xe(m=c)&&ye(m)?u=function(e,t){var o=-1,n=e.length;t||(t=Array(n));for(;++o<n;)t[o]=e[o];return t}(c):h?(d=!1,u=function(e,t){if(t)return e.slice();var o=e.length,n=D?D(o):new e.constructor(o);return e.copy(n),n}(a,!0)):f?(d=!1,v=a,k=!0?(b=v.buffer,y=new b.constructor(b.byteLength),new L(y).set(new L(b)),y):v.buffer,u=new v.constructor(k,v.byteOffset,v.length)):u=[]:function(e){if(!xe(e)||"[object Object]"!=ne(e))return!1;var t=N(e);if(null===t)return!0;var o=S.call(t,"constructor")&&t.constructor;return"function"==typeof o&&o instanceof o&&_.call(o)==P}(a)||ke(a)?(u=c,ke(c)?u=function(e){return function(e,t,o,n){var i=!o;o||(o={});var s=-1,r=t.length;for(;++s<r;){var c=t[s],a=n?n(o[c],e[c],c,o,e):void 0;void 0===a&&(a=e[c]),i?ee(o,c,a):Z(o,c,a)}return o}(e,Se(e))}(c):Ce(c)&&!we(c)||(u=function(e){return"function"!=typeof e.constructor||pe(e)?{}:J(N(e))}(a))):d=!1}var v,k,b,y;var m;d&&(r.set(a,u),i(u,a,n,s,r),r.delete(a));V(e,o,u)}(e,t,r,o,ce,n,i);else{var c=n?n(he(e,r),s,r+"",e,t,i):void 0;void 0===c&&(c=s),V(e,r,c)}}),Se)}function ae(e,t){return fe(function(e,t,o){return t=z(void 0===t?e.length-1:t,0),function(){for(var n=arguments,i=-1,s=z(n.length-t,0),r=Array(s);++i<s;)r[i]=n[t+i];i=-1;for(var c=Array(t+1);++i<t;)c[i]=n[i];return c[t]=o(r),k(e,this,c)}}(e,t,Pe),e+"")}function le(e,t){var o,i,s=e.__data__;return("string"==(i=n(o=t))||"number"==i||"symbol"==i||"boolean"==i?"__proto__"!==o:null===o)?s["string"==typeof t?"string":"hash"]:s.map}function ue(e,t){var o=function(e,t){return null==e?void 0:e[t]}(e,t);return se(o)?o:void 0}function de(e,t){var o=n(e);return!!(t=null==t?9007199254740991:t)&&("number"==o||"symbol"!=o&&s.test(e))&&e>-1&&e%1==0&&e<t}function pe(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||C)}function he(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}var fe=function(e){var t=0,o=0;return function(){var n=U(),i=16-(n-o);if(o=n,i>0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(F?function(e,t){return F(e,"toString",{configurable:!0,enumerable:!1,value:(o=t,function(){return o}),writable:!0});var o}:Pe);function ve(e,t){return e===t||e!=e&&t!=t}var ke=ie(function(){return arguments}())?ie:function(e){return xe(e)&&S.call(e,"callee")&&!M.call(e,"callee")},be=Array.isArray;function ye(e){return null!=e&&ge(e.length)&&!we(e)}var me=H||function(){return!1};function we(e){if(!Ce(e))return!1;var t=ne(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}function ge(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}function Ce(e){var t=n(e);return null!=e&&("object"==t||"function"==t)}function xe(e){return null!=e&&"object"==n(e)}var _e=v?function(e){return function(t){return e(t)}}(v):function(e){return xe(e)&&ge(e.length)&&!!r[ne(e)]};function Se(e){return ye(e)?X(e,!0):re(e)}var Oe,Ee=(Oe=function(e,t,o){ce(e,t,o)},ae((function(e,t){var o=-1,i=t.length,s=i>1?t[i-1]:void 0,r=i>2?t[2]:void 0;for(s=Oe.length>3&&"function"==typeof s?(i--,s):void 0,r&&function(e,t,o){if(!Ce(o))return!1;var i=n(t);return!!("number"==i?ye(o)&&de(t,o.length):"string"==i&&t in o)&&ve(o[t],e)}(t[0],t[1],r)&&(s=i<3?void 0:s,i=1),e=Object(e);++o<i;){var c=t[o];c&&Oe(e,c,o,s)}return e})));function Pe(e){return e}o.exports=Ee}).call(this,o(13),o(14)(e))},function(e,t){e.exports='<div class="cc-compliance cc-highlight"> {{allow}} {{allow-all}} </div> '},function(e,t){e.exports='<div class=dp--cookie-check xmlns:f=http://www.w3.org/1999/html> <label for=dp--cookie-require> <input type=checkbox id=dp--cookie-require class=dp--check-box checked=checked disabled=disabled /> {{dpRequire}} </label> <label for=dp--cookie-statistics> <input type=checkbox id=dp--cookie-statistics class=dp--check-box {{checked.statistics}} value=""/> {{dpStatistik}} </label> <label for=dp--cookie-marketing> <input type=checkbox id=dp--cookie-marketing class=dp--check-box {{checked.marketing}} value=""/> {{dpMarketing}} </label> </div> '},function(e,t){e.exports="<span id=cookieconsent:desc class=cc-message> {{cookieDesc}} </span> "},function(e,t){e.exports="<span id=cookieconsent:desc class=cc-message> {{cookieDesc}} {{cookieSelect}} </span> "},function(e,t){e.exports='<a aria-label="dismiss cookies" role=button tabindex=0 class="cc-btn cc-dismiss"> {{allow-all}} </a> '},function(e,t){e.exports="{{dpmessagelink}}{{compliance}} "},function(e,t){e.exports="<div class=dp--overlay-inner> <div class=dp--overlay-header>{{notice}}</div> <div class=dp--overlay-description>{{desc}}</div> <div class=dp--overlay-button> <button class=db--overlay-submit onclick=window.DPCookieConsent.forceAccept(this) data-cookieconsent={{type}} {{style}}> {{btn}} </button> </div> </div> "},function(e,t){e.exports=function(){this.lang={message:"We use cookies and other tracking technologies to personalize and improve your experience. By continuing to use our website you consent to this.",dismiss:"allow cookies",allow:"allow cookies","allow-all":"allow all!",deny:"decline",policy:"Cookie Policy",link:"More info",dpRequire:"necessary",dpStatistik:"statistics",dpMarketing:"marketing",media:{notice:"Cookie Notice",desc:"Loading this resource will c
20934onnect to external servers which use cookies and other tracking technologies to personalize and improve experience. Further information can be found in our privacy policy.",btn:"allow cookies and load this resource"}}}},function(e,t,o){o(12),e.exports=o(16)},function(e,t,o){"use strict";o.r(t);var n=o(3),i=o.n(n),s=o(4),r=o.n(s),c=o(0),a=o.n(c),l=o(5),u=o.n(l),d=o(6),p=o.n(d),h=o(7),f=o.n(h),v=o(8),k=o.n(v),b=o(1),y=o.n(b),m=o(9),w=o.n(m),g=o(2),C=o.n(g),x=o(10),_=o.n(x);function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}
20935/*!
20936  * Cookie Consent Adapter
20937  * Copyright 2019 Dirk Persky (https://github.com/DirkPersky/typo3-dp_cookieconsent)
20938  * Licensed under GPL v3+ (https://github.com/DirkPersky/typo3-dp_cookieconsent/blob/master/LICENSE)
20939  */window.addEventListener("load",(function(){function e(){this.cookie_name="dp_cookieconsent_status",this.cookie={path:"/",domain:"",expiryDays:365,secure:!1},this.prevCheckboxes=!1,this.checkboxes=[{name:"statistics",checked:!0},{name:"marketing",checked:!1}],this.settings={autoOpen:!0,revokable:!0,dismissOnScroll:!1,layout:"dpextend",type:"opt-in",theme:"edgeless",position:"bottom-right",reloadOnRevoke:!1,overlay:{notice:!0,box:{background:"rgba(0,0,0,.8)",text:"#fff"},btn:{background:"#F96332",text:"#fff"}},palette:{popup:{background:"rgba(0,0,0,.8)",text:"#FFFFFF"},button:{background:"#F96332",text:"#FFFFFF"}}}}"undefined"==typeof dpCookieConsentLang&&(window.DPCookieConsentL10N=_.a),window.DPCookieConsentL10N.prototype.replace=function(){window.cookieconsent_options.content=C()(this.lang,window.cookieconsent_options.content)},(new window.DPCookieConsentL10N).replace(),e.prototype.asyncLoad=function(e,t,o){var n=document,i=n.createElement(t),s=n.getElementsByTagName(t)[0];switch(t){case"script":i.src=e,i.setAttribute("defer","");break;case"link":i.rel="stylesheet",i.type="text/css",i.setAttribute("defer",""),i.href=e}o&&i.addEventListener("load",(function(e){o(null,e)}),!1),s.parentNode.insertBefore(i,s)},e.prototype.asyncJS=function(e,t){this.asyncLoad(e,"script",t)},e.prototype.getCookieElementsByTag=function(e,t){void 0===t&&(t="data-cookieconsent");var o=[];if(void 0===document.querySelectorAll)o=document.querySelectorAll(e+"["+t+"]");else{var n=document.getElementsByTagName(e);for(var i in n){var s=n[i];void 0!==s.getAttribute&&s.getAttribute(t)&&o.push(s)}}return o},e.prototype.callIframeHandler=function(e){var t=e.cloneNode(!0);t.getAttribute("data-src")&&(t.src=t.getAttribute("data-src")),e.parentNode.replaceChild(t,e),t.classList.add("dp--loaded"),t.setAttribute("data-cookieconsent-loaded",t.getAttribute("data-cookieconsent")),t.removeAttribute("data-cookieconsent"),window.DPCookieConsent.fireEvent("dp--cookie-iframe",t)},e.prototype.callScriptHandler=function(e){var t=e.innerHTML;t&&t.length&&(t=t.trim()),t&&t.length?(eval.call(this,t),window.DPCookieConsent.fireEvent("dp--cookie-fire",e)):e.getAttribute("data-src")?this.asyncJS(e.getAttribute("data-src"),(function(t){window.DPCookieConsent.fireEvent("dp--cookie-fire",e)})):e.src&&this.asyncJS(e.src,(function(t){window.DPCookieConsent.fireEvent("dp--cookie-fire",e)})),e.setAttribute("data-cookieconsent-loaded",e.getAttribute("data-cookieconsent")),e.removeAttribute("data-cookieconsent")},e.prototype.loadCookies=function(){var e,t=this.getCookieElementsByTag("script");if((t=t.concat(this.getCookieElementsByTag("iframe"))).length>0)for(e=0;e<t.length;e++){if("dpextend"===window.cookieconsent_options.layout){var o=t[e].getAttribute("data-cookieconsent");if("required"!=o&&(this.loadCookiesPreset(),!this.dpCookies.hasOwnProperty("dp--cookie-"+o)||!0!==this.dpCookies["dp--cookie-"+o]))continue}if(void 0!==t[e].tagName)switch(t[e].tagName.toUpperCase()){case"IFRAME":this.callIframeHandler(t[e]);break;default:this.callScriptHandler(t[e])}}window.DPCookieConsent.prevCheckboxes=[],window.DPCookieConsent.checkboxes.map((function(e){e&&window.DPCookieConsent.prevCheckboxes.push({name:e.name,checked:e.checked})}))},e.prototype.setClass=function(e){!0===e?document.querySelector("body").classList.remove("dp--cookie-consent"):document.querySelector("body").classList.add("dp--cookie-consent")},e.prototype.initCheckboxes=function(){if("object"===S(window.cookieconsent_options.checkboxes))for(var e in this.checkboxes=[],window.cookieconsent_options.checkboxes)this.checkboxes.push({name:e,checked:window.cookieconsent_options.checkboxes[e]});var t=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieSelect");t=t.length>0?t[0].innerHTML:r.a,this.checkboxes.map((function(e){var o="";(!0===e.checked||!1!==e.checked&&"true"===e.checked.toLowerCase())&&(o='checked="checked"'),t=t.replace("{{checked."+e.name+"}}",o)})),t=this.replaceLabels(t),window.cookieconsent_options.content.cookieSelect=t},e.prototype.replaceLabels=function(e){for(var t in window.cookieconsent_options.content)e=e.replace("{{"+t+"}}",window.cookieconsent_options.content[t]);return e},e.prototype.setCheckboxes=function(){if("dpextend"==window.cookieconsent_options.layout){var e=this,t=e.checkboxes.map((function(t){return e.loadCheckbox(t.name)}));this.saveCookie(t)}},e.prototype.loadCheckboxes=function(){if("dpextend"==window.cookieconsent_options.layout){var e=this;e.loadCookiesPreset(),e.checkboxes.map((function(t){e.loadCheckbox(t.name,!0)}))}},e.prototype.saveCookie=function(e){var t={};e.map((function(e){e&&(t[e.id]=e.checked)}
20939)),this.dpCookies=e,window.cookieconsent.utils.setCookie(this.cookie_name,JSON.stringify(t),this.cookie.expiryDays,this.cookie.domain,this.cookie.path,this.cookie.secure)},e.prototype.loadCookiesPreset=function(){if(0!=this.dpCookies&&(this.dpCookies=window.cookieconsent.utils.getCookie(this.cookie_name)),void 0!==this.dpCookies)try{this.dpCookies=JSON.parse(this.dpCookies)}catch(e){this.dpCookies=!1}else this.dpCookies=!1},e.prototype.loadCheckbox=function(e,t,o){var n=this,i="dp--cookie-"+e,s=document.getElementById(i),r=!1,c=!1;if(!0===t?this.dpCookies&&this.dpCookies.hasOwnProperty(i)&&(r=this.dpCookies[i],c=!0):void 0!==o&&(r=o,c=!0),s)return c&&(s.checked=r),n.checkboxes.map((function(t,o){t.name==e&&(n.checkboxes[o].checked=s.checked)})),s;n.checkboxes.map((function(t,o){c&&t.name==e&&(n.checkboxes[o].checked=r)}))},e.prototype.loadContentDescription=function(){var e=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieDesc");e=e.length>0?e[0].innerHTML:a.a,window.cookieconsent_options.content.cookieDesc=this.replaceLabels(e)},e.prototype.loadContentRevoke=function(){var e=DPCookieConsent.getCookieElementsByTag("script","data-dp-cookieRevoke");e.length>0?window.cookieconsent_options.revokeBtn=e[0].innerHTML:window.cookieconsent_options.revokeBtn=y.a},e.prototype.defaults=function(){window.cookieconsent_options=C()(this.settings,window.cookieconsent_options)},e.prototype.init=function(){this.defaults(),o(15),this.loadContentDescription("data-dp-cookieDesc",a.a),this.loadContentRevoke("data-dp-cookieRevoke",y.a),"dpextend"==window.cookieconsent_options.layout&&this.initCheckboxes();var e={autoOpen:window.cookieconsent_options.autoOpen,content:window.cookieconsent_options.content,theme:window.cookieconsent_options.theme,position:window.cookieconsent_options.position,palette:window.cookieconsent_options.palette,dismissOnScroll:window.cookieconsent_options.dismissOnScroll,type:window.cookieconsent_options.type,layout:window.cookieconsent_options.layout,revokable:window.cookieconsent_options.revokable,cookie:window.DPCookieConsent.cookie,layouts:{dpextend:k.a},elements:{messagelink:u.a,dpmessagelink:p.a,"allow-all":f.a},revokeBtn:window.cookieconsent_options.revokeBtn,compliance:{"opt-in":i.a},onPopupOpen:function(){window.DPCookieConsent.setClass(),window.DPCookieConsent.loadCheckboxes()},onPopupClose:function(){window.DPCookieConsent.setClass(!0)},onInitialise:function(e){!this.hasConsented()||"dismiss"!=e&&"allow"!=e||(window.DPCookieConsent.loadCheckboxes(),window.DPCookieConsent.loadCookies(),window.DPCookieConsent.fireEvent("dp--cookie-accept-init"))},onStatusChange:function(e){"opt-in"==window.cookieconsent_options.type&&"dpextend"===window.cookieconsent_options.layout&&"dismiss"==e&&window.DPCookieConsent.checkboxes.map((function(e){window.DPCookieConsent.loadCheckbox(e.name,!1,!0)}));if(window.DPCookieConsent.setCheckboxes(),!this.hasConsented()||"dismiss"!=e&&"allow"!=e)window.DPCookieConsent.fireEvent("dp--cookie-deny");else{var t=!1;window.DPCookieConsent.settings.reloadOnRevoke&&window.DPCookieConsent.prevCheckboxes&&window.DPCookieConsent.prevCheckboxes.map((function(e,o){var n=window.DPCookieConsent.checkboxes[o];!0===e.checked&&(n&&0!=n.checked||(t=!0))})),window.DPCookieConsent.loadCookies(),window.DPCookieConsent.fireEvent("dp--cookie-accept"),t&&location.reload()}},onRevokeChoice:function(){window.DPCookieConsent.fireEvent("dp--cookie-revoke")}};window.cookieconsent.initialise(e,(function(e){window.DPCookieConsent.setPopup(e),window.DPCookieConsent.overlays(),window.DPCookieConsent.fireEvent("dp--cookie-init")}))},e.prototype.setPopup=function(e){this.popup=e},e.prototype.forceAccept=function(e){var t=this;void 0!==t.popup&&setTimeout((function(){if("dpextend"===window.cookieconsent_options.layout){t.loadCheckboxes();var o=e.getAttribute("data-cookieconsent");t.checkboxes.map((function(e,n){e.name==o?t.loadCheckbox(e.name,!1,!0):t.popup.hasAnswered()||t.loadCheckbox(e.name,!1,!1)}))}t.popup.setStatus(window.cookieconsent.status.allow),t.popup.close(!0)}),250)},e.prototype.forceDeny=function(e){var t=this;void 0!==t.popup&&setTimeout((function(){if("dpextend"===window.cookieconsent_options.layout){t.loadCheckboxes();var o=e.getAttribute("data-cookieconsent");t.checkboxes.map((function(e,n){e.name==o&&t.loadCheckbox(e.name,!1,!1)}))}t.popup.setStatus(window.cookieconsent.status.deny),t.popup.close(!0)}),250)},e.prototype.fireEvent=function(e,t){var o;t?(o=document.createEvent("CustomEvent")).initCustomEvent(e,!0,!0,{$el:t}):(o=document.createEvent("Event")).initEvent(e,!0,!0),document.dispatchEvent(o)},e.prototype.overlays=function(){if(window.cookieconsent_options.overlay.notice){var e,t=this.getCookieElementsByTag("iframe");
20939if(t.length>0)for(e=0;e<t.length;e++){var o=t[e],n=o.getAttribute("data-cookieconsent-notice")||window.cookieconsent_options.content.media.notice,i=o.getAttribute("data-cookieconsent-description")||window.cookieconsent_options.content.media.desc,s=o.getAttribute("data-cookieconsent-btn")||window.cookieconsent_options.content.media.btn,r=o.getAttribute("data-cookieconsent"),c=document.createElement("div");c.classList.add("dp--overlay");var a="";window.cookieconsent_options.overlay.btn.background&&(a+="background:"+window.cookieconsent_options.overlay.btn.background+";"),window.cookieconsent_options.overlay.btn.text&&(a+="color:"+window.cookieconsent_options.overlay.btn.text+";"),c.innerHTML=w.a.replace("{{notice}}",n).replace("{{desc}}",i).replace("{{type}}",r).replace("{{style}}",'style="'+a+'"').replace("{{btn}}",s),window.cookieconsent_options.overlay.box.background&&(c.style.background=window.cookieconsent_options.overlay.box.background),window.cookieconsent_options.overlay.box.text&&(c.style.color=window.cookieconsent_options.overlay.box.text),o.parentNode.appendChild(c)}}},window.DPCookieConsent=new e,window.DPCookieConsent.init()}))},function(e,t){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"===("undefined"==typeof window?"undefined":o(window))&&(n=window)}e.exports=n},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}},function(e,t){function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var o=" ";return 1===e.nodeType&&(o+e.className+o).replace(/[\n\t]/g,o).indexOf(o+t+o)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var o=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(o,"")},interpolateString:function(e,t){return e.replace(/{{([a-z][a-z0-9\-_]*)}}/gi,(function(e){return t(arguments[1])||""}))},getCookie:function(e){var t=("; "+document.cookie).split("; "+e+"=");return t.length<2?void 0:t.pop().split(";").shift()}
vendor: 1,445 bytes, line 20939
20939,setCookie:function(e,t,o,n,i,s){var r=new Date;r.setHours(r.getHours()+24*(o||365));var c=[e+"="+t,"expires="+r.toUTCString(),"path="+(i||"/")];n&&c.push("domain="+n),s&&c.push("secure"),document.cookie=c.join(";")},deepExtend:function(e,t){for(var o in t)t.hasOwnProperty(o)&&(o in e&&this.isPlainObject(e[o])&&this.isPlainObject(t[o])?this.deepExtend(e[o],t[o]):e[o]=t[o]);return e},throttle:function(e,t){var o=!1;return function(){o||(e.apply(this,arguments),o=!0,setTimeout((function(){o=!1}),t))}},hash:function(e){var t,o,n=0;if(0===e.length)return n;for(t=0,o=e.length;t<o;++t)n=(n<<5)-n+e.charCodeAt(t),n|=0;return n},normaliseHex:function(e){return"#"==e[0]&&(e=e.substr(1)),3==e.length&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),e},getContrast:function(e){return e=this.normaliseHex(e),(299*parseInt(e.substr(0,2),16)+587*parseInt(e.substr(2,2),16)+114*parseInt(e.substr(4,2),16))/1e3>=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),o=38+(t>>16),n=38+(t>>8&255),i=38+(255&t);return"#"+(16777216+65536*(o<255?o<1?0:o:255)+256*(n<255?n<1?0:n:255)+(i<255?i<1?0:i:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"===o(e)&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,o){return e&&e.parentNode?t.hasClass(e,o)?e:this.traverseDOMPath(e.parentNode,o):null}};
20939e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var o in t)if(t.hasOwnProperty(o)&&void 0!==e.style[o+"ransition"])return t[o];return""}(),e.hasTransition=!!e.transitionEnd;var n=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){var o={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"&#x274c;",target:"_blank",policy:"Cookie Policy"},elements:{header:'<span class="cc-header">{{header}}</span>&nbsp;',message:'<span id="cookieconsent:desc" class="cc-message">{{message}}</span>',messagelink:'<span id="cookieconsent:desc" class="cc-message">{{message}} <a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a></span>',dismiss:'<a aria-label="dismiss cookie message" role=button tabindex="0" class="cc-btn cc-dismiss">{{dismiss}}</a>',allow:'<a aria-label="allow cookies" role=button tabindex="0"  class="cc-btn cc-allow">{{allow}}</a>',deny:'<a aria-label="deny cookies" role=button tabindex="0" class="cc-btn cc-deny">{{deny}}</a>',link:'<a aria-label="learn more about cookies" role=button tabindex="0" class="cc-link" href="{{href}}" rel="noopener noreferrer nofollow" target="{{target}}">{{link}}</a>',close:'<span aria-label="dismiss cookie message" role=button tabindex="0" class="cc-close">{{close}}</span>'},window:'<div role="dialog" aria-live="polite" aria-label="cookieconsent" aria-describedby="cookieconsent:desc" class="cc-window {{classes}}">\x3c!--googleoff: all--\x3e{{children}}\x3c!--googleon: all--\x3e</div>',revokeBtn:'<div class="cc-revoke {{classes}}">{{policy}}</div>',compliance:{info:'<div class="cc-compliance">{{dismiss}}</div>',"opt-in":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>',"opt-out":'<div class="cc-compliance cc-highlight">{{deny}}{{allow}}</div>'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};function i(){this.initialise.apply(this,arguments)}function s(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function r(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function c(){var t=this.options.onInitialise.bind(this);if(!window.navigator.cookieEnabled)return t(e.status.deny),!0;if(window.CookiesOK||window.navigator.CookiesOK)return t(e.status.allow),!0;var o=Object.keys(e.status),n=this.getStatus(),i=o.indexOf(n)>=0;return i&&t(n),i}function a(){var e=this.options.position.split("-"),t=[];return e.forEach((function(e){t.push("cc-"+e)})),t}function l(){var e=this.options,o="top"==e.position||"bottom"==e.position?"banner":"floating";t.isMobile()&&(o="floating");var n=["cc-"+o,"cc-type-"+e.type,"cc-theme-"+e.theme];e.static&&n.push("cc-static"),n.push.apply(n,a.call(this));h.call(this,this.options.palette);return this.customStyleSelector&&n.push(this.customStyleSelector),n}function u(){var e={},o=this.options;o.showLink||(o.elements.link="",o.elements.messagelink=o.elements.message),Object.keys(o.elements).forEac
20939h((function(n){e[n]=t.interpolateString(o.elements[n],(function(e){var t=o.content[e];return e&&"string"==typeof t&&t.length?t:""}))}));var n=o.compliance[o.type];n||(n=o.compliance.info),e.compliance=t.interpolateString(n,(function(t){return e[t]}));var i=o.layouts[o.layout];return i||(i=o.layouts.basic),t.interpolateString(i,(function(t){return e[t]}))}function d(o){var n=this.options,i=document.createElement("div"),s=n.container&&1===n.container.nodeType?n.container:document.body;i.innerHTML=o;var r=i.children[0];return r.style.display="none",t.hasClass(r,"cc-window")&&e.hasTransition&&t.addClass(r,"cc-invisible"),this.onButtonClick=p.bind(this),r.addEventListener("click",this.onButtonClick),n.autoAttach&&(s.firstChild?s.insertBefore(r,s.firstChild):s.appendChild(r)),r}function p(o){var i=t.traverseDOMPath(o.target,"cc-btn")||o.target;if(t.hasClass(i,"cc-btn")){var s=i.className.match(new RegExp("\\bcc-("+n.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(i,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0)),t.hasClass(i,"cc-revoke")&&this.revokeChoice()}function h(o){var n=t.hash(JSON.stringify(o)),i="cc-color-override-"+n,s=t.isPlainObject(o);return this.customStyleSelector=s?i:null,s&&function(o,n,i){if(e.customStyles[o])return void++e.customStyles[o].references;var s={},r=n.popup,c=n.button,a=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[i+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[i+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[i+" .cc-link,"+i+" .cc-link:active,"+i+" .cc-link:visited"]=["color: "+r.link],c&&(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[i+" .cc-btn"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background],c.padding&&s[i+" .cc-btn"].push("padding: "+c.padding),"transparent"!=c.background&&(s[i+" .cc-btn:hover, "+i+" .cc-btn:focus"]=["background-color: "+(c.hover||f(c.background))]),a?(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[i+" .cc-highlight .cc-btn:first-child"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background]):s[i+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var l=document.createElement("style");document.head.appendChild(l),e.customStyles[o]={references:1,element:l.sheet};var u=-1;for(var d in s)s.hasOwnProperty(d)&&l.sheet.insertRule(d+"{"+s[d].join(";")+"}",++u)}(n,o,"."+i),s}function f(e){return"000000"==(e=t.normaliseHex(e))?"#222":t.getLuminance(e)}function v(e,t){for(var o=0,n=e.length;o<n;++o){var i=e[o];if(i instanceof RegExp&&i.test(t)||"string"==typeof i&&i.length&&i===t)return!0}return!1}function k(){var o=this.setStatus.bind(this),n=this.close.bind(this),i=this.options.dismissOnTimeout;"number"==typeof i&&i>=0&&(this.dismissTimeout=window.setTimeout((function(){o(e.status.dismiss),n(!0)}),Math.floor(i)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function t(i){window.pageYOffset>Math.floor(s)&&(o(e.status.dismiss),n(!0),window.removeEventListener("scroll",t),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var c=this.options.dismissOnWindowClick,a=this.options.ignoreClicksFrom;if(c){var l=function(i){for(var s=!1,r=i.path.length,c=a.length,u=0;u<r;u++)if(!s)for(var d=0;d<c;d++)s||(s=t.hasClass(i.path[u],a[d]));s||(o(e.status.dismiss),n(!0),window.removeEventListener("click",l),window.removeEventListener("touchend",l),this.onWindowClick=null)}.bind(this);this.options.enabled&&(this.onWindowClick=l,window.addEventListener("click",l),window.addEventListener("touchend",l))}}function b(){if("info"!=this.options.type&&(this.options.revokable=!0),t.isMobile()&&(this.options.animateRevokable=!1),this.options.revokable){var e=a.call(this);this.options.animateRevokable&&e.push("cc-animate"),this.customStyleSelector&&e.push(this.customStyleSelector);var o=this.options.revokeBtn.replace("{{classes}}",e.join(" ")).replace("{{policy}}",this.options.content.policy);this.revokeBtn=d.call(this,o);var n=this.revokeBtn;if(this.options.animateRevokable){var i=t.throttle((function(e){var o=!1,i=window.innerHeight-20;
vendor: 4,691 bytes, line 20939
20939t.hasClass(n,"cc-top")&&e.clientY<20&&(o=!0),t.hasClass(n,"cc-bottom")&&e.clientY>i&&(o=!0),o?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")}),200);this.onMouseMove=i,window.addEventListener("mousemove",i)}}}return i.prototype.initialise=function(e){this.options&&this.destroy(),t.deepExtend(this.options={},o),t.isPlainObject(e)&&t.deepExtend(this.options,e),c.call(this)&&(this.options.enabled=!1),v(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),v(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var n=this.options.window.replace("{{classes}}",l.call(this).join(" ")).replace("{{children}}",u.call(this)),i=this.options.overrideHTML;if("string"==typeof i&&i.length&&(n=i),this.options.static){var s=d.call(this,'<div class="cc-grower">'+n+"</div>");s.style.display="",this.element=s.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=d.call(this,n);k.call(this),b.call(this),this.options.autoOpen&&this.autoOpen()},i.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(o){if(t.isPlainObject(o)){var n=t.hash(JSON.stringify(o)),i=e.customStyles[n];if(i&&!--i.references){var s=i.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}(this.options.palette),this.options=null},i.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},i.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},i.prototype.fadeIn=function(){var o=this.element;if(e.hasTransition&&o&&(this.afterTransition&&r.call(this,o),t.hasClass(o,"cc-invisible"))){if(o.style.display="",this.options.static){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}this.openingTimeout=setTimeout(s.bind(this,o),20)}},i.prototype.fadeOut=function(){var o=this.element;e.hasTransition&&o&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),s.bind(this,o)),t.hasClass(o,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=r.bind(this,o),o.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(o,"cc-invisible")))},i.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},i.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},i.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},i.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},i.prototype.hasConsented=function(t){var o=this.getStatus();return o==e.status.allow||o==e.status.dismiss},i.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},i.prototype.setStatus=function(o){var n=this.options.cookie,i=t.getCookie(n.name),s=Object.keys(e.status).indexOf(i)>=0;Object.keys(e.status).indexOf(o)>=0?(t.setCookie(n.name,o,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,o,s)):this.clearStatus()},i.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},i.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},i}(),e.Location=function(){var e={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var o=JSON.parse(t);return o.error?s(o):{code:o.country}}
20939catch(e){return s({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var o=JSON.parse(t);return"ERROR"==o.statusCode?s({error:o.statusMessage}):{code:o.countryCode}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){window.geoip2?geoip2.country((function(t){try{e({code:t.country.iso_code})}catch(t){e(s(t))}}),(function(t){e(s(t))})):e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};function o(o){t.deepExtend(this.options={},e),t.isPlainObject(o)&&t.deepExtend(this.options,o),this.currentServiceIndex=-1}function n(e,t,o){var n,i=document.createElement("script");i.type="text/"+(e.type||"javascript"),i.src=e.src||e,i.async=!1,i.onreadystatechange=i.onload=function(){var e=i.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),i.onreadystatechange=i.onload=null)},document.body.appendChild(i),n=setTimeout((function(){t.done=!0,t(),i.onreadystatechange=i.onload=null}),o)}function i(e,t,o,n,i){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(i))for(var r=0,c=i.length;r<c;++r){var a=i[r].split(":",2);s.setRequestHeader(a[0].replace(/^\s+|\s+$/g,""),a[1].replace(/^\s+|\s+$/g,""))}"function"==typeof t&&(s.onreadystatechange=function(){s.readyState>3&&t(s)}),s.send(n)}function s(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}return o.prototype.getNextService=function(){var e;do{e=this.getServiceByIdx(++this.currentServiceIndex)}while(this.currentServiceIndex<this.options.services.length&&!e);return e},o.prototype.getServiceByIdx=function(e){var o=this.options.services[e];if("function"==typeof o){var n=o();return n.name&&t.deepExtend(n,this.options.serviceDefinitions[n.name](n)),n}return"string"==typeof o?this.options.serviceDefinitions[o]():t.isPlainObject(o)?this.options.serviceDefinitions[o.name](o):null},o.prototype.locate=function(e,t){var o=this.getNextService();o?(this.callbackComplete=e,this.callbackError=t,this.runService(o,this.runNextServiceOnError.bind(this))):t(new Error("No services to run"))},o.prototype.setupUrl=function(e){var t=this.getCurrentServiceOpts();return e.url.replace(/\{(.*?)\}/g,(function(o,n){if("callback"===n){var i="callback"+Date.now();return window[i]=function(t){e.__JSONP_DATA=JSON.stringify(t)},i}if(n in t.interpolateUrl)return t.interpolateUrl[n]}))},o.prototype.runService=function(e,t){var o=this;e&&e.url&&e.callback&&(e.isScript?n:i)(this.setupUrl(e),(function(n){var i=n?n.responseText:"";e.__JSONP_DATA&&(i=e.__JSONP_DATA,delete e.__JSONP_DATA),o.runServiceCallback.call(o,t,e,i)}),this.options.timeout,e.data,e.headers)},o.prototype.runServiceCallback=function(e,t,o){var n=this,i=t.callback((function(t){i||n.onServiceResult.call(n,e,t)}),o);i&&this.onServiceResult.call(this,e,i)},o.prototype.onServiceResult=function(e,t){t instanceof Error||t&&t.error?e.call(this,t,null):e.call(this,null,t)},o.prototype.runNextServiceOnError=function(e,t){if(e){this.logError(e);var o=this.getNextService();o?this.runService(o,this.runNextServiceOnError.bind(this)):this.completeService.call(this,this.callbackError,new Error("All services failed"))}else this.completeService.call(this,this.callbackComplete,t)},o.prototype.getCurrentServiceOpts=function(){var e=this.options.services[this.currentServiceIndex];return"string"==typeof e?{name:e}:"function"==typeof e?e():t.isPlainObject(e)?e:{}},o.prototype.completeService=function(e,t){this.currentServiceIndex=-1,e&&e(t)},o.prototype.logError=function(e){var t=this.currentServiceIndex,o=this.getServiceByIdx(t);console.warn("The service["+t+"] ("+o.url+") responded with the following error",e)},o}(),e.Law=function(){var e={regionalLaw:!0,hasLaw:["AT","BE","BG","HR","CZ","CY","DK","EE","FI","FR","DE","EL","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","SK","ES","SE","GB","UK","GR","EU"],revokable:["HR","CY","DK","EE","FR","DE","LV","LT","NL","PT","ES"],explicitAction:["HR","IT","ES"]};function o(e){this.initialise.apply(this,arguments)}return o.prototype.initialise=function(o){t.deepExtend(this.options={},e),t.isPlainObject(o)&&t.deepExtend(this.options,o)},o.prototype.get=function(e){var t=this.options;return{hasLaw:t.hasLaw.indexOf(e)>=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},o.prototype.applyLaw=function(e,t){var o=this.get(t);return o.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,o)),this.options.regionalLaw&&(o.revokable&&(e.revokable=!0),o.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},o}(),e.initialise=function(o,n,i){var s=new e.Law(o.law);n||(n=function(){}),i||(i=function(){});var r=Object.keys(e.status),c=t.getCookie("cookieconsent_status");r.indexOf(c)>=0?n(new e.Popup(o)):e.getCountryCode(o,(function(t){delete o.law,delete o.location,t.code&&(o=s.applyLaw(o,t.code)),n(new e.Popup(o))}),(function(t){delete o.law,delete o.location,i(t,new e.Popup(o))}))},e.getCountryCode=function(t,o,n){t.law&&t.law.countryCode?o({code:t.law.countryCode}):t.location?new e.Location(t.location).locate((function(e){o(e||{})}),n):o({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{})},function(e,t){}]);
20940
20941jQuery(document).ready(function () {
20942
20943    $.support.cors = true;
20944
20945    /*!
20946     * jQuery Cookie Plugin v1.3.1
20947     * https://github.com/carhartl/jquery-cookie
20948     *
20949     * Copyright 2013 Klaus Hartl
20950     * Released under the MIT license
20951     */
20952    (function (factory) {
20953        if (typeof define === 'function' && define.amd) {
20954// AMD. Register as anonymous module.
20955            define(['jquery'], factory);
20956        } else {
20957// Browser globals.
20958            factory(jQuery);
20959        }
20960    }(function ($) {
20961
20962        var pluses = /\+/g;
20963
20964        function raw(s) {
20965            return s;
20966        }
20967
20968        function decoded(s) {
20969            return decodeURIComponent(s.replace(pluses, ' '));
20970        }
20971
20972        function converted(s) {
20973            if (s.indexOf('"') === 0) {
20974// This is a quoted cookie as according to RFC2068, unescape
20975                s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
20976            }
20977            try {
20978                return config.json ? JSON.parse(s) : s;
20979            } catch (er) {
20980            }
20981        }
20982
20983        var config = $.cookie = function (key, value, options) {
20984
20985// write
20986            if (value !== undefined) {
20987                options = $.extend({}, config.defaults, options);
20988
20989                if (typeof options.expires === 'number') {
20990                    var days = options.expires, t = options.expires = new Date();
20991                    t.setDate(t.getDate() + days);
20992                }
20993
20994                value = config.json ? JSON.stringify(value) : String(value);
20995
20996                return (document.cookie = [
20997                    config.raw ? key : encodeURIComponent(key),
20998                    '=',
20999                    config.raw ? value : encodeURIComponent(value),
21000                    options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
21001                    options.path ? '; path=' + options.path : '',
21002                    options.domain ? '; domain=' + options.domain : '',
21003                    options.secure ? '; secure' : ''
21004                ].join(''));
21005            }
21006
21007// read
21008            var decode = config.raw ? raw : decoded;
21009            var cookies = document.cookie.split('; ');
21010            var result = key ? undefined : {};
21011            for (var i = 0, l = cookies.length; i < l; i++) {
21012                var parts = cookies[i].split('=');
21013                var name = decode(parts.shift());
21014                var cookie = decode(parts.join('='));
21015
21016                if (key && key === name) {
21017                    result = converted(cookie);
21018                    break;
21019                }
21020
21021                if (!key) {
21022                    result[name] = converted(cookie);
21023                }
21024            }
21025
21026            return result;
21027        };
21028
21029        config.defaults = {};
21030
21031        $.removeCookie = function (key, options) {
21032            if ($.cookie(key) !== undefined) {
21033// Must not alter options, thus extending a fresh object...
21034                $.cookie(key, '', $.extend({}, options, {expires: -1}));
21035                return true;
21036            }
21037            return false;
21038        };
21039
21040    }));
21041
21042    /* -------------------------------------------------------------------------------------------------
21043     * spinner
21044     * -------------------------------------------------------------------------------------------------
21045     */
21046
21047    (function ($) {
21048        $.fn.spin = function (opts, color) {
21049            var presets = {
21050                "tiny": {
21051                    lines: 8,
21052                    length: 2,
21053                    width: 2,
21054                    radius: 3
21055                },
21056                "small": {
21057                    lines: 8,
21058                    length: 4,
21059                    width: 3,
21060                    radius: 5
21061                },
21062                "large": {
21063                    lines: 10,
21064                    length: 8,
21065                    width: 4,
21066                    radius: 8
21067                }
21068            };
21069            if (Spinner) {
21070                return this.each(function () {
21071                    var $this = $(this),
21072                            data = $this.data();
21073
21074                    if (data.spinner) {
21075                        data.spinner.stop();
21076                        delete data.spinner;
21077                    }
21078                    if (opts !== false) {
21079                        if (typeof opts === "string") {
21080                            if (opts in presets) {
21081                                opts = presets[opts];
21082                            } else {
21083                                opts = {};
21084                            }
21085                            if (color) {
21086                                opts.color = color;
21087                            }
21088                        }
21089                        data.spinner = new Spinner($.extend({
21090                            color: $this.css('color')
21091                        }, opts)).spin(this);
21092                    }
21093                });
21094            } else {
21095                throw "Spinner class not available.";
21096            }
21097        };
21098    })(jQuery);
21099
21100
21101
21102    function number_format(number, decimals, dec_point, thousands_sep) {
21103        // http://kevin.vanzonneveld.net
21104        // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
21105        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
21106        // +     bugfix by: Michael White (http://getsprink.com)
21107        // +     bugfix by: Benjamin Lupton
21108        // +     bugfix by: Allan Jensen (http://www.winternet.no)
21109        // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
21110        // +     bugfix by: Howard Yeend
21111        // +    revised by: Luke Smith (http://lucassmith.name)
21112        // +     bugfix by: Diogo Resende
21113        // +     bugfix by: Rival
21114        // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
21115        // +   improved by: davook
21116        // +   improved by: Brett Zamir (http://brett-zamir.me)
21117        // +      input by: Jay Klehr
21118        // +   improved by: Brett Zamir (http://brett-zamir.me)
21119        // +      input by: Amir Habibi (http://www.residence-mixte.com/)
21120        // +     bugfix by: Brett Zamir (http://brett-zamir.me)
21121        // +   improved by: Theriault
21122        // +      input by: Amirouche
21123        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
21124        // *     example 1: number_format(1234.56);
21125        // *     returns 1: '1,235'
21126        // *     example 2: number_format(1234.56, 2, ',', ' ');
21127        // *     returns 2: '1 234,56'
21128        // *     example 3: number_format(1234.5678, 2, '.', '');
21129        // *     returns 3: '1234.57'
21130        // *     example 4: number_format(67, 2, ',', '.');
21131        // *     returns 4: '67,00'
21132        // *     example 5: number_format(1000);
21133        // *     returns 5: '1,000'
21134        // *     example 6: number_format(67.311, 2);
21135        // *     returns 6: '67.31'
21136        // *     example 7: number_format(1000.55, 1);
21137        // *     returns 7: '1,000.6'
21138        // *     example 8: number_format(67000, 5, ',', '.');
21139        // *     returns 8: '67.000,00000'
21140        // *     example 9: number_format(0.9, 0);
21141        // *     returns 9: '1'
21142        // *    example 10: number_format('1.20', 2);
21143        // *    returns 10: '1.20'
21144        // *    example 11: number_format('1.20', 4);
21145        // *    returns 11: '1.2000'
21146        // *    example 12: number_format('1.2000', 3);
21147        // *    returns 12: '1.200'
21148        // *    example 13: number_format('1 000,50', 2, '.', ' ');
21149        // *    returns 13: '100 050.00'
21150        // Strip all characters but numerical ones.
21151        number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
21152        var n = !isFinite(+number) ? 0 : +number,
21153                prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
21154                sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
21155                dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
21156                s = '',
21157                toFixedFix = function (n, prec) {
21158                    var k = Math.pow(10, prec);
21159                    return '' + Math.round(n * k) / k;
21160                };
21161        // Fix for IE parseFloat(0.55).toFixed(0) = 0;
21162        s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
21163        if (s[0].length > 3) {
21164            s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
21165        }
21166        if ((s[1] || '').length < prec) {
21167            s[1] = s[1] || '';
21168            s[1] += new Array(prec - s[1].length + 1).join('0');
21169        }
21170        return s.join(dec);
21171    }
21172
21173
21174
21175    /* -------------------------------------------------------------------------------------------------
21176     * NeundreiviertelSmartObjects Class
21177     * -------------------------------------------------------------------------------------------------
21178     */
21179
21180
21181
21182    NeundreiviertelSmartObjects = function (config) {
21183
21184        // configuration
21185        this.config = {
21186            baseUrl: '',
21187            view: 'category',
21188            language: 'de',
21189            bbqEnabled: true,
21190            filters: {
21191                categories: {
21192                    type: 'occurrences',
21193                    field: 'categories',
21194                    title: {
21195                        de: 'Kategorie',
21196                        en: 'Category'
21197                    },
21198                    templateId: 'template-filter-selection-occurrences',
21199                    build: function ($this, filter, filterName) {
21200                        $this.buildFilterFunctions.occurrences($this, filter, filterName);
21201                        $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links');
21202//                        $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, category) {
21203//                            for (pIndex in $this.data.products) {
21204//                                if (jQuery.inArray(String($(category).data('value')), $this.data.products[pIndex]['categories']) >= 0 && $this.data.products[pIndex]['products_image']) {
21205//                                    $(category).css({
21206//                                        'background-image': 'url(media/images/info/' + $this.data.products[pIndex]['products_image'] + ')',
21207//                                        'background-repeat': 'no-repeat',
21208//                                        'background-position': 'center center',
21209//                                        'background-size': 'cover'
21210//                                    });
21211//                                    break;
21212//                                }
21213//                            }
21214//                        });
21215                    }
21216                },
21217                size: {
21218                    type: 'occurrences',
21219                    field: 'ext_size',
21220                    isProductOption: true,
21221                    title: {
21222                        de: 'Größe',
21223                        en: 'Size'
21224                    },
21225                    templateId: 'template-filter-selection-occurrences',
21226                    letterSizesOrder: ['XXS', 'XS', 'S', "S\\/M", 'M', "M\\/L", 'L', 'LL', 'XL', 'XXL'],
21227                    build: function ($this, filter, filterName) {
21228                        $this.buildFilterFunctions.occurrences($this, filter, filterName);
21229                        container = $('#filter-' + filterName + ' .element-' + filterName).first().parents('.filter-elements').first();
21230
21231                        // seperate integer-sizes
21232                        integerSizes = new Array();
21233                        $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, size) {
21234                            safeValue = $(size).data('value').replace('/', '\/');
21235                            regexpResult = safeValue.match(/^([0-9]+)([A-Z]{1})$/);
21236                            if (jQuery.isNumeric($(size).data('value')) || regexpResult) {
21237                                integerSizes.push($(size));
21238                            }
21239                        });
21240                        integerSizes.sort($this.compareSizeByIntegerValue);
21241                        $(container).prepend('<div class="integerSizes btn-group"></div>');
21242                        for (sIndex in integerSizes) {
21243                            $(integerSizes[sIndex]).addClass('btn');
21244                            $(container).find('.integerSizes').append(integerSizes[sIndex]);
21245                        }
21246
21247                        $(container).find('.inner').removeClass('font-bold');
21248                        $(container).find('.inner').addClass('btn-group');
21249                        $(container).find('.inner a').addClass('btn');
21250                        $(container).find('.inner').addClass('stringSizes');
21251                        $(container).find('.stringSizes').removeClass('inner');
21252
21253                        // seperate letter sizes
21254                        letterSizes = new Array();
21255                        $('#filter-' + filterName + ' .stringSizes .element-' + filterName).each(function (cIndex, size) {
21256                            letterPosition = jQuery.inArray($(size).data('value'), $this.config.filters.size.letterSizesOrder);
21257                            if (letterPosition >= 0) {
21258                                $(size).data('position', letterPosition);
21259                                letterSizes.push($(size));
21260                            }
21261                        });
21262
21263                        $(container).find('.integerSizes').after('<div class="letterSizes btn-group"></div>');
21264                        for (lIndex in $this.config.filters.size.letterSizesOrder) {
21265                            for (sIndex in letterSizes) {
21266                                if ($(letterSizes[sIndex]).data('position') == lIndex) {
21267                                    $(container).find('.letterSizes').append(letterSizes[sIndex]);
21268                                }
21269                            }
21270                        }
21271
21272
21273
21274                        $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links');
21275                    },
21276                    sortOptions: function (options, context) {
21277                        if (options.length > 0) {
21278                            if (jQuery.isNumeric(options[0])) {
21279                                options.sort();
21280                            }
21281                            else if (options[0].match(/^[0-9]+(\.[0-9]+)*/)) {
21282                                options.sort(context.compareSizeByShoeSize);
21283                            }
21284                            else {
21285                                options.sort(context.compareSizeByLetter);
21286                            }
21287                        }
21288                    },
21289                    onOptionChange: function () {
21290
21291                    }
21292                },
21293                color: {
21294                    type: 'occurrences',
21295                    //field: ['ext_color_primary', 'ext_color_secondary'],
21296                    field: 'ext_color_primary',
21297                    isProductOption: true,
21298                    imageSensitive: true,
21299                    title: {
21300                        de: 'Farbe',
21301                        en: 'Color'
21302                    },
21303                    templateId: 'template-filter-selection-occurrences',
21304                    build: function ($this, filter, filterName) {
21305                        $this.buildFilterFunctions.occurrences($this, filter, filterName);
21306                        $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links');
21307                    },
21308                    sortOptions: function (options, context) {
21309                        options.sort();
21310                    }
21311                },
21312                material: {
21313                    type: 'occurrences',
21314                    //field: ['ext_material_primary', 'ext_material_secondary'],
21315                    field: 'ext_material_primary',
21316                    title: {
21317                        de: 'Material',
21318                        en: 'Material'
21319                    },
21320                    templateId: 'template-filter-selection-occurrences',
21321                    build: function ($this, filter, filterName) {
21322                        $this.buildFilterFunctions.occurrences($this, filter, filterName);
21323                        $this.bindFilterEventFunctions.addToExecutionQueue($this, 'links');
21324                    }
21325                },
21326                price: {
21327                    type: 'range',
21328                    field: 'price_plain',
21329                    title: {
21330                        de: 'Preis',
21331                        en: 'Price'
21332                    },
21333                    templateId: 'template-filter-selection-range',
21334                    build: function ($this, filter, filterName) {
21335                        $this.buildFilterFunctions.range($this, filter, filterName);
21336                        $this.bindFilterEventFunctions.addToExecutionQueue($this, 'range');
21337                    }
21338                }
21339            },
21340            filterCols: 5,
21341            productsCols: 4,
21342            pagination: {
21343                maxPages: 5,
21344                prevNextPages: 2
21345            },
21346            translations: {
21347                from: {
21348                    de: 'ab',
21349                    en: 'from'
21350                },
21351                to: {
21352                    de: 'bis',
21353                    en: 'to'
21354                },
21355                min: {
21356                    de: 'ab',
21357                    en: 'from'
21358                },
21359                max: {
21360                    de: 'bis',
21361                    en: 'to'
21362                },
21363                resultAmount: {
21364                    none: {
21365                        de: 'keine Produkte gefunden.',
21366                        en: 'no products found.'
21367                    },
21368                    singular: {
21369                        de: 'Produkt gefunden.',
21370                        en: 'product found.'
21371                    },
21372                    plural: {
21373                        de: 'Produkte gefunden.',
21374                        en: 'products found.'
21375                    }
21376                },
21377                moreImages: {
21378                    de: 'weitere Bilder',
21379                    en: 'more images'
21380                },
21381                badges: {
21382                    'new': {
21383                        de: 'Neu!',
21384                        en: 'New!'
21385                    },
21386                    specialOffer: {
21387                        de: 'Angebot!',
21388                        en: 'Special Offer!'
21389                    }
21390                }
21391            },
21392            selectors: {
21393                filtersContainer: '.products-filter',
21394                templateFiltersNewRow: 'template-filter-new-row',
21395                filterRow: '.filter-row',
21396                filterTitle: '.filter-title .text',
21397                filterElements: '.filter-elements',
21398                filterRange: {
21399                    mover: '#box-filter .filter-range .mover',
21400                    titleMin: '.title-min',
21401                    titleMax: '.title-max',
21402                    valueMin: '.value-min',
21403                    valueMax: '.value-max',
21404                },
21405                selectedFiltersContainer: 'box-filter-selected',
21406                templateSelectedFilterLink: 'template-selected-filter-link',
21407                configuration: {
21408                    container: '.products-configuration',
21409                    sortBy: '.products-configuration .sortBy',
21410                    sortOrder: '.products-configuration .sortOrder',
21411                    presentation: '.products-configuration .presentation',
21412                    resultsPerPage: '.products-configuration .resultsPerPage'
21413                },
21414                pagination: {
21415                    container: '.page-controls-pages',
21416                    first: '.page-controls-pages .first-page',
21417                    prev: '.page-controls-pages .prev-page',
21418                    pages: '.page-controls-pages .pages-group',
21419                    next: '.page-controls-pages .next-page',
21420                    last: '.page-controls-pages .last-page',
21421                    resultAmount: '.page-controls-result-amount'
21422                },
21423                productsContainer: '#box-products',
21424                productsAppend: {
21425                    grid: '#box-products .row-fluid:last',
21426                    list: '#box-products'
21427                },
21428                templateProduct: {
21429                    grid: 'template-product-grid',
21430                    list: 'template-product-list'
21431                },
21432                templateProductOptions: {
21433                    grid: 'template-product-options-grid',
21434                    list: 'template-product-options-list',
21435                    detail: 'template-product-options-detail'
21436                },
21437                productsLinks: '.product .product-link',
21438                productOptions: '.options',
21439                productOptionLinks: '.options .values a',
21440                productsAddToCart: '.product .actions .cart a.action',
21441                productsAddToFavourites: '.product .actions .fav a.action',
21442                productDetail: '#product-detail',
21443                productDetailFull: '#product-detail-full',
21444                productDetailAddToCart: '.addToCart',
21445                templateProductDetailInfo: 'template-product-additional-info',
21446                productDetailAdditionalInfo: '#product-detail-additional-infos',
21447                templateProductsNewRow: 'template-products-new-row',
21448                cart: '#header-cart',
21449                cartContent: '#header-cart-content',
21450                favourites: '#header-favourites',
21451                favouritesContent: '#header-favourites-content',
21452                search: {
21453                    form: '#globalSearch',
21454                    input: '#globalSearch-query'
21455                }
21456            },
21457            classes: {
21458                filterAddLink: 'filter-add',
21459                optionLink: 'btn option-value',
21460                resultAmount: 'amount font-bold',
21461                buttonActive: 'btn-danger',
21462                buttonActiveIcon: 'icon-white'
21463            },
21464            detail: {
21465                additonalInfos: [
21466                    {
21467                        field: 'ext_color_secondary',
21468                        title: 'weitere Farbe'
21469                    },
21470                    {
21471                        field: 'ext_material_primary',
21472                        title: 'Material'
21473                    },
21474                    {
21475                        field: 'ext_material_secondary',
21476                        title: 'weiteres Material'
21477                    }
21478                ]
21479            },
21480            cart: {
21481                bindFixedPositionOn: '#nav'
21482            },
21483            favourites: {
21484                cookieName: 'site-favourites',
21485                bindFixedPositionOn: '#nav'
21486            },
21487            events: {
21488                onBeforeFilterBuild: function ($this) {
21489                    if ($this.calc.filtersCount % $this.config.filterCols == 0) {
21490                        $newRow = $this.getTemplate($this.config.selectors.templateFiltersNewRow, 'filter-row-' + String($this.calc.filtersCount));
21491                        $($this.config.selectors.filtersContainer).append($newRow);
21492                    }
21493                },
21494                onAfterApplyFilter: function ($this) {
21495                    newFoundProducts = [];
21496                    if ($this.activeFilters.hasOwnProperty('size') || $this.activeFilters.hasOwnProperty('color') || $this.activeFilters.hasOwnProperty('material')) {
21497                        for (index in $this.foundProducts) {
21498                            if ($this.foundProducts[index]['products_master_model'] || (!$this.foundProducts[index]['products_master_model'] && $this.foundProducts[index]['products_master_flag'] == 0)) {
21499                                newFoundProducts.push($this.foundProducts[index]);
21500                            }
21501                        }
21502                    }
21503                    else {
21504                        for (index in $this.foundProducts) {
21505                            if (!$this.foundProducts[index]['products_master_model']) {
21506                                newFoundProducts.push($this.foundProducts[index]);
21507                            }
21508                        }
21509                    }
21510                    $this.foundProducts = newFoundProducts;
21511                },
21512                onBeforeProductBuild: function ($this) {
21513                    if ($this.searchParams.presentation == 'grid') {
21514                        if ($this.calc.productsCount % $this.config.productsCols == 0) {
21515                            $newRow = $this.getTemplate($this.config.selectors.templateProductsNewRow, 'products-row-' + String($this.calc.productsCount));
21516                            $($this.config.selectors.productsContainer).append($newRow);
21517                        }
21518                    }
21519                },
21520                onAfterProductsBuild: function ($this) {
21521                    if ($this.config.onLoadProduct) {
21522                        $this.openDetailView($this.config.onLoadProduct);
21523                        $($this.config.selectors.productDetail).modal('show');
21524                    }
21525                }
21526            },
21527            onLoadProduct: false
21528
21529        }
21530
21531        $.extend(true, this.config, config);
21532
21533        // properties
21534        this.data = {};
21535        this.calc = {
21536            filtersCount: 0,
21537            productsCount: 0
21538        }
21539        this.activeFilters = {};
21540        this.foundProducts = [];
21541        this.searchParams = {
21542            start: 0,
21543            range: 8,
21544            presentation: 'grid',
21545            sortBy: 'price',
21546            sortOrder: 'DESC'
21547        };
21548
21549
21550        // init function        
21551        this.init = function () {
21552            $this = this;
21553            this.documentTitle = document.title;
21554
21555            // BBQ
21556            if (this.config.bbqEnabled && !$('body').data('bbq-window-hashchange')) {
21557
21558                $('body').data('bbq-window-hashchange', true);
21559                $(window).bind('hashchange', {context: this}, function (event) {
21560                    bbqState = event.getState();
21561
21562                    if (bbqState.hasOwnProperty('product') && bbqState.product != '0') {
21563//                        bbqStateProductData = event.data.context.findInObjectArray(event.data.context.data.products, 'products_id', bbqState.product);
21564//
21565//                        if (bbqStateProductData && !$(event.data.context.config.selectors.productDetail).hasClass('open')) {
21566//                            event.data.context.config.onLoadProduct = bbqStateProductData;
21567//                        }
21568                    }
21569                    else {
21570                        if ($(event.data.context.config.selectors.productDetail).hasClass('open') && !bbqState.hasOwnProperty('bundle')) {
21571                            $(event.data.context.config.selectors.productDetail).modal('hide');
21572                        }
21573                    }
21574
21575                    if (event.data.context.config.view == 'category') {
21576                        hashFilter = bbqState.hasOwnProperty('filter') ? bbqState.filter : false;
21577                        filterChanges = event.data.context.findFilterChanges(hashFilter);
21578
21579
21580                        if (filterChanges.add) {
21581                            for (aIndex in filterChanges.add) {
21582                                event.data.context.selectFilter(filterChanges.add[aIndex]);
21583                            }
21584                        }
21585
21586                        if (filterChanges.remove) {
21587                            for (aIndex in filterChanges.remove) {
21588                                filterLink = $(filterChanges.remove[aIndex]);
21589                                event.data.context.removeFilter(filterLink.data(), filterLink);
21590                            }
21591                        }
21592
21593                    }
21594
21595                    switch (event.data.context.config.view) {
21596                        case 'category':
21597                        case 'search':
21598                            if (bbqState.hasOwnProperty('settings')) {
21599
21600                                settingsChanged = false;
21601                                if (bbqState.settings.hasOwnProperty('start') && event.data.context.searchParams.start != parseInt(bbqState.settings.start)) {
21602                                    settingsChanged = true;
21603                                }
21604                                if (bbqState.settings.hasOwnProperty('range') && event.data.context.searchParams.range != parseInt(bbqState.settings.range)) {
21605                                    settingsChanged = true;
21606                                }
21607                                if (bbqState.settings.hasOwnProperty('presentation') && event.data.context.searchParams.presentation != bbqState.settings.presentation) {
21608                                    settingsChanged = true;
21609                                }
21610                                if (bbqState.settings.hasOwnProperty('sortBy') && event.data.context.searchParams.sortBy != bbqState.settings.sortBy) {
21611                                    settingsChanged = true;
21612                                }
21613                                if (bbqState.settings.hasOwnProperty('sortOrder') && event.data.context.searchParams.sortOrder != bbqState.settings.sortOrder) {
21614                                    settingsChanged = true;
21615                                }
21616
21617                                event.data.context.searchParams = {
21618                                    start: bbqState.settings.hasOwnProperty('start') ? parseInt(bbqState.settings.start) : 0,
21619                                    range: bbqState.settings.hasOwnProperty('range') ? parseInt(bbqState.settings.range) : 8,
21620                                    presentation: bbqState.settings.hasOwnProperty('presentation') ? bbqState.settings.presentation : 'grid',
21621                                    sortBy: bbqState.settings.hasOwnProperty('sortBy') ? bbqState.settings.sortBy : 'price',
21622                                    sortOrder: bbqState.settings.hasOwnProperty('sortOrder') ? bbqState.settings.sortOrder : 'ASC'
21623                                };
21624
21625
21626                                if (settingsChanged) {
21627
21628                                    event.data.context.buildPagination();
21629
21630                                    //event.data.context.applyFilters();
21631                                }
21632                            }
21633                            break;
21634                    }
21635
21636                    if (bbqState.hasOwnProperty('bg')) {
21637                        $('.products-grid .product .image').css({
21638                            'background-size': bbqState.bg
21639                        });
21640                    }
21641
21642                });
21643            }
21644
21645            switch ($this.config.view) {
21646                case 'category':
21647                    // load products
21648                    this.config.rootContainer.spin();
21649                    $.ajax('/json.php', {
21650                        data: {
21651                            action: 'products',
21652                            category: this.config.currentCategoryId,
21653                            language: this.config.language
21654                        },
21655                        dataType: 'json',
21656                        error: function (jqXHR, textStatus, errorThrown) {
21657                            if (typeof console != 'undefined') {
21658
21659                            }
21660                            else {
21661                                alert(errorThrown);
21662                            }
21663                        },
21664                        success: function (data, textStatus, jqXHR) {
21665
21666                            $this.config.rootContainer.spin(false);
21667                            // products data
21668                            $.extend(true, $this.data, data);
21669
21670                            $this.assignMastersAndSlaves();
21671                            $this.buildFilters();
21672                            $this.bindConfigurationLinkEvents();
21673
21674                            $(window).trigger('hashchange');
21675
21676//                            if ($this.config.currentCategoryId && data.currentCategoryType == 'sub') {
21677//                                startUpCategoryData = {
21678//                                    'filter': 'categories',
21679//                                    'value': String($this.config.currentCategoryId),
21680//                                    'title': data.currentCategory.categories_name
21681//                                };
21682//                                for (cIndex in $this.data.categories) {
21683//                                    if ($this.data.categories[cIndex]['id'] == $this.config.currentCategoryId) {
21684//                                        if ($this.data.categories[cIndex].hasOwnProperty('childIds')) {
21685//                                            for (pIndex in $this.data.products) {
21686//                                                for (pcIndex in $this.data.products[pIndex]['categories']) {
21687//                                                    if (jQuery.inArray($this.data.products[pIndex]['categories'][pcIndex], $this.data.categories[cIndex]['childIds']) >= 0) {
21688//                                                        $this.data.products[pIndex]['categories'].push($this.config.currentCategoryId);
21689//                                                    }
21690//                                                }
21691//                                            }
21692//                                        }
21693//                                    }
21694//                                }
21695//
21696//                                $this.selectFilter(startUpCategoryData);
21697//                            }
21698//                            else {
21699                                $this.applyFilters();
21700//                            }
21701
21702
21703
21704                        }
21705                    });
21706                    break;
21707
21708
21709
21710
21711
21712                case 'cart':
21713                    // cart events
21714                    if ($('#welcome').length == 0) {
21715                        $(window).bind('scroll', {context: $this}, function (event) {
21716                            cartOffset = $(event.data.context.config.selectors.cart).offset();
21717                            bindOffset = $(event.data.context.config.cart.bindFixedPositionOn).offset();
21718                            if ($(window).scrollTop() > bindOffset.top) {
21719                                if (!$(event.data.context.config.selectors.cart).hasClass('fixed')) {
21720                                    cartLeft = cartOffset.left;
21721                                    if ($(document).innerWidth() <= 767) {
21722                                        cartLeft = 0;
21723                                    }
21724                                    $(event.data.context.config.selectors.cart).css({
21725                                        'position': 'fixed',
21726                                        'top': $(event.data.context.config.selectors.cart).innerHeight() * (-1),
21727                                        'left': cartLeft
21728                                    });
21729                                    $(event.data.context.config.selectors.cart).addClass('fixed');
21730                                    $(event.data.context.config.selectors.cartContent).addClass('fixed');
21731                                    $(event.data.context.config.selectors.cart).stop().animate({
21732                                        'top': -1,
21733                                    }, 300);
21734
21735                                    cartContentLeft = cartOffset.left - 100;
21736                                    if ($(document).innerWidth() <= 767) {
21737                                        cartContentLeft = 0;
21738                                    }
21739                                    $(event.data.context.config.selectors.cartContent).css({
21740                                        'position': 'fixed',
21741                                        'top': $(event.data.context.config.selectors.cart).innerHeight() - 10,
21742                                        'left': cartContentLeft
21743                                    });
21744
21745                                }
21746
21747                            }
21748                            else {
21749                                if ($(event.data.context.config.selectors.cart).hasClass('fixed')) {
21750
21751                                    cartPosition = 'absolute';
21752                                    cartTop = '30px';
21753
21754                                    if ($(document).innerWidth() <= 767) {
21755                                        cartPosition = 'relative';
21756                                        cartTop = '0';
21757                                    }
21758                                    $(event.data.context.config.selectors.cart).css({
21759                                        'position': cartPosition,
21760                                        'top': cartTop,
21761                                        'left': 'auto'
21762                                    });
21763                                    $(event.data.context.config.selectors.cart).removeClass('fixed');
21764                                    $(event.data.context.config.selectors.cartContent).removeClass('fixed');
21765                                    $(event.data.context.config.selectors.cartContent).css({
21766                                        'position': 'absolute',
21767                                        'top': '65px',
21768                                        'left': 'auto'
21769                                    });
21770                                }
21771
21772                            }
21773
21774                        });
21775                    }
21776
21777
21778                    $($this.config.selectors.cartContent).popover({
21779                    });
21780                    $($this.config.selectors.cart).bind('mouseenter', {context: $this}, function (event) {
21781                        if ($(event.data.context.config.selectors.cartContent).data('totalCount') > 0) {
21782                            $(event.data.context.config.selectors.cartContent).show();
21783                        }
21784                    });
21785                    $($this.config.selectors.cart).bind('mouseleave', {context: $this}, function (event) {
21786                        overContent = $(event.data.context.config.selectors.cartContent).data('mouseover');
21787                        if (!overContent) {
21788                            //$(event.data.context.config.selectors.cartContent).hide();
21789                        }
21790                    });
21791                    $($this.config.selectors.cartContent).bind('mouseenter', {context: $this}, function (event) {
21792                        $(this).data('mouseover', true);
21793                    });
21794                    $($this.config.selectors.cartContent).bind('mouseleave', {context: $this}, function (event) {
21795                        $(this).data('mouseover', false);
21796                        $(this).hide();
21797                    });
21798
21799                    $($this.config.selectors.cartContent + ' .remove-cart-product').live('click', {context: $this}, function (event) {
21800                        event.preventDefault();
21801                        event.data.context.removeFromCart($(this).parents('.cart
21801-product').first());
21802                    });
21803
21804                    $('#button-sale').live('click', {context: $this}, function (event) {
21805
21806                        event.preventDefault();
21807                        event.data.context.config.rootContainer.spin();
21808                        
21809                        $.ajax('/json.php', {
21810                            data: {
21811                                action: 'search',
21812                                query: '::specials::',
21813                                language: event.data.context.config.language
21814                            },
21815                            dataType: 'json',
21816                            context: event.data.context,
21817                            error: function (jqXHR, textStatus, errorThrown) {
21818                                if (typeof console != 'undefined') {
21819
21820                                }
21821                                else {
21822                                    alert(errorThrown);
21823                                }
21824                            },
21825                            success: function (data, textStatus, jqXHR) {
21826                                this.config.rootContainer.spin(false);
21827                                if (data.products.length > 0) {
21828                                    $('.original-content').hide();
21829                                    $('#globalSearch-result').removeClass('hide');
21830
21831                                    // products data
21832                                    this.data = {};
21833                                    $.extend(true, this.data, data);
21834                                    this.assignMastersAndSlaves();
21835                                    //$this.buildFilters();
21836                                    this.bindConfigurationLinkEvents();
21837                                    this.config.selectors.productsContainer = '#globalSearch-box-products';
21838
21839                                    this.applyFilters();
21840                                }
21841                                else {
21842
21843                                    $('#global-message .message-header').text('Ihre Suchanfrage');
21844                                    $('#global-message .message').text('Für Ihre Suchanfrage konnten leider keine Produkte gefunden werden.');
21845                                    $('#global-message').modal('show');
21846                                }
21847
21848                                $(window).trigger('hashchange');
21849
21850                            }
21851                        });
21852                    });
21853                    break;
21854
21855                case 'favourites':
21856
21857                    favouritesCookie = $.cookie($this.config.favourites.cookieName);
21858                    if (favouritesCookie) {
21859
21860                        $container = $($this.config.selectors.favourites);
21861                        $container.show();
21862                        $container.spin();
21863                        favouriteModels = favouritesCookie.split(',');
21864                        $($this.config.selectors.favourites).data('favouriteModels', favouriteModels);
21865
21866                        $.ajax('/json.php', {
21867                            data: {
21868                                action: 'staticProducts',
21869                                products: favouriteModels,
21870                                includeSub: 1,
21871                                language: this.config.language
21872                            },
21873                            dataType: 'json',
21874                            context: $container,
21875                            error: function (jqXHR, textStatus, errorThrown) {
21876                                if (typeof console != 'undefined') {
21877
21878                                }
21879                                else {
21880                                    alert(errorThrown);
21881                                }
21882                            },
21883                            success: function (data, textStatus, jqXHR) {
21884                                $(this).spin(false);
21885                                $.extend(true, $this.data, data);
21886                                $this.assignMastersAndSlaves();
21887                                $($this.config.selectors.favourites).data('content', $this.data.products);
21888                                $($this.config.selectors.favourites).data('contentCount', 0);
21889                                $this.refreshFavourites();
21890                            }
21891                        });
21892                    }
21893                    else {
21894                        $($this.config.selectors.favourites).data('favouriteModels', new Array());
21895                        $this.refreshFavourites();
21896                    }
21897
21898                    $(window).bind('scroll', {context: $this}, function (event) {
21899                        if (!$(event.data.context.config.selectors.favourites).data('show')) {
21900                            $(event.data.context.config.selectors.favourites).show();
21901                        }
21902                        favouritesOffset = $(event.data.context.config.selectors.favourites).offset();
21903                        if (!$(event.data.context.config.selectors.favourites).data('show')) {
21904                            $(event.data.context.config.selectors.favourites).hide();
21905                        }
21906                        bindOffset = $(event.data.context.config.favourites.bindFixedPositionOn).offset();
21907                        if ($(window).scrollTop() > bindOffset.top) {
21908                            if (!$(event.data.context.config.selectors.favourites).hasClass('fixed')) {
21909                                favouritesLeft = favouritesOffset.left;
21910                                favouritesTop = $(event.data.context.config.selectors.favourites).innerHeight() * (-1);
21911                                favouritesTopTarget = -1;
21912                                if ($(document).innerWidth() <= 767) {
21913                                    favouritesLeft = 0;
21914                                    favouritesTopTarget = 40;
21915                                }
21916                                $(event.data.context.config.selectors.favourites).css({
21917                                    'position': 'fixed',
21918                                    'top': favouritesTop,
21919                                    'left': favouritesLeft
21920                                });
21921                                $(event.data.context.config.selectors.favourites).addClass('fixed');
21922                                $(event.data.context.config.selectors.favouritesContent).addClass('fixed');
21923                                $(event.data.context.config.selectors.favourites).stop().animate({
21924                                    'top': favouritesTopTarget,
21925                                }, 300);
21926                                favouritesContentLeft = favouritesOffset.left - 280;
21927                                if ($(document).innerWidth() <= 767) {
21928                                    favouritesContentLeft = 0;
21929                                }
21930                                $(event.data.context.config.selectors.favouritesContent).css({
21931                                    'position': 'fixed',
21932                                    'top': $(event.data.context.config.selectors.favourites).innerHeight() - 10,
21933                                    'left': favouritesContentLeft
21934                                });
21935                            }
21936
21937                        }
21938                        else {
21939                            if ($(event.data.context.config.selectors.favourites).hasClass('fixed')) {
21940                                favouritesPosition = 'absolute';
21941                                favouritesTop = '30px';
21942
21943                                if ($(document).innerWidth() <= 767) {
21944                                    favouritesPosition = 'relative';
21945                                    favouritesTop = '0';
21946                                }
21947                                $(event.data.context.config.selectors.favourites).css({
21948                                    'position': favouritesPosition,
21949                                    'top': favouritesTop,
21950                                    'left': 'auto'
21951                                });
21952                                $(event.data.context.config.selectors.favourites).removeClass('fixed');
21953                                $(event.data.context.config.selectors.favouritesContent).removeClass('fixed');
21954                                $(event.data.context.config.selectors.favouritesContent).css({
21955                                    'position': 'absolute',
21956                                    'top': '65px',
21957                                    'left': 'auto'
21958                                });
21959                            }
21960
21961                        }
21962
21963                    });
21964
21965                    $($this.config.selectors.favouritesContent).popover({
21966                    });
21967                    $($this.config.selectors.favourites).bind('mouseenter', {context: $this}, function (event) {
21968                        $(event.data.context.config.selectors.favouritesContent).show();
21969                    });
21970                    $($this.config.selectors.favouritesContent).bind('mouseleave', {context: $this}, function (event) {
21971                        $(this).data('mouseover', false);
21972                        $(this).hide();
21973                    });
21974
21975                    $($this.config.selectors.favouritesContent + ' .remove-favourites-product').live('click', {context: $this}, function (event) {
21976                        event.preventDefault();
21977                        event.data.context.removeFromFavourites($(this).parents('.favourites-product').first().data(), $($this.config.selectors.favourites));
21978                    });
21979
21980
21981                    break;
21982
21983
21984                case 'staticProducts':
21985                    // load products
21986                    this.config.rootContainer.spin();
21987
21988                    productModels = new Array();
21989                    $(this.config.rootContainer).find('.product').each(function (pIndex, $product) {
21990                        productModels.push($($product).data('model'));
21991                    });
21992
21993                    $.ajax('/json.php', {
21994                        data: {
21995                            action: 'staticProducts',
21996                            products: productModels,
21997                            includeSub: 1,
21998                            language: this.config.language
21999                        },
22000                        context: this,
22001                        dataType: 'json',
22002                        error: function (jqXHR, textStatus, errorThrown) {
22003                            if (typeof console != 'undefined') {
22004
22005                            }
22006                            else {
22007                                alert(errorThrown);
22008                            }
22009                        },
22010                        success: function (data, textStatus, jqXHR) {
22011
22012                            this.config.rootContainer.spin(false);
22013                            // products data
22014                            $.extend(true, this.data, data);
22015
22016                            this.assignMastersAndSlaves();
22017
22018                            $this = this;
22019                            this.config.rootContainer.find('.product').each(function (pIndex, $product) {
22020                                product = $this.data.products[$($product).data('id')];
22021                                $($product).data(product);
22022                                $($product).find('.product-link').attr('href', '/' + product.url_text);
22023                                $this.buildProductPrice($($product), product);
22024
22025                                $this.buildProductOptions($($product), product);
22026
22027                                if (product.ext_discount > 0) {
22028                                    $($product).find('.discount').show();
22029                                    $($product).addClass('with-discount');
22030                                }
22031
22032
22033                            });
22034
22035                            this.bindProductsEvents(this.config.rootContainer);
22036
22037                            $(window).trigger('hashchange');
22038                        }
22039                    });
22040
22041                    break;
22042
22043                case 'bundles':
22044                    // load products
22045                    this.config.rootContainer.spin();
22046
22047                    bundleIds = new Array();
22048                    $(this.config.rootContainer).find('.product').each(function (pIndex, $product) {
22049                        bundleIds.push($($product).data('id'));
22050                    });
22051
22052                    $.ajax('/json.php', {
22053                        data: {
22054                            action: 'bundles',
22055                            bundles: bundleIds,
22056                            includeSub: 1,
22057                            language: this.config.language
22058                        },
22059                        context: this,
22060                        dataType: 'json',
22061                        error: function (jqXHR, textStatus, errorThrown) {
22062                            if (typeof console != 'undefined') {
22063
22064                            }
22065                            else {
22066                                alert(errorThrown);
22067                            }
22068                        },
22069                        success: function (data, textStatus, jqXHR) {
22070
22071                            this.config.rootContainer.spin(false);
22072                            // products data
22073                            $.extend(true, this.data, data);
22074
22075                            this.assignMastersAndSlaves();
22076                            $this = this;
22077                            if (this.data.bundles.length == 0) {
22078                                this.config.rootContainer.hide();
22079                                this.config.rootContainer.prev('.headline-special-center').hide();
22080                            }
22081                            else {
22082                                this.config.rootContainer.show();
22083                                this.config.rootContainer.prev('.headline-special-center').show();
22084                                for (bIndex in this.data.bundles) {
22085                                    this.data.bundles[bIndex]['products'] = new Array();
22086                                    for (pIdIndex in this.data.bundles[bIndex]['productIds']) {
22087                                        this.data.bundles[bIndex]['products'].push(this.data.products[this.data.bundles[bIndex]['productIds'][pIdIndex]]);
22088                                    }
22089                                }
22090
22091
22092                                this.config.rootContainer.find('.product').each(function (pIndex, $bundle) {
22093                                    if ($this.data.bundles.hasOwnProperty($($bundle).data('id'))) {
22094                                        bundle = $this.data.bundles[$($bundle).data('id')];
22095                                        bundle.type = 'bundle';
22096                                        $($bundle).data(bundle);
22097                                        $($bundle).addClass('bundle');
22098
22099                                        bundleImageFilename = 'noimage.png';
22100
22101
22102
22103                                        if (bundle.ssag_image) {
22104                                            bundleImageFilename = bundle.ssag_image;
22105                                        }
22106                                        else {
22107                                            if (bundle.products.length > 0) {
22108                                                for (pIndex in bundle.products) {
22109                                                    productImageFilename = $this.findFirstProductImage(bundle.products[pIndex]);
22110                                                    if (bundleImageFilename != productImageFilename) {
22111                                                        bundleImageFilename = productImageFilename;
22112                                                        break;
22113                                                    }
22114                                                }
22115                                            }
22116                                        }
22117                                        $($bundle).find('.image').css({
22118                                            'background-image': 'url(/media/images/info/' + bundleImageFilename + ')'
22119                                        });
22120                                        $this.buildBundlePrice($($bundle), bundle);
22121//
22122//                                $this.buildProductOptions($($product), product);
22123//
22124//                                if (product.ext_discount > 0) {
22125//                                    $($product).find('.discount').show();
22126//                                    $($product).addClass('with-discount');
22127//                                }
22128                                    }
22129                                    else {
22130                                        $($bundle).parents('.span3').first().detach();
22131                                    }
22132
22133
22134
22135                                });
22136
22137                                this.bindProductsEvents(this.config.rootContainer);
22138
22139                                $(window).trigger('hashchange');
22140                            }
22141
22142                        }
22143                    });
22144
22145                    break;
22146
22147
22148                case 'detail':
22149                    // load products
22150                    this.config.rootContainer.spin();
22151                    if ($(this.config.rootContainer).data('masterModel')) {
22152                        productModels = new Array($(this.config.rootContainer).data('masterModel'));
22153                    }
22154                    else {
22155                        productModels = new Array(String($(this.config.rootContainer).data('model')));
22156                    }
22157
22158
22159                    $.ajax('/json.php', {
22160                        data: {
22161                            action: 'staticProducts',
22162                            products: productModels,
22163                            includeSub: 1,
22164                            language: this.config.language
22165                        },
22166                        dataType: 'json',
22167                        error: function (jqXHR, textStatus, errorThrown) {
22168                            if (typeof console != 'undefined') {
22169
22170                            }
22171                            else {
22172                                alert(errorThrown);
22173                            }
22174                        },
22175                        success: function (data, textStatus, jqXHR) {
22176
22177                            $this.config.rootContainer.spin(false);
22178
22179                            // products data
22180                            $.extend(true, $this.data, data);
22181
22182
22183                            $this.assignMastersAndSlaves();
22184
22185                            product = $this.data.products[$this.config.rootContainer.data('id')];
22186                            $this.openDetailView(product, $this.config.rootContainer);
22187
22188
22189                        }
22190                    });
22191                    break;
22192
22193                case 'search':
22194
22195
22196                    $(this.config.selectors.search.form).bind('submit', {context: this}, function (event) {
22197                        event.preventDefault();
22198                        event.data.context.config.rootContainer.spin();
22199
22200
22201                        $.ajax('/json.php', {
22202                            data: {
22203                                action: 'search',
22204                                query: $(event.data.context.config.selectors.search.input).val(),
22205                                language: event.data.context.config.language
22206                            },
22207                            dataType: 'json',
22208                            context: event.data.context,
22209                            error: function (jqXHR, textStatus, errorThrown) {
22210                                if (typeof console != 'undefined') {
22211
22212                                }
22213                                else {
22214                                    alert(errorThrown);
22215                                }
22216                            },
22217                            success: function (data, textStatus, jqXHR) {
22218                                this.config.rootContainer.spin(false);
22219                                if (data.products.length > 0) {
22220                                    $('.original-content').hide();
22221                                    $('#globalSearch-result').removeClass('hide');
22222
22223                                    // products data
22224                                    this.data = {};
22225                                    $.extend(true, this.data, data);
22226                                    this.assignMastersAndSlaves();
22227                                    //$this.buildFilters();
22228                                    this.bindConfigurationLinkEvents();
22229
22230
22231                                    this.applyFilters();
22232                                }
22233                                else {
22234
22235                                    $('#global-message .message-header').text('Ihre Suchanfrage');
22236                                    $('#global-message .message').text('Für Ihre Suchanfrage konnten leider keine Produkte gefunden werden.');
22237                                    $('#global-message').modal('show');
22238                                }
22239
22240                                $(window).trigger('hashchange');
22241
22242                            }
22243                        });
22244
22245                    });
22246
22247
22248
22249
22250
22251                    break;
22252
22253
22254            }
22255
22256
22257
22258        };
22259
22260        this.assignMastersAndSlaves = function () {
22261            // assign products by model
22262            this.data.productsByModel = {};
22263            for (index in this.data.products) {
22264                this.data.productsByModel[this.data.products[index]['products_model']] = this.data.products[index];
22265            }
22266
22267            // assign master / slaves
22268            for (index in this.data.products) {
22269                if (this.data.products[index]['products_master_model'] != '') {
22270                    if (this.data.productsByModel.hasOwnProperty(this.data.products[index]['products_master_model'])) {
22271                        product = this.data.productsByModel[this.data.products[index]['products_master_model']];
22272
22273                        this.data.products[index]['master'] = product;
22274                        if (product.hasOwnProperty('children')) {
22275                            product.children.push(this.data.products[index]);
22276                        }
22277                        else {
22278                            product.children = new Array(this.data.products[index]);
22279                        }
22280                    }
22281                }
22282            }
22283
22284            // assign options for masters and product-types
22285            for (index in this.data.products) {
22286                product = this.data.products[index];
22287                if (product['products_master_model'] == '' && product.hasOwnProperty('children') && product.children.length > 0) {
22288                    product.type = 'master';
22289                    product.options = {};
22290                    for (filterKey in this.config.filters) {
22291                        filter = this.config.filters[filterKey];
22292
22293                        if (filter.hasOwnProperty('isProductOption') && filter.isProductOption) {
22294                            optionFields = filter.field;
22295                            if (!jQuery.isArray(optionFields)) {
22296                                optionFields = new Array(optionFields);
22297                            }
22298                            product.options[filterKey] = new Array();
22299                            for (cIndex in product.children) {
22300                                child = product.children[cIndex];
22301                                for (fIndex in optionFields) {
22302
22303
22304                                    if (child[optionFields[fIndex]] != '' && jQuery.inArray(child[optionFields[fIndex]], product.options[filterKey]) < 0) {
22305                                        product.options[filterKey].push(child[optionFields[fIndex]]);
22306
22307                                    }
22308                                }
22309                            }
22310
22311                            if (product.options[filterKey].length > 0) {
22312                                filter.sortOptions(product.options[filterKey], this);
22313                            }
22314                            else {
22315                                delete product.options[filterKey];
22316                            }
22317
22318                        }
22319                    }
22320
22321                }
22322                else if (product['products_master_model'] != '') {
22323                    product.type = 'child';
22324                }
22325                else {
22326                    product.type = 'standalone';
22327                }
22328
22329
22330            }
22331
22332        };
22333
22334
22335
22336        // filter functions - build & bind
22337
22338        this.buildFilters = function () {
22339
22340            // html creation
22341            this.calc.filtersCount = 0;
22342            $(this.config.selectors.filtersContainer).empty();
22343            for (filterName in this.config.filters) {
22344                filter = this.config.filters[filterName];
22345                if (this.data.hasOwnProperty(filterName)) {
22346                    this.config.events.onBeforeFilterBuild(this);
22347                    filter.build(this, filter, filterName);
22348                    this.calc.filtersCount++;
22349                }
22350            }
22351            // event binding
22352            this.bindFilterEventFunctions.runQueue(this);
22353
22354            $('.filter-add.element-size div').detach();
22355            $('.filter-add.element-color div').detach();
22356            $('.filter-add.element-material div').detach();
22357        };
22358
22359        this.buildFilterFunctions = {
22360            vlist: function ($this, filter, filterName) {
22361                $template = $this.getTemplate(filter.templateId, 'filter-' + filterName);
22362                $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]);
22363                $template.find($this.config.selectors.filterElements + ' ul').empty();
22364                for (c = 0; c < $this.data[filterName].length; c++) {
22365                    element = $this.data[filterName][c];
22366                    $template.find($this.config.selectors.filterElements + ' ul').append('<li><a href="#" class="' + $this.config.classes.filterAddLink + '">' + element.title + '</a></li>');
22367                    $template.find($this.config.selectors.filterElements + ' ul li:last a').data({
22368                        'filter': filterName,
22369                        'value': element.id,
22370                        'title': element.title
22371                    });
22372                    $template.find($this.config.selectors.filterElements + ' ul li:last a').data('elementId', element.id);
22373                }
22374                $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template);
22375
22376            },
22377            occurrences: function ($this, filter, filterName) {
22378                if ($this.data[filterName].length > 0) {
22379                    $template = $this.getTemplate(filter.templateId, 'filter-' + filterName);
22380                    $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]);
22381                    $template.find($this.config.selectors.filterElements + ' .inner').empty();
22382                    for (c = 0; c < $this.data[filterName].length; c++) {
22383                        element = $this.data[filterName][c];
22384                        if (typeof element === 'object') {
22385                            elementValue = element.id;
22386                            elementTitle = element.title;
22387                        }
22388                        else {
22389                            elementValue = element;
22390                            elementTitle = element.replace("\\/", '/');
22391                        }
22392                        elementData = {
22393                            'filter': filterName,
22394                            'value': elementValue,
22395                            'title': elementTitle
22396                        };
22397                        linkId = 'filter-link-' + filterName + '-' + String(c);
22398                        if (element.hasOwnProperty('childIds')) {
22399                            elementData.value = [elementData.value];
22400                            elementData.value = elementData.value.concat(element.childIds);
22401//                            $elementWithChildren = $('<div class="row-fluid"><div class="span4 root"></div><div class="span8 children"></div></div>');
22402//                            $elementWithChildren.find('.root').append('<a href="#" id="' + linkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + elementTitle + '</span></a>');
22403                            $elementWithChildren = $('<div class="element-with-children" style="clear:both;"><div class="root"></div><div class="children"></div></div>');
22404                            $elementWithChildren.find('.root').append('<h4 class="font-bold font-highlight">' + elementTitle + '</h4>');
22405
22406                            for (d = 0; d < element.children.length; d++) {
22407                                childElement = element.children[d];
22408                                childElementData = {
22409                                    'filter': filterName,
22410                                    'value': childElement.id,
22411                                    'title': childElement.title,
22412                                    'parent': elementValue
22413                                }
22414                                childLinkId = 'filter-link-' + filterName + '-' + String(c) + '-' + String(d);
22415                                $elementWithChildren.find('.children').append('<a href="#" id="' + childLinkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + childElement.title + '</span></a>');
22416                                $elementWithChildren.find('#' + childLinkId).data(childElementData);
22417                            }
22418                            $template.find($this.config.selectors.filterElements + ' .inner').append($elementWithChildren);
22419                        }
22420                        else {
22421                            $template.find($this.config.selectors.filterElements + ' .inner').append('<a href="#" id="' + linkId + '" class="' + $this.config.classes.filterAddLink + ' element-' + filterName + '"><span class="bg"></span><span class="title">' + elementTitle + '</span></a>');
22422                        }
22423
22424
22425                        $template.find('#' + linkId).data(elementData);
22426
22427                    }
22428
22429                    // mobile -> accordion
22430                    if ($(document).innerWidth() <= 479) {
22431                        $template.find('.dropdown-toggle').removeClass('dropdown-toggle').addClass('accordion-toggle');
22432                        $template.find('.dropdown-menu').removeClass('dropdown-menu').addClass('accordion-body collapse');
22433
22434                        $template.find('.accordion-body').attr('id', 'filter-accordion-' + filterName);
22435                        $template.find('.accordion-toggle').attr('href', '#f
22435ilter-accordion-' + filterName);
22436                        $template.find('.accordion-toggle').attr('data-toggle', 'collapse');
22437                        $template.find('.accordion-toggle').attr('data-parent', '#box-filter');
22438                        $('#box-filter').addClass('accordion-group');
22439                    }
22440
22441
22442                    $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template);
22443
22444                }
22445
22446            },
22447            range: function ($this, filter, filterName) {
22448                $template = $this.getTemplate(filter.templateId, 'filter-' + filterName);
22449                $template.find($this.config.selectors.filterTitle).text(filter.title[$this.config.language]);
22450                $template.find($this.config.selectors.filterRange.titleMin).text($this.config.translations.from[$this.config.language]);
22451                $template.find($this.config.selectors.filterRange.titleMax).text($this.config.translations.to[$this.config.language]);
22452                $template.find($this.config.selectors.filterRange.valueMin).html($this.formatPrice($this.data[filterName]['min']));
22453                $template.find($this.config.selectors.filterRange.valueMax).html($this.formatPrice($this.data[filterName]['max']));
22454                $template.find($this.config.selectors.filterRange.valueMin).data({
22455                    'filter': filterName,
22456                    'type': 'min',
22457                    'value': $this.data[filterName]['min'],
22458                    'valueMin': $this.data[filterName]['min'],
22459                    'valueMax': $this.data[filterName]['max']
22460                });
22461                $template.find($this.config.selectors.filterRange.valueMax).data({
22462                    'filter': filterName,
22463                    'type': 'max',
22464                    'value': $this.data[filterName]['max'],
22465                    'valueMin': $this.data[filterName]['min'],
22466                    'valueMax': $this.data[filterName]['max']
22467                });
22468                $($this.config.selectors.filtersContainer + ' ' + $this.config.selectors.filterRow).last().append($template);
22469            }
22470
22471        };
22472
22473
22474        this.bindFilterEventFunctions = {
22475            executionQueue: [],
22476            addToExecutionQueue: function ($this, functionName) {
22477                if (jQuery.inArray(functionName, $this.bindFilterEventFunctions.executionQueue) < 0) {
22478                    $this.bindFilterEventFunctions.executionQueue.push(functionName);
22479                }
22480            },
22481            runQueue: function ($this) {
22482                for (index in $this.bindFilterEventFunctions.executionQueue) {
22483                    functionName = $this.bindFilterEventFunctions.executionQueue[index];
22484                    $this.bindFilterEventFunctions[functionName]($this);
22485                }
22486            },
22487            links: function ($this) {
22488
22489                $('.' + $this.config.classes.filterAddLink).bind('touchend click', function (event) {
22490                    event.preventDefault();
22491                    $this.selectFilter($(this).data());
22492                    //$(this).addClass('disabled');
22493                    if (typeof event.originalEvent != 'undefined' &&
22494                            typeof event.originalEvent.touches != 'undefined') {
22495                        event.stopPropagation();
22496                    }
22497
22498
22499                });
22500            },
22501            range: function ($this) {
22502
22503                $($this.config.selectors.filterRange.mover).each(function (mIndex, mover) {
22504
22505                    positionKey = $(mover).data('type') == 'min' ? 'left' : 'right';
22506                    $(mover).data({
22507                        'startPosition': false,
22508                        'positionKey': positionKey,
22509                        'positionStart': parseInt($(mover).css(positionKey).replace('px', ''))
22510                    });
22511
22512                    value = $(mover).nextAll($(mover).data('nextSelector')).first();
22513
22514                    $(mover).add(value).bind('touchstart mousedown', {mover: mover}, function (event) {
22515                        event.preventDefault();
22516//                        var debug = '';
22517//                        for (var key in event.originalEvent.touches[0]) {
22518//                            debug += ',' + key +'=[' + event.originalEvent.touches[0][key] + ']';
22519//                        }
22520//                        alert(debug);
22521                        if (typeof event.originalEvent != 'undefined' &&
22522                                typeof event.originalEvent.touches != 'undefined') {
22523                            pageX = event.originalEvent.touches[0].pageX;
22524                        }
22525                        else {
22526                            pageX = event.pageX;
22527                        }
22528                        filterContainer = $(event.data.mover).parents('.products-listing-filter').first();
22529                        filterContainer.find('.dropdown-toggle').first().attr('data-toggle', '');
22530                        progress = $(event.data.mover).parents('.progress').first();
22531                        $(event.data.mover).data({
22532                            'totalWidth': $(progress).innerWidth(),
22533                            'startPosition': pageX,
22534                            'position': parseInt($(event.data.mover).css($(event.data.mover).data('positionKey')).replace('px', ''))
22535                        });
22536                        $('body').data('currentMover', event.data.mover);
22537                    });
22538
22539
22540
22541                });
22542
22543                $('body').bind('touchmove mousemove', {context: $this}, function (event) {
22544
22545                    if ($(this).data('currentMover')) {
22546                        // values
22547
22548                        if (typeof event.originalEvent != 'undefined' &&
22549                                typeof event.originalEvent.touches != 'undefined') {
22550                            pageX = event.originalEvent.touches[0].pageX;
22551                            pageY = event.originalEvent.touches[0].pageY;
22552                        }
22553                        else {
22554                            pageX = event.pageX;
22555                            pageY = event.pageY;
22556                        }
22557
22558                        mover = $(this).data('currentMover');
22559                        value = $(mover).nextAll($(mover).data('nextSelector')).first();
22560                        progress = $(mover).parents('.progress').first();
22561                        movement = pageX - $(mover).data('startPosition');
22562                        positionCorrection = ($(mover).data('positionStart') < 0 ? $(mover).data('positionStart') * -1 : $(mover).data('positionStart'));
22563                        if ($(mover).data('type') == 'max') {
22564                            movement *= -1;
22565                        }
22566                        newPosition = $(mover).data('positionStart') + positionCorrection + $(mover).data('position') + movement;
22567
22568                        // prevent movement above max and under min
22569                        if (newPosition < $(mover).data('positionStart')) {
22570                            newPosition = $(mover).data('positionStart');
22571                        }
22572                        if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth')) {
22573                            newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth');
22574                        }
22575                        // prevent movement min over max or max under min
22576                        if ($(mover).data('type') == 'min') {
22577                            moverMax = $(mover).nextAll('.mover.range-max').first();
22578                            moverMaxPosition = parseInt($(moverMax).css($(moverMax).data('positionKey')).replace('px', ''));
22579                            if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMaxPosition - $(mover).innerWidth()) {
22580                                newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMaxPosition - $(mover).innerWidth();
22581                            }
22582                        }
22583                        else {
22584                            moverMin = $(mover).prevAll('.mover.range-min').first();
22585                            moverMinPosition = parseInt($(moverMin).css($(moverMin).data('positionKey')).replace('px', ''));
22586                            if (newPosition > $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMinPosition - $(mover).innerWidth()) {
22587                                newPosition = $(mover).data('positionStart') + $(mover).data('totalWidth') - moverMinPosition - $(mover).innerWidth();
22588                            }
22589                        }
22590                        // apply movement
22591                        $(mover).css($(mover).data('positionKey'), String(newPosition) + 'px');
22592                        $(mover).nextAll($(mover).data('nextSelector')).css($(mover).data('positionKey'), String(newPosition + $(mover).data('valueSpace')) + 'px');
22593
22594                        // set bar
22595                        moverProgressValue = newPosition + positionCorrection;
22596                        moverPercentage = parseInt(100 / $(mover).data('totalWidth') * moverProgressValue);
22597
22598                        if ($(mover).data('type') == 'max') {
22599                            $(progress).find('.bar').css('margin-right', String(moverPercentage) + '%');
22600                            $(progress).find('.bar').data('status', moverPercentage);
22601                        }
22602                        else {
22603                            currentWidth = parseInt($(progress).find('.bar').data('status'));
22604                            $(progress).find('.bar').css({
22605                                'margin-left': String(moverPercentage) + '%'
22606                            });
22607                        }
22608
22609                        // set value
22610                        valueDiff = ($(value).data('valueMax') - $(value).data('valueMin')) * (moverPercentage / 100);
22611                        if ($(mover).data('type') == 'min') {
22612                            newValue = $(value).data('valueMin') + valueDiff;
22613                        }
22614                        else {
22615                            newValue = $(value).data('valueMax') - valueDiff;
22616                        }
22617
22618
22619                        newValue = parseInt(newValue);
22620                        $(value).data('value', newValue);
22621                        $(value).html(event.data.context.formatPrice(newValue));
22622
22623                        // select filter
22624                        event.data.context.selectFilter($.extend(true, $(value).data(), {
22625                            'moverElement': mover,
22626                            'valueElement': value
22627                        }), true);
22628
22629                    }
22630                });
22631                $('body').bind('touchend mouseup', {context: $this}, function (event) {
22632
22633                    if ($(this).data('currentMover')) {
22634                        mover = $(this).data('currentMover');
22635                        filterContainer = $(mover).parents('.products-listing-filter').first();
22636                        filterContainer.find('.dropdown-toggle').first().attr('data-toggle', 'dropdown');
22637                        $(mover).data('startPosition', false);
22638                        $('body').data('currentMover', false);
22639                        event.data.context.rerangeFilters();
22640                    }
22641                });
22642            }
22643        };
22644
22645        // filter functions - select & search
22646        this.selectFilter = function (filterData, disableRerange) {
22647            if (!disableRerange) {
22648                disableRerange = false;
22649            }
22650            filterConf = this.config.filters[filterData['filter']];
22651            if (!this.activeFilters.hasOwnProperty(filterData['filter'])) {
22652                this.activeFilters[filterData['filter']] = {};
22653                $('#' + this.config.selectors.selectedFiltersContainer).show();
22654            }
22655            switch (filterConf.type) {
22656                case 'vlist':
22657                case 'occurrences':
22658
22659                    if (!this.activeFilters[filterData['filter']].hasOwnProperty('elements')) {
22660                        this.activeFilters[filterData['filter']]['elements'] = [];
22661                    }
22662                    if (jQuery.inArray(filterData['value'], this.activeFilters[filterData['filter']]['elements']) < 0) {
22663                        if (jQuery.isArray(filterData['value'])) {
22664                            for (vIndex in filterData['value']) {
22665                                this.activeFilters[filterData['filter']]['elements'].push(filterData['value'][vIndex]);
22666                            }
22667                        }
22668                        else {
22669                            this.activeFilters[filterData['filter']]['elements'].push(filterData['value']);
22670                        }
22671                        newFilterId = 'selected-filter-' + filterData['filter'];
22672                        newFilter = this.getTemplate(this.config.selectors.templateSelectedFilterLink, newFilterId);
22673                        newFilter.data(filterData);
22674                        newFilter.addClass('selected-filter-' + filterData['filter']);
22675                        newFilter.find('.filter-title').text(filterConf.title[this.config.language]);
22676                        newFilter.find('.filter-value').text(filterData['title']);
22677                        newFilter.bind('click', {
22678                            filterData: filterData,
22679                            context: this
22680                        }, function (event) {
22681                            event.preventDefault();
22682                            event.data.context.removeFilter(event.data.filterData, this);
22683                        });
22684                        $('#' + this.config.selectors.selectedFiltersContainer).append(newFilter);
22685                        if (filterData.parent) {
22686                            $('#' + this.config.selectors.selectedFiltersContainer).find('a').each(function (sfIndex, selectedFilter) {
22687
22688                                if ($(selectedFilter).data('filter') == filterData['filter'] &&
22689                                        ($(selectedFilter).data('value') == filterData.parent) ||
22690                                        (jQuery.isArray($(selectedFilter).data('value')) && jQuery.inArray(filterData.parent, $(selectedFilter).data('value')) >= 0)
22691                                        ) {
22692                                    $(selectedFilter).click();
22693                                }
22694                            });
22695                        }
22696                    }
22697                    break;
22698                case 'range':
22699
22700                    if ((filterData['type'] == 'min' && filterData['value'] == 0) || (filterData['type'] == 'max' && filterData['value'] == parseInt(filterData['valueMax']))) {
22701                        this.removeFilter(filterData, $('#selected-filter-' + filterData['filter'] + '-' + filterData['type']));
22702                    }
22703                    else {
22704                        if (!this.activeFilters[filterData['filter']].hasOwnProperty(filterData['type'])) {
22705                            newFilter = this.getTemplate(this.config.selectors.templateSelectedFilterLink, 'selected-filter-' + filterData['filter'] + '-' + filterData['type']);
22706                            newFilter.find('.filter-title').text(filterConf.title[this.config.language] + ' (' + this.config.translations[filterData['type']][this.config.language] + ')');
22707                            newFilter.find('.filter-value').html(this.formatPrice(filterData['value']));
22708                            newFilter.bind('click', {
22709                                filterData: filterData,
22710                                context: this
22711                            }, function (event) {
22712                                event.preventDefault();
22713                                event.data.context.removeFilter(event.data.filterData, this);
22714                            });
22715                            $('#' + this.config.selectors.selectedFiltersContainer).append(newFilter);
22716                        }
22717                        else {
22718                            existingFilter = $('#selected-filter-' + filterData['filter'] + '-' + filterData['type']);
22719                            existingFilter.find('.filter-value').html(this.formatPrice(filterData['value']));
22720                        }
22721                        this.activeFilters[filterData['filter']][filterData['type']] = filterData['value'];
22722                    }
22723
22724                    break;
22725            }
22726
22727            if ($(window).width() <= 767) {
22728                $(window).scrollTop($('#box-filter-selected').offset().top);
22729            }
22730
22731
22732            this.applyFilters(disableRerange);
22733        };
22734
22735        this.removeFilter = function (filterData, link) {
22736            filterConf = this.config.filters[filterData['filter']];
22737            if (this.activeFilters.hasOwnProperty(filterData['filter'])) {
22738                switch (filterConf.type) {
22739                    case 'vlist':
22740                    case 'occurrences':
22741                        newElements = [];
22742                        for (index in this.activeFilters[filterData['filter']]['elements']) {
22743                            if (this.activeFilters[filterData['filter']]['elements'][index] != filterData['value']) {
22744                                newElements.push(this.activeFilters[filterData['filter']]['elements'][index]);
22745                            }
22746                        }
22747                        this.activeFilters[filterData['filter']]['elements'] = newElements;
22748                        if (newElements.length == 0) {
22749                            delete this.activeFilters[filterData['filter']];
22750                        }
22751                        break;
22752                    case 'range':
22753                        $(filterData['moverElement']).css($(filterData['moverElement']).data('positionKey'), String($(filterData['moverElement']).data('positionStart')) + 'px');
22754                        $(filterData['moverElement']).nextAll($(filterData['moverElement']).data('nextSelector')).css($(filterData['moverElement']).data('positionKey'), String($(filterData['moverElement']).data('positionStart') + $(filterData['moverElement']).data('valueSpace')) + 'px');
22755                        newValue = 0;
22756                        if (filterData['type'] == 'max') {
22757                            newValue = $(filterData['valueElement']).data('valueMax');
22758                        }
22759                        $(filterData['valueElement']).html(this.formatPrice(newValue));
22760                        progress = $(filterData['moverElement']).parents('.progress').first();
22761                        if (filterData['type'] == 'max') {
22762                            $(progress).find('.bar').css('margin-right', '0%');
22763                        }
22764                        else {
22765                            $(progress).find('.bar').css('margin-left', '0%');
22766                        }
22767                        delete this.activeFilters[filterData['filter']][filterData['type']];
22768                        if (!this.activeFilters[filterData['filter']].hasOwnProperty('min') && !this.activeFilters[filterData['filter']].hasOwnProperty('max')) {
22769                            delete this.activeFilters[filterData['filter']];
22770                        }
22771                        break;
22772                }
22773
22774                $(link).detach();
22775            }
22776
22777            this.applyFilters();
22778
22779            if (jQuery.isEmptyObject(this.activeFilters)) {
22780                $('#' + this.config.selectors.selectedFiltersContainer).hide();
22781            }
22782        };
22783
22784        this.removeAllFilters = function () {
22785            this.activeFilters = {};
22786            $('#' + this.config.selectors.selectedFiltersContainer).empty();
22787        };
22788
22789
22790        this.applyFilters = function (disableRerange) {
22791            $this = this;
22792            this.searchParams.start = 0;
22793            $('#' + this.config.selectors.selectedFiltersContainer).data('activeFilters', this.activeFilters);
22794
22795            if (jQuery.isEmptyObject(this.activeFilters)) {
22796                this.foundProducts = this.data.products;
22797            }
22798            else {
22799                this.foundProducts = [];
22800                productsToSearchIn = this.data.products;
22801                prevProduct = false;
22802                for (filterName in this.activeFilters) {
22803                    filterConf = this.config.filters[filterName];
22804                    foundProducts = [];
22805                    for (index in productsToSearchIn) {
22806                        product = productsToSearchIn[index];
22807                        found = true;
22808
22809                        switch (filterConf.type) {
22810                            case 'vlist':
22811                            case 'occurrences':
22812                                if (jQuery.isArray(filterConf.field)) {
22813                                    productValues = [];
22814                                    for (fieldIndex in filterConf.field) {
22815                                        if (product[filterConf.field[fieldIndex]]) {
22816                                            productValues.push(product[filterConf.field[fieldIndex]]);
22817                                        }
22818                                    }
22819                                }
22820                                else {
22821                                    if (!jQuery.isArray(product[filterConf.field])) {
22822                                        productValues = [product[filterConf.field]];
22823                                    }
22824                                    else {
22825                                        productValues = product[filterConf.field];
22826                                    }
22827                                }
22828                                if (productValues.length == 0) {
22829                                    found = false;
22830                                }
22831                                foundInValues = false;
22832                                for (valueIndex in productValues) {
22833                                    for (eIndex in this.activeFilters[filterName]['elements']) {
22834                                        if (jQuery.isArray(this.activeFilters[filterName]['elements'][eIndex])) {
22835                                            if (jQuery.inArray(String(productValues[valueIndex]), this.activeFilters[filterName]['elements'][eIndex]) >= 0) {
22836                                                foundInValues = true;
22837                                                break;
22838                                            }
22839                                        }
22840                                        else {
22841                                            if (String(productValues[valueIndex]) == this.activeFilters[filterName]['elements'][eIndex]) {
22842                                                foundInValues = true;
22843                                                break;
22844                                            }
22845                                        }
22846                                    }
22847                                    if (foundInValues) {
22848                                        break;
22849                                    }
22850
22851                                }
22852                                if (!foundInValues) {
22853                                    found = false;
22854                                }
22855
22856                                break;
22857                            case 'range':
22858                                if (this.activeFilters[filterName].hasOwnProperty('min')) {
22859                                    if (product[filterConf.field] < this.activeFilters[filterName]['min']) {
22860                                        found = false;
22861                                    }
22862                                }
22863                                if (this.activeFilters[filterName].hasOwnProperty('max')) {
22864                                    if (product[filterConf.field] > this.activeFilters[filterName]['max']) {
22865                                        found = false;
22866                                    }
22867                                }
22868                                break;
22869                        }
22870
22871                        if (found) {
22872                            foundProducts.push(product);
22873                        }
22874                    }
22875                    productsToSearchIn = foundProducts;
22876
22877                }
22878                this.foundProducts = foundProducts;
22879            }
22880
22881            if (!disableRerange) {
22882                this.rerangeFilters();
22883            }
22884            this.config.events.onAfterApplyFilter(this);
22885            this.applySorting();
22886            this.showSearchResult();
22887        };
22888
22889
22890        this.rerangeFilters = function () {
22891            if (jQuery.isEmptyObject(this.activeFilters)) {
22892                $('.products-listing-filter').show();
22893                $('.products-listing-filter .filter-add').show();
22894                for (filterName in this.config.filters) {
22895                    filterConf = this.config.filters[filterName];
22896                    $('#filter-' + filterName).show();
22897                    switch (filterConf.type) {
22898                        case 'range':
22899                            $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).html($this.formatPrice($this.data[filterName]['min']));
22900                            $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).html($this.formatPrice($this.data[filterName]['max']));
22901                            $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).data({
22902                                'value': $this.data[filterName]['min'],
22903                                'valueMin': $this.data[filterName]['min'],
22904                                'valueMax': $this.data[filterName]['max']
22905                            });
22906                            $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).data({
22907                                'value': $this.data[filterName]['max'],
22908                                'valueMin': $this.data[filterName]['min'],
22909                                'valueMax': $this.data[filterName]['max']
22910                            });
22911                            break;
22912                    }
22913                }
22914
22915            }
22916            else {
22917                for (filterName in this.config.filters) {
22918                    filterConf = this.config.filters[filterName];
22919
22920                    if (!this.activeFilters.hasOwnProperty(filterName)) {
22921
22922                        switch (filterConf.type) {
22923                            case 'vlist':
22924                            case 'occurrences':
22925                                visibleElements = 0;
22926                                $('#filter-' + filterName + ' .element-' + filterName).each(function (cIndex, element) {
22927                                    isInFoundProducts = false;
22928                                    for (pIndex in $this.foundProducts) {
22929                                        fields = filterConf.field;
22930                                        if (!jQuery.isArray(fields)) {
22931                                            fields = new Array(fields);
22932                                        }
22933
22934                                        for (fIndex in fields) {
22935                                            values = $this.foundProducts[pIndex][fields[fIndex]];
22936                                            if (!jQuery.isArray(values)) {
22937                                                values = new Array(values);
22938                                            }
22939
22940                                            if (jQuery.inArray(String($(element).data('value')), values) >= 0) {
22941                                                isInFoundProducts = true;
22942                                            }
22943
22944                                        }
22945                                    }
22946                                    if (isInFoundProducts) {
22947                                        $(element).show();
22948                                        visibleElements++;
22949                                    }
22950                                    else {
22951                                        $(element).hide();
22952                                    }
22953                                });
22954                                if (visibleElements > 1) {
22955                                    $('#filter-' + filterName).show();
22956                                }
22957                                else {
22958                                    $('#filter-' + filterName).hide();
22959                                }
22960
22961                                break;
22962
22963                            case 'range':
22964
22965                                minMaxValues = $this.getMinMaxValuesForRangeFilter(filterConf);
22966//                                $this.data[filterName]['min'] = minMaxValues.min;
22967//                                $this.data[filterName]['max'] = minMaxValues.max;
22968                                $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).html($this.formatPrice(minMaxValues.min));
22969                                $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).html($this.formatPrice(minMaxValues.max));
22970                                $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMin).data({
22971                                    'value': minMaxValues.min,
22972                                    'va
22972lueMin': minMaxValues.min,
22973                                    'valueMax': minMaxValues.max
22974                                });
22975                                $('#filter-' + filterName).find($this.config.selectors.filterRange.valueMax).data({
22976                                    'value': minMaxValues.max,
22977                                    'valueMin': minMaxValues.min,
22978                                    'valueMax': minMaxValues.max
22979                                });
22980
22981                                if (minMaxValues.min == minMaxValues.max) {
22982                                    $('#filter-' + filterName).hide();
22983                                }
22984                                else {
22985                                    $('#filter-' + filterName).show();
22986                                }
22987
22988                                break;
22989
22990                        }
22991
22992                    }
22993                    else {
22994                        $('#filter-' + filterName).show();
22995                        $('#filter-' + filterName + ' .element-' + filterName).show();
22996                    }
22997                }
22998            }
22999        };
23000
23001
23002        this.getMinMaxValuesForRangeFilter = function (filter) {
23003            result = {
23004                min: -1,
23005                max: 0
23006            };
23007            for (index in this.foundProducts) {
23008                value = this.foundProducts[index][filter.field];
23009                if (result.min < 0) {
23010                    result.min = value;
23011                }
23012                else {
23013                    if (value < result.min) {
23014                        result.min = value;
23015                    }
23016                    if (value > result.max) {
23017                        result.max = value;
23018                    }
23019                }
23020            }
23021            return result;
23022        }
23023
23024        this.findFilterChanges = function (hashFilters) {
23025            result = new Object();
23026            result.add = new Array();
23027            result.remove = new Array();
23028            // not in active filters
23029            if (hashFilters) {
23030
23031                for (filterName in hashFilters) {
23032                    hashFilter = hashFilters[filterName];
23033                    filterConf = this.config.filters[filterName];
23034                    switch (filterConf.type) {
23035                        case 'vlist':
23036                        case 'occurrences':
23037                            for (eIndex in hashFilter['elements']) {
23038                                element = hashFilter['elements'][eIndex];
23039                                if (!this.activeFilters.hasOwnProperty(filterName) ||
23040                                        jQuery.inArray(element, this.activeFilters[filterName]['elements']) < 0
23041                                        ) {
23042                                    $('#filter-' + filterName + ' .filter-elements a').each(function (lIndex, filterLink) {
23043                                        if (element == $(filterLink).data('value')) {
23044                                            result.add.push($(filterLink).data());
23045                                        }
23046                                    });
23047
23048                                }
23049                            }
23050                            break;
23051                        case 'range':
23052
23053                            break;
23054                    }
23055                }
23056            }
23057
23058            // not in hash filters
23059
23060
23061            for (filterName in this.activeFilters) {
23062                filter = this.activeFilters[filterName];
23063                filterConf = this.config.filters[filterName];
23064                switch (filterConf.type) {
23065                    case 'vlist':
23066                    case 'occurrences':
23067                        $('.selected-filter-' + filterName).each(function (sIndex, selectedFilter) {
23068                            if (!hashFilters.hasOwnProperty(filterName) ||
23069                                    jQuery.inArray($(selectedFilter).data('value'), hashFilters[filterName]['elements']) < 0
23070                                    ) {
23071                                result.remove.push($(selectedFilter));
23072                            }
23073                        });
23074                        break;
23075                }
23076            }
23077
23078            return result;
23079
23080        };
23081
23082        this.showSearchResult = function () {
23083            this.buildProducts();
23084            this.buildPagination();
23085            // BBQ
23086            if (this.config.bbqEnabled) {
23087                jQuery.bbq.pushState({
23088                    filter: this.activeFilters
23089                });
23090                if (String(this.searchParams.start) +
23091                        String(this.searchParams.range) +
23092                        this.searchParams.presentation +
23093                        this.searchParams.sortBy +
23094                        this.searchParams.sortOrder != '08gridpriceASC'
23095                        ) {
23096                    jQuery.bbq.pushState({
23097                        settings: this.searchParams
23098                    });
23099                }
23100                else {
23101                    jQuery.bbq.removeState('settings');
23102                }
23103            }
23104        };
23105
23106
23107
23108        // product functions - build & bind
23109        this.buildProducts = function () {
23110            this.calc.productsCount = 0;
23111            $(this.config.selectors.productsContainer).empty();
23112            var index = 0;
23113            for (pIndex in this.foundProducts) {
23114                if (pIndex >= this.searchParams.start && index < this.searchParams.range) {
23115                    this.config.events.onBeforeProductBuild(this);
23116                    var product = this.foundProducts[pIndex];
23117                    if (typeof (product.products_id) != "undefined") {
23118                        var $productTemplate = this.getTemplate(this.config.selectors.templateProduct[this.searchParams.presentation], 'product-' + product.products_id);
23119                        $productTemplate.find('.title').html(product.products_short_description ? product.products_short_description : product.products_name);
23120                        $productTemplate.find('.description').html(product.products_description);
23121
23122                        this.buildProductPrice($productTemplate, jQuery.extend({}, product), $productTemplate.find('.product'));
23123
23124                        productImageFilename = this.findFirstProductImage(product);
23125
23126                        $productTemplate.find('.product-link').attr('href', '/' + product.url_text);
23127
23128                        $productTemplate.find('.image').css({
23129                            'background-image': 'url(/media/images/info/' + productImageFilename + ')'
23130                        });
23131
23132                        $productTemplate.find('.product').data(product);
23133
23134                        this.buildProductOptions($productTemplate, product);
23135
23136                        if (product.ext_discount > 0 && $('#page-index').length > 0) {
23137                            $productTemplate.find('.discount').show();
23138                            $productTemplate.find('.product').addClass('with-discount');
23139                        }
23140
23141
23142                        $(this.config.selectors.productsAppend[this.searchParams.presentation]).append($productTemplate);
23143                        this.calc.productsCount++;
23144                        index++;
23145                    }
23146
23147                }
23148            }
23149            // event binding
23150            this.bindProductsEvents();
23151            this.config.events.onAfterProductsBuild(this);
23152        }
23153
23154        this.findFirstProductImage = function (product) {
23155            productImageFilename = 'noimage.png';
23156            if (product.type != 'master') {
23157                if (product.products_image) {
23158                    productImageFilename = product.products_image;
23159                }
23160            }
23161            else {
23162                if (product.children) {
23163                    for (cIndex in product.children) {
23164                        if (product.children[cIndex].products_image) {
23165                            productImageFilename = product.children[cIndex].products_image;
23166                            break;
23167                        }
23168                    }
23169                }
23170            }
23171            return productImageFilename;
23172        };
23173
23174        this.findProductImages = function ($productData) {
23175            if ($productData.children) {
23176                for (cIndex in $productData.children) {
23177                    if ($productData.children[cIndex].products_image) {
23178                        return [
23179                            $productData.children[cIndex].products_image,
23180                            $productData.children[cIndex].products_image_2,
23181                            $productData.children[cIndex].products_image_3,
23182                            $productData.children[cIndex].products_image_4,
23183                            $productData.children[cIndex].products_image_5
23184                        ];
23185                    }
23186                }
23187            }
23188            return [];
23189        };
23190
23191
23192        this.buildProductPrice = function ($productObject, product, badgePosition) {
23193
23194            $productObject.data('priceBuild', true);
23195
23196            if (!badgePosition) {
23197                badgePosition = $productObject;
23198            }
23199
23200            if (product['special_price']) {
23201                $productObject.find('.price').html('<span class="old">' + (product.hasOwnProperty('price') ? product.price.formated : '') + '</span><span class="new font-highlight">' + product.special_price.formated + '</span>');
23202            }
23203            else {
23204
23205                $productObject.find('.price').html((product.hasOwnProperty('price') ? product.price.formated : ''));
23206
23207            }
23208
23209            if (product.type == 'master') {
23210                if (product.children) {
23211                    var smallestPrice = product.price;
23212                    specialPriceCount = 0;
23213                    product['child_has_special_price'] = false;
23214                    for (cIndex in product.children) {
23215
23216                        if (product.children[cIndex].price.plain < smallestPrice.plain) {
23217                            smallestPrice = product.children[cIndex].price;
23218                        }
23219                        if (product.children[cIndex].hasOwnProperty('special_price')) {
23220                            if (product.children[cIndex].special_price.plain < smallestPrice.plain) {
23221                                smallestPrice = product.children[cIndex].special_price;
23222                            }
23223                            product['child_has_special_price'] = true;
23224                            specialPriceCount++;
23225                        }
23226                    }
23227                    if (specialPriceCount == product.children.length) {
23228                        $productObject.find('.price').html('<span class="old">' + product.price.formated + '</span><span class="new font-highlight">' + smallestPrice.formated + '</span>');
23229                    }
23230                    else {
23231                        if (smallestPrice.plain < product.price.plain) {
23232                            $productObject.find('.price').html('ab ' + smallestPrice.formated);
23233                        }
23234                    }
23235                }
23236            }
23237
23238//            if (product.ext_discount == 0) {
23239//                if (product['special_price'] || product['child_has_special_price']) {
23240//                    badgePosition.append('<span class="badge badge-warning badge-special">' + this.config.translations.badges.specialOffer[this.config.language] + '</span>');
23241//                }
23242//                else {
23243//                    if (product['new']) {
23244//                        badgePosition.append('<span class="badge badge-important badge-new">' + this.config.translations.badges['new'][this.config.language] + '</span>');
23245//                    }
23246//                }
23247//            }
23248
23249        };
23250
23251
23252        this.buildBundlePrice = function ($bundleTemplate, bundle) {
23253
23254
23255            switch (bundle.bundleType) {
23256                case 'package':
23257                    productsPrice = 0;
23258                    for (pIndex in bundle.products) {
23259                        productsPrice += bundle.products[pIndex]['price']['plain'];
23260                    }
23261                    $bundleTemplate.find('.price').html('<span class="old">' + this.formatPrice(productsPrice) + '</span><span class="new font-highlight">' + bundle.price.formated + '</span>');
23262                    break;
23263                default:
23264                    $bundleTemplate.find('.price').html(bundle.price.formated);
23265                    break;
23266            }
23267
23268
23269
23270
23271//            if (product.type == 'master') {
23272//                if (product.children) {
23273//                    smallestPrice = product.price;
23274//                    specialPriceCount = 0;
23275//                    product['child_has_special_price'] = false;
23276//                    for (cIndex in product.children) {
23277//
23278//                        if (product.children[cIndex].price.plain < smallestPrice.plain) {
23279//                            smallestPrice = product.children[cIndex].price;
23280//                        }
23281//                        if (product.children[cIndex].hasOwnProperty('special_price')) {
23282//                            if (product.children[cIndex].special_price.plain < smallestPrice.plain) {
23283//                                smallestPrice = product.children[cIndex].special_price;
23284//                            }
23285//                            product['child_has_special_price'] = true;
23286//                            specialPriceCount++;
23287//                        }
23288//                    }
23289//                    if (specialPriceCount == product.children.length) {
23290//                        $productTemplate.find('.price').html('<span class="old">' + product.price.formated + '</span><span class="new">' + smallestPrice.formated + '</span>');
23291//                    }
23292//                    else {
23293//                        if (smallestPrice.plain < product.price.plain) {
23294//                            $productTemplate.find('.price').html('ab ' + smallestPrice.formated);
23295//                        }
23296//                    }
23297//                }
23298//            }
23299
23300
23301        };
23302
23303        this.buildProductOptions = function ($productTemplate, product) {
23304            if (product.type == 'master') {
23305                for (optionKey in product.options) {
23306                    if (product.options[optionKey].length > 0) {
23307                        $optionTemplate = this.getTemplate(this.config.selectors.templateProductOptions[this.searchParams.presentation], 'productOptions-' + product.products_id + '-' + optionKey);
23308                        $optionTemplate.find('.title').text(this.config.filters[optionKey].title[this.config.language]);
23309                        $optionTemplate.data('optionKey', optionKey);
23310                        for (vIndex in product.options[optionKey]) {
23311                            $optionLink = $('<a href="#" class="' + this.config.classes.optionLink + '">' + product.options[optionKey][vIndex].replace("\\/", '/') + '</a>');
23312                            $optionLink.data({
23313                                optionKey: optionKey,
23314                                value: String(product.options[optionKey][vIndex]),
23315                                masterId: product.products_id
23316                            });
23317                            $optionLink.attr('rel', product.options[optionKey][vIndex]);
23318                            $optionTemplate.find('.values').append($optionLink);
23319                        }
23320                        if (product.options[optionKey].length == 1) {
23321                            $optionLink.addClass(this.config.classes.buttonActive);
23322                            this.selectProductOption($optionLink.data(), ($productTemplate.hasClass('product') ? $productTemplate : $productTemplate.find('.product')), true);
23323                        }
23324                        $productTemplate.find(this.config.selectors.productOptions).append($optionTemplate);
23325                    }
23326                }
23327                $productTemplate.find('.actions .cart .action').addClass('dropdown-toggle');
23328         
23328   }
23329            else {
23330                $productTemplate.find(this.config.selectors.productOptions).detach();
23331            }
23332        }
23333
23334        this.bindProductsEvents = function (container) {
23335
23336
23337            if (!container) {
23338                container = $(this.config.selectors.productsContainer);
23339            }
23340
23341            // detail link
23342            var $this = this;
23343
23344            this.config.rootContainer.find(this.config.selectors.productsLinks).each(function (pIndex, productLink) {
23345                product = $(productLink).parents('.product').first();
23346                $(productLink).bind('click', {context: $this, product: product}, function (event) {
23347                    $detailModal = $(event.data.context.config.selectors.productDetail);
23348                    if (event.data.product.hasClass('bundle')) {
23349                        $detailModal.addClass('bundle');
23350                    }
23351                    else {
23352                        $detailModal.removeClass('bundle');
23353                    }
23354
23355                    event.data.context.openDetailView(event.data.product.data(), $detailModal);
23356                });
23357            });
23358
23359            // detail modal
23360            $(this.config.selectors.productDetail).bind('hidden', {context: this}, function (event) {
23361                $(this).removeClass('open');
23362                //jQuery.bbq.removeState('product');
23363                if (!$(this).hasClass('bundle')) {
23364                    jQuery.bbq.pushState({
23365                        product: 0
23366                    });
23367                }
23368            });
23369
23370            // add to favourites link
23371            this.config.rootContainer.find(this.config.selectors.productsAddToFavourites).each(function (pIndex, addToFavouritesLink) {
23372                product = $(addToFavouritesLink).parents('.product').first();
23373                $(addToFavouritesLink).bind('click', {context: $this, product: product}, function (event) {
23374                    event.preventDefault();
23375                    event.data.context.addToFavourites(event.data.product.data(), $(event.data.context.config.selectors.favourites));
23376                });
23377            });
23378
23379
23380            // add to cart link
23381            this.config.rootContainer.find(this.config.selectors.productsAddToCart).each(function (pIndex, addToCartLink) {
23382                product = $(addToCartLink).parents('.product').first();
23383                $(addToCartLink).bind('click', {context: $this, product: product}, function (event) {
23384                    event.preventDefault();
23385                    if (event.data.product.data('type') == 'master') {
23386//                        $optionsContainer = $(event.data.product).find(event.data.context.config.selectors.productOptions);
23387//                        $optionsContainer.show();
23388//                        containerHeight = $optionsContainer.innerHeight();
23389//                        $optionsContainer.css({'height':0});
23390//                        $optionsContainer.stop().animate({'height':containerHeight}, 200);
23391                    }
23392                    else {
23393                        event.data.context.addToCart(event.data.product.data(), event.data.product);
23394                    }
23395
23396                });
23397            });
23398
23399            // option links
23400            this.bindProductOptionLinksEvents(container);
23401
23402        };
23403
23404
23405        this.bindProductOptionLinksEvents = function (context) {
23406            var $this = this;
23407            $(context).find(this.config.selectors.productOptionLinks).each(function (pIndex, optionLink) {
23408                product = $(optionLink).parents('.product').first();
23409                $(optionLink).bind('touchstart click', {context: $this, product: product}, function (event) {
23410                    event.preventDefault();
23411                    if (!$(this).hasClass('disabled')) {
23412                        var product = event.data.product;
23413
23414                        $(this).addClass(event.data.context.config.classes.buttonActive);
23415                        $(this).siblings().removeClass(event.data.context.config.classes.buttonActive);
23416
23417                        selectResult = event.data.context.selectProductOption($(this).data(), product, $(this).data('disable') == 'addToCart' ? true : false);
23418                        if (!selectResult) {
23419                            event.stopPropagation();
23420                        }
23421
23422                        event.data.context.disableInvalidOptionCombinations(product, $(optionLink).parents('.option').first().data('optionKey'));
23423
23424                    }
23425
23426                });
23427            });
23428        };
23429
23430        // product functions - detail view
23431        this.openDetailView = function ($productData, $detailModal, openBundleProductIndex) {
23432            if (!$detailModal) {
23433                $detailModal = $(this.config.selectors.productDetail);
23434            }
23435
23436
23437            var $this = this;
23438
23439
23440
23441            if (!openBundleProductIndex) {
23442                openBundleProductIndex = 0;
23443            }
23444            $detailModal.data('openBundleProductIndex', openBundleProductIndex);
23445
23446            $detailModal.find('.alert').hide();
23447            $detailModal.addClass('open');
23448            $detailModal.data($productData);
23449            $detailModal.find('#bundle-nav').hide();
23450
23451            // base data                       
23452            if ($productData.type == 'bundle') {
23453                productTitle = $productData.ssag_name;
23454
23455                $detailModal.find('.model .value').text($productData.products[openBundleProductIndex].products_model);
23456                $detailModal.find('.description').html($productData.products[openBundleProductIndex].products_description);
23457
23458                var selectedBundleOptions = $detailModal.data('selectedBundleOptions');
23459                if (!selectedBundleOptions) {
23460                    selectedBundleOptions = new Object();
23461                    $detailModal.data('selectedBundleOptions', selectedBundleOptions);
23462                }
23463
23464
23465                switch ($productData.bundleType) {
23466                    case 'package':
23467
23468                    case 'freeAddOn':
23469                        $detailModal.find('#bundle-nav').empty();
23470                        $detailModal.find('#bundle-nav').show();
23471
23472                        for (pIndex in $productData.productIds) {
23473                            bundleProduct = this.data.products[$productData.productIds[pIndex]];
23474                            $bundleNavItem = $('<li></li>');
23475                            $bundleNavLink = $('<a href="#">' + bundleProduct.products_name + '</a>');
23476                            $bundleNavLink.data({
23477                                'bundle': $productData,
23478                                'index': pIndex
23479                            });
23480                            $bundleNavItem.append($bundleNavLink);
23481                            $detailModal.find('#bundle-nav').append($bundleNavItem);
23482                        }
23483
23484                        $('#bundle-nav a').bind('click', {context: this}, function (event) {
23485                            event.preventDefault();
23486                            $(this).tab('show');
23487                            event.data.context.openDetailView($(this).data('bundle'), false, $(this).data('index'));
23488                        });
23489
23490
23491                        $('#bundle-nav a').eq(openBundleProductIndex).tab('show');
23492
23493                        break;
23494                    default:
23495                        break;
23496                }
23497
23498                currentProduct = this.data.products[$productData.productIds[openBundleProductIndex]];
23499                this.buildBundlePrice($detailModal, $productData);
23500            }
23501            else {
23502                productTitle = $productData.products_name;
23503                $detailModal.find('.model .value').text($productData.products_model);
23504                $detailModal.find('.description').html($productData.products_description);
23505                var currentProduct = $productData;
23506                if (!$detailModal.hasClass('bundle')) {
23507                    this.buildProductPrice($detailModal, $productData, $detailModal.find('.badges'));
23508                }
23509
23510            }
23511            $detailModal.find('.title').text(productTitle);
23512            $detailModal.find('.badges').empty();
23513
23514
23515
23516            // browser title
23517            document.title = productTitle + ' - ' + this.documentTitle;
23518
23519            // facebook-like
23520
23521            $('#facebook-like').html('<fb:like href="' + location.href + '" width="250" layout="button_count" show_faces="true" send="true"></fb:like>');
23522            if (typeof FB !== 'undefined') {
23523                FB.XFBML.parse(document.getElementById('facebook-like'));
23524            }
23525
23526
23527            // images
23528            $detailModal.find('.zoom_thumbnails').empty();
23529            $detailModal.find('#zoom_container').empty();
23530
23531            var detailImages = [
23532                currentProduct.products_image,
23533                currentProduct.products_image_2,
23534                currentProduct.products_image_3,
23535                currentProduct.products_image_4,
23536                currentProduct.products_image_5
23537            ];
23538
23539            if (currentProduct.type == 'master') {
23540                detailImages = this.findProductImages(currentProduct);
23541            }
23542
23543
23544//            if ($productData.type == 'bundle') {
23545//
23546//                if ($productData.ssag_image) {
23547//                    detailImages = [
23548//                        bundle.ssag_image
23549//                    ];
23550//                }
23551//                else {
23552//                    if ($productData.products.length > 0) {
23553//                        for (pIndex in $productData.products) {
23554//                            detailImages = this.findProductImages($productData.products[pIndex]);
23555//                            if (detailImages) {
23556//                                break;
23557//                            }
23558//                        }
23559//                    }
23560//                }
23561//            }
23562
23563
23564            infoImage = {
23565                width: 430,
23566                height: 430
23567            };
23568            panButtonsShow = false;
23569            zoomButtonsShow = false;
23570            if ($(document).innerWidth() >= 768 && $(document).innerWidth() <= 979) {
23571                infoImage = {
23572                    width: 350,
23573                    height: 350
23574                };
23575            }
23576            if ($(document).innerWidth() >= 481 && $(document).innerWidth() <= 767) {
23577                infoImage = {
23578                    width: 230,
23579                    height: 230
23580                };
23581            }
23582            if ($(document).innerWidth() <= 768) {
23583                infoImage = {
23584                    width: $('#product-detail').innerWidth() - 40,
23585                    height: 200
23586                };
23587                panButtonsShow = false;
23588                zoomButtonsShow = false;
23589            }
23590
23591            if ($(window).innerHeight() <= 800) {
23592//                $('#product-detail').css({
23593//                    'margin-top': -300
23594//                });
23595                $('#product-detail .modal-body').css({
23596                    'max-height': $(window).innerHeight() - 220
23597                });
23598            }
23599
23600            if ($(document).innerWidth() <= 479) {
23601//                $('#product-detail').css({
23602//                    'margin-top': -280
23603//                });
23604                $('#product-detail .modal-body').css({
23605                    'max-height': $(window).innerHeight() - 200
23606                });
23607            }
23608            if ($(document).innerWidth() >= 480 && $(document).innerWidth() <= 768) {
23609//                $('#product-detail').css({
23610//                    'margin-top': -130
23611//                });
23612                $('#product-detail .modal-body').css({
23613                    'max-height': $(window).innerHeight() - 180
23614                });
23615            }
23616
23617            for (iIndex in detailImages) {
23618                if (detailImages[iIndex]) {
23619                    $thumbnail = $('<li><a href="#" data-src="/media/images/popup/' + detailImages[iIndex] + '" data-size="' + infoImage.width + ',' + infoImage.height + '" style="background-image:url(/media/images/info/' + detailImages[iIndex] + ')"></a></li>');
23620                    $thumbnail.find('img').data('filename', detailImages[iIndex]);
23621                    $thumbnail.find('img').bind('error', function () {
23622                        $(this).parents('li').first().detach();
23623                    });
23624
23625                    $thumbnail.bind('click', {src: '/media/images/popup/' + detailImages[iIndex]}, function (event) {
23626
23627                        event.preventDefault();
23628                        $(this).parents('.zoom_thumbnails').first().find('li a').removeClass('active');
23629                        $(this).addClass('active');
23630                        //Add your zoom settings here
23631
23632                        $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({
23633                            image_url: event.data.src,
23634                            width: infoImage.width,
23635                            height: infoImage.height,
23636                            /******************************************
23637                             Enable Responsive settings below if needed.
23638                             Max width and height values are optional.
23639                             ******************************************/
23640                            responsive: false,
23641                            responsive_maintain_ratio: true,
23642                            max_WIDTH: '',
23643                            max_HEIGHT: '',
23644                            pan_BUTTONS_SHOW: panButtonsShow,
23645                            zoom_BUTTONS_SHOW: zoomButtonsShow
23646                        });
23647                        return false;
23648
23649                    });
23650                    $detailModal.find('.zoom_thumbnails').append($thumbnail);
23651                }
23652            }
23653
23654
23655
23656
23657            if ($detailModal.find('.zoom_thumbnails').find('li').length > 0) {
23658                $detailModal.find('.zoom_thumbnails').find('li a').eq(0).trigger('click');
23659//                $('.zoom_thumbnails').find('li a').each(function(tIndex, thumbnail) {
23660//                    $(thumbnail).live('click', {src: $(this).attr('href'), thumbnail: thumbnail}, function(e) {
23661//                        $(e.data.thumbnail).addClass('active');
23662//                        //Add your zoom settings here
23663//                        $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({
23664//                            image_url: e.data.src,
23665//                            width: 430,
23666//                            height: 430,
23667//                            /******************************************
23668//                             Enable Responsive settings below if needed.
23669//                             Max width and height values are optional.
23670//                             ******************************************/
23671//                            responsive: false,
23672//                            responsive_maintain_ratio: true,
23673//                            max_WIDTH: '',
23674//                            max_HEIGHT: ''
23675//                        });
23676//                        return false;
23677//
23678//                    });
23679//                }).eq(0).trigger('click');
23680            }
23681
23682
23683
23684
23685
23686
23687            // options
23688            productOptions = false;
23689            if (currentProduct.type == 'master') {
23690                productOptions = currentProduct.options;
23691                $master = currentProduct;
23692            }
23693            else {
23694                if (currentProduct.master) {
23695                    productOptions = currentProduct.master.options;
23696                    $master = currentProduct.master;
23697                }
23698            }
23699
23700            $detailModal.find(this.config.selectors.productOptions).empty();
23701
23702            if (productOptions) {
23703                for (optionKey in productOptions) {
23704
23705                    if (productOptions[optionKey].length > 0) {
23706                        $optionTemplate = this.getTemplate(this.config.selectors.templateProductOptions.detail, 'productOptionsDetail-' + currentProduct.products_id + '-' + optionKey);
23707                        $optionTemplate.find('.title').text(this.config.filters[optionKey].title[this.config.language]);
23708                        $optionTemplate.data('optionKey', optionKey);
23709                        for (vIndex in productOptions[optionKey]) {
23710                            $optionLink = $('<a href="#" class="' + this.config.classes.optionLink + '">' + productOptions[optionKey][vIndex].replace("\\/", '/') + '</a>');
23711                            $optionLink.data({
23712                                optionKey: optionKey,
23713                                value: productOptions[optionKey][vIndex],
23714                                masterId: $master.products_id,
23715                                disable: 'addToCart'
23716                            });
23717                            $optionTemplate.find('.values').append($optionLink);
23718                        }
23719                        if (productOptions[optionKey].length == 1) {
23720                            $optionLink.addClass(this.config.classes.buttonActive);
23721                            this.selectProductOption($optionLink.data(), $detailModal, true, true);
23722                        }
23723
23724                        $detailModal.find(this.config.selectors.productOptions).append($optionTemplate);
23725                    }
23726                }
23727                if (currentProduct.type == 'child') {
23728                    for (optionKey in productOptions) {
23729                        filterConf = this.config.filters[optionKey];
23730                        fields = filterConf.field;
23731                        if (!jQuery.isArray(fields)) {
23732                            fields = new Array(fields);
23733                        }
23734                        for (vIndex in productOptions[optionKey]) {
23735                            if (productOptions[optionKey][vIndex] == currentProduct[fields[0]]) {
23736                                $optionLink = $('#productOptionsDetail-' + currentProduct.products_id + '-' + optionKey).find('a').eq(vIndex);
23737                                $optionLink.addClass(this.config.classes.buttonActive);
23738                                this.selectProductOption($optionLink.data(), $detailModal, true, true);
23739                                this.disableInvalidOptionCombinations($detailModal, optionKey);
23740                            }
23741                        }
23742                    }
23743
23744                }
23745            }
23746
23747            this.bindProductOptionLinksEvents($detailModal);
23748
23749            if ($productData.type == 'bundle') {
23750                var selectedBundleOptions = $detailModal.data('selectedBundleOptions');
23751                if (selectedBundleOptions.hasOwnProperty($master.products_id)) {
23752                    for (optionKey in productOptions) {
23753                        filterConf = this.config.filters[optionKey];
23754                        for (vIndex in productOptions[optionKey]) {
23755                            if (selectedBundleOptions[$master.products_id][filterConf.field] == productOptions[optionKey][vIndex]) {
23756                                $('#productOptionsDetail-' + $master.products_id + '-' + optionKey).find('a').each(function (aIndex, optionLink) {
23757                                    if ($(optionLink).data('value') == productOptions[optionKey][vIndex]) {
23758                                        $(optionLink).addClass($this.config.classes.buttonActive);
23759                                    }
23760                                });
23761                                this.selectProductOption({
23762                                    optionKey: optionKey,
23763                                    value: productOptions[optionKey][vIndex],
23764                                    masterId: $master.products_id,
23765                                    disable: 'addToCart'
23766                                }, $detailModal, true, true);
23767                            }
23768                        }
23769                    }
23770                }
23771            }
23772
23773            // additional infos
23774
23775            if (this.config.detail.additonalInfos) {
23776                $(this.config.selectors.productDetailAdditionalInfo).empty();
23777                for (aiIndex in this.config.detail.additonalInfos) {
23778                    aInfo = this.config.detail.additonalInfos[aiIndex];
23779                    if (currentProduct[aInfo.field]) {
23780                        $infoTemplate = this.getTemplate(this.config.selectors.templateProductDetailInfo, 'product-additional-info-' + currentProduct.products_id + '-' + aInfo.field);
23781                        $infoTemplate.find('.title').text(aInfo.title + ': ');
23782                        $infoTemplate.find('.value').text(currentProduct[aInfo.field]);
23783                        $(this.config.selectors.productDetailAdditionalInfo).append($infoTemplate);
23784                    }
23785                }
23786            }
23787
23788
23789            // events
23790            if ($productData.prev) {
23791                $detailModal.find('.navigation-product-prev').unbind('click').bind('click', {context: this, product: $productData.prev}, function (event) {
23792                    event.preventDefault();
23793                    event.data.context.openDetailView(event.data.product);
23794//                    $.History.go(event.data.context.getPath());
23795                });
23796                $detailModal.find('.navigation-product-prev').removeClass('disabled');
23797            }
23798            else {
23799                $detailModal.find('.navigation-product-prev').addClass('disabled');
23800            }
23801
23802            if ($productData.next) {
23803                $detailModal.find('.navigation-product-next').unbind('click').bind('click', {context: this, product: $productData.next}, function (event) {
23804                    event.preventDefault();
23805                    event.data.context.openDetailView(event.data.product);
23806//                    $.History.go(event.data.context.getPath());
23807                });
23808                $detailModal.find('.navigation-product-next').removeClass('disabled');
23809            }
23810            else {
23811                $detailModal.find('.navigation-product-next').addClass('disabled');
23812            }
23813
23814            $detailModal.find('.btn-fullscreen').live('click', {context: this}, function (event) {
23815                event.preventDefault();
23816                activeImage = $detailModal.find('.zoom_thumbnails .active a').first();
23817
23818                $('.fullscreen-element').detach();
23819                $('body').append('<div id="fullscreen-zoom" class="fullscreen-element"><div class="inner"></div></div>');
23820                $('body').append('<a id="fullscreen-zoom-close" class="btn btn-danger fullscreen-element" href="#"><i class="icon-remove icon-white"></i></a>');
23821                $('body').append('<div id="fullscreen-galery" class="fullscreen-element"><h4>' + event.data.context.config.translations.moreImages[event.data.context.config.language] + '</h4></div>');
23822                $('#fullscreen-zoom .inner').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({
23823                    image_url: $(activeImage).data('src'),
23824                    width: $(window).innerWidth(),
23825                    height: $(window).innerHeight(),
23826                    /******************************************
23827                     Enable Responsive settings below if needed.
23828                     Max width and height values are optional.
23829                     ******************************************/
23830                    responsive: false,
23831                    responsive_maintain_ratio: true,
23832                    max_WIDTH: '',
23833                    max_HEIGHT: '',
23834                    background_COLOR: 'transparent'
23835                });
23836                $('#fullscreen-galery').append($detailModal.find('.zoom_thumbnails').clone());
23837
23838                $('#fullscreen-galery .zoom_thumbnails').find('li a').each(function (tIndex, thumbnail) {
23839                    $(thumbnail).live('click', {thumbnail: thumbnail}, function (e) {
23840                        e.preventDefault();
23841                        $(e.data.thumbnail).addClass('active');
23842                        //Add your zoom settings here
23843                        $('#fullscreen-zoom .inner').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({
23844                            image_url: $(e.data.thumbnail).data('src'),
23845                            width: $(window).innerWidth(),
23846                            height: $(window).innerHeight(),
23847                            /******************************************
23848                             Enable Responsive settings below if needed.
23849                             Max width and height values are optional.
23850                             ******************************************/
23851                            responsive: false,
23852                            responsive_maintain_ratio: true,
23853                            max_WIDTH: '',
23854                            max_HEIGHT: '',
23855                            background_COLOR: 'transparent'
23856                        });
23857                        return false;
23858
23859                    });
23860                })
23861
23862
23863                $('#fullscreen-zoom-close').bind('click', function (event) {
23864                    event.preventDefault();
23865                    $('.fullscreen-element').detach();
23866                });
23867
23868
23869
23870            });
23871
23872
23873
23874            $(".alert .hide-alert").bind('click', function (event) {
23875                event.preventDefault();
23876                $alert = $(this).parents('.alert').first();
23877                $alert.stop().animate({'opacity': 0}, 250, function () {
23878                    $alert.hide();
23879                });
23880            });
23881
23882            $detailModal.find(this.config.selectors.productDetailAddToCart).unbind('click').bind('click', {context: this, product: $detailModal}, function (event) {
23883                event.preventDefault();
23884                product = event.data.product;
23885                productData = $(product).data();
23886
23887                var qty = 1;
23888                if ($('#product-detail-qty').val() != '' && jQuery.isNumeric($('#product-detail-qty').val())) {
23889                    qty = parseInt($('#product-detail-qty').val());
23890                }
23891
23892                switch (productData.type) {
23893                    case 'standalone':
23894                        event.data.context.addToCart(productData, $(product), qty);
23895                        break;
23896
23897                    case 'bundle':
23898                        var selectedBundleOptions = $(product).data('selectedBundleOptions');
23899                        if (selectedBundleOptions['allSelected']) {
23900                            $("#message-errorAddToCart").hide();
23901
23902                            event.data.context.addToCart(productData, $(product), qty);
23903                        }
23904                        else {
23905                            $('#message-errorAddToCart').find('.message').text(productData.errorBundleNotAllSelected);
23906                            $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
23907                        }
23908                        break;
23909
23910                    default:
23911                        $master = productData.master ? productData.master : productData;
23912
23913
23914                        allOptionsSelected = true;
23915                        if ($master.hasOwnProperty('selectedOptions')) {
23916                            for (optionKey in $master['options']) {
23917                                if (!$master['selectedOptions'][optionKey]) {
23918                                    allOptionsSelected = false;
23919                                }
23920                            }
23921                        }
23922                        else {
23923                            allOptionsSelected = false;
23924                        }
23925
23926
23927                        if (allOptionsSelected) {
23928
23929                            children = event.data.context.findChildrenForSelectedOptions($master, false);
23930
23931                            if (children.length >= 1) {
23932                                event.data.context.addToCart(children[0], $(product), qty);
23933
23934                            }
23935                        }
23936                        else {
23937                            $("#message-selectOptions").show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
23938                        }
23939                        break;
23940                }
23941
23942            });
23943
23944
23945            // fb like hack
23946            $detailModal.find('.fb_iframe_widget>span, .fb_iframe_widget iframe').css({
23947                height: '25px',
23948                width: '100%',
23949                position: 'relative'
23950            });
23951
23952
23953
23954            // BBQ
23955            if ($productData.type == 'bundle') {
23956                if (this.config.bbqEnabled) {
23957                    jQuery.bbq.pushState({
23958                        bundle: $productData.id
23959                    });
23960                    jQuery.bbq.removeState('product');
23961                }
23962            }
23963            else {
23964                if (this.config.bbqEnabled && !$detailModal.hasClass('bundle') && $productData.products_id) {
23965                    jQuery.bbq.pushState({
23966                        product: $productData.products_id
23967                    });
23968
23969                }
23970            }
23971
23972
23973
23974
23975
23976
23977        };
23978
23979        // product functions - options
23980        this.selectProductOption = function (option, product, disableAddToCart, inDetail) {
23981
23982            if (typeof option['optionKey'] != 'undefined') {
23983
23984                productData = $(product).data();
23985                var isBundle = false;
23986                var bundleIds = new Array();
23987                if (productData.type == 'bundle') {
23988                    isBundle = true;
23989                    bundleIds = productData.productIds;
23990                    openBundleProductIndex = $(product).data('openBundleProductIndex');
23991                    productData = this.data.products[productData.productIds[openBundleProductIndex]];
23992                }
23993
23994
23995                $master = productData.master ? productData.master : productData;
23996                if ($master['selectedOptions']) {
23997                    selectedOptions = $master['selectedOptions'];
23998                }
23999                else {
24000                    selectedOptions = {};
24001                }
24002                filterConf = this.config.filters[option['optionKey']];
24003                selectedOptions[option['optionKey']] = option['value'];
24004
24005                $master['selectedOptions'] = selectedOptions;
24006                $(product).data('selectedOptions', selectedOptions);
24007
24008                $detailModal = $(this.config.selectors.productDetail);
24009                if ($(this.config.selectors.productDetailFull).length > 0) {
24010                    $detailModal = $(this.config.selectors.productDetailFull);
24011                }
24012
24013                children = this.findChildrenForSelectedOptions(productData, option['optionKey']);
24014
24015                if ((inDetail || $detailModal.hasClass('open') || $('#product-detail-full').length > 0) && filterConf.hasOwnProperty('imageSensitive') && filterConf.imageSensitive) {
24016
24017
24018                    if (children.length > 0) {
24019
24020
24021
24022                        optionImages = [
24023                            children[0].products_image,
24024                            children[0].products_image_2,
24025                            children[0].products_image_3,
24026                            children[0].products_image_4,
24027                            children[0].products_image_5
24028                        ];
24029
24030
24031                        $detailModal.find('.zoom_thumbnails').empty();
24032                        for (iIndex in optionImages) {
24033                            if (optionImages[iIndex]) {
24034                                $thumbnail = $('<li><a href="#" data-src="/media/images/popup/' + optionImages[iIndex] + '" data-size="430,430" style="background-image: url(/media/images/info/' + optionImages[iIndex] + ')"></a></li>');
24035                                $thumbnail.find('img').data('filename', optionImages[iIndex]);
24036                                $thumbnail.find('img').bind('error', function () {
24037                                    $(this).parents('li').first().detach();
24038                                });
24039                                $thumbnail.bind('click', {src: '/media/images/popup/' + optionImages[iIndex]}, function (event) {
24040
24041                                    event.preventDefault();
24042                                    $(this).parents('.zoom_thumbnails').first().find('li a').removeClass('active');
24043                                    $(this).addClass('active');
24044                                    //Add your zoom settings here
24045
24046                                    $('#zoom_container').smoothZoom('destroy').css('background-image', 'url(/templates/veryzofcin/images/smoothZoom/preloader.gif)').smoothZoom({
24047                                        image_url: event.data.src,
24048                                        width: infoImage.width,
24049                                        height: infoImage.height,
24050                                        /******************************************
24051                                         Enable Responsive settings below if needed.
24052                                         Max width and height values are optional.
24053                                         ******************************************/
24054                                        responsive: false,
24055                                        responsive_maintain_ratio: true,
24056                                        max_WIDTH: '',
24057                                        max_HEIGHT: '',
24058                                        pan_BUTTONS_SHOW: panButtonsShow,
24059                                        zoom_BUTTONS_SHOW: zoomButtonsShow
24060                                    });
24061                                    return false;
24062
24063                                });
24064
24065                                $detailModal.find('.zoom_thumbnails').append($thumbnail);
24066                            }
24067                        }
24068                        $detailModal.find('.zoom_thumbnails li a').first().trigger('click');
24069                    }
24070
24071                }
24072
24073                // all options selected?
24074                allOptionsSelected = true;
24075                for (optionKey in $master['options']) {
24076                    if (!selectedOptions[optionKey]) {
24077                        allOptionsSelected = false;
24078                    }
24079                }
24080
24081
24082                if (allOptionsSelected) {
24083                    foundChild = false;
24084                    children = $master['children'];
24085                    for (cIndex in children) {
24086                        child = children[cIndex];
24087                        childResult = true;
24088                        for (optionKey in selectedOptions) {
24089                            filterConf = this.config.filters[optionKey];
24090                            fields = filterConf.field;
24091                            if (!jQuery.isArray(fields)) {
24092                                fields = new Array(fields);
24093                            }
24094                            optionResult = false;
24095                            for (fIndex in fields) {
24096                                if (child[fields[fIndex]] == selectedOptions[optionKey]) {
24097                                    optionResult = true;
24098                                }
24099                            }
24100                            if (!optionResult) {
24101                                childResult = false;
24102                            }
24103                        }
24104                        if (childResult) {
24105                            foundChild = child;
24106                        }
24107                    }
24108
24109
24110                    if (foundChild) {
24111
24112                        if (isBundle) {
24113                            var selectedBundleOptions = $(product).data('selectedBundleOptions');
24114                            if (!selectedBundleOptions) {
24115                                selectedBundleOptions = new Object();
24116                            }
24117                            selectedBundleOptions[bundleIds[openBundleProductIndex]] = foundChild;
24118                            var bundleAllSelected = 0;
24119                            for (bIndex in bundleIds) {
24120                                if (selectedBundleOptions.hasOwnProperty(bundleIds[bIndex]) || this.data.products[bundleIds[bIndex]].type != 'master') {
24121                                    bundleAllSelected++;
24122                                }
24123                            }
24124                            selectedBundleOptions['allSelected'] = (bundleAllSelected == bundleIds.length);
24125                            $(product).data('selectedBundleOptions', selectedBundleOptions);
24126
24127                        }
24128
24129                        // change price, title, description
24130                        if (inDetail || $detailModal.hasClass('open') || $('#product-detail-full').length > 0) {
24131                            $(product).find('.product-title').text(foundChild.products_name);
24132                            $(product).find('.model .value').text(foundChild.products_model);
24133                            $(product).find('.description').html(foundChild.products_description);
24134
24135                            $
24135detailModal.find('.badges').empty();
24136                            if (!$detailModal.hasClass('bundle')) {
24137                                this.buildProductPrice($detailModal, foundChild, $detailModal.find('.badges'));
24138                            }
24139                        }
24140
24141                        if (!disableAddToCart) {
24142                            if (isBundle) {
24143                                if (selectedBundleOptions['allSelected']) {
24144                                    this.addToCart(foundChild, product);
24145                                }
24146                                else {
24147                                    if ($(product).hasClass('detail-view')) {
24148                                        $('#message-errorAddToCart').find('.message').text(productData.errorBundleNotAllSelected);
24149                                        $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
24150                                    }
24151
24152                                }
24153                            }
24154                            else {
24155                                this.addToCart(foundChild, product);
24156                            }
24157                            return true;
24158                        }
24159                    }
24160                }
24161            }
24162
24163            return false;
24164
24165        };
24166
24167
24168        this.findChildrenForSelectedOptions = function (product, currentOptionKey) {
24169            result = [];
24170            $master = product.master ? product.master : product;
24171            children = $master['children'];
24172
24173            for (cIndex in children) {
24174                child = children[cIndex];
24175                childResult = true;
24176                for (optionKey in $master['selectedOptions']) {
24177
24178                    if ((typeof optionKey != 'undefined') && (!currentOptionKey || optionKey == currentOptionKey)) {
24179                        filterConf = this.config.filters[optionKey];
24180                        fields = filterConf.field;
24181                        if (!jQuery.isArray(fields)) {
24182                            fields = new Array(fields);
24183                        }
24184                        optionResult = false;
24185                        for (fIndex in fields) {
24186                            if (child[fields[fIndex]] == $master['selectedOptions'][optionKey]) {
24187                                optionResult = true;
24188                            }
24189                        }
24190                        if (!optionResult) {
24191                            childResult = false;
24192                        }
24193                    }
24194
24195                }
24196                if (childResult) {
24197                    result.push(child);
24198                }
24199            }
24200
24201            return result;
24202        }
24203
24204        this.disableInvalidOptionCombinations = function (product, currentOptionKey) {
24205            $this = this;
24206            productData = $(product).data();
24207            if (productData.type == 'bundle') {
24208                openBundleProductIndex = $(product).data('openBundleProductIndex');
24209                productData = this.data.products[productData.productIds[openBundleProductIndex]];
24210            }
24211            $master = productData.master ? productData.master : productData;
24212            if ($master['selectedOptions']) {
24213                children = this.findChildrenForSelectedOptions(productData, currentOptionKey);
24214                $(product).find('.option').not('.template').each(function (oIndex, option) {
24215
24216                    if (currentOptionKey != $(option).data('optionKey')) {
24217                        filterConf = $this.config.filters[$(option).data('optionKey')];
24218                        fields = filterConf.field;
24219                        if (!jQuery.isArray(fields)) {
24220                            fields = new Array(fields);
24221                        }
24222                        foundValues = [];
24223                        for (cIndex in children) {
24224                            child = children[cIndex];
24225                            for (fIndex in fields) {
24226                                if (jQuery.inArray(child[fields[fIndex]], foundValues) < 0) {
24227                                    foundValues.push(child[fields[fIndex]]);
24228                                }
24229                            }
24230                        }
24231                        $(option).find('a').each(function (lIndex, optionLink) {
24232                            if (jQuery.inArray($(optionLink).data('value'), foundValues) >= 0) {
24233                                $(optionLink).removeClass('disabled');
24234                            }
24235                            else {
24236                                $(optionLink).addClass('disabled');
24237                            }
24238                        });
24239                    }
24240                });
24241
24242            }
24243        };
24244
24245
24246
24247        // pagination             
24248        this.buildPagination = function () {
24249
24250            if (this.foundProducts.length) {
24251                if (this.foundProducts.length > 1) {
24252                    $(this.config.selectors.pagination.resultAmount).html('<span class="' + this.config.classes.resultAmount + '">' + String(this.foundProducts.length) + '</span> ' + this.config.translations.resultAmount.plural[this.config.language]);
24253                }
24254                else {
24255                    $(this.config.selectors.pagination.resultAmount).html('<span class="' + this.config.classes.resultAmount + '">' + String(this.foundProducts.length) + '</span> ' + this.config.translations.resultAmount.singular[this.config.language]);
24256                }
24257            }
24258            else {
24259                $(this.config.selectors.pagination.resultAmount).html(this.config.translations.resultAmount.none[this.config.language]);
24260            }
24261
24262
24263            if (this.foundProducts.length > this.searchParams.range) {
24264
24265                $(this.config.selectors.pagination.container).show();
24266                // pages vars
24267                pages = parseInt(this.foundProducts.length / this.searchParams.range);
24268                if (this.foundProducts.length % this.searchParams.range > 0) {
24269                    pages++;
24270                }
24271                firstPage = !(this.searchParams.start);
24272                lastPage = (this.searchParams.start + this.searchParams.range >= this.foundProducts.length);
24273                currentPage = this.searchParams.start / this.searchParams.range;
24274
24275                // activate/deactivate prev/next
24276                if (firstPage) {
24277                    $(this.config.selectors.pagination.prev).addClass('disabled');
24278                }
24279                else {
24280                    $(this.config.selectors.pagination.prev).removeClass('disabled');
24281                    $(this.config.selectors.pagination.prev).data('start', this.searchParams.start - this.searchParams.range);
24282                }
24283                if (lastPage) {
24284                    $(this.config.selectors.pagination.next).addClass('disabled');
24285                }
24286                else {
24287                    $(this.config.selectors.pagination.next).removeClass('disabled');
24288                    $(this.config.selectors.pagination.next).data('start', this.searchParams.start + this.searchParams.range);
24289                }
24290                // activate/deactivate first/last
24291
24292                if (pages > this.config.pagination.maxPages) {
24293                    $(this.config.selectors.pagination.first).show();
24294                    $(this.config.selectors.pagination.last).show();
24295                    if (firstPage) {
24296                        $(this.config.selectors.pagination.first).addClass('disabled');
24297                    }
24298                    else {
24299                        $(this.config.selectors.pagination.first).removeClass('disabled');
24300                        $(this.config.selectors.pagination.first).data('start', 0);
24301                    }
24302                    if (lastPage) {
24303                        $(this.config.selectors.pagination.last).addClass('disabled');
24304                    }
24305                    else {
24306                        $(this.config.selectors.pagination.last).removeClass('disabled');
24307                        $(this.config.selectors.pagination.last).data('start', (pages - 1) * this.searchParams.range);
24308                    }
24309                }
24310                else {
24311                    $(this.config.selectors.pagination.first).hide();
24312                    $(this.config.selectors.pagination.last).hide();
24313                }
24314                // build pages-links
24315                $(this.config.selectors.pagination.pages).empty();
24316
24317                startPage = currentPage - this.config.pagination.prevNextPages;
24318
24319                if (startPage > pages - this.config.pagination.maxPages) {
24320                    startPage = pages - this.config.pagination.maxPages;
24321                }
24322                if (startPage < 0) {
24323                    startPage = 0;
24324                }
24325
24326                if (pages > this.config.pagination.maxPages && currentPage > this.config.pagination.maxPages - this.config.pagination.prevNextPages) {
24327                    this.addPageLink(0);
24328                    $(this.config.selectors.pagination.pages).append('<span class="divider">...</span>');
24329                }
24330
24331                for (c = startPage, d = 0; c < pages && d < this.config.pagination.maxPages; c++, d++) {
24332                    this.addPageLink(c);
24333                }
24334                if (pages > this.config.pagination.maxPages && pages - currentPage > this.config.pagination.maxPages - this.config.pagination.prevNextPages) {
24335                    $(this.config.selectors.pagination.pages).append('<span class="divider">...</span>');
24336                    this.addPageLink(pages - 1);
24337                }
24338
24339
24340                // bind link-click event
24341                $(this.config.selectors.pagination.container).find('a').unbind('click').bind('click', {
24342                    context: this
24343                }, function (event) {
24344                    event.preventDefault();
24345                    if (!$(this).hasClass('disabled')) {
24346                        event.data.context.showPage($(this).data('start'));
24347                        filtersOffset = $(event.data.context.config.selectors.filtersContainer).offset();
24348                        $(window).scrollTop(filtersOffset.top - 40);
24349                    }
24350                });
24351
24352            }
24353            else {
24354                $(this.config.selectors.pagination.container).hide();
24355            }
24356
24357        }
24358
24359        this.addPageLink = function (index) {
24360            $pageLink = $('<a href="#" class="btn">' + String(index + 1) + '</a>');
24361            if (index * this.searchParams.range == this.searchParams.start) {
24362                $pageLink.addClass(this.config.classes.buttonActive);
24363            }
24364            $pageLink.data('start', index * this.searchParams.range);
24365            $(this.config.selectors.pagination.pages).append($pageLink);
24366        };
24367
24368        this.showPage = function (start) {
24369            this.searchParams.start = start;
24370            this.showSearchResult();
24371        };
24372
24373
24374
24375        // configuration functions
24376        this.bindConfigurationLinkEvents = function () {
24377
24378            // sortBy links
24379            $(this.config.selectors.configuration.sortBy).find('a').bind('click', {
24380                context: this
24381            }, function (event) {
24382                event.preventDefault();
24383                $(event.data.context.config.selectors.configuration.sortBy).find('a').removeClass(event.data.context.config.classes.buttonActive);
24384                $(this).addClass(event.data.context.config.classes.buttonActive);
24385                event.data.context.searchParams.sortBy = $(this).data('value');
24386                event.data.context.applySorting();
24387                event.data.context.showSearchResult();
24388            });
24389
24390            // sortOrder links
24391            $(this.config.selectors.configuration.sortOrder).find('a').bind('click', {
24392                context: this
24393            }, function (event) {
24394                event.preventDefault();
24395                $(event.data.context.config.selectors.configuration.sortOrder).find('a').removeClass(event.data.context.config.classes.buttonActive);
24396                $(event.data.context.config.selectors.configuration.sortOrder).find('a i').removeClass(event.data.context.config.classes.buttonActiveIcon);
24397                $(this).addClass(event.data.context.config.classes.buttonActive);
24398                $(this).find('i').addClass(event.data.context.config.classes.buttonActiveIcon);
24399                event.data.context.searchParams.sortOrder = $(this).data('value');
24400                event.data.context.applySorting();
24401                event.data.context.showSearchResult();
24402            });
24403
24404            // presentation links
24405            $(this.config.selectors.configuration.presentation).find('a').bind('click', {
24406                context: this
24407            }, function (event) {
24408                event.preventDefault();
24409                $(event.data.context.config.selectors.configuration.presentation).find('a').removeClass(event.data.context.config.classes.buttonActive);
24410                $(event.data.context.config.selectors.configuration.presentation).find('a i').removeClass(event.data.context.config.classes.buttonActiveIcon);
24411                $(this).addClass(event.data.context.config.classes.buttonActive);
24412                $(this).find('i').addClass(event.data.context.config.classes.buttonActiveIcon);
24413                event.data.context.searchParams.presentation = $(this).data('value');
24414                event.data.context.showSearchResult();
24415            });
24416
24417            // resultsPerPage links
24418            $(this.config.selectors.configuration.resultsPerPage).find('a').bind('click', {
24419                context: this
24420            }, function (event) {
24421                event.preventDefault();
24422                $(event.data.context.config.selectors.configuration.resultsPerPage).find('a').removeClass(event.data.context.config.classes.buttonActive);
24423                $(this).addClass(event.data.context.config.classes.buttonActive);
24424                event.data.context.searchParams.start = 0;
24425                event.data.context.searchParams.range = parseInt($(this).data('value'));
24426                event.data.context.showSearchResult();
24427            });
24428
24429        };
24430
24431
24432        this.applySorting = function () {
24433            this.searchParams.start = 0;
24434            switch (this.searchParams.sortBy) {
24435                case 'name':
24436                    this.foundProducts.sort(this.compareByName);
24437                    break;
24438                case 'price':
24439                    this.foundProducts.sort(this.compareByPrice);
24440                    break;
24441                case 'size':
24442                    this.foundProducts.sort(this.compareBySize);
24443                    break;
24444                case 'color':
24445                    this.foundProducts.sort(this.compareByColor);
24446                    break;
24447                case 'material':
24448                    this.foundProducts.sort(this.compareByMaterial);
24449                    break;
24450            }
24451
24452            if (this.searchParams.sortOrder == 'DESC') {
24453                this.foundProducts.reverse();
24454            }
24455
24456            // assign prev/next
24457            prevProduct = false;
24458            for (pIndex in this.foundProducts) {
24459                this.foundProducts[pIndex]['prev'] = false;
24460                this.foundProducts[pIndex]['next'] = false;
24461                if (prevProduct) {
24462                    prevProduct['next'] = this.foundProducts[pIndex];
24463                    this.foundProducts[pIndex]['prev'] = prevProduct;
24464                }
24465                prevProduct = this.foundProducts[pIndex];
24466            }
24467
24468        };
24469
24470        // find functions
24471        this.findOneBy = function (field, value) {
24472            for (pIndex in this.data.products) {
24473                if (this.data.products[pIndex][field] == value) {
24474                    return this.data.products[pIndex];
24475                }
24476            }
24477            return false;
24478        };
24479
24480
24481        // compare functions                    
24482
24483        this.compareByName = function (first, second) {
24484            if (first['products_name'] < second['products_name'])
24485                return -1;
24486            if (first['products_name'] > second['products_name'])
24487                return 1;
24488            return 0;
24489        };
24490
24491        this.compareByPrice = function (first, second) {
24492            if (parseInt(first['products_price']) < parseInt(second['products_price']))
24493                return -1;
24494            if (parseInt(first['products_price']) > parseInt(second['products_price']))
24495                return 1;
24496            return 0;
24497        };
24498
24499        this.compareBySize = function (first, second) {
24500            if (jQuery.isNumeric(first['ext_size']) && jQuery.isNumeric(second['ext_size'])) {
24501                if (parseInt(first['ext_size']) < parseInt(second['ext_size']))
24502                    return -1;
24503                if (parseInt(first['ext_size']) > parseInt(second['ext_size']))
24504                    return 1;
24505            }
24506
24507            return 0;
24508        };
24509
24510        this.compareByColor = function (first, second) {
24511            if (first['ext_color_primary'] < second['ext_color_primary'])
24512                return -1;
24513            if (first['ext_color_primary'] > second['ext_color_primary'])
24514                return 1;
24515            return 0;
24516        };
24517
24518        this.compareByMaterial = function (first, second) {
24519            if (first['ext_material_primary'] < second['ext_material_primary'])
24520                return -1;
24521            if (first['ext_material_primary'] > second['ext_material_primary'])
24522                return 1;
24523            return 0;
24524        };
24525
24526        this.compareSizeByIntegerValue = function (first, second) {
24527            if ($(first).data('value') < $(second).data('value'))
24528                return -1;
24529            if ($(first).data('value') > $(second).data('value'))
24530                return 1;
24531            return 0;
24532        };
24533
24534        this.compareSizeByLetter = function (first, second) {
24535            letters = $this.config.filters.size.letterSizesOrder;
24536            fIndex = jQuery.inArray(first, letters);
24537            sIndex = jQuery.inArray(second, letters);
24538            if (fIndex < sIndex)
24539                return -1;
24540            if (fIndex > sIndex)
24541                return 1;
24542            return 0;
24543        };
24544
24545        this.compareSizeByShoeSize = function (first, second) {
24546
24547
24548            firstRes = first.split(' ');
24549            secondRes = second.split(' ');
24550            if (firstRes && secondRes) {
24551                if (parseFloat(firstRes[0]) < parseFloat(secondRes[0]))
24552                    return -1;
24553                if (parseFloat(firstRes[0]) > parseFloat(secondRes[0]))
24554                    return 1;
24555            }
24556
24557            return 0;
24558        };
24559
24560
24561        // cart functions 
24562        this.addToCart = function (product, container, qty) {
24563
24564
24565            $this = this;
24566            if (!qty) {
24567                qty = 1;
24568            }
24569            if (container) {
24570                $(container).append('<div class="mask"></div>');
24571                $(container).spin();
24572            }
24573
24574            productData = $(container).data();
24575            if (productData.type == 'bundle') {
24576                bundleIds = new Array();
24577                var selectedBundleOptions = $(container).data('selectedBundleOptions');
24578                for (iIndex in productData.productIds) {
24579                    bundleIds.push(selectedBundleOptions[productData.productIds[iIndex]].products_id);
24580                }
24581                var ajaxData = {
24582                    action: 'addProduct',
24583                    productType: 'bundle',
24584                    product: productData.ssag_id,
24585                    bundleIds: bundleIds,
24586                    qty: qty,
24587                    language: this.config.language
24588                };
24589            }
24590            else {
24591                var ajaxData = {
24592                    action: 'addProduct',
24593                    productType: 'default',
24594                    product: product.products_id,
24595                    qty: qty,
24596                    language: this.config.language
24597                };
24598            }
24599
24600
24601
24602            $.ajax('/json.php', {
24603                data: ajaxData,
24604                dataType: 'json',
24605                context: container,
24606                error: function (jqXHR, textStatus, errorThrown) {
24607                    if (typeof console != 'undefined') {
24608
24609                    }
24610                    else {
24611                        alert(errorThrown);
24612                    }
24613                },
24614                success: function (data, textStatus, jqXHR) {
24615
24616                    $(this).find('.mask').detach();
24617                    $(this).spin(false);
24618
24619                    if (data.code == 0) {
24620                        // success
24621                        if ($(this).hasClass('detail-view')) {
24622                            $("#message-productAdded").find('.name').text(data.product.products_name);
24623                            $("#message-productAdded").show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
24624                        }
24625                        else {
24626                            $('.product .list-alert').detach();
24627                            $message = $("#message-list-productAdded").clone(true);
24628                            $message.attr('id', 'message-list-productAdded-' + $(this).data('products_id'));
24629                            $message.find('.name').text(data.product.products_name);
24630                            $(this).append($message);
24631                            $message.show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
24632                            $message.find('.hide-alert').bind('click', function (event) {
24633                                event.preventDefault();
24634                                $(this).parents('.alert').first().detach();
24635                            });
24636                            closeMessage = window.setTimeout(function () {
24637                                $message.detach();
24638                            }, 2000);
24639                        }
24640
24641                        $this.refreshCart(data.cart);
24642
24643                    }
24644                    else {
24645                        // error
24646                        if ($(this).hasClass('detail-view')) {
24647                            $('#message-errorAddToCart').find('.message').text(data.error);
24648                            $("#message-errorAddToCart").show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
24649                        }
24650                        else {
24651                            $('.product .list-alert').detach();
24652                            $message = $("#message-list-errorAddToCart").clone(true);
24653                            $message.attr('id', 'message-list-errorAddToCart-' + $(this).data('products_id'));
24654                            $message.find('.message').text(data.error);
24655                            $(this).append($message);
24656                            $message.show().css('opacity', 0).stop().animate({'opacity': 1}, 250);
24657                            $message.find('.hide-alert').bind('click', function (event) {
24658                                event.preventDefault();
24659                                $(this).parents('.alert').first().detach();
24660                            });
24661                            closeMessage = window.setTimeout(function () {
24662                                $message.detach();
24663                            }, 4000);
24664                        }
24665                    }
24666                }
24667            });
24668
24669        };
24670
24671
24672        this.removeFromCart = function ($cartProduct) {
24673            $this = this;
24674            $cartProduct.append('<div class="mask"></div>');
24675            $cartProduct.spin();
24676
24677            $.ajax('/json.php', {
24678                data: {
24679                    action: 'removeProduct',
24680                    key: $cartProduct.data('key'),
24681                    language: this.config.language
24682                },
24683                dataType: 'json',
24684                error: function (jqXHR, textStatus, errorThrown) {
24685                    if (typeof console != 'undefined') {
24686
24687                    }
24688                    else {
24689                        alert(errorThrown);
24690                    }
24691                },
24692                success: function (data, textStatus, jqXHR) {
24693
24694                    $cartProduct.find('.mask').detach();
24695                    $cartProduct.spin(false);
24696                    if (data.code == 0) {
24697                        // success
24698                        $cartProduct.detach();
24699                        $this.refreshCart(data.cart);
24700
24701                    }
24702                    else {
24703                        // error
24704                    }
24705                }
24706            });
24707
24708        };
24709
24710
24711        this.refreshCart = function (cart) {
24712            // totalCount
24713            if (!cart.content_count) {
24714                cart.content_count = 0;
24715            }
24716            $($this.config.selectors.cart).find('.totalCount').text(cart.content_count);
24717            $($this.config.selectors.cartContent).data('totalCount', cart.content_count);
24718
24719            $('.cartTotal').html(cart.content_total.formated);
24720
24721
24722            // cart content
24723            if (cart.content_count) {
24724                $($this.config.selectors.cartContent).find('.cart
24724-products').empty();
24725                for (pKey in cart.content) {
24726                    cartProduct = cart.content[pKey];
24727                    $cartProductTemplate = $this.getTemplate('cartProduct-template', 'cartProduct-' + pKey);
24728                    $cartProductTemplate.find('.link-to-product').attr('href', cartProduct.products_link);
24729                    if (cartProduct.products_image) {
24730                        $cartProductTemplate.find('.cart-product-image a').css('background-image', 'url(/media/images/thumb/' + cartProduct.products_image.replace('product:', '') + ')');
24731                    }
24732                    $cartProductTemplate.find('.qty').text(cartProduct.products_quantity);
24733                    $cartProductTemplate.find('.product-name').text(cartProduct.products_name);
24734                    $cartProductTemplate.find('.price').html(cartProduct.products_final_price.formated);
24735                    $cartProductTemplate.data({
24736                        'key': cartProduct.products_key,
24737                        'qty': cartProduct.products_quantity
24738                    });
24739                    $($this.config.selectors.cartContent).find('.cart-products').append($cartProductTemplate);
24740                }
24741
24742                $($this.config.selectors.cartContent).find('.cart-taxes').empty();
24743                for (tKey in cart.content_tax) {
24744                    tax = cart.content_tax[tKey];
24745                    $taxTemplate = $('<div class="tax"></div>');
24746                    $taxTemplate.html('MwSt. ' + tax.tax_key + '%: ' + tax.tax_value.formated);
24747                    $($this.config.selectors.cartContent).find('.cart-taxes').append($taxTemplate);
24748                }
24749
24750            }
24751            else {
24752                $($this.config.selectors.cartContent).hide();
24753            }
24754
24755
24756        };
24757
24758        // favourites functions
24759        this.addToFavourites = function (product, container) {
24760
24761            $this = this;
24762            if ($($this.config.selectors.favourites).data('contentCount') < 10) {
24763                var content = $(container).data('content');
24764                var favouriteModels = $(container).data('favouriteModels');
24765                if (!content) {
24766                    content = {};
24767                    favouriteModels = [];
24768                }
24769                if (!content.hasOwnProperty(product['products_id'])) {
24770                    content[product['products_id']] = product;
24771                    favouriteModels.push(product.products_model);
24772                }
24773                $(container).data('content', content);
24774                $(container).data('favouriteModels', favouriteModels);
24775                $this.refreshFavourites();
24776            }
24777            else {
24778                $('#global-message .message-header').text('Ihre Wunschliste');
24779                $('#global-message .message').text('Sie können nur max. 10 Artikel in Ihre Wunschliste aufnehmen.');
24780                $('#global-message').modal('show');
24781            }
24782
24783        };
24784
24785        this.removeFromFavourites = function (product, container) {
24786            $this = this;
24787            var content = $(container).data('content');
24788            if (content.hasOwnProperty(product['products_id'])) {
24789                delete content[product['products_id']];
24790            }
24791            var newFavouriteModels = new Array();
24792            var favouriteModels = $(container).data('favouriteModels');
24793            for (fIndex in favouriteModels) {
24794                if (favouriteModels[fIndex] != product.products_model) {
24795                    newFavouriteModels.push(favouriteModels[fIndex]);
24796                }
24797            }
24798            $(container).data('content', content);
24799            $(container).data('favouriteModels', newFavouriteModels);
24800            $this.refreshFavourites();
24801        };
24802
24803        this.refreshFavourites = function () {
24804            if ($($this.config.selectors.favourites).data('content')) {
24805                var content = $($this.config.selectors.favourites).data('content');
24806                var favouriteModels = $($this.config.selectors.favourites).data('favouriteModels');
24807            }
24808            else {
24809                var content = false;
24810            }
24811
24812            contentCount = 0;
24813            $($this.config.selectors.favouritesContent).find('.favourites-products').empty();
24814            if (content) {
24815                $($this.config.selectors.favourites).data('show', true);
24816                $($this.config.selectors.favourites).show();
24817                $(window).trigger('scroll');
24818                productModels = new Array();
24819
24820                for (cIndex in content) {
24821
24822                    product = content[cIndex];
24823                    if (jQuery.inArray(product.products_model, favouriteModels) >= 0) {
24824                        productImage = product.products_image;
24825                        if (product.type == 'master') {
24826                            if (product.children) {
24827                                for (cIndex in product.children) {
24828                                    if (product.children[cIndex].products_image) {
24829                                        productImage = product.children[cIndex].products_image;
24830                                    }
24831                                }
24832                            }
24833                        }
24834                        productModels.push(product.products_model);
24835                        $productTemplate = $this.getTemplate('favouritesProduct-template', 'favouritesProduct-' + cIndex);
24836                        $productTemplate.find('.link-to-product').attr('href', product.products_link);
24837                        if (productImage) {
24838                            $productTemplate.find('.favourites-product-image a').css('background-image', 'url(/media/images/thumb/' + productImage.replace('product:', '') + ')');
24839                        }
24840                        $productTemplate.find('.product-name').text(product.products_name);
24841                        $productTemplate.find('.price').html(product.price.formated);
24842                        $productTemplate.data(product);
24843                        $($this.config.selectors.favouritesContent).find('.favourites-products').append($productTemplate);
24844                        contentCount++;
24845                    }
24846
24847                }
24848                $($this.config.selectors.favourites).find('.totalCount').text(contentCount);
24849                $.cookie($this.config.favourites.cookieName, productModels.join(','), {expires: 14, path: '/'})
24850            }
24851            $($this.config.selectors.favourites).data('contentCount', contentCount);
24852
24853            if (contentCount == 0) {
24854                $($this.config.selectors.favourites).data('show', false);
24855                $($this.config.selectors.favourites).hide();
24856                $($this.config.selectors.favouritesContent).hide();
24857                $.removeCookie($this.config.favourites.cookieName);
24858            }
24859
24860        };
24861
24862
24863        // path functions
24864
24865
24866        this.getPath = function () {
24867            return this.getFilterPath() + '/' + this.getSettingsPath() + '/' + this.getDetailPath();
24868        };
24869
24870        this.getFilterPath = function () {
24871            path = '';
24872            for (filterName in this.config.filters) {
24873                if (this.activeFilters.hasOwnProperty(filterName)) {
24874                    filterConf = this.config.filters[filterName];
24875                    switch (filterConf.type) {
24876                        case 'vlist':
24877                        case 'occurrences':
24878                            values = '';
24879                            for (elementIndex in this.activeFilters[filterName]['elements']) {
24880                                values += (values ? '|' : '') + this.activeFilters[filterName]['elements'][elementIndex];
24881                            }
24882                            break;
24883                        case 'range':
24884                            values = this.activeFilters[filterName]['min'] + ':' + this.activeFilters[filterName]['max'];
24885                            break;
24886                    }
24887                    path += (path ? ';' : '') + filterName + '[' + values + ']';
24888                }
24889            }
24890            return path;
24891
24892        };
24893
24894        this.getSettingsPath = function () {
24895            return 'settings[' + String(this.searchParams.start) + '|' +
24896                    String(this.searchParams.range) + '|' +
24897                    this.searchParams.presentation + '|' +
24898                    this.searchParams.sortBy + '|' +
24899                    this.searchParams.sortOrder + '|' +
24900                    String(this.searchParams.resultsPerPage) + ']';
24901        };
24902
24903        this.getDetailPath = function () {
24904            $detailModal = $(this.config.selectors.productDetail);
24905
24906            if ($detailModal.hasClass('open')) {
24907                product = $detailModal.data();
24908                return 'product[' + String(product.products_id) + ']';
24909            }
24910            else {
24911                return '';
24912            }
24913        };
24914
24915        this.parsePath = function (path) {
24916
24917
24918            pathElements = path.split('/');
24919
24920            //this.removeAllFilters();
24921
24922            if (path) {
24923
24924                if (pathElements.length == 3) {
24925
24926                    filterPath = pathElements[0];
24927                    settingsPath = pathElements[1];
24928                    detailPath = pathElements[2];
24929
24930//                    // parse filter path
24931//                    filterPathElements = filterPath.split(';');
24932//                    for (pathElementsIndex = 0; pathElementsIndex < filterPathElements.length; pathElementsIndex++) {
24933//                        var findCommandRE = /^([a-zA-Z]+)\((.+)\)$/;
24934//                        cResult = findCommandRE.exec(filterPathElements[pathElementsIndex]);
24935//
24936//                        if (cResult && cResult.length == 3) {
24937//                            if (this.config.filters.hasOwnProperty(cResult[1])) {
24938//                                filterName = cResult[1];
24939//                                filterConf = this.config.filters[filterName];
24940//                                switch (filterConf.type) {
24941//                                    case 'vlist':
24942//                                    case 'occurrences':
24943//                                        filterValues = cResult[2].split('|');
24944//                                        for (filterValuesIndex = 0; filterValuesIndex < filterValues.length; filterValuesIndex++) {
24945//
24946//                                            this.addFilter(filterName, filterValues[filterValuesIndex]);
24947//                                            this.selectFilter(filterName, filterValues[filterValuesIndex]);
24948//                                            this.checkFilter(filterName, filterValues[filterValuesIndex]);
24949//                                        }
24950//                                        break;
24951//                                    case 'range':
24952//                                        values = cResult[2].split(':');
24953//                                        sliderElement = $('#filter-' + filterName).find('.range-slider');
24954//                                        filterValues = {
24955//                                            start: values[0],
24956//                                            end: values[1]
24957//                                        }
24958//                                        this.addRangeFilter(filterName, filterValues.start, filterValues.end);
24959//
24960//                                        amountFunction = $(sliderElement).data('amountFunction');
24961//                                        $('#filter-' + filterName).find('.range-amount').html(amountFunction(this, filterValues.start, filterValues.end));
24962//
24963//                                        $(sliderElement).slider('values', 0, filterValues.start);
24964//                                        $(sliderElement).slider('values', 1, filterValues.end);
24965//                                        filterConf.onChange(this);
24966//
24967//                                        break;
24968//                                }
24969//                            }
24970//
24971//                        }
24972//
24973//                    }
24974//
24975//                    // parse settings path
24976//                    findSettingsRE = /^settings\(([a-z]+)\|([a-zA-Z]+)\|([a-zA-Z]+)\|([0-9]+)\|([0-9]+)\)$/;
24977//                    cResult = findSettingsRE.exec(settingsPath);
24978//                    if (cResult && cResult.length == 6) {
24979//                        this.config.settings.presentation = cResult[1];
24980//                        this.config.settings.sorting.field = cResult[2];
24981//                        this.config.settings.sorting.order = cResult[3];
24982//                        this.config.settings.start = parseInt(cResult[4]);
24983//                        this.config.settings.resultsPerPage = parseInt(cResult[5]);
24984//
24985//                        // apply settings
24986//                        this.applySettings();
24987//
24988//
24989//                    }
24990
24991
24992                    // parse detail view
24993                    findProductRE = /^product\[([0-9]+)\]$/;
24994                    cResult = findProductRE.exec(detailPath);
24995                    if (cResult && cResult.length == 2) {
24996
24997                        productId = cResult[1];
24998                        product = this.findInObjectArray(this.data.products, 'products_id', productId);
24999                        if (product) {
25000                            this.openDetailView(product);
25001                            $(this.config.selectors.productDetail).modal('show');
25002                        }
25003                    }
25004                    else {
25005                        if ($(this.config.selectors.productDetail).hasClass('open')) {
25006                            $(this.config.selectors.productDetail).modal('hide');
25007                        }
25008                    }
25009
25010                }
25011
25012
25013
25014            }
25015
25016
25017        };
25018
25019
25020        // template functions
25021        this.getTemplate = function (id, newId) {
25022            $template = $('#' + id).clone();
25023            $template.removeClass('template');
25024            $template.attr('id', newId);
25025            return $template;
25026        };
25027
25028        // helper functions
25029        this.formatPrice = function (price) {
25030            return '&euro;&nbsp;' + number_format(price, 2, ',', '.').replace(',00', ',-');
25031        }
25032
25033        this.findInObjectArray = function (source, field, value) {
25034            for (index in source) {
25035                if (source[index][field] == value) {
25036                    return source[index];
25037                }
25038            }
25039            return false;
25040        }
25041
25042        // run init function        
25043        this.init();
25044
25045    };
25046
25047
25048    /* -------------------------------------------------------------------------------------------------
25049     * NeundreiviertelSmartObjects Declaration
25050     * -------------------------------------------------------------------------------------------------
25051     */
25052
25053
25054    $('.neundreiviertel-smart-objects').each(function (oIndex, objectContainer) {
25055        smartObjectsConfig = {
25056            baseUrl: 'http://www.veryzofcin.com/',
25057            language: $('meta[name=language]').first().attr('content'),
25058            view: $(objectContainer).data('view'),
25059            rootContainer: $(objectContainer),
25060            favourites: {
25061                cookieName: 'veryZofcin-favourites'
25062            }
25063        };
25064        if ($(objectContainer).data('currentCategoryId')) {
25065            smartObjectsConfig.currentCategoryId = $(objectContainer).data('currentCategoryId');
25066        }
25067        switch ($(objectContainer).data('view')) {
25068            case 'search':
25069            case 'cart':
25070                smartObjectsConfig.selectors = {
25071                    productsContainer: '#globalSearch-box-products',
25072                    productsAppend: {
25073                        grid: '#globalSearch-box-products .row-fluid:last',
25074                        list: '#globalSearch-box-products'
25075                    }
25076                };            
25077            case 'favourites':
25078            case 'detail':
25079                smartObjectsConfig.bbqEnabled = false;
25080                break;
25081        }
25082        ;
25083
25084        $(objectContainer).data('smartObjects', new NeundreiviertelSmartObjects(smartObjectsConfig));
25085    });
25086
25087
25088
25089});
25090
25091jQuery(document).ready(function() {
25092
25093
25094
25095    /* -------------------------------------------------------------------------------------------------
25096     * spinner
25097     * -------------------------------------------------------------------------------------------------
25098     */
25099
25100    (function($) {
25101        $.fn.spin = function(opts, color) {
25102            var presets = {
25103                "tiny": {
25104                    lines: 8,
25105                    length: 2,
25106                    width: 2,
25107                    radius: 3
25108                },
25109                "small": {
25110                    lines: 8,
25111                    length: 4,
25112                    width: 3,
25113                    radius: 5
25114                },
25115                "large": {
25116                    lines: 10,
25117                    length: 8,
25118                    width: 4,
25119                    radius: 8
25120                }
25121            };
25122            if (Spinner) {
25123                return this.each(function() {
25124                    var $this = $(this),
25125                            data = $this.data();
25126
25127                    if (data.spinner) {
25128                        data.spinner.stop();
25129                        delete data.spinner;
25130                    }
25131                    if (opts !== false) {
25132                        if (typeof opts === "string") {
25133                            if (opts in presets) {
25134                                opts = presets[opts];
25135                            } else {
25136                                opts = {};
25137                            }
25138                            if (color) {
25139                                opts.color = color;
25140                            }
25141                        }
25142                        data.spinner = new Spinner($.extend({
25143                            color: $this.css('color')
25144                        }, opts)).spin(this);
25145                    }
25146                });
25147            } else {
25148                throw "Spinner class not available.";
25149            }
25150        };
25151    })(jQuery);
25152
25153
25154    /* -------------------------------------------------------------------------------------------------
25155     * Navigation (Superfish)
25156     * -------------------------------------------------------------------------------------------------
25157     */
25158
25159    jQuery('ul.sf-menu').superfish({
25160        delay: 1000,
25161        animation: {opacity: 'show', height: 'show'},
25162        speed: 'fast',
25163        autoArrows: false
25164    });
25165
25166    /*
25167     * Slider
25168     */
25169
25170
25171    $('#slideshow').rhinoslider({
25172        effect: 'fade',
25173        showTime: 5000,
25174        effectTime: 500,
25175        controlsPrevNext: false,
25176        controlsPlayPause: false,
25177        autoPlay: true,
25178        showBullets: 'always',
25179        changeBullets: 'before',
25180        showControls: 'never',
25181        styles: ''
25182    });
25183
25184
25185    /*
25186     * EqualHeight
25187     */
25188    setEqualHeight = function() {
25189        $('.row.equal-height, .row-fluid.equal-height').each(function(rIndex, row) {
25190            spanSelector = '[class^="span"], [class*=" span"]';
25191            maxHeight = 0;
25192            $(row).children(spanSelector).css({
25193                'height': 'auto'
25194            });
25195            $(row).children(spanSelector).each(function(sIndex, span) {
25196                if ($(span).height() > maxHeight) {
25197                    maxHeight = $(span).height();
25198                }
25199            });
25200            $(row).children(spanSelector).css({
25201                'height': maxHeight
25202            });
25203        });
25204    }
25205    setEqualHeight();
25206
25207
25208
25209
25210
25211    /*
25212     * sidenav
25213     */
25214    $('.nav-tabs a').mouseover(function(event) {
25215        event.preventDefault();
25216        $(this).tab('show');
25217    })
25218
25219
25220
25221    /*
25222     * select buttons
25223     */
25224    $('.btn-selector').bind('click', function(event) {
25225        event.preventDefault();
25226        $(this).find('input[type="radio"]').first().attr('checked', true);
25227        $(this).parents('form').first().find('.btn-selector').removeClass('btn-danger');
25228        $(this).addClass('btn-danger');
25229    });
25230
25231
25232
25233    /* -------------------------------------------------------------------------------------------------
25234     * Nav on phones
25235     * -------------------------------------------------------------------------------------------------
25236     */
25237
25238    if ($(document).innerWidth() <= 767) {
25239        if ($('#page-home').length == 0) {
25240            $('#navMain').before('<a href="#" id="show-navMain" class="btn btn-primary btn-block">Menü</a>');
25241            $('#navMain').hide();
25242            $('#show-navMain').bind('click', function(event) {
25243                event.preventDefault();
25244                $('#navMain').show();
25245                $(this).detach();
25246            });
25247
25248            if ($('#filter-wrap').length > 0) {
25249                $('#filter-wrap').before('<a href="#" id="show-filter" class="btn btn-primary btn-block">Filter</a>');
25250                $('#filter-wrap').hide();
25251                $('#show-filter').bind('click', function(event) {
25252                    event.preventDefault();
25253                    $('#filter-wrap').show();
25254                    $(this).detach();
25255                });
25256            }
25257        }
25258    }
25259
25260    /* -------------------------------------------------------------------------------------------------
25261     * searchbox
25262     * -------------------------------------------------------------------------------------------------
25263     */   
25264    
25265    $('#globalSearch').removeClass('hide');
25266    
25267    
25268    $('#searchbox-toggle').bind('click', function(event) {
25269        event.preventDefault();
25270        $('#globalSearch').submit();
25271//        if ($('#globalSearch').hasClass('hide')) {
25272//            
25273//            $('#globalSearch').css('opacity',0);
25274//            $('#globalSearch').stop().animate({
25275//                'opacity': 1
25276//            },300);
25277//            $('#globalSearch-query').focus();
25278//        }
25279//        else {
25280//            $('#globalSearch').stop().animate({
25281//                'opacity': 0
25282//            },300, function() {
25283//                $('#globalSearch').addClass('hide');
25284//            });    
25285//            
25286//        }
25287    });
25288
25289
25290    /* -------------------------------------------------------------------------------------------------
25291     * language-content
25292     * -------------------------------------------------------------------------------------------------
25293     */
25294    
25295    $('.language-content').each(function(cIndex, content) {
25296        $(content).html($(content).data($('body').data('language')));
25297    });
25298    
25299    
25300    $('#dropdownMenuLanguage').on('click', function(event) {
25301        event.preventDefault();
25302    });
25303
25304
25305    /* -------------------------------------------------------------------------------------------------
25306     * welcome
25307     * -------------------------------------------------------------------------------------------------
25308     */
25309    
25310    if ($('#welcome').length > 0) {
25311        
25312        $(window).on('resize', function() {
25313            $('#welcome').height($(window).height());
25314        });
25315        $(window).trigger('resize');
25316
25317        var hideHeaderValue = -222;
25318        if ($(document).innerWidth() <= 767) {
25319            hideHeaderValue = -537;
25320        }
25321        if ($(document).innerWidth() > 767) {
25322            $('#header-container').css({
25323                'position':'fixed',
25324                'width': '100%',
25325                'top': hideHeaderValue
25326            });
25327        
25328            $(window).bind('scroll', function(event) {
25329                if ($(window).scrollTop() > 300) {
25330                    $('#header-container').stop().animate({
25331                        'top': 0,
25332                    }, 300);                
25333                }
25334                else {
25335                    $('#header-container').stop().animate({
25336                        'top': hideHeaderValue,
25337                    }, 300);                 
25338                }
25339            });
25340        }
25341    }
25342
25343    /* -------------------------------------------------------------------------------------------------
25344     * navMobile
25345     * -------------------------------------------------------------------------------------------------
25346     */
25347
25348    $('#navMobile').multilevelpushmenu({
25349        overlapWidth: 0,
25350        backText: 'zurück',
25351        collapsed: true,
25352        onItemClick: function() {
25353
25354            var event = arguments[0],
25355            $menuLevelHolder = arguments[1],
25356            $item = arguments[2],
25357            options = arguments[3],
25358            title = $menuLevelHolder.find( 'h3:first' ).text(),
25359            href = $item.find( 'a:first' ).attr('href'),
25360            linkId = $item.find( 'a:first' ).attr('id'),
25361            target = $item.find( 'a:first' ).attr('target');
25362            if (linkId == 'button-sale-mobile') {
25363                $('#button-sale').trigger('click');
25364            }
25365            else {
25366                if ($item.find('a:first').hasClass('scrollclass')) {
25367                    if ($('#page_3').length) {
25368                        href = '';
25369                    }
25370
25371                }
25372                if (href) {
25373                    if (target) {
25374                        window.open(href,target); 
25375                    } else {
25376                        window.location.href = href;
25377                    }
25378                }                
25379            }
25380            $('#navMobileCollapse').find('.fa-close').removeClass('fa-close').addClass('fa-bars');
25381            $('#navMobileCollapse').removeClass('active');
25382            $('#navMobile').multilevelpushmenu('collapse');
25383//                console.log('<br />Item <i>' + options + ' ' + itemName + '</i>' + ' on <i>' + title + '</i> menu level clicked!' )
25384        },        
25385    });
25386
25387    $('#navMobileCollapse').on('click', function (event) {
25388        event.preventDefault();
25389        if ($(this).hasClass('active')) {
25390            $(this).find('.fa-close').removeClass('fa-close').addClass('fa-bars');
25391            $(this).removeClass('active');
25392            $('#navMobile').multilevelpushmenu('collapse');
25393        }
25394        else {
25395            $(this).find('.fa-bars').removeClass('fa-bars').addClass('fa-close');
25396            $(this).addClass('active');
25397            $('#navMobile').multilevelpushmenu('expand');
25398        }
25399
25400    });    
25401    
25402});

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.