Inic_Productzoom - Version 1.0.0.1

Version Notes

product zoom

Download this release

Release Info

Developer indianic
Extension Inic_Productzoom
Version 1.0.0.1
Comparing to
See all releases


Version 1.0.0.1

app/code/community/Inic/Productzoom/Helper/Data.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Inic_Productzoom_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
+ }
app/code/community/Inic/Productzoom/etc/config.xml ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Inic_Productzoom>
5
+ <version>0.1.0</version>
6
+ </Inic_Productzoom>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <productzoom>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Inic_Productzoom</module>
14
+ <frontName>productzoom</frontName>
15
+ </args>
16
+ </productzoom>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <productzoom>
21
+ <file>productzoom.xml</file>
22
+ </productzoom>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <global>
27
+ <resources>
28
+ <productzoom_setup>
29
+ <setup>
30
+ <module>Inic_Productzoom</module>
31
+ </setup>
32
+ <connection>
33
+ <use>core_setup</use>
34
+ </connection>
35
+ </productzoom_setup>
36
+ <productzoom_write>
37
+ <connection>
38
+ <use>core_write</use>
39
+ </connection>
40
+ </productzoom_write>
41
+ <productzoom_read>
42
+ <connection>
43
+ <use>core_read</use>
44
+ </connection>
45
+ </productzoom_read>
46
+ </resources>
47
+ <helpers>
48
+ <productzoom>
49
+ <class>Inic_Productzoom_Helper</class>
50
+ </productzoom>
51
+ </helpers>
52
+ </global>
53
+ <adminhtml>
54
+ <acl>
55
+ <resources>
56
+ <all>
57
+ <title>Allow Everything</title>
58
+ </all>
59
+ <admin>
60
+ <children>
61
+ <system>
62
+ <children>
63
+ <config>
64
+ <children>
65
+ <productzoom>
66
+ <title>overwrite - All</title>
67
+ </productzoom>
68
+ </children>
69
+ </config>
70
+ </children>
71
+ </system>
72
+ </children>
73
+ </admin>
74
+ </resources>
75
+ </acl>
76
+ </adminhtml>
77
+ </config>
app/code/community/Inic/Productzoom/etc/system.xml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <tabname translate="label" module="productzoom">
5
+ <label>Product Zoom</label>
6
+ <sort_order>100</sort_order>
7
+ </tabname>
8
+ </tabs>
9
+ <sections>
10
+ <productzoom translate="label" module="productzoom">
11
+ <label>Product Zoom</label>
12
+ <tab>tabname</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>10</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>0</show_in_store>
18
+ <groups>
19
+ <columns translate="label">
20
+ <label>Settings</label>
21
+ <sort_order>100</sort_order>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <fields>
25
+
26
+
27
+ <zoomheight translate="label">
28
+ <label>Height</label>
29
+ <frontend_type>text</frontend_type>
30
+ <sort_order>11</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ </zoomheight>
34
+
35
+ <zoomwidth translate="label">
36
+ <label>Width</label>
37
+ <frontend_type>text</frontend_type>
38
+ <sort_order>12</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ </zoomwidth>
42
+ </fields>
43
+ </columns>
44
+ </groups>
45
+ </productzoom>
46
+ </sections>
47
+ </config>
app/design/frontend/default/default/layout/productzoom.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ </default>
5
+ <productzoom_index_index>
6
+ <reference name="content">
7
+ <block type="productzoom/productzoom" name="productzoom" template="productzoom/productzoom.phtml" />
8
+ </reference>
9
+ </productzoom_index_index>
10
+
11
+ <catalog_product_view>
12
+ <reference name="head">
13
+ <action method="addJs"><script>productzoom/jquery-1.7.2.js</script></action>
14
+ <!--for newarrivals-->
15
+ <action method="addJs"><script>productzoom/jquery.carouFredSel-2.6.0.js</script></action>
16
+ <!--product zoom-->
17
+ <action method="addJs"><script>productzoom/jquery.jqzoom-core.js</script></action>
18
+ <action method="addCss"><stylesheet>productzoom/jquery.jqzoom.css</stylesheet></action>
19
+ <action method="addCss"><stylesheet>productzoom/carosal.css</stylesheet></action>
20
+ </reference>
21
+ <reference name="product.info">
22
+ <block type="catalog/product_view_media" name="product.info.media" as="media" template="productzoom/media.phtml" />
23
+ </reference>
24
+ </catalog_product_view>
25
+ </layout>
app/design/frontend/default/default/template/productzoom/media.phtml ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category design
22
+ * @package base_default
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Product media data template
29
+ *
30
+ * @see Mage_Catalog_Block_Product_View_Media
31
+ */
32
+ if(Mage::getStoreConfig('productzoom/columns/zoomwidth'))
33
+ {
34
+ $zoomwidth=Mage::getStoreConfig('productzoom/columns/zoomwidth');
35
+ }
36
+ else
37
+ {
38
+ $zoomwidth='350';
39
+ }
40
+ if(Mage::getStoreConfig('productzoom/columns/zoomheight'))
41
+ {
42
+ $zoomheight=Mage::getStoreConfig('productzoom/columns/zoomheight');
43
+ }
44
+ else
45
+ {
46
+ $zoomheight='350';
47
+ }
48
+ ?>
49
+ <script type="text/javascript">
50
+
51
+ jQuery(window).load(function() {
52
+ //jQuery('ul#basic_config').carouFredSel();
53
+ jQuery('ul#thumblist').carouFredSel({
54
+ height: 80,
55
+ items : 4,
56
+ scroll:{duration:800},
57
+ auto: {play:false,duration:800,pauseOnHover:true},
58
+ prev: "#prev1",
59
+ next: "#next1"
60
+ });
61
+ jQuery('.jqzoom').jqzoom({
62
+ zoomType: 'standard',
63
+ lens:true,
64
+ preloadImages: false,
65
+ alwaysOn:false,
66
+ zoomWidth:<?php echo $zoomwidth; ?>,
67
+ zoomHeight:<?php echo $zoomheight; ?>
68
+ });
69
+ });
70
+ </script>
71
+ <?php
72
+ $_product = $this->getProduct();
73
+ $_helper = $this->helper('catalog/output');
74
+ ?>
75
+ <div class="clearfix" id="content" style="position:relative;" >
76
+ <div class="clearfix">
77
+ <a href="<?php echo $this->helper('catalog/image')->init($_product, 'image')?>" class="jqzoom" rel='gal1' title="<?php echo $_product->getName();?>" >
78
+ <img src="<?php echo $this->helper('catalog/image')->init($_product, 'image')->resize(350)?>" title="<?php echo $_product->getName();?>" style="border: 1px solid #666;">
79
+ </a>
80
+ </div>
81
+ <p id="mouse-hover-massage" style=" "><span style="">Rollover Mouse To Zoom</span></p>
82
+ <br/>
83
+ <?php if (count($this->getGalleryImages()) > 0): ?>
84
+ <div class="clearfix" >
85
+ <div id="wrapper">
86
+ <div id="content">
87
+ <div class="list_carousel">
88
+ <ul id="thumblist" class="clearfix" >
89
+ <?php foreach ($this->getGalleryImages() as $_image): ?>
90
+ <li>
91
+ <a class="" href='javascript:void(0);' rel="{gallery: 'gal1', smallimage: '<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $_image->getFile())->resize(350); ?>',largeimage: '<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $_image->getFile()); ?>'}">
92
+ <img src='<?php echo $this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $_image->getFile())->resize(70); ?>'>
93
+ </a>
94
+ </li>
95
+ <?php endforeach; ?>
96
+ </ul>
97
+ <div class="clearfix"></div>
98
+ <a id="prev1" href="#">&lt;</a>
99
+ <a id="next1" href="#">&gt;</a>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <?php endif; ?>
106
+ </div>
app/etc/modules/Inic_Productzoom.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Inic_Productzoom>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Inic_Productzoom>
8
+ </modules>
9
+ </config>
js/productzoom/jquery-1.7.2.js ADDED
@@ -0,0 +1,9407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery JavaScript Library v1.7.2
3
+ * http://jquery.com/
4
+ *
5
+ * Copyright 2011, John Resig
6
+ * Dual licensed under the MIT or GPL Version 2 licenses.
7
+ * http://jquery.org/license
8
+ *
9
+ * Includes Sizzle.js
10
+ * http://sizzlejs.com/
11
+ * Copyright 2011, The Dojo Foundation
12
+ * Released under the MIT, BSD, and GPL Licenses.
13
+ *
14
+ * Date: Wed Mar 21 12:46:34 2012 -0700
15
+ */
16
+ (function( window, undefined ) {
17
+
18
+ // Use the correct document accordingly with window argument (sandbox)
19
+ var document = window.document,
20
+ navigator = window.navigator,
21
+ location = window.location;
22
+ var jQuery = (function() {
23
+
24
+ // Define a local copy of jQuery
25
+ var jQuery = function( selector, context ) {
26
+ // The jQuery object is actually just the init constructor 'enhanced'
27
+ return new jQuery.fn.init( selector, context, rootjQuery );
28
+ },
29
+
30
+ // Map over jQuery in case of overwrite
31
+ _jQuery = window.jQuery,
32
+
33
+ // Map over the $ in case of overwrite
34
+ _$ = window.$,
35
+
36
+ // A central reference to the root jQuery(document)
37
+ rootjQuery,
38
+
39
+ // A simple way to check for HTML strings or ID strings
40
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
41
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
42
+
43
+ // Check if a string has a non-whitespace character in it
44
+ rnotwhite = /\S/,
45
+
46
+ // Used for trimming whitespace
47
+ trimLeft = /^\s+/,
48
+ trimRight = /\s+$/,
49
+
50
+ // Match a standalone tag
51
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
52
+
53
+ // JSON RegExp
54
+ rvalidchars = /^[\],:{}\s]*$/,
55
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
56
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
57
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
58
+
59
+ // Useragent RegExp
60
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
61
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
62
+ rmsie = /(msie) ([\w.]+)/,
63
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
64
+
65
+ // Matches dashed string for camelizing
66
+ rdashAlpha = /-([a-z]|[0-9])/ig,
67
+ rmsPrefix = /^-ms-/,
68
+
69
+ // Used by jQuery.camelCase as callback to replace()
70
+ fcamelCase = function( all, letter ) {
71
+ return ( letter + "" ).toUpperCase();
72
+ },
73
+
74
+ // Keep a UserAgent string for use with jQuery.browser
75
+ userAgent = navigator.userAgent,
76
+
77
+ // For matching the engine and version of the browser
78
+ browserMatch,
79
+
80
+ // The deferred used on DOM ready
81
+ readyList,
82
+
83
+ // The ready event handler
84
+ DOMContentLoaded,
85
+
86
+ // Save a reference to some core methods
87
+ toString = Object.prototype.toString,
88
+ hasOwn = Object.prototype.hasOwnProperty,
89
+ push = Array.prototype.push,
90
+ slice = Array.prototype.slice,
91
+ trim = String.prototype.trim,
92
+ indexOf = Array.prototype.indexOf,
93
+
94
+ // [[Class]] -> type pairs
95
+ class2type = {};
96
+
97
+ jQuery.fn = jQuery.prototype = {
98
+ constructor: jQuery,
99
+ init: function( selector, context, rootjQuery ) {
100
+ var match, elem, ret, doc;
101
+
102
+ // Handle $(""), $(null), or $(undefined)
103
+ if ( !selector ) {
104
+ return this;
105
+ }
106
+
107
+ // Handle $(DOMElement)
108
+ if ( selector.nodeType ) {
109
+ this.context = this[0] = selector;
110
+ this.length = 1;
111
+ return this;
112
+ }
113
+
114
+ // The body element only exists once, optimize finding it
115
+ if ( selector === "body" && !context && document.body ) {
116
+ this.context = document;
117
+ this[0] = document.body;
118
+ this.selector = selector;
119
+ this.length = 1;
120
+ return this;
121
+ }
122
+
123
+ // Handle HTML strings
124
+ if ( typeof selector === "string" ) {
125
+ // Are we dealing with HTML string or an ID?
126
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
127
+ // Assume that strings that start and end with <> are HTML and skip the regex check
128
+ match = [ null, selector, null ];
129
+
130
+ } else {
131
+ match = quickExpr.exec( selector );
132
+ }
133
+
134
+ // Verify a match, and that no context was specified for #id
135
+ if ( match && (match[1] || !context) ) {
136
+
137
+ // HANDLE: $(html) -> $(array)
138
+ if ( match[1] ) {
139
+ context = context instanceof jQuery ? context[0] : context;
140
+ doc = ( context ? context.ownerDocument || context : document );
141
+
142
+ // If a single string is passed in and it's a single tag
143
+ // just do a createElement and skip the rest
144
+ ret = rsingleTag.exec( selector );
145
+
146
+ if ( ret ) {
147
+ if ( jQuery.isPlainObject( context ) ) {
148
+ selector = [ document.createElement( ret[1] ) ];
149
+ jQuery.fn.attr.call( selector, context, true );
150
+
151
+ } else {
152
+ selector = [ doc.createElement( ret[1] ) ];
153
+ }
154
+
155
+ } else {
156
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
157
+ selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
158
+ }
159
+
160
+ return jQuery.merge( this, selector );
161
+
162
+ // HANDLE: $("#id")
163
+ } else {
164
+ elem = document.getElementById( match[2] );
165
+
166
+ // Check parentNode to catch when Blackberry 4.6 returns
167
+ // nodes that are no longer in the document #6963
168
+ if ( elem && elem.parentNode ) {
169
+ // Handle the case where IE and Opera return items
170
+ // by name instead of ID
171
+ if ( elem.id !== match[2] ) {
172
+ return rootjQuery.find( selector );
173
+ }
174
+
175
+ // Otherwise, we inject the element directly into the jQuery object
176
+ this.length = 1;
177
+ this[0] = elem;
178
+ }
179
+
180
+ this.context = document;
181
+ this.selector = selector;
182
+ return this;
183
+ }
184
+
185
+ // HANDLE: $(expr, $(...))
186
+ } else if ( !context || context.jquery ) {
187
+ return ( context || rootjQuery ).find( selector );
188
+
189
+ // HANDLE: $(expr, context)
190
+ // (which is just equivalent to: $(context).find(expr)
191
+ } else {
192
+ return this.constructor( context ).find( selector );
193
+ }
194
+
195
+ // HANDLE: $(function)
196
+ // Shortcut for document ready
197
+ } else if ( jQuery.isFunction( selector ) ) {
198
+ return rootjQuery.ready( selector );
199
+ }
200
+
201
+ if ( selector.selector !== undefined ) {
202
+ this.selector = selector.selector;
203
+ this.context = selector.context;
204
+ }
205
+
206
+ return jQuery.makeArray( selector, this );
207
+ },
208
+
209
+ // Start with an empty selector
210
+ selector: "",
211
+
212
+ // The current version of jQuery being used
213
+ jquery: "1.7.2",
214
+
215
+ // The default length of a jQuery object is 0
216
+ length: 0,
217
+
218
+ // The number of elements contained in the matched element set
219
+ size: function() {
220
+ return this.length;
221
+ },
222
+
223
+ toArray: function() {
224
+ return slice.call( this, 0 );
225
+ },
226
+
227
+ // Get the Nth element in the matched element set OR
228
+ // Get the whole matched element set as a clean array
229
+ get: function( num ) {
230
+ return num == null ?
231
+
232
+ // Return a 'clean' array
233
+ this.toArray() :
234
+
235
+ // Return just the object
236
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
237
+ },
238
+
239
+ // Take an array of elements and push it onto the stack
240
+ // (returning the new matched element set)
241
+ pushStack: function( elems, name, selector ) {
242
+ // Build a new jQuery matched element set
243
+ var ret = this.constructor();
244
+
245
+ if ( jQuery.isArray( elems ) ) {
246
+ push.apply( ret, elems );
247
+
248
+ } else {
249
+ jQuery.merge( ret, elems );
250
+ }
251
+
252
+ // Add the old object onto the stack (as a reference)
253
+ ret.prevObject = this;
254
+
255
+ ret.context = this.context;
256
+
257
+ if ( name === "find" ) {
258
+ ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
259
+ } else if ( name ) {
260
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
261
+ }
262
+
263
+ // Return the newly-formed element set
264
+ return ret;
265
+ },
266
+
267
+ // Execute a callback for every element in the matched set.
268
+ // (You can seed the arguments with an array of args, but this is
269
+ // only used internally.)
270
+ each: function( callback, args ) {
271
+ return jQuery.each( this, callback, args );
272
+ },
273
+
274
+ ready: function( fn ) {
275
+ // Attach the listeners
276
+ jQuery.bindReady();
277
+
278
+ // Add the callback
279
+ readyList.add( fn );
280
+
281
+ return this;
282
+ },
283
+
284
+ eq: function( i ) {
285
+ i = +i;
286
+ return i === -1 ?
287
+ this.slice( i ) :
288
+ this.slice( i, i + 1 );
289
+ },
290
+
291
+ first: function() {
292
+ return this.eq( 0 );
293
+ },
294
+
295
+ last: function() {
296
+ return this.eq( -1 );
297
+ },
298
+
299
+ slice: function() {
300
+ return this.pushStack( slice.apply( this, arguments ),
301
+ "slice", slice.call(arguments).join(",") );
302
+ },
303
+
304
+ map: function( callback ) {
305
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
306
+ return callback.call( elem, i, elem );
307
+ }));
308
+ },
309
+
310
+ end: function() {
311
+ return this.prevObject || this.constructor(null);
312
+ },
313
+
314
+ // For internal use only.
315
+ // Behaves like an Array's method, not like a jQuery method.
316
+ push: push,
317
+ sort: [].sort,
318
+ splice: [].splice
319
+ };
320
+
321
+ // Give the init function the jQuery prototype for later instantiation
322
+ jQuery.fn.init.prototype = jQuery.fn;
323
+
324
+ jQuery.extend = jQuery.fn.extend = function() {
325
+ var options, name, src, copy, copyIsArray, clone,
326
+ target = arguments[0] || {},
327
+ i = 1,
328
+ length = arguments.length,
329
+ deep = false;
330
+
331
+ // Handle a deep copy situation
332
+ if ( typeof target === "boolean" ) {
333
+ deep = target;
334
+ target = arguments[1] || {};
335
+ // skip the boolean and the target
336
+ i = 2;
337
+ }
338
+
339
+ // Handle case when target is a string or something (possible in deep copy)
340
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
341
+ target = {};
342
+ }
343
+
344
+ // extend jQuery itself if only one argument is passed
345
+ if ( length === i ) {
346
+ target = this;
347
+ --i;
348
+ }
349
+
350
+ for ( ; i < length; i++ ) {
351
+ // Only deal with non-null/undefined values
352
+ if ( (options = arguments[ i ]) != null ) {
353
+ // Extend the base object
354
+ for ( name in options ) {
355
+ src = target[ name ];
356
+ copy = options[ name ];
357
+
358
+ // Prevent never-ending loop
359
+ if ( target === copy ) {
360
+ continue;
361
+ }
362
+
363
+ // Recurse if we're merging plain objects or arrays
364
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
365
+ if ( copyIsArray ) {
366
+ copyIsArray = false;
367
+ clone = src && jQuery.isArray(src) ? src : [];
368
+
369
+ } else {
370
+ clone = src && jQuery.isPlainObject(src) ? src : {};
371
+ }
372
+
373
+ // Never move original objects, clone them
374
+ target[ name ] = jQuery.extend( deep, clone, copy );
375
+
376
+ // Don't bring in undefined values
377
+ } else if ( copy !== undefined ) {
378
+ target[ name ] = copy;
379
+ }
380
+ }
381
+ }
382
+ }
383
+
384
+ // Return the modified object
385
+ return target;
386
+ };
387
+
388
+ jQuery.extend({
389
+ noConflict: function( deep ) {
390
+ if ( window.$ === jQuery ) {
391
+ window.$ = _$;
392
+ }
393
+
394
+ if ( deep && window.jQuery === jQuery ) {
395
+ window.jQuery = _jQuery;
396
+ }
397
+
398
+ return jQuery;
399
+ },
400
+
401
+ // Is the DOM ready to be used? Set to true once it occurs.
402
+ isReady: false,
403
+
404
+ // A counter to track how many items to wait for before
405
+ // the ready event fires. See #6781
406
+ readyWait: 1,
407
+
408
+ // Hold (or release) the ready event
409
+ holdReady: function( hold ) {
410
+ if ( hold ) {
411
+ jQuery.readyWait++;
412
+ } else {
413
+ jQuery.ready( true );
414
+ }
415
+ },
416
+
417
+ // Handle when the DOM is ready
418
+ ready: function( wait ) {
419
+ // Either a released hold or an DOMready/load event and not yet ready
420
+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
421
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
422
+ if ( !document.body ) {
423
+ return setTimeout( jQuery.ready, 1 );
424
+ }
425
+
426
+ // Remember that the DOM is ready
427
+ jQuery.isReady = true;
428
+
429
+ // If a normal DOM Ready event fired, decrement, and wait if need be
430
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
431
+ return;
432
+ }
433
+
434
+ // If there are functions bound, to execute
435
+ readyList.fireWith( document, [ jQuery ] );
436
+
437
+ // Trigger any bound ready events
438
+ if ( jQuery.fn.trigger ) {
439
+ jQuery( document ).trigger( "ready" ).off( "ready" );
440
+ }
441
+ }
442
+ },
443
+
444
+ bindReady: function() {
445
+ if ( readyList ) {
446
+ return;
447
+ }
448
+
449
+ readyList = jQuery.Callbacks( "once memory" );
450
+
451
+ // Catch cases where $(document).ready() is called after the
452
+ // browser event has already occurred.
453
+ if ( document.readyState === "complete" ) {
454
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
455
+ return setTimeout( jQuery.ready, 1 );
456
+ }
457
+
458
+ // Mozilla, Opera and webkit nightlies currently support this event
459
+ if ( document.addEventListener ) {
460
+ // Use the handy event callback
461
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
462
+
463
+ // A fallback to window.onload, that will always work
464
+ window.addEventListener( "load", jQuery.ready, false );
465
+
466
+ // If IE event model is used
467
+ } else if ( document.attachEvent ) {
468
+ // ensure firing before onload,
469
+ // maybe late but safe also for iframes
470
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
471
+
472
+ // A fallback to window.onload, that will always work
473
+ window.attachEvent( "onload", jQuery.ready );
474
+
475
+ // If IE and not a frame
476
+ // continually check to see if the document is ready
477
+ var toplevel = false;
478
+
479
+ try {
480
+ toplevel = window.frameElement == null;
481
+ } catch(e) {}
482
+
483
+ if ( document.documentElement.doScroll && toplevel ) {
484
+ doScrollCheck();
485
+ }
486
+ }
487
+ },
488
+
489
+ // See test/unit/core.js for details concerning isFunction.
490
+ // Since version 1.3, DOM methods and functions like alert
491
+ // aren't supported. They return false on IE (#2968).
492
+ isFunction: function( obj ) {
493
+ return jQuery.type(obj) === "function";
494
+ },
495
+
496
+ isArray: Array.isArray || function( obj ) {
497
+ return jQuery.type(obj) === "array";
498
+ },
499
+
500
+ isWindow: function( obj ) {
501
+ return obj != null && obj == obj.window;
502
+ },
503
+
504
+ isNumeric: function( obj ) {
505
+ return !isNaN( parseFloat(obj) ) && isFinite( obj );
506
+ },
507
+
508
+ type: function( obj ) {
509
+ return obj == null ?
510
+ String( obj ) :
511
+ class2type[ toString.call(obj) ] || "object";
512
+ },
513
+
514
+ isPlainObject: function( obj ) {
515
+ // Must be an Object.
516
+ // Because of IE, we also have to check the presence of the constructor property.
517
+ // Make sure that DOM nodes and window objects don't pass through, as well
518
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
519
+ return false;
520
+ }
521
+
522
+ try {
523
+ // Not own constructor property must be Object
524
+ if ( obj.constructor &&
525
+ !hasOwn.call(obj, "constructor") &&
526
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
527
+ return false;
528
+ }
529
+ } catch ( e ) {
530
+ // IE8,9 Will throw exceptions on certain host objects #9897
531
+ return false;
532
+ }
533
+
534
+ // Own properties are enumerated firstly, so to speed up,
535
+ // if last one is own, then all properties are own.
536
+
537
+ var key;
538
+ for ( key in obj ) {}
539
+
540
+ return key === undefined || hasOwn.call( obj, key );
541
+ },
542
+
543
+ isEmptyObject: function( obj ) {
544
+ for ( var name in obj ) {
545
+ return false;
546
+ }
547
+ return true;
548
+ },
549
+
550
+ error: function( msg ) {
551
+ throw new Error( msg );
552
+ },
553
+
554
+ parseJSON: function( data ) {
555
+ if ( typeof data !== "string" || !data ) {
556
+ return null;
557
+ }
558
+
559
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
560
+ data = jQuery.trim( data );
561
+
562
+ // Attempt to parse using the native JSON parser first
563
+ if ( window.JSON && window.JSON.parse ) {
564
+ return window.JSON.parse( data );
565
+ }
566
+
567
+ // Make sure the incoming data is actual JSON
568
+ // Logic borrowed from http://json.org/json2.js
569
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
570
+ .replace( rvalidtokens, "]" )
571
+ .replace( rvalidbraces, "")) ) {
572
+
573
+ return ( new Function( "return " + data ) )();
574
+
575
+ }
576
+ jQuery.error( "Invalid JSON: " + data );
577
+ },
578
+
579
+ // Cross-browser xml parsing
580
+ parseXML: function( data ) {
581
+ if ( typeof data !== "string" || !data ) {
582
+ return null;
583
+ }
584
+ var xml, tmp;
585
+ try {
586
+ if ( window.DOMParser ) { // Standard
587
+ tmp = new DOMParser();
588
+ xml = tmp.parseFromString( data , "text/xml" );
589
+ } else { // IE
590
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
591
+ xml.async = "false";
592
+ xml.loadXML( data );
593
+ }
594
+ } catch( e ) {
595
+ xml = undefined;
596
+ }
597
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
598
+ jQuery.error( "Invalid XML: " + data );
599
+ }
600
+ return xml;
601
+ },
602
+
603
+ noop: function() {},
604
+
605
+ // Evaluates a script in a global context
606
+ // Workarounds based on findings by Jim Driscoll
607
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
608
+ globalEval: function( data ) {
609
+ if ( data && rnotwhite.test( data ) ) {
610
+ // We use execScript on Internet Explorer
611
+ // We use an anonymous function so that context is window
612
+ // rather than jQuery in Firefox
613
+ ( window.execScript || function( data ) {
614
+ window[ "eval" ].call( window, data );
615
+ } )( data );
616
+ }
617
+ },
618
+
619
+ // Convert dashed to camelCase; used by the css and data modules
620
+ // Microsoft forgot to hump their vendor prefix (#9572)
621
+ camelCase: function( string ) {
622
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
623
+ },
624
+
625
+ nodeName: function( elem, name ) {
626
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
627
+ },
628
+
629
+ // args is for internal usage only
630
+ each: function( object, callback, args ) {
631
+ var name, i = 0,
632
+ length = object.length,
633
+ isObj = length === undefined || jQuery.isFunction( object );
634
+
635
+ if ( args ) {
636
+ if ( isObj ) {
637
+ for ( name in object ) {
638
+ if ( callback.apply( object[ name ], args ) === false ) {
639
+ break;
640
+ }
641
+ }
642
+ } else {
643
+ for ( ; i < length; ) {
644
+ if ( callback.apply( object[ i++ ], args ) === false ) {
645
+ break;
646
+ }
647
+ }
648
+ }
649
+
650
+ // A special, fast, case for the most common use of each
651
+ } else {
652
+ if ( isObj ) {
653
+ for ( name in object ) {
654
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
655
+ break;
656
+ }
657
+ }
658
+ } else {
659
+ for ( ; i < length; ) {
660
+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
661
+ break;
662
+ }
663
+ }
664
+ }
665
+ }
666
+
667
+ return object;
668
+ },
669
+
670
+ // Use native String.trim function wherever possible
671
+ trim: trim ?
672
+ function( text ) {
673
+ return text == null ?
674
+ "" :
675
+ trim.call( text );
676
+ } :
677
+
678
+ // Otherwise use our own trimming functionality
679
+ function( text ) {
680
+ return text == null ?
681
+ "" :
682
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
683
+ },
684
+
685
+ // results is for internal usage only
686
+ makeArray: function( array, results ) {
687
+ var ret = results || [];
688
+
689
+ if ( array != null ) {
690
+ // The window, strings (and functions) also have 'length'
691
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
692
+ var type = jQuery.type( array );
693
+
694
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
695
+ push.call( ret, array );
696
+ } else {
697
+ jQuery.merge( ret, array );
698
+ }
699
+ }
700
+
701
+ return ret;
702
+ },
703
+
704
+ inArray: function( elem, array, i ) {
705
+ var len;
706
+
707
+ if ( array ) {
708
+ if ( indexOf ) {
709
+ return indexOf.call( array, elem, i );
710
+ }
711
+
712
+ len = array.length;
713
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
714
+
715
+ for ( ; i < len; i++ ) {
716
+ // Skip accessing in sparse arrays
717
+ if ( i in array && array[ i ] === elem ) {
718
+ return i;
719
+ }
720
+ }
721
+ }
722
+
723
+ return -1;
724
+ },
725
+
726
+ merge: function( first, second ) {
727
+ var i = first.length,
728
+ j = 0;
729
+
730
+ if ( typeof second.length === "number" ) {
731
+ for ( var l = second.length; j < l; j++ ) {
732
+ first[ i++ ] = second[ j ];
733
+ }
734
+
735
+ } else {
736
+ while ( second[j] !== undefined ) {
737
+ first[ i++ ] = second[ j++ ];
738
+ }
739
+ }
740
+
741
+ first.length = i;
742
+
743
+ return first;
744
+ },
745
+
746
+ grep: function( elems, callback, inv ) {
747
+ var ret = [], retVal;
748
+ inv = !!inv;
749
+
750
+ // Go through the array, only saving the items
751
+ // that pass the validator function
752
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
753
+ retVal = !!callback( elems[ i ], i );
754
+ if ( inv !== retVal ) {
755
+ ret.push( elems[ i ] );
756
+ }
757
+ }
758
+
759
+ return ret;
760
+ },
761
+
762
+ // arg is for internal usage only
763
+ map: function( elems, callback, arg ) {
764
+ var value, key, ret = [],
765
+ i = 0,
766
+ length = elems.length,
767
+ // jquery objects are treated as arrays
768
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
769
+
770
+ // Go through the array, translating each of the items to their
771
+ if ( isArray ) {
772
+ for ( ; i < length; i++ ) {
773
+ value = callback( elems[ i ], i, arg );
774
+
775
+ if ( value != null ) {
776
+ ret[ ret.length ] = value;
777
+ }
778
+ }
779
+
780
+ // Go through every key on the object,
781
+ } else {
782
+ for ( key in elems ) {
783
+ value = callback( elems[ key ], key, arg );
784
+
785
+ if ( value != null ) {
786
+ ret[ ret.length ] = value;
787
+ }
788
+ }
789
+ }
790
+
791
+ // Flatten any nested arrays
792
+ return ret.concat.apply( [], ret );
793
+ },
794
+
795
+ // A global GUID counter for objects
796
+ guid: 1,
797
+
798
+ // Bind a function to a context, optionally partially applying any
799
+ // arguments.
800
+ proxy: function( fn, context ) {
801
+ if ( typeof context === "string" ) {
802
+ var tmp = fn[ context ];
803
+ context = fn;
804
+ fn = tmp;
805
+ }
806
+
807
+ // Quick check to determine if target is callable, in the spec
808
+ // this throws a TypeError, but we will just return undefined.
809
+ if ( !jQuery.isFunction( fn ) ) {
810
+ return undefined;
811
+ }
812
+
813
+ // Simulated bind
814
+ var args = slice.call( arguments, 2 ),
815
+ proxy = function() {
816
+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
817
+ };
818
+
819
+ // Set the guid of unique handler to the same of original handler, so it can be removed
820
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
821
+
822
+ return proxy;
823
+ },
824
+
825
+ // Mutifunctional method to get and set values to a collection
826
+ // The value/s can optionally be executed if it's a function
827
+ access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
828
+ var exec,
829
+ bulk = key == null,
830
+ i = 0,
831
+ length = elems.length;
832
+
833
+ // Sets many values
834
+ if ( key && typeof key === "object" ) {
835
+ for ( i in key ) {
836
+ jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
837
+ }
838
+ chainable = 1;
839
+
840
+ // Sets one value
841
+ } else if ( value !== undefined ) {
842
+ // Optionally, function values get executed if exec is true
843
+ exec = pass === undefined && jQuery.isFunction( value );
844
+
845
+ if ( bulk ) {
846
+ // Bulk operations only iterate when executing function values
847
+ if ( exec ) {
848
+ exec = fn;
849
+ fn = function( elem, key, value ) {
850
+ return exec.call( jQuery( elem ), value );
851
+ };
852
+
853
+ // Otherwise they run against the entire set
854
+ } else {
855
+ fn.call( elems, value );
856
+ fn = null;
857
+ }
858
+ }
859
+
860
+ if ( fn ) {
861
+ for (; i < length; i++ ) {
862
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
863
+ }
864
+ }
865
+
866
+ chainable = 1;
867
+ }
868
+
869
+ return chainable ?
870
+ elems :
871
+
872
+ // Gets
873
+ bulk ?
874
+ fn.call( elems ) :
875
+ length ? fn( elems[0], key ) : emptyGet;
876
+ },
877
+
878
+ now: function() {
879
+ return ( new Date() ).getTime();
880
+ },
881
+
882
+ // Use of jQuery.browser is frowned upon.
883
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
884
+ uaMatch: function( ua ) {
885
+ ua = ua.toLowerCase();
886
+
887
+ var match = rwebkit.exec( ua ) ||
888
+ ropera.exec( ua ) ||
889
+ rmsie.exec( ua ) ||
890
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
891
+ [];
892
+
893
+ return { browser: match[1] || "", version: match[2] || "0" };
894
+ },
895
+
896
+ sub: function() {
897
+ function jQuerySub( selector, context ) {
898
+ return new jQuerySub.fn.init( selector, context );
899
+ }
900
+ jQuery.extend( true, jQuerySub, this );
901
+ jQuerySub.superclass = this;
902
+ jQuerySub.fn = jQuerySub.prototype = this();
903
+ jQuerySub.fn.constructor = jQuerySub;
904
+ jQuerySub.sub = this.sub;
905
+ jQuerySub.fn.init = function init( selector, context ) {
906
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
907
+ context = jQuerySub( context );
908
+ }
909
+
910
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
911
+ };
912
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
913
+ var rootjQuerySub = jQuerySub(document);
914
+ return jQuerySub;
915
+ },
916
+
917
+ browser: {}
918
+ });
919
+
920
+ // Populate the class2type map
921
+ jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
922
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
923
+ });
924
+
925
+ browserMatch = jQuery.uaMatch( userAgent );
926
+ if ( browserMatch.browser ) {
927
+ jQuery.browser[ browserMatch.browser ] = true;
928
+ jQuery.browser.version = browserMatch.version;
929
+ }
930
+
931
+ // Deprecated, use jQuery.browser.webkit instead
932
+ if ( jQuery.browser.webkit ) {
933
+ jQuery.browser.safari = true;
934
+ }
935
+
936
+ // IE doesn't match non-breaking spaces with \s
937
+ if ( rnotwhite.test( "\xA0" ) ) {
938
+ trimLeft = /^[\s\xA0]+/;
939
+ trimRight = /[\s\xA0]+$/;
940
+ }
941
+
942
+ // All jQuery objects should point back to these
943
+ rootjQuery = jQuery(document);
944
+
945
+ // Cleanup functions for the document ready method
946
+ if ( document.addEventListener ) {
947
+ DOMContentLoaded = function() {
948
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
949
+ jQuery.ready();
950
+ };
951
+
952
+ } else if ( document.attachEvent ) {
953
+ DOMContentLoaded = function() {
954
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
955
+ if ( document.readyState === "complete" ) {
956
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
957
+ jQuery.ready();
958
+ }
959
+ };
960
+ }
961
+
962
+ // The DOM ready check for Internet Explorer
963
+ function doScrollCheck() {
964
+ if ( jQuery.isReady ) {
965
+ return;
966
+ }
967
+
968
+ try {
969
+ // If IE is used, use the trick by Diego Perini
970
+ // http://javascript.nwbox.com/IEContentLoaded/
971
+ document.documentElement.doScroll("left");
972
+ } catch(e) {
973
+ setTimeout( doScrollCheck, 1 );
974
+ return;
975
+ }
976
+
977
+ // and execute any waiting functions
978
+ jQuery.ready();
979
+ }
980
+
981
+ return jQuery;
982
+
983
+ })();
984
+
985
+
986
+ // String to Object flags format cache
987
+ var flagsCache = {};
988
+
989
+ // Convert String-formatted flags into Object-formatted ones and store in cache
990
+ function createFlags( flags ) {
991
+ var object = flagsCache[ flags ] = {},
992
+ i, length;
993
+ flags = flags.split( /\s+/ );
994
+ for ( i = 0, length = flags.length; i < length; i++ ) {
995
+ object[ flags[i] ] = true;
996
+ }
997
+ return object;
998
+ }
999
+
1000
+ /*
1001
+ * Create a callback list using the following parameters:
1002
+ *
1003
+ * flags: an optional list of space-separated flags that will change how
1004
+ * the callback list behaves
1005
+ *
1006
+ * By default a callback list will act like an event callback list and can be
1007
+ * "fired" multiple times.
1008
+ *
1009
+ * Possible flags:
1010
+ *
1011
+ * once: will ensure the callback list can only be fired once (like a Deferred)
1012
+ *
1013
+ * memory: will keep track of previous values and will call any callback added
1014
+ * after the list has been fired right away with the latest "memorized"
1015
+ * values (like a Deferred)
1016
+ *
1017
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
1018
+ *
1019
+ * stopOnFalse: interrupt callings when a callback returns false
1020
+ *
1021
+ */
1022
+ jQuery.Callbacks = function( flags ) {
1023
+
1024
+ // Convert flags from String-formatted to Object-formatted
1025
+ // (we check in cache first)
1026
+ flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
1027
+
1028
+ var // Actual callback list
1029
+ list = [],
1030
+ // Stack of fire calls for repeatable lists
1031
+ stack = [],
1032
+ // Last fire value (for non-forgettable lists)
1033
+ memory,
1034
+ // Flag to know if list was already fired
1035
+ fired,
1036
+ // Flag to know if list is currently firing
1037
+ firing,
1038
+ // First callback to fire (used internally by add and fireWith)
1039
+ firingStart,
1040
+ // End of the loop when firing
1041
+ firingLength,
1042
+ // Index of currently firing callback (modified by remove if needed)
1043
+ firingIndex,
1044
+ // Add one or several callbacks to the list
1045
+ add = function( args ) {
1046
+ var i,
1047
+ length,
1048
+ elem,
1049
+ type,
1050
+ actual;
1051
+ for ( i = 0, length = args.length; i < length; i++ ) {
1052
+ elem = args[ i ];
1053
+ type = jQuery.type( elem );
1054
+ if ( type === "array" ) {
1055
+ // Inspect recursively
1056
+ add( elem );
1057
+ } else if ( type === "function" ) {
1058
+ // Add if not in unique mode and callback is not in
1059
+ if ( !flags.unique || !self.has( elem ) ) {
1060
+ list.push( elem );
1061
+ }
1062
+ }
1063
+ }
1064
+ },
1065
+ // Fire callbacks
1066
+ fire = function( context, args ) {
1067
+ args = args || [];
1068
+ memory = !flags.memory || [ context, args ];
1069
+ fired = true;
1070
+ firing = true;
1071
+ firingIndex = firingStart || 0;
1072
+ firingStart = 0;
1073
+ firingLength = list.length;
1074
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1075
+ if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1076
+ memory = true; // Mark as halted
1077
+ break;
1078
+ }
1079
+ }
1080
+ firing = false;
1081
+ if ( list ) {
1082
+ if ( !flags.once ) {
1083
+ if ( stack && stack.length ) {
1084
+ memory = stack.shift();
1085
+ self.fireWith( memory[ 0 ], memory[ 1 ] );
1086
+ }
1087
+ } else if ( memory === true ) {
1088
+ self.disable();
1089
+ } else {
1090
+ list = [];
1091
+ }
1092
+ }
1093
+ },
1094
+ // Actual Callbacks object
1095
+ self = {
1096
+ // Add a callback or a collection of callbacks to the list
1097
+ add: function() {
1098
+ if ( list ) {
1099
+ var length = list.length;
1100
+ add( arguments );
1101
+ // Do we need to add the callbacks to the
1102
+ // current firing batch?
1103
+ if ( firing ) {
1104
+ firingLength = list.length;
1105
+ // With memory, if we're not firing then
1106
+ // we should call right away, unless previous
1107
+ // firing was halted (stopOnFalse)
1108
+ } else if ( memory && memory !== true ) {
1109
+ firingStart = length;
1110
+ fire( memory[ 0 ], memory[ 1 ] );
1111
+ }
1112
+ }
1113
+ return this;
1114
+ },
1115
+ // Remove a callback from the list
1116
+ remove: function() {
1117
+ if ( list ) {
1118
+ var args = arguments,
1119
+ argIndex = 0,
1120
+ argLength = args.length;
1121
+ for ( ; argIndex < argLength ; argIndex++ ) {
1122
+ for ( var i = 0; i < list.length; i++ ) {
1123
+ if ( args[ argIndex ] === list[ i ] ) {
1124
+ // Handle firingIndex and firingLength
1125
+ if ( firing ) {
1126
+ if ( i <= firingLength ) {
1127
+ firingLength--;
1128
+ if ( i <= firingIndex ) {
1129
+ firingIndex--;
1130
+ }
1131
+ }
1132
+ }
1133
+ // Remove the element
1134
+ list.splice( i--, 1 );
1135
+ // If we have some unicity property then
1136
+ // we only need to do this once
1137
+ if ( flags.unique ) {
1138
+ break;
1139
+ }
1140
+ }
1141
+ }
1142
+ }
1143
+ }
1144
+ return this;
1145
+ },
1146
+ // Control if a given callback is in the list
1147
+ has: function( fn ) {
1148
+ if ( list ) {
1149
+ var i = 0,
1150
+ length = list.length;
1151
+ for ( ; i < length; i++ ) {
1152
+ if ( fn === list[ i ] ) {
1153
+ return true;
1154
+ }
1155
+ }
1156
+ }
1157
+ return false;
1158
+ },
1159
+ // Remove all callbacks from the list
1160
+ empty: function() {
1161
+ list = [];
1162
+ return this;
1163
+ },
1164
+ // Have the list do nothing anymore
1165
+ disable: function() {
1166
+ list = stack = memory = undefined;
1167
+ return this;
1168
+ },
1169
+ // Is it disabled?
1170
+ disabled: function() {
1171
+ return !list;
1172
+ },
1173
+ // Lock the list in its current state
1174
+ lock: function() {
1175
+ stack = undefined;
1176
+ if ( !memory || memory === true ) {
1177
+ self.disable();
1178
+ }
1179
+ return this;
1180
+ },
1181
+ // Is it locked?
1182
+ locked: function() {
1183
+ return !stack;
1184
+ },
1185
+ // Call all callbacks with the given context and arguments
1186
+ fireWith: function( context, args ) {
1187
+ if ( stack ) {
1188
+ if ( firing ) {
1189
+ if ( !flags.once ) {
1190
+ stack.push( [ context, args ] );
1191
+ }
1192
+ } else if ( !( flags.once && memory ) ) {
1193
+ fire( context, args );
1194
+ }
1195
+ }
1196
+ return this;
1197
+ },
1198
+ // Call all the callbacks with the given arguments
1199
+ fire: function() {
1200
+ self.fireWith( this, arguments );
1201
+ return this;
1202
+ },
1203
+ // To know if the callbacks have already been called at least once
1204
+ fired: function() {
1205
+ return !!fired;
1206
+ }
1207
+ };
1208
+
1209
+ return self;
1210
+ };
1211
+
1212
+
1213
+
1214
+
1215
+ var // Static reference to slice
1216
+ sliceDeferred = [].slice;
1217
+
1218
+ jQuery.extend({
1219
+
1220
+ Deferred: function( func ) {
1221
+ var doneList = jQuery.Callbacks( "once memory" ),
1222
+ failList = jQuery.Callbacks( "once memory" ),
1223
+ progressList = jQuery.Callbacks( "memory" ),
1224
+ state = "pending",
1225
+ lists = {
1226
+ resolve: doneList,
1227
+ reject: failList,
1228
+ notify: progressList
1229
+ },
1230
+ promise = {
1231
+ done: doneList.add,
1232
+ fail: failList.add,
1233
+ progress: progressList.add,
1234
+
1235
+ state: function() {
1236
+ return state;
1237
+ },
1238
+
1239
+ // Deprecated
1240
+ isResolved: doneList.fired,
1241
+ isRejected: failList.fired,
1242
+
1243
+ then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1244
+ deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1245
+ return this;
1246
+ },
1247
+ always: function() {
1248
+ deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1249
+ return this;
1250
+ },
1251
+ pipe: function( fnDone, fnFail, fnProgress ) {
1252
+ return jQuery.Deferred(function( newDefer ) {
1253
+ jQuery.each( {
1254
+ done: [ fnDone, "resolve" ],
1255
+ fail: [ fnFail, "reject" ],
1256
+ progress: [ fnProgress, "notify" ]
1257
+ }, function( handler, data ) {
1258
+ var fn = data[ 0 ],
1259
+ action = data[ 1 ],
1260
+ returned;
1261
+ if ( jQuery.isFunction( fn ) ) {
1262
+ deferred[ handler ](function() {
1263
+ returned = fn.apply( this, arguments );
1264
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
1265
+ returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1266
+ } else {
1267
+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1268
+ }
1269
+ });
1270
+ } else {
1271
+ deferred[ handler ]( newDefer[ action ] );
1272
+ }
1273
+ });
1274
+ }).promise();
1275
+ },
1276
+ // Get a promise for this deferred
1277
+ // If obj is provided, the promise aspect is added to the object
1278
+ promise: function( obj ) {
1279
+ if ( obj == null ) {
1280
+ obj = promise;
1281
+ } else {
1282
+ for ( var key in promise ) {
1283
+ obj[ key ] = promise[ key ];
1284
+ }
1285
+ }
1286
+ return obj;
1287
+ }
1288
+ },
1289
+ deferred = promise.promise({}),
1290
+ key;
1291
+
1292
+ for ( key in lists ) {
1293
+ deferred[ key ] = lists[ key ].fire;
1294
+ deferred[ key + "With" ] = lists[ key ].fireWith;
1295
+ }
1296
+
1297
+ // Handle state
1298
+ deferred.done( function() {
1299
+ state = "resolved";
1300
+ }, failList.disable, progressList.lock ).fail( function() {
1301
+ state = "rejected";
1302
+ }, doneList.disable, progressList.lock );
1303
+
1304
+ // Call given func if any
1305
+ if ( func ) {
1306
+ func.call( deferred, deferred );
1307
+ }
1308
+
1309
+ // All done!
1310
+ return deferred;
1311
+ },
1312
+
1313
+ // Deferred helper
1314
+ when: function( firstParam ) {
1315
+ var args = sliceDeferred.call( arguments, 0 ),
1316
+ i = 0,
1317
+ length = args.length,
1318
+ pValues = new Array( length ),
1319
+ count = length,
1320
+ pCount = length,
1321
+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1322
+ firstParam :
1323
+ jQuery.Deferred(),
1324
+ promise = deferred.promise();
1325
+ function resolveFunc( i ) {
1326
+ return function( value ) {
1327
+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1328
+ if ( !( --count ) ) {
1329
+ deferred.resolveWith( deferred, args );
1330
+ }
1331
+ };
1332
+ }
1333
+ function progressFunc( i ) {
1334
+ return function( value ) {
1335
+ pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1336
+ deferred.notifyWith( promise, pValues );
1337
+ };
1338
+ }
1339
+ if ( length > 1 ) {
1340
+ for ( ; i < length; i++ ) {
1341
+ if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1342
+ args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1343
+ } else {
1344
+ --count;
1345
+ }
1346
+ }
1347
+ if ( !count ) {
1348
+ deferred.resolveWith( deferred, args );
1349
+ }
1350
+ } else if ( deferred !== firstParam ) {
1351
+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1352
+ }
1353
+ return promise;
1354
+ }
1355
+ });
1356
+
1357
+
1358
+
1359
+
1360
+ jQuery.support = (function() {
1361
+
1362
+ var support,
1363
+ all,
1364
+ a,
1365
+ select,
1366
+ opt,
1367
+ input,
1368
+ fragment,
1369
+ tds,
1370
+ events,
1371
+ eventName,
1372
+ i,
1373
+ isSupported,
1374
+ div = document.createElement( "div" ),
1375
+ documentElement = document.documentElement;
1376
+
1377
+ // Preliminary tests
1378
+ div.setAttribute("className", "t");
1379
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1380
+
1381
+ all = div.getElementsByTagName( "*" );
1382
+ a = div.getElementsByTagName( "a" )[ 0 ];
1383
+
1384
+ // Can't get basic test support
1385
+ if ( !all || !all.length || !a ) {
1386
+ return {};
1387
+ }
1388
+
1389
+ // First batch of supports tests
1390
+ select = document.createElement( "select" );
1391
+ opt = select.appendChild( document.createElement("option") );
1392
+ input = div.getElementsByTagName( "input" )[ 0 ];
1393
+
1394
+ support = {
1395
+ // IE strips leading whitespace when .innerHTML is used
1396
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1397
+
1398
+ // Make sure that tbody elements aren't automatically inserted
1399
+ // IE will insert them into empty tables
1400
+ tbody: !div.getElementsByTagName("tbody").length,
1401
+
1402
+ // Make sure that link elements get serialized correctly by innerHTML
1403
+ // This requires a wrapper element in IE
1404
+ htmlSerialize: !!div.getElementsByTagName("link").length,
1405
+
1406
+ // Get the style information from getAttribute
1407
+ // (IE uses .cssText instead)
1408
+ style: /top/.test( a.getAttribute("style") ),
1409
+
1410
+ // Make sure that URLs aren't manipulated
1411
+ // (IE normalizes it by default)
1412
+ hrefNormalized: ( a.getAttribute("href") === "/a" ),
1413
+
1414
+ // Make sure that element opacity exists
1415
+ // (IE uses filter instead)
1416
+ // Use a regex to work around a WebKit issue. See #5145
1417
+ opacity: /^0.55/.test( a.style.opacity ),
1418
+
1419
+ // Verify style float existence
1420
+ // (IE uses styleFloat instead of cssFloat)
1421
+ cssFloat: !!a.style.cssFloat,
1422
+
1423
+ // Make sure that if no value is specified for a checkbox
1424
+ // that it defaults to "on".
1425
+ // (WebKit defaults to "" instead)
1426
+ checkOn: ( input.value === "on" ),
1427
+
1428
+ // Make sure that a selected-by-default option has a working selected property.
1429
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1430
+ optSelected: opt.selected,
1431
+
1432
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1433
+ getSetAttribute: div.className !== "t",
1434
+
1435
+ // Tests for enctype support on a form(#6743)
1436
+ enctype: !!document.createElement("form").enctype,
1437
+
1438
+ // Makes sure cloning an html5 element does not cause problems
1439
+ // Where outerHTML is undefined, this still works
1440
+ html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1441
+
1442
+ // Will be defined later
1443
+ submitBubbles: true,
1444
+ changeBubbles: true,
1445
+ focusinBubbles: false,
1446
+ deleteExpando: true,
1447
+ noCloneEvent: true,
1448
+ inlineBlockNeedsLayout: false,
1449
+ shrinkWrapBlocks: false,
1450
+ reliableMarginRight: true,
1451
+ pixelMargin: true
1452
+ };
1453
+
1454
+ // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead
1455
+ jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");
1456
+
1457
+ // Make sure checked status is properly cloned
1458
+ input.checked = true;
1459
+ support.noCloneChecked = input.cloneNode( true ).checked;
1460
+
1461
+ // Make sure that the options inside disabled selects aren't marked as disabled
1462
+ // (WebKit marks them as disabled)
1463
+ select.disabled = true;
1464
+ support.optDisabled = !opt.disabled;
1465
+
1466
+ // Test to see if it's possible to delete an expando from an element
1467
+ // Fails in Internet Explorer
1468
+ try {
1469
+ delete div.test;
1470
+ } catch( e ) {
1471
+ support.deleteExpando = false;
1472
+ }
1473
+
1474
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1475
+ div.attachEvent( "onclick", function() {
1476
+ // Cloning a node shouldn't copy over any
1477
+ // bound event handlers (IE does this)
1478
+ support.noCloneEvent = false;
1479
+ });
1480
+ div.cloneNode( true ).fireEvent( "onclick" );
1481
+ }
1482
+
1483
+ // Check if a radio maintains its value
1484
+ // after being appended to the DOM
1485
+ input = document.createElement("input");
1486
+ input.value = "t";
1487
+ input.setAttribute("type", "radio");
1488
+ support.radioValue = input.value === "t";
1489
+
1490
+ input.setAttribute("checked", "checked");
1491
+
1492
+ // #11217 - WebKit loses check when the name is after the checked attribute
1493
+ input.setAttribute( "name", "t" );
1494
+
1495
+ div.appendChild( input );
1496
+ fragment = document.createDocumentFragment();
1497
+ fragment.appendChild( div.lastChild );
1498
+
1499
+ // WebKit doesn't clone checked state correctly in fragments
1500
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1501
+
1502
+ // Check if a disconnected checkbox will retain its checked
1503
+ // value of true after appended to the DOM (IE6/7)
1504
+ support.appendChecked = input.checked;
1505
+
1506
+ fragment.removeChild( input );
1507
+ fragment.appendChild( div );
1508
+
1509
+ // Technique from Juriy Zaytsev
1510
+ // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
1511
+ // We only care about the case where non-standard event systems
1512
+ // are used, namely in IE. Short-circuiting here helps us to
1513
+ // avoid an eval call (in setAttribute) which can cause CSP
1514
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1515
+ if ( div.attachEvent ) {
1516
+ for ( i in {
1517
+ submit: 1,
1518
+ change: 1,
1519
+ focusin: 1
1520
+ }) {
1521
+ eventName = "on" + i;
1522
+ isSupported = ( eventName in div );
1523
+ if ( !isSupported ) {
1524
+ div.setAttribute( eventName, "return;" );
1525
+ isSupported = ( typeof div[ eventName ] === "function" );
1526
+ }
1527
+ support[ i + "Bubbles" ] = isSupported;
1528
+ }
1529
+ }
1530
+
1531
+ fragment.removeChild( div );
1532
+
1533
+ // Null elements to avoid leaks in IE
1534
+ fragment = select = opt = div = input = null;
1535
+
1536
+ // Run tests that need a body at doc ready
1537
+ jQuery(function() {
1538
+ var container, outer, inner, table, td, offsetSupport,
1539
+ marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,
1540
+ paddingMarginBorderVisibility, paddingMarginBorder,
1541
+ body = document.getElementsByTagName("body")[0];
1542
+
1543
+ if ( !body ) {
1544
+ // Return for frameset docs that don't have a body
1545
+ return;
1546
+ }
1547
+
1548
+ conMarginTop = 1;
1549
+ paddingMarginBorder = "padding:0;margin:0;border:";
1550
+ positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";
1551
+ paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";
1552
+ style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";
1553
+ html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" +
1554
+ "<table " + style + "' cellpadding='0' cellspacing='0'>" +
1555
+ "<tr><td></td></tr></table>";
1556
+
1557
+ container = document.createElement("div");
1558
+ container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1559
+ body.insertBefore( container, body.firstChild );
1560
+
1561
+ // Construct the test element
1562
+ div = document.createElement("div");
1563
+ container.appendChild( div );
1564
+
1565
+ // Check if table cells still have offsetWidth/Height when they are set
1566
+ // to display:none and there are still other visible table cells in a
1567
+ // table row; if so, offsetWidth/Height are not reliable for use when
1568
+ // determining if an element has been hidden directly using
1569
+ // display:none (it is still safe to use offsets if a parent element is
1570
+ // hidden; don safety goggles and see bug #4512 for more information).
1571
+ // (only IE 8 fails this test)
1572
+ div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";
1573
+ tds = div.getElementsByTagName( "td" );
1574
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
1575
+
1576
+ tds[ 0 ].style.display = "";
1577
+ tds[ 1 ].style.display = "none";
1578
+
1579
+ // Check if empty table cells still have offsetWidth/Height
1580
+ // (IE <= 8 fail this test)
1581
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1582
+
1583
+ // Check if div with explicit width and no margin-right incorrectly
1584
+ // gets computed margin-right based on width of container. For more
1585
+ // info see bug #3333
1586
+ // Fails in WebKit before Feb 2011 nightlies
1587
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1588
+ if ( window.getComputedStyle ) {
1589
+ div.innerHTML = "";
1590
+ marginDiv = document.createElement( "div" );
1591
+ marginDiv.style.width = "0";
1592
+ marginDiv.style.marginRight = "0";
1593
+ div.style.width = "2px";
1594
+ div.appendChild( marginDiv );
1595
+ support.reliableMarginRight =
1596
+ ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1597
+ }
1598
+
1599
+ if ( typeof div.style.zoom !== "undefined" ) {
1600
+ // Check if natively block-level elements act like inline-block
1601
+ // elements when setting their display to 'inline' and giving
1602
+ // them layout
1603
+ // (IE < 8 does this)
1604
+ div.innerHTML = "";
1605
+ div.style.width = div.style.padding = "1px";
1606
+ div.style.border = 0;
1607
+ div.style.overflow = "hidden";
1608
+ div.style.display = "inline";
1609
+ div.style.zoom = 1;
1610
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1611
+
1612
+ // Check if elements with layout shrink-wrap their children
1613
+ // (IE 6 does this)
1614
+ div.style.display = "block";
1615
+ div.style.overflow = "visible";
1616
+ div.innerHTML = "<div style='width:5px;'></div>";
1617
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1618
+ }
1619
+
1620
+ div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;
1621
+ div.innerHTML = html;
1622
+
1623
+ outer = div.firstChild;
1624
+ inner = outer.firstChild;
1625
+ td = outer.nextSibling.firstChild.firstChild;
1626
+
1627
+ offsetSupport = {
1628
+ doesNotAddBorder: ( inner.offsetTop !== 5 ),
1629
+ doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1630
+ };
1631
+
1632
+ inner.style.position = "fixed";
1633
+ inner.style.top = "20px";
1634
+
1635
+ // safari subtracts parent border width here which is 5px
1636
+ offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1637
+ inner.style.position = inner.style.top = "";
1638
+
1639
+ outer.style.overflow = "hidden";
1640
+ outer.style.position = "relative";
1641
+
1642
+ offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1643
+ offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1644
+
1645
+ if ( window.getComputedStyle ) {
1646
+ div.style.marginTop = "1%";
1647
+ support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
1648
+ }
1649
+
1650
+ if ( typeof container.style.zoom !== "undefined" ) {
1651
+ container.style.zoom = 1;
1652
+ }
1653
+
1654
+ body.removeChild( container );
1655
+ marginDiv = div = container = null;
1656
+
1657
+ jQuery.extend( support, offsetSupport );
1658
+ });
1659
+
1660
+ return support;
1661
+ })();
1662
+
1663
+
1664
+
1665
+
1666
+ var rbrace = /^(?:\{.*\}|\[.*\])$/,
1667
+ rmultiDash = /([A-Z])/g;
1668
+
1669
+ jQuery.extend({
1670
+ cache: {},
1671
+
1672
+ // Please use with caution
1673
+ uuid: 0,
1674
+
1675
+ // Unique for each copy of jQuery on the page
1676
+ // Non-digits removed to match rinlinejQuery
1677
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1678
+
1679
+ // The following elements throw uncatchable exceptions if you
1680
+ // attempt to add expando properties to them.
1681
+ noData: {
1682
+ "embed": true,
1683
+ // Ban all objects except for Flash (which handle expandos)
1684
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1685
+ "applet": true
1686
+ },
1687
+
1688
+ hasData: function( elem ) {
1689
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1690
+ return !!elem && !isEmptyDataObject( elem );
1691
+ },
1692
+
1693
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1694
+ if ( !jQuery.acceptData( elem ) ) {
1695
+ return;
1696
+ }
1697
+
1698
+ var privateCache, thisCache, ret,
1699
+ internalKey = jQuery.expando,
1700
+ getByName = typeof name === "string",
1701
+
1702
+ // We have to handle DOM nodes and JS objects differently because IE6-7
1703
+ // can't GC object references properly across the DOM-JS boundary
1704
+ isNode = elem.nodeType,
1705
+
1706
+ // Only DOM nodes need the global jQuery cache; JS object data is
1707
+ // attached directly to the object so GC can occur automatically
1708
+ cache = isNode ? jQuery.cache : elem,
1709
+
1710
+ // Only defining an ID for JS objects if its cache already exists allows
1711
+ // the code to shortcut on the same path as a DOM node with no cache
1712
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
1713
+ isEvents = name === "events";
1714
+
1715
+ // Avoid doing any more work than we need to when trying to get data on an
1716
+ // object that has no data at all
1717
+ if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
1718
+ return;
1719
+ }
1720
+
1721
+ if ( !id ) {
1722
+ // Only DOM nodes need a new unique ID for each element since their data
1723
+ // ends up in the global cache
1724
+ if ( isNode ) {
1725
+ elem[ internalKey ] = id = ++jQuery.uuid;
1726
+ } else {
1727
+ id = internalKey;
1728
+ }
1729
+ }
1730
+
1731
+ if ( !cache[ id ] ) {
1732
+ cache[ id ] = {};
1733
+
1734
+ // Avoids exposing jQuery metadata on plain JS objects when the object
1735
+ // is serialized using JSON.stringify
1736
+ if ( !isNode ) {
1737
+ cache[ id ].toJSON = jQuery.noop;
1738
+ }
1739
+ }
1740
+
1741
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
1742
+ // shallow copied over onto the existing cache
1743
+ if ( typeof name === "object" || typeof name === "function" ) {
1744
+ if ( pvt ) {
1745
+ cache[ id ] = jQuery.extend( cache[ id ], name );
1746
+ } else {
1747
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1748
+ }
1749
+ }
1750
+
1751
+ privateCache = thisCache = cache[ id ];
1752
+
1753
+ // jQuery data() is stored in a separate object inside the object's internal data
1754
+ // cache in order to avoid key collisions between internal data and user-defined
1755
+ // data.
1756
+ if ( !pvt ) {
1757
+ if ( !thisCache.data ) {
1758
+ thisCache.data = {};
1759
+ }
1760
+
1761
+ thisCache = thisCache.data;
1762
+ }
1763
+
1764
+ if ( data !== undefined ) {
1765
+ thisCache[ jQuery.camelCase( name ) ] = data;
1766
+ }
1767
+
1768
+ // Users should not attempt to inspect the internal events object using jQuery.data,
1769
+ // it is undocumented and subject to change. But does anyone listen? No.
1770
+ if ( isEvents && !thisCache[ name ] ) {
1771
+ return privateCache.events;
1772
+ }
1773
+
1774
+ // Check for both converted-to-camel and non-converted data property names
1775
+ // If a data property was specified
1776
+ if ( getByName ) {
1777
+
1778
+ // First Try to find as-is property data
1779
+ ret = thisCache[ name ];
1780
+
1781
+ // Test for null|undefined property data
1782
+ if ( ret == null ) {
1783
+
1784
+ // Try to find the camelCased property
1785
+ ret = thisCache[ jQuery.camelCase( name ) ];
1786
+ }
1787
+ } else {
1788
+ ret = thisCache;
1789
+ }
1790
+
1791
+ return ret;
1792
+ },
1793
+
1794
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1795
+ if ( !jQuery.acceptData( elem ) ) {
1796
+ return;
1797
+ }
1798
+
1799
+ var thisCache, i, l,
1800
+
1801
+ // Reference to internal data cache key
1802
+ internalKey = jQuery.expando,
1803
+
1804
+ isNode = elem.nodeType,
1805
+
1806
+ // See jQuery.data for more information
1807
+ cache = isNode ? jQuery.cache : elem,
1808
+
1809
+ // See jQuery.data for more information
1810
+ id = isNode ? elem[ internalKey ] : internalKey;
1811
+
1812
+ // If there is already no cache entry for this object, there is no
1813
+ // purpose in continuing
1814
+ if ( !cache[ id ] ) {
1815
+ return;
1816
+ }
1817
+
1818
+ if ( name ) {
1819
+
1820
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
1821
+
1822
+ if ( thisCache ) {
1823
+
1824
+ // Support array or space separated string names for data keys
1825
+ if ( !jQuery.isArray( name ) ) {
1826
+
1827
+ // try the string as a key before any manipulation
1828
+ if ( name in thisCache ) {
1829
+ name = [ name ];
1830
+ } else {
1831
+
1832
+ // split the camel cased version by spaces unless a key with the spaces exists
1833
+ name = jQuery.camelCase( name );
1834
+ if ( name in thisCache ) {
1835
+ name = [ name ];
1836
+ } else {
1837
+ name = name.split( " " );
1838
+ }
1839
+ }
1840
+ }
1841
+
1842
+ for ( i = 0, l = name.length; i < l; i++ ) {
1843
+ delete thisCache[ name[i] ];
1844
+ }
1845
+
1846
+ // If there is no data left in the cache, we want to continue
1847
+ // and let the cache object itself get destroyed
1848
+ if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1849
+ return;
1850
+ }
1851
+ }
1852
+ }
1853
+
1854
+ // See jQuery.data for more information
1855
+ if ( !pvt ) {
1856
+ delete cache[ id ].data;
1857
+
1858
+ // Don't destroy the parent cache unless the internal data object
1859
+ // had been the only thing left in it
1860
+ if ( !isEmptyDataObject(cache[ id ]) ) {
1861
+ return;
1862
+ }
1863
+ }
1864
+
1865
+ // Browsers that fail expando deletion also refuse to delete expandos on
1866
+ // the window, but it will allow it on all other JS objects; other browsers
1867
+ // don't care
1868
+ // Ensure that `cache` is not a window object #10080
1869
+ if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1870
+ delete cache[ id ];
1871
+ } else {
1872
+ cache[ id ] = null;
1873
+ }
1874
+
1875
+ // We destroyed the cache and need to eliminate the expando on the node to avoid
1876
+ // false lookups in the cache for entries that no longer exist
1877
+ if ( isNode ) {
1878
+ // IE does not allow us to delete expando properties from nodes,
1879
+ // nor does it have a removeAttribute function on Document nodes;
1880
+ // we must handle all of these cases
1881
+ if ( jQuery.support.deleteExpando ) {
1882
+ delete elem[ internalKey ];
1883
+ } else if ( elem.removeAttribute ) {
1884
+ elem.removeAttribute( internalKey );
1885
+ } else {
1886
+ elem[ internalKey ] = null;
1887
+ }
1888
+ }
1889
+ },
1890
+
1891
+ // For internal use only.
1892
+ _data: function( elem, name, data ) {
1893
+ return jQuery.data( elem, name, data, true );
1894
+ },
1895
+
1896
+ // A method for determining if a DOM node can handle the data expando
1897
+ acceptData: function( elem ) {
1898
+ if ( elem.nodeName ) {
1899
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1900
+
1901
+ if ( match ) {
1902
+ return !(match === true || elem.getAttribute("classid") !== match);
1903
+ }
1904
+ }
1905
+
1906
+ return true;
1907
+ }
1908
+ });
1909
+
1910
+ jQuery.fn.extend({
1911
+ data: function( key, value ) {
1912
+ var parts, part, attr, name, l,
1913
+ elem = this[0],
1914
+ i = 0,
1915
+ data = null;
1916
+
1917
+ // Gets all values
1918
+ if ( key === undefined ) {
1919
+ if ( this.length ) {
1920
+ data = jQuery.data( elem );
1921
+
1922
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1923
+ attr = elem.attributes;
1924
+ for ( l = attr.length; i < l; i++ ) {
1925
+ name = attr[i].name;
1926
+
1927
+ if ( name.indexOf( "data-" ) === 0 ) {
1928
+ name = jQuery.camelCase( name.substring(5) );
1929
+
1930
+ dataAttr( elem, name, data[ name ] );
1931
+ }
1932
+ }
1933
+ jQuery._data( elem, "parsedAttrs", true );
1934
+ }
1935
+ }
1936
+
1937
+ return data;
1938
+ }
1939
+
1940
+ // Sets multiple values
1941
+ if ( typeof key === "object" ) {
1942
+ return this.each(function() {
1943
+ jQuery.data( this, key );
1944
+ });
1945
+ }
1946
+
1947
+ parts = key.split( ".", 2 );
1948
+ parts[1] = parts[1] ? "." + parts[1] : "";
1949
+ part = parts[1] + "!";
1950
+
1951
+ return jQuery.access( this, function( value ) {
1952
+
1953
+ if ( value === undefined ) {
1954
+ data = this.triggerHandler( "getData" + part, [ parts[0] ] );
1955
+
1956
+ // Try to fetch any internally stored data first
1957
+ if ( data === undefined && elem ) {
1958
+ data = jQuery.data( elem, key );
1959
+ data = dataAttr( elem, key, data );
1960
+ }
1961
+
1962
+ return data === undefined && parts[1] ?
1963
+ this.data( parts[0] ) :
1964
+ data;
1965
+ }
1966
+
1967
+ parts[1] = value;
1968
+ this.each(function() {
1969
+ var self = jQuery( this );
1970
+
1971
+ self.triggerHandler( "setData" + part, parts );
1972
+ jQuery.data( this, key, value );
1973
+ self.triggerHandler( "changeData" + part, parts );
1974
+ });
1975
+ }, null, value, arguments.length > 1, null, false );
1976
+ },
1977
+
1978
+ removeData: function( key ) {
1979
+ return this.each(function() {
1980
+ jQuery.removeData( this, key );
1981
+ });
1982
+ }
1983
+ });
1984
+
1985
+ function dataAttr( elem, key, data ) {
1986
+ // If nothing was found internally, try to fetch any
1987
+ // data from the HTML5 data-* attribute
1988
+ if ( data === undefined && elem.nodeType === 1 ) {
1989
+
1990
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1991
+
1992
+ data = elem.getAttribute( name );
1993
+
1994
+ if ( typeof data === "string" ) {
1995
+ try {
1996
+ data = data === "true" ? true :
1997
+ data === "false" ? false :
1998
+ data === "null" ? null :
1999
+ jQuery.isNumeric( data ) ? +data :
2000
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
2001
+ data;
2002
+ } catch( e ) {}
2003
+
2004
+ // Make sure we set the data so it isn't changed later
2005
+ jQuery.data( elem, key, data );
2006
+
2007
+ } else {
2008
+ data = undefined;
2009
+ }
2010
+ }
2011
+
2012
+ return data;
2013
+ }
2014
+
2015
+ // checks a cache object for emptiness
2016
+ function isEmptyDataObject( obj ) {
2017
+ for ( var name in obj ) {
2018
+
2019
+ // if the public data object is empty, the private is still empty
2020
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
2021
+ continue;
2022
+ }
2023
+ if ( name !== "toJSON" ) {
2024
+ return false;
2025
+ }
2026
+ }
2027
+
2028
+ return true;
2029
+ }
2030
+
2031
+
2032
+
2033
+
2034
+ function handleQueueMarkDefer( elem, type, src ) {
2035
+ var deferDataKey = type + "defer",
2036
+ queueDataKey = type + "queue",
2037
+ markDataKey = type + "mark",
2038
+ defer = jQuery._data( elem, deferDataKey );
2039
+ if ( defer &&
2040
+ ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
2041
+ ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
2042
+ // Give room for hard-coded callbacks to fire first
2043
+ // and eventually mark/queue something else on the element
2044
+ setTimeout( function() {
2045
+ if ( !jQuery._data( elem, queueDataKey ) &&
2046
+ !jQuery._data( elem, markDataKey ) ) {
2047
+ jQuery.removeData( elem, deferDataKey, true );
2048
+ defer.fire();
2049
+ }
2050
+ }, 0 );
2051
+ }
2052
+ }
2053
+
2054
+ jQuery.extend({
2055
+
2056
+ _mark: function( elem, type ) {
2057
+ if ( elem ) {
2058
+ type = ( type || "fx" ) + "mark";
2059
+ jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
2060
+ }
2061
+ },
2062
+
2063
+ _unmark: function( force, elem, type ) {
2064
+ if ( force !== true ) {
2065
+ type = elem;
2066
+ elem = force;
2067
+ force = false;
2068
+ }
2069
+ if ( elem ) {
2070
+ type = type || "fx";
2071
+ var key = type + "mark",
2072
+ count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
2073
+ if ( count ) {
2074
+ jQuery._data( elem, key, count );
2075
+ } else {
2076
+ jQuery.removeData( elem, key, true );
2077
+ handleQueueMarkDefer( elem, type, "mark" );
2078
+ }
2079
+ }
2080
+ },
2081
+
2082
+ queue: function( elem, type, data ) {
2083
+ var q;
2084
+ if ( elem ) {
2085
+ type = ( type || "fx" ) + "queue";
2086
+ q = jQuery._data( elem, type );
2087
+
2088
+ // Speed up dequeue by getting out quickly if this is just a lookup
2089
+ if ( data ) {
2090
+ if ( !q || jQuery.isArray(data) ) {
2091
+ q = jQuery._data( elem, type, jQuery.makeArray(data) );
2092
+ } else {
2093
+ q.push( data );
2094
+ }
2095
+ }
2096
+ return q || [];
2097
+ }
2098
+ },
2099
+
2100
+ dequeue: function( elem, type ) {
2101
+ type = type || "fx";
2102
+
2103
+ var queue = jQuery.queue( elem, type ),
2104
+ fn = queue.shift(),
2105
+ hooks = {};
2106
+
2107
+ // If the fx queue is dequeued, always remove the progress sentinel
2108
+ if ( fn === "inprogress" ) {
2109
+ fn = queue.shift();
2110
+ }
2111
+
2112
+ if ( fn ) {
2113
+ // Add a progress sentinel to prevent the fx queue from being
2114
+ // automatically dequeued
2115
+ if ( type === "fx" ) {
2116
+ queue.unshift( "inprogress" );
2117
+ }
2118
+
2119
+ jQuery._data( elem, type + ".run", hooks );
2120
+ fn.call( elem, function() {
2121
+ jQuery.dequeue( elem, type );
2122
+ }, hooks );
2123
+ }
2124
+
2125
+ if ( !queue.length ) {
2126
+ jQuery.removeData( elem, type + "queue " + type + ".run", true );
2127
+ handleQueueMarkDefer( elem, type, "queue" );
2128
+ }
2129
+ }
2130
+ });
2131
+
2132
+ jQuery.fn.extend({
2133
+ queue: function( type, data ) {
2134
+ var setter = 2;
2135
+
2136
+ if ( typeof type !== "string" ) {
2137
+ data = type;
2138
+ type = "fx";
2139
+ setter--;
2140
+ }
2141
+
2142
+ if ( arguments.length < setter ) {
2143
+ return jQuery.queue( this[0], type );
2144
+ }
2145
+
2146
+ return data === undefined ?
2147
+ this :
2148
+ this.each(function() {
2149
+ var queue = jQuery.queue( this, type, data );
2150
+
2151
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
2152
+ jQuery.dequeue( this, type );
2153
+ }
2154
+ });
2155
+ },
2156
+ dequeue: function( type ) {
2157
+ return this.each(function() {
2158
+ jQuery.dequeue( this, type );
2159
+ });
2160
+ },
2161
+ // Based off of the plugin by Clint Helfers, with permission.
2162
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
2163
+ delay: function( time, type ) {
2164
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
2165
+ type = type || "fx";
2166
+
2167
+ return this.queue( type, function( next, hooks ) {
2168
+ var timeout = setTimeout( next, time );
2169
+ hooks.stop = function() {
2170
+ clearTimeout( timeout );
2171
+ };
2172
+ });
2173
+ },
2174
+ clearQueue: function( type ) {
2175
+ return this.queue( type || "fx", [] );
2176
+ },
2177
+ // Get a promise resolved when queues of a certain type
2178
+ // are emptied (fx is the type by default)
2179
+ promise: function( type, object ) {
2180
+ if ( typeof type !== "string" ) {
2181
+ object = type;
2182
+ type = undefined;
2183
+ }
2184
+ type = type || "fx";
2185
+ var defer = jQuery.Deferred(),
2186
+ elements = this,
2187
+ i = elements.length,
2188
+ count = 1,
2189
+ deferDataKey = type + "defer",
2190
+ queueDataKey = type + "queue",
2191
+ markDataKey = type + "mark",
2192
+ tmp;
2193
+ function resolve() {
2194
+ if ( !( --count ) ) {
2195
+ defer.resolveWith( elements, [ elements ] );
2196
+ }
2197
+ }
2198
+ while( i-- ) {
2199
+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2200
+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2201
+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2202
+ jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
2203
+ count++;
2204
+ tmp.add( resolve );
2205
+ }
2206
+ }
2207
+ resolve();
2208
+ return defer.promise( object );
2209
+ }
2210
+ });
2211
+
2212
+
2213
+
2214
+
2215
+ var rclass = /[\n\t\r]/g,
2216
+ rspace = /\s+/,
2217
+ rreturn = /\r/g,
2218
+ rtype = /^(?:button|input)$/i,
2219
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
2220
+ rclickable = /^a(?:rea)?$/i,
2221
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
2222
+ getSetAttribute = jQuery.support.getSetAttribute,
2223
+ nodeHook, boolHook, fixSpecified;
2224
+
2225
+ jQuery.fn.extend({
2226
+ attr: function( name, value ) {
2227
+ return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2228
+ },
2229
+
2230
+ removeAttr: function( name ) {
2231
+ return this.each(function() {
2232
+ jQuery.removeAttr( this, name );
2233
+ });
2234
+ },
2235
+
2236
+ prop: function( name, value ) {
2237
+ return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2238
+ },
2239
+
2240
+ removeProp: function( name ) {
2241
+ name = jQuery.propFix[ name ] || name;
2242
+ return this.each(function() {
2243
+ // try/catch handles cases where IE balks (such as removing a property on window)
2244
+ try {
2245
+ this[ name ] = undefined;
2246
+ delete this[ name ];
2247
+ } catch( e ) {}
2248
+ });
2249
+ },
2250
+
2251
+ addClass: function( value ) {
2252
+ var classNames, i, l, elem,
2253
+ setClass, c, cl;
2254
+
2255
+ if ( jQuery.isFunction( value ) ) {
2256
+ return this.each(function( j ) {
2257
+ jQuery( this ).addClass( value.call(this, j, this.className) );
2258
+ });
2259
+ }
2260
+
2261
+ if ( value && typeof value === "string" ) {
2262
+ classNames = value.split( rspace );
2263
+
2264
+ for ( i = 0, l = this.length; i < l; i++ ) {
2265
+ elem = this[ i ];
2266
+
2267
+ if ( elem.nodeType === 1 ) {
2268
+ if ( !elem.className && classNames.length === 1 ) {
2269
+ elem.className = value;
2270
+
2271
+ } else {
2272
+ setClass = " " + elem.className + " ";
2273
+
2274
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2275
+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2276
+ setClass += classNames[ c ] + " ";
2277
+ }
2278
+ }
2279
+ elem.className = jQuery.trim( setClass );
2280
+ }
2281
+ }
2282
+ }
2283
+ }
2284
+
2285
+ return this;
2286
+ },
2287
+
2288
+ removeClass: function( value ) {
2289
+ var classNames, i, l, elem, className, c, cl;
2290
+
2291
+ if ( jQuery.isFunction( value ) ) {
2292
+ return this.each(function( j ) {
2293
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
2294
+ });
2295
+ }
2296
+
2297
+ if ( (value && typeof value === "string") || value === undefined ) {
2298
+ classNames = ( value || "" ).split( rspace );
2299
+
2300
+ for ( i = 0, l = this.length; i < l; i++ ) {
2301
+ elem = this[ i ];
2302
+
2303
+ if ( elem.nodeType === 1 && elem.className ) {
2304
+ if ( value ) {
2305
+ className = (" " + elem.className + " ").replace( rclass, " " );
2306
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2307
+ className = className.replace(" " + classNames[ c ] + " ", " ");
2308
+ }
2309
+ elem.className = jQuery.trim( className );
2310
+
2311
+ } else {
2312
+ elem.className = "";
2313
+ }
2314
+ }
2315
+ }
2316
+ }
2317
+
2318
+ return this;
2319
+ },
2320
+
2321
+ toggleClass: function( value, stateVal ) {
2322
+ var type = typeof value,
2323
+ isBool = typeof stateVal === "boolean";
2324
+
2325
+ if ( jQuery.isFunction( value ) ) {
2326
+ return this.each(function( i ) {
2327
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2328
+ });
2329
+ }
2330
+
2331
+ return this.each(function() {
2332
+ if ( type === "string" ) {
2333
+ // toggle individual class names
2334
+ var className,
2335
+ i = 0,
2336
+ self = jQuery( this ),
2337
+ state = stateVal,
2338
+ classNames = value.split( rspace );
2339
+
2340
+ while ( (className = classNames[ i++ ]) ) {
2341
+ // check each className given, space seperated list
2342
+ state = isBool ? state : !self.hasClass( className );
2343
+ self[ state ? "addClass" : "removeClass" ]( className );
2344
+ }
2345
+
2346
+ } else if ( type === "undefined" || type === "boolean" ) {
2347
+ if ( this.className ) {
2348
+ // store className if set
2349
+ jQuery._data( this, "__className__", this.className );
2350
+ }
2351
+
2352
+ // toggle whole className
2353
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2354
+ }
2355
+ });
2356
+ },
2357
+
2358
+ hasClass: function( selector ) {
2359
+ var className = " " + selector + " ",
2360
+ i = 0,
2361
+ l = this.length;
2362
+ for ( ; i < l; i++ ) {
2363
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2364
+ return true;
2365
+ }
2366
+ }
2367
+
2368
+ return false;
2369
+ },
2370
+
2371
+ val: function( value ) {
2372
+ var hooks, ret, isFunction,
2373
+ elem = this[0];
2374
+
2375
+ if ( !arguments.length ) {
2376
+ if ( elem ) {
2377
+ hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2378
+
2379
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2380
+ return ret;
2381
+ }
2382
+
2383
+ ret = elem.value;
2384
+
2385
+ return typeof ret === "string" ?
2386
+ // handle most common string cases
2387
+ ret.replace(rreturn, "") :
2388
+ // handle cases where value is null/undef or number
2389
+ ret == null ? "" : ret;
2390
+ }
2391
+
2392
+ return;
2393
+ }
2394
+
2395
+ isFunction = jQuery.isFunction( value );
2396
+
2397
+ return this.each(function( i ) {
2398
+ var self = jQuery(this), val;
2399
+
2400
+ if ( this.nodeType !== 1 ) {
2401
+ return;
2402
+ }
2403
+
2404
+ if ( isFunction ) {
2405
+ val = value.call( this, i, self.val() );
2406
+ } else {
2407
+ val = value;
2408
+ }
2409
+
2410
+ // Treat null/undefined as ""; convert numbers to string
2411
+ if ( val == null ) {
2412
+ val = "";
2413
+ } else if ( typeof val === "number" ) {
2414
+ val += "";
2415
+ } else if ( jQuery.isArray( val ) ) {
2416
+ val = jQuery.map(val, function ( value ) {
2417
+ return value == null ? "" : value + "";
2418
+ });
2419
+ }
2420
+
2421
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2422
+
2423
+ // If set returns undefined, fall back to normal setting
2424
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2425
+ this.value = val;
2426
+ }
2427
+ });
2428
+ }
2429
+ });
2430
+
2431
+ jQuery.extend({
2432
+ valHooks: {
2433
+ option: {
2434
+ get: function( elem ) {
2435
+ // attributes.value is undefined in Blackberry 4.7 but
2436
+ // uses .value. See #6932
2437
+ var val = elem.attributes.value;
2438
+ return !val || val.specified ? elem.value : elem.text;
2439
+ }
2440
+ },
2441
+ select: {
2442
+ get: function( elem ) {
2443
+ var value, i, max, option,
2444
+ index = elem.selectedIndex,
2445
+ values = [],
2446
+ options = elem.options,
2447
+ one = elem.type === "select-one";
2448
+
2449
+ // Nothing was selected
2450
+ if ( index < 0 ) {
2451
+ return null;
2452
+ }
2453
+
2454
+ // Loop through all the selected options
2455
+ i = one ? index : 0;
2456
+ max = one ? index + 1 : options.length;
2457
+ for ( ; i < max; i++ ) {
2458
+ option = options[ i ];
2459
+
2460
+ // Don't return options that are disabled or in a disabled optgroup
2461
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2462
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2463
+
2464
+ // Get the specific value for the option
2465
+ value = jQuery( option ).val();
2466
+
2467
+ // We don't need an array for one selects
2468
+ if ( one ) {
2469
+ return value;
2470
+ }
2471
+
2472
+ // Multi-Selects return an array
2473
+ values.push( value );
2474
+ }
2475
+ }
2476
+
2477
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2478
+ if ( one && !values.length && options.length ) {
2479
+ return jQuery( options[ index ] ).val();
2480
+ }
2481
+
2482
+ return values;
2483
+ },
2484
+
2485
+ set: function( elem, value ) {
2486
+ var values = jQuery.makeArray( value );
2487
+
2488
+ jQuery(elem).find("option").each(function() {
2489
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2490
+ });
2491
+
2492
+ if ( !values.length ) {
2493
+ elem.selectedIndex = -1;
2494
+ }
2495
+ return values;
2496
+ }
2497
+ }
2498
+ },
2499
+
2500
+ attrFn: {
2501
+ val: true,
2502
+ css: true,
2503
+ html: true,
2504
+ text: true,
2505
+ data: true,
2506
+ width: true,
2507
+ height: true,
2508
+ offset: true
2509
+ },
2510
+
2511
+ attr: function( elem, name, value, pass ) {
2512
+ var ret, hooks, notxml,
2513
+ nType = elem.nodeType;
2514
+
2515
+ // don't get/set attributes on text, comment and attribute nodes
2516
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2517
+ return;
2518
+ }
2519
+
2520
+ if ( pass && name in jQuery.attrFn ) {
2521
+ return jQuery( elem )[ name ]( value );
2522
+ }
2523
+
2524
+ // Fallback to prop when attributes are not supported
2525
+ if ( typeof elem.getAttribute === "undefined" ) {
2526
+ return jQuery.prop( elem, name, value );
2527
+ }
2528
+
2529
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2530
+
2531
+ // All attributes are lowercase
2532
+ // Grab necessary hook if one is defined
2533
+ if ( notxml ) {
2534
+ name = name.toLowerCase();
2535
+ hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2536
+ }
2537
+
2538
+ if ( value !== undefined ) {
2539
+
2540
+ if ( value === null ) {
2541
+ jQuery.removeAttr( elem, name );
2542
+ return;
2543
+
2544
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2545
+ return ret;
2546
+
2547
+ } else {
2548
+ elem.setAttribute( name, "" + value );
2549
+ return value;
2550
+ }
2551
+
2552
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2553
+ return ret;
2554
+
2555
+ } else {
2556
+
2557
+ ret = elem.getAttribute( name );
2558
+
2559
+ // Non-existent attributes return null, we normalize to undefined
2560
+ return ret === null ?
2561
+ undefined :
2562
+ ret;
2563
+ }
2564
+ },
2565
+
2566
+ removeAttr: function( elem, value ) {
2567
+ var propName, attrNames, name, l, isBool,
2568
+ i = 0;
2569
+
2570
+ if ( value && elem.nodeType === 1 ) {
2571
+ attrNames = value.toLowerCase().split( rspace );
2572
+ l = attrNames.length;
2573
+
2574
+ for ( ; i < l; i++ ) {
2575
+ name = attrNames[ i ];
2576
+
2577
+ if ( name ) {
2578
+ propName = jQuery.propFix[ name ] || name;
2579
+ isBool = rboolean.test( name );
2580
+
2581
+ // See #9699 for explanation of this approach (setting first, then removal)
2582
+ // Do not do this for boolean attributes (see #10870)
2583
+ if ( !isBool ) {
2584
+ jQuery.attr( elem, name, "" );
2585
+ }
2586
+ elem.removeAttribute( getSetAttribute ? name : propName );
2587
+
2588
+ // Set corresponding property to false for boolean attributes
2589
+ if ( isBool && propName in elem ) {
2590
+ elem[ propName ] = false;
2591
+ }
2592
+ }
2593
+ }
2594
+ }
2595
+ },
2596
+
2597
+ attrHooks: {
2598
+ type: {
2599
+ set: function( elem, value ) {
2600
+ // We can't allow the type property to be changed (since it causes problems in IE)
2601
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2602
+ jQuery.error( "type property can't be changed" );
2603
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2604
+ // Setting the type on a radio button after the value resets the value in IE6-9
2605
+ // Reset value to it's default in case type is set after value
2606
+ // This is for element creation
2607
+ var val = elem.value;
2608
+ elem.setAttribute( "type", value );
2609
+ if ( val ) {
2610
+ elem.value = val;
2611
+ }
2612
+ return value;
2613
+ }
2614
+ }
2615
+ },
2616
+ // Use the value property for back compat
2617
+ // Use the nodeHook for button elements in IE6/7 (#1954)
2618
+ value: {
2619
+ get: function( elem, name ) {
2620
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2621
+ return nodeHook.get( elem, name );
2622
+ }
2623
+ return name in elem ?
2624
+ elem.value :
2625
+ null;
2626
+ },
2627
+ set: function( elem, value, name ) {
2628
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2629
+ return nodeHook.set( elem, value, name );
2630
+ }
2631
+ // Does not return so that setAttribute is also used
2632
+ elem.value = value;
2633
+ }
2634
+ }
2635
+ },
2636
+
2637
+ propFix: {
2638
+ tabindex: "tabIndex",
2639
+ readonly: "readOnly",
2640
+ "for": "htmlFor",
2641
+ "class": "className",
2642
+ maxlength: "maxLength",
2643
+ cellspacing: "cellSpacing",
2644
+ cellpadding: "cellPadding",
2645
+ rowspan: "rowSpan",
2646
+ colspan: "colSpan",
2647
+ usemap: "useMap",
2648
+ frameborder: "frameBorder",
2649
+ contenteditable: "contentEditable"
2650
+ },
2651
+
2652
+ prop: function( elem, name, value ) {
2653
+ var ret, hooks, notxml,
2654
+ nType = elem.nodeType;
2655
+
2656
+ // don't get/set properties on text, comment and attribute nodes
2657
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2658
+ return;
2659
+ }
2660
+
2661
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2662
+
2663
+ if ( notxml ) {
2664
+ // Fix name and attach hooks
2665
+ name = jQuery.propFix[ name ] || name;
2666
+ hooks = jQuery.propHooks[ name ];
2667
+ }
2668
+
2669
+ if ( value !== undefined ) {
2670
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2671
+ return ret;
2672
+
2673
+ } else {
2674
+ return ( elem[ name ] = value );
2675
+ }
2676
+
2677
+ } else {
2678
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2679
+ return ret;
2680
+
2681
+ } else {
2682
+ return elem[ name ];
2683
+ }
2684
+ }
2685
+ },
2686
+
2687
+ propHooks: {
2688
+ tabIndex: {
2689
+ get: function( elem ) {
2690
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2691
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2692
+ var attributeNode = elem.getAttributeNode("tabindex");
2693
+
2694
+ return attributeNode && attributeNode.specified ?
2695
+ parseInt( attributeNode.value, 10 ) :
2696
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2697
+ 0 :
2698
+ undefined;
2699
+ }
2700
+ }
2701
+ }
2702
+ });
2703
+
2704
+ // Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
2705
+ jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
2706
+
2707
+ // Hook for boolean attributes
2708
+ boolHook = {
2709
+ get: function( elem, name ) {
2710
+ // Align boolean attributes with corresponding properties
2711
+ // Fall back to attribute presence where some booleans are not supported
2712
+ var attrNode,
2713
+ property = jQuery.prop( elem, name );
2714
+ return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
2715
+ name.toLowerCase() :
2716
+ undefined;
2717
+ },
2718
+ set: function( elem, value, name ) {
2719
+ var propName;
2720
+ if ( value === false ) {
2721
+ // Remove boolean attributes when set to false
2722
+ jQuery.removeAttr( elem, name );
2723
+ } else {
2724
+ // value is true since we know at this point it's type boolean and not false
2725
+ // Set boolean attributes to the same name and set the DOM property
2726
+ propName = jQuery.propFix[ name ] || name;
2727
+ if ( propName in elem ) {
2728
+ // Only set the IDL specifically if it already exists on the element
2729
+ elem[ propName ] = true;
2730
+ }
2731
+
2732
+ elem.setAttribute( name, name.toLowerCase() );
2733
+ }
2734
+ return name;
2735
+ }
2736
+ };
2737
+
2738
+ // IE6/7 do not support getting/setting some attributes with get/setAttribute
2739
+ if ( !getSetAttribute ) {
2740
+
2741
+ fixSpecified = {
2742
+ name: true,
2743
+ id: true,
2744
+ coords: true
2745
+ };
2746
+
2747
+ // Use this for any attribute in IE6/7
2748
+ // This fixes almost every IE6/7 issue
2749
+ nodeHook = jQuery.valHooks.button = {
2750
+ get: function( elem, name ) {
2751
+ var ret;
2752
+ ret = elem.getAttributeNode( name );
2753
+ return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
2754
+ ret.nodeValue :
2755
+ undefined;
2756
+ },
2757
+ set: function( elem, value, name ) {
2758
+ // Set the existing or create a new attribute node
2759
+ var ret = elem.getAttributeNode( name );
2760
+ if ( !ret ) {
2761
+ ret = document.createAttribute( name );
2762
+ elem.setAttributeNode( ret );
2763
+ }
2764
+ return ( ret.nodeValue = value + "" );
2765
+ }
2766
+ };
2767
+
2768
+ // Apply the nodeHook to tabindex
2769
+ jQuery.attrHooks.tabindex.set = nodeHook.set;
2770
+
2771
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2772
+ // This is for removals
2773
+ jQuery.each([ "width", "height" ], function( i, name ) {
2774
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2775
+ set: function( elem, value ) {
2776
+ if ( value === "" ) {
2777
+ elem.setAttribute( name, "auto" );
2778
+ return value;
2779
+ }
2780
+ }
2781
+ });
2782
+ });
2783
+
2784
+ // Set contenteditable to false on removals(#10429)
2785
+ // Setting to empty string throws an error as an invalid value
2786
+ jQuery.attrHooks.contenteditable = {
2787
+ get: nodeHook.get,
2788
+ set: function( elem, value, name ) {
2789
+ if ( value === "" ) {
2790
+ value = "false";
2791
+ }
2792
+ nodeHook.set( elem, value, name );
2793
+ }
2794
+ };
2795
+ }
2796
+
2797
+
2798
+ // Some attributes require a special call on IE
2799
+ if ( !jQuery.support.hrefNormalized ) {
2800
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2801
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2802
+ get: function( elem ) {
2803
+ var ret = elem.getAttribute( name, 2 );
2804
+ return ret === null ? undefined : ret;
2805
+ }
2806
+ });
2807
+ });
2808
+ }
2809
+
2810
+ if ( !jQuery.support.style ) {
2811
+ jQuery.attrHooks.style = {
2812
+ get: function( elem ) {
2813
+ // Return undefined in the case of empty string
2814
+ // Normalize to lowercase since IE uppercases css property names
2815
+ return elem.style.cssText.toLowerCase() || undefined;
2816
+ },
2817
+ set: function( elem, value ) {
2818
+ return ( elem.style.cssText = "" + value );
2819
+ }
2820
+ };
2821
+ }
2822
+
2823
+ // Safari mis-reports the default selected property of an option
2824
+ // Accessing the parent's selectedIndex property fixes it
2825
+ if ( !jQuery.support.optSelected ) {
2826
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2827
+ get: function( elem ) {
2828
+ var parent = elem.parentNode;
2829
+
2830
+ if ( parent ) {
2831
+ parent.selectedIndex;
2832
+
2833
+ // Make sure that it also works with optgroups, see #5701
2834
+ if ( parent.parentNode ) {
2835
+ parent.parentNode.selectedIndex;
2836
+ }
2837
+ }
2838
+ return null;
2839
+ }
2840
+ });
2841
+ }
2842
+
2843
+ // IE6/7 call enctype encoding
2844
+ if ( !jQuery.support.enctype ) {
2845
+ jQuery.propFix.enctype = "encoding";
2846
+ }
2847
+
2848
+ // Radios and checkboxes getter/setter
2849
+ if ( !jQuery.support.checkOn ) {
2850
+ jQuery.each([ "radio", "checkbox" ], function() {
2851
+ jQuery.valHooks[ this ] = {
2852
+ get: function( elem ) {
2853
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2854
+ return elem.getAttribute("value") === null ? "on" : elem.value;
2855
+ }
2856
+ };
2857
+ });
2858
+ }
2859
+ jQuery.each([ "radio", "checkbox" ], function() {
2860
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2861
+ set: function( elem, value ) {
2862
+ if ( jQuery.isArray( value ) ) {
2863
+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2864
+ }
2865
+ }
2866
+ });
2867
+ });
2868
+
2869
+
2870
+
2871
+
2872
+ var rformElems = /^(?:textarea|input|select)$/i,
2873
+ rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2874
+ rhoverHack = /(?:^|\s)hover(\.\S+)?\b/,
2875
+ rkeyEvent = /^key/,
2876
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
2877
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2878
+ rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2879
+ quickParse = function( selector ) {
2880
+ var quick = rquickIs.exec( selector );
2881
+ if ( quick ) {
2882
+ // 0 1 2 3
2883
+ // [ _, tag, id, class ]
2884
+ quick[1] = ( quick[1] || "" ).toLowerCase();
2885
+ quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2886
+ }
2887
+ return quick;
2888
+ },
2889
+ quickIs = function( elem, m ) {
2890
+ var attrs = elem.attributes || {};
2891
+ return (
2892
+ (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2893
+ (!m[2] || (attrs.id || {}).value === m[2]) &&
2894
+ (!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
2895
+ );
2896
+ },
2897
+ hoverHack = function( events ) {
2898
+ return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2899
+ };
2900
+
2901
+ /*
2902
+ * Helper functions for managing events -- not part of the public interface.
2903
+ * Props to Dean Edwards' addEvent library for many of the ideas.
2904
+ */
2905
+ jQuery.event = {
2906
+
2907
+ add: function( elem, types, handler, data, selector ) {
2908
+
2909
+ var elemData, eventHandle, events,
2910
+ t, tns, type, namespaces, handleObj,
2911
+ handleObjIn, quick, handlers, special;
2912
+
2913
+ // Don't attach events to noData or text/comment nodes (allow plain objects tho)
2914
+ if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2915
+ return;
2916
+ }
2917
+
2918
+ // Caller can pass in an object of custom data in lieu of the handler
2919
+ if ( handler.handler ) {
2920
+ handleObjIn = handler;
2921
+ handler = handleObjIn.handler;
2922
+ selector = handleObjIn.selector;
2923
+ }
2924
+
2925
+ // Make sure that the handler has a unique ID, used to find/remove it later
2926
+ if ( !handler.guid ) {
2927
+ handler.guid = jQuery.guid++;
2928
+ }
2929
+
2930
+ // Init the element's event structure and main handler, if this is the first
2931
+ events = elemData.events;
2932
+ if ( !events ) {
2933
+ elemData.events = events = {};
2934
+ }
2935
+ eventHandle = elemData.handle;
2936
+ if ( !eventHandle ) {
2937
+ elemData.handle = eventHandle = function( e ) {
2938
+ // Discard the second event of a jQuery.event.trigger() and
2939
+ // when an event is called after a page has unloaded
2940
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2941
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2942
+ undefined;
2943
+ };
2944
+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2945
+ eventHandle.elem = elem;
2946
+ }
2947
+
2948
+ // Handle multiple events separated by a space
2949
+ // jQuery(...).bind("mouseover mouseout", fn);
2950
+ types = jQuery.trim( hoverHack(types) ).split( " " );
2951
+ for ( t = 0; t < types.length; t++ ) {
2952
+
2953
+ tns = rtypenamespace.exec( types[t] ) || [];
2954
+ type = tns[1];
2955
+ namespaces = ( tns[2] || "" ).split( "." ).sort();
2956
+
2957
+ // If event changes its type, use the special event handlers for the changed type
2958
+ special = jQuery.event.special[ type ] || {};
2959
+
2960
+ // If selector defined, determine special event api type, otherwise given type
2961
+ type = ( selector ? special.delegateType : special.bindType ) || type;
2962
+
2963
+ // Update special based on newly reset type
2964
+ special = jQuery.event.special[ type ] || {};
2965
+
2966
+ // handleObj is passed to all event handlers
2967
+ handleObj = jQuery.extend({
2968
+ type: type,
2969
+ origType: tns[1],
2970
+ data: data,
2971
+ handler: handler,
2972
+ guid: handler.guid,
2973
+ selector: selector,
2974
+ quick: selector && quickParse( selector ),
2975
+ namespace: namespaces.join(".")
2976
+ }, handleObjIn );
2977
+
2978
+ // Init the event handler queue if we're the first
2979
+ handlers = events[ type ];
2980
+ if ( !handlers ) {
2981
+ handlers = events[ type ] = [];
2982
+ handlers.delegateCount = 0;
2983
+
2984
+ // Only use addEventListener/attachEvent if the special events handler returns false
2985
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2986
+ // Bind the global event handler to the element
2987
+ if ( elem.addEventListener ) {
2988
+ elem.addEventListener( type, eventHandle, false );
2989
+
2990
+ } else if ( elem.attachEvent ) {
2991
+ elem.attachEvent( "on" + type, eventHandle );
2992
+ }
2993
+ }
2994
+ }
2995
+
2996
+ if ( special.add ) {
2997
+ special.add.call( elem, handleObj );
2998
+
2999
+ if ( !handleObj.handler.guid ) {
3000
+ handleObj.handler.guid = handler.guid;
3001
+ }
3002
+ }
3003
+
3004
+ // Add to the element's handler list, delegates in front
3005
+ if ( selector ) {
3006
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
3007
+ } else {
3008
+ handlers.push( handleObj );
3009
+ }
3010
+
3011
+ // Keep track of which events have ever been used, for event optimization
3012
+ jQuery.event.global[ type ] = true;
3013
+ }
3014
+
3015
+ // Nullify elem to prevent memory leaks in IE
3016
+ elem = null;
3017
+ },
3018
+
3019
+ global: {},
3020
+
3021
+ // Detach an event or set of events from an element
3022
+ remove: function( elem, types, handler, selector, mappedTypes ) {
3023
+
3024
+ var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3025
+ t, tns, type, origType, namespaces, origCount,
3026
+ j, events, special, handle, eventType, handleObj;
3027
+
3028
+ if ( !elemData || !(events = elemData.events) ) {
3029
+ return;
3030
+ }
3031
+
3032
+ // Once for each type.namespace in types; type may be omitted
3033
+ types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
3034
+ for ( t = 0; t < types.length; t++ ) {
3035
+ tns = rtypenamespace.exec( types[t] ) || [];
3036
+ type = origType = tns[1];
3037
+ namespaces = tns[2];
3038
+
3039
+ // Unbind all events (on this namespace, if provided) for the element
3040
+ if ( !type ) {
3041
+ for ( type in events ) {
3042
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
3043
+ }
3044
+ continue;
3045
+ }
3046
+
3047
+ special = jQuery.event.special[ type ] || {};
3048
+ type = ( selector? special.delegateType : special.bindType ) || type;
3049
+ eventType = events[ type ] || [];
3050
+ origCount = eventType.length;
3051
+ namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3052
+
3053
+ // Remove matching events
3054
+ for ( j = 0; j < eventType.length; j++ ) {
3055
+ handleObj = eventType[ j ];
3056
+
3057
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
3058
+ ( !handler || handler.guid === handleObj.guid ) &&
3059
+ ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
3060
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
3061
+ eventType.splice( j--, 1 );
3062
+
3063
+ if ( handleObj.selector ) {
3064
+ eventType.delegateCount--;
3065
+ }
3066
+ if ( special.remove ) {
3067
+ special.remove.call( elem, handleObj );
3068
+ }
3069
+ }
3070
+ }
3071
+
3072
+ // Remove generic event handler if we removed something and no more handlers exist
3073
+ // (avoids potential for endless recursion during removal of special event handlers)
3074
+ if ( eventType.length === 0 && origCount !== eventType.length ) {
3075
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3076
+ jQuery.removeEvent( elem, type, elemData.handle );
3077
+ }
3078
+
3079
+ delete events[ type ];
3080
+ }
3081
+ }
3082
+
3083
+ // Remove the expando if it's no longer used
3084
+ if ( jQuery.isEmptyObject( events ) ) {
3085
+ handle = elemData.handle;
3086
+ if ( handle ) {
3087
+ handle.elem = null;
3088
+ }
3089
+
3090
+ // removeData also checks for emptiness and clears the expando if empty
3091
+ // so use it instead of delete
3092
+ jQuery.removeData( elem, [ "events", "handle" ], true );
3093
+ }
3094
+ },
3095
+
3096
+ // Events that are safe to short-circuit if no handlers are attached.
3097
+ // Native DOM events should not be added, they may have inline handlers.
3098
+ customEvent: {
3099
+ "getData": true,
3100
+ "setData": true,
3101
+ "changeData": true
3102
+ },
3103
+
3104
+ trigger: function( event, data, elem, onlyHandlers ) {
3105
+ // Don't do events on text and comment nodes
3106
+ if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
3107
+ return;
3108
+ }
3109
+
3110
+ // Event object or event type
3111
+ var type = event.type || event,
3112
+ namespaces = [],
3113
+ cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
3114
+
3115
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
3116
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
3117
+ return;
3118
+ }
3119
+
3120
+ if ( type.indexOf( "!" ) >= 0 ) {
3121
+ // Exclusive events trigger only for the exact event (no namespaces)
3122
+ type = type.slice(0, -1);
3123
+ exclusive = true;
3124
+ }
3125
+
3126
+ if ( type.indexOf( "." ) >= 0 ) {
3127
+ // Namespaced trigger; create a regexp to match event type in handle()
3128
+ namespaces = type.split(".");
3129
+ type = namespaces.shift();
3130
+ namespaces.sort();
3131
+ }
3132
+
3133
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3134
+ // No jQuery handlers for this event type, and it can't have inline handlers
3135
+ return;
3136
+ }
3137
+
3138
+ // Caller can pass in an Event, Object, or just an event type string
3139
+ event = typeof event === "object" ?
3140
+ // jQuery.Event object
3141
+ event[ jQuery.expando ] ? event :
3142
+ // Object literal
3143
+ new jQuery.Event( type, event ) :
3144
+ // Just the event type (string)
3145
+ new jQuery.Event( type );
3146
+
3147
+ event.type = type;
3148
+ event.isTrigger = true;
3149
+ event.exclusive = exclusive;
3150
+ event.namespace = namespaces.join( "." );
3151
+ event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3152
+ ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
3153
+
3154
+ // Handle a global trigger
3155
+ if ( !elem ) {
3156
+
3157
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
3158
+ cache = jQuery.cache;
3159
+ for ( i in cache ) {
3160
+ if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3161
+ jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
3162
+ }
3163
+ }
3164
+ return;
3165
+ }
3166
+
3167
+ // Clean up the event in case it is being reused
3168
+ event.result = undefined;
3169
+ if ( !event.target ) {
3170
+ event.target = elem;
3171
+ }
3172
+
3173
+ // Clone any incoming data and prepend the event, creating the handler arg list
3174
+ data = data != null ? jQuery.makeArray( data ) : [];
3175
+ data.unshift( event );
3176
+
3177
+ // Allow special events to draw outside the lines
3178
+ special = jQuery.event.special[ type ] || {};
3179
+ if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3180
+ return;
3181
+ }
3182
+
3183
+ // Determine event propagation path in advance, per W3C events spec (#9951)
3184
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3185
+ eventPath = [[ elem, special.bindType || type ]];
3186
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3187
+
3188
+ bubbleType = special.delegateType || type;
3189
+ cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
3190
+ old = null;
3191
+ for ( ; cur; cur = cur.parentNode ) {
3192
+ eventPath.push([ cur, bubbleType ]);
3193
+ old = cur;
3194
+ }
3195
+
3196
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
3197
+ if ( old && old === elem.ownerDocument ) {
3198
+ eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3199
+ }
3200
+ }
3201
+
3202
+ // Fire handlers on the event path
3203
+ for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
3204
+
3205
+ cur = eventPath[i][0];
3206
+ event.type = eventPath[i][1];
3207
+
3208
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
3209
+ if ( handle ) {
3210
+ handle.apply( cur, data );
3211
+ }
3212
+ // Note that this is a bare JS function and not a jQuery handler
3213
+ handle = ontype && cur[ ontype ];
3214
+ if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
3215
+ event.preventDefault();
3216
+ }
3217
+ }
3218
+ event.type = type;
3219
+
3220
+ // If nobody prevented the default action, do it now
3221
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
3222
+
3223
+ if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3224
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3225
+
3226
+ // Call a native DOM method on the target with the same name name as the event.
3227
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
3228
+ // Don't do default actions on window, that's where global variables be (#6170)
3229
+ // IE<9 dies on focus/blur to hidden element (#1486)
3230
+ if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3231
+
3232
+ // Don't re-trigger an onFOO event when we call its FOO() method
3233
+ old = elem[ ontype ];
3234
+
3235
+ if ( old ) {
3236
+ elem[ ontype ] = null;
3237
+ }
3238
+
3239
+ // Prevent re-triggering of the same event, since we already bubbled it above
3240
+ jQuery.event.triggered = type;
3241
+ elem[ type ]();
3242
+ jQuery.event.triggered = undefined;
3243
+
3244
+ if ( old ) {
3245
+ elem[ ontype ] = old;
3246
+ }
3247
+ }
3248
+ }
3249
+ }
3250
+
3251
+ return event.result;
3252
+ },
3253
+
3254
+ dispatch: function( event ) {
3255
+
3256
+ // Make a writable jQuery.Event from the native event object
3257
+ event = jQuery.event.fix( event || window.event );
3258
+
3259
+ var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3260
+ delegateCount = handlers.delegateCount,
3261
+ args = [].slice.call( arguments, 0 ),
3262
+ run_all = !event.exclusive && !event.namespace,
3263
+ special = jQuery.event.special[ event.type ] || {},
3264
+ handlerQueue = [],
3265
+ i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
3266
+
3267
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
3268
+ args[0] = event;
3269
+ event.delegateTarget = this;
3270
+
3271
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
3272
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3273
+ return;
3274
+ }
3275
+
3276
+ // Determine handlers that should run if there are delegated events
3277
+ // Avoid non-left-click bubbling in Firefox (#3861)
3278
+ if ( delegateCount && !(event.button && event.type === "click") ) {
3279
+
3280
+ // Pregenerate a single jQuery object for reuse with .is()
3281
+ jqcur = jQuery(this);
3282
+ jqcur.context = this.ownerDocument || this;
3283
+
3284
+ for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3285
+
3286
+ // Don't process events on disabled elements (#6911, #8165)
3287
+ if ( cur.disabled !== true ) {
3288
+ selMatch = {};
3289
+ matches = [];
3290
+ jqcur[0] = cur;
3291
+ for ( i = 0; i < delegateCount; i++ ) {
3292
+ handleObj = handlers[ i ];
3293
+ sel = handleObj.selector;
3294
+
3295
+ if ( selMatch[ sel ] === undefined ) {
3296
+ selMatch[ sel ] = (
3297
+ handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
3298
+ );
3299
+ }
3300
+ if ( selMatch[ sel ] ) {
3301
+ matches.push( handleObj );
3302
+ }
3303
+ }
3304
+ if ( matches.length ) {
3305
+ handlerQueue.push({ elem: cur, matches: matches });
3306
+ }
3307
+ }
3308
+ }
3309
+ }
3310
+
3311
+ // Add the remaining (directly-bound) handlers
3312
+ if ( handlers.length > delegateCount ) {
3313
+ handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3314
+ }
3315
+
3316
+ // Run delegates first; they may want to stop propagation beneath us
3317
+ for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3318
+ matched = handlerQueue[ i ];
3319
+ event.currentTarget = matched.elem;
3320
+
3321
+ for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3322
+ handleObj = matched.matches[ j ];
3323
+
3324
+ // Triggered event must either 1) be non-exclusive and have no namespace, or
3325
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3326
+ if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3327
+
3328
+ event.data = handleObj.data;
3329
+ event.handleObj = handleObj;
3330
+
3331
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3332
+ .apply( matched.elem, args );
3333
+
3334
+ if ( ret !== undefined ) {
3335
+ event.result = ret;
3336
+ if ( ret === false ) {
3337
+ event.preventDefault();
3338
+ event.stopPropagation();
3339
+ }
3340
+ }
3341
+ }
3342
+ }
3343
+ }
3344
+
3345
+ // Call the postDispatch hook for the mapped type
3346
+ if ( special.postDispatch ) {
3347
+ special.postDispatch.call( this, event );
3348
+ }
3349
+
3350
+ return event.result;
3351
+ },
3352
+
3353
+ // Includes some event props shared by KeyEvent and MouseEvent
3354
+ // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3355
+ props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3356
+
3357
+ fixHooks: {},
3358
+
3359
+ keyHooks: {
3360
+ props: "char charCode key keyCode".split(" "),
3361
+ filter: function( event, original ) {
3362
+
3363
+ // Add which for key events
3364
+ if ( event.which == null ) {
3365
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
3366
+ }
3367
+
3368
+ return event;
3369
+ }
3370
+ },
3371
+
3372
+ mouseHooks: {
3373
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3374
+ filter: function( event, original ) {
3375
+ var eventDoc, doc, body,
3376
+ button = original.button,
3377
+ fromElement = original.fromElement;
3378
+
3379
+ // Calculate pageX/Y if missing and clientX/Y available
3380
+ if ( event.pageX == null && original.clientX != null ) {
3381
+ eventDoc = event.target.ownerDocument || document;
3382
+ doc = eventDoc.documentElement;
3383
+ body = eventDoc.body;
3384
+
3385
+ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3386
+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3387
+ }
3388
+
3389
+ // Add relatedTarget, if necessary
3390
+ if ( !event.relatedTarget && fromElement ) {
3391
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3392
+ }
3393
+
3394
+ // Add which for click: 1 === left; 2 === middle; 3 === right
3395
+ // Note: button is not normalized, so don't use it
3396
+ if ( !event.which && button !== undefined ) {
3397
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3398
+ }
3399
+
3400
+ return event;
3401
+ }
3402
+ },
3403
+
3404
+ fix: function( event ) {
3405
+ if ( event[ jQuery.expando ] ) {
3406
+ return event;
3407
+ }
3408
+
3409
+ // Create a writable copy of the event object and normalize some properties
3410
+ var i, prop,
3411
+ originalEvent = event,
3412
+ fixHook = jQuery.event.fixHooks[ event.type ] || {},
3413
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3414
+
3415
+ event = jQuery.Event( originalEvent );
3416
+
3417
+ for ( i = copy.length; i; ) {
3418
+ prop = copy[ --i ];
3419
+ event[ prop ] = originalEvent[ prop ];
3420
+ }
3421
+
3422
+ // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3423
+ if ( !event.target ) {
3424
+ event.target = originalEvent.srcElement || document;
3425
+ }
3426
+
3427
+ // Target should not be a text node (#504, Safari)
3428
+ if ( event.target.nodeType === 3 ) {
3429
+ event.target = event.target.parentNode;
3430
+ }
3431
+
3432
+ // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3433
+ if ( event.metaKey === undefined ) {
3434
+ event.metaKey = event.ctrlKey;
3435
+ }
3436
+
3437
+ return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3438
+ },
3439
+
3440
+ special: {
3441
+ ready: {
3442
+ // Make sure the ready event is setup
3443
+ setup: jQuery.bindReady
3444
+ },
3445
+
3446
+ load: {
3447
+ // Prevent triggered image.load events from bubbling to window.load
3448
+ noBubble: true
3449
+ },
3450
+
3451
+ focus: {
3452
+ delegateType: "focusin"
3453
+ },
3454
+ blur: {
3455
+ delegateType: "focusout"
3456
+ },
3457
+
3458
+ beforeunload: {
3459
+ setup: function( data, namespaces, eventHandle ) {
3460
+ // We only want to do this special case on windows
3461
+ if ( jQuery.isWindow( this ) ) {
3462
+ this.onbeforeunload = eventHandle;
3463
+ }
3464
+ },
3465
+
3466
+ teardown: function( namespaces, eventHandle ) {
3467
+ if ( this.onbeforeunload === eventHandle ) {
3468
+ this.onbeforeunload = null;
3469
+ }
3470
+ }
3471
+ }
3472
+ },
3473
+
3474
+ simulate: function( type, elem, event, bubble ) {
3475
+ // Piggyback on a donor event to simulate a different one.
3476
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
3477
+ // simulated event prevents default then we do the same on the donor.
3478
+ var e = jQuery.extend(
3479
+ new jQuery.Event(),
3480
+ event,
3481
+ { type: type,
3482
+ isSimulated: true,
3483
+ originalEvent: {}
3484
+ }
3485
+ );
3486
+ if ( bubble ) {
3487
+ jQuery.event.trigger( e, null, elem );
3488
+ } else {
3489
+ jQuery.event.dispatch.call( elem, e );
3490
+ }
3491
+ if ( e.isDefaultPrevented() ) {
3492
+ event.preventDefault();
3493
+ }
3494
+ }
3495
+ };
3496
+
3497
+ // Some plugins are using, but it's undocumented/deprecated and will be removed.
3498
+ // The 1.7 special event interface should provide all the hooks needed now.
3499
+ jQuery.event.handle = jQuery.event.dispatch;
3500
+
3501
+ jQuery.removeEvent = document.removeEventListener ?
3502
+ function( elem, type, handle ) {
3503
+ if ( elem.removeEventListener ) {
3504
+ elem.removeEventListener( type, handle, false );
3505
+ }
3506
+ } :
3507
+ function( elem, type, handle ) {
3508
+ if ( elem.detachEvent ) {
3509
+ elem.detachEvent( "on" + type, handle );
3510
+ }
3511
+ };
3512
+
3513
+ jQuery.Event = function( src, props ) {
3514
+ // Allow instantiation without the 'new' keyword
3515
+ if ( !(this instanceof jQuery.Event) ) {
3516
+ return new jQuery.Event( src, props );
3517
+ }
3518
+
3519
+ // Event object
3520
+ if ( src && src.type ) {
3521
+ this.originalEvent = src;
3522
+ this.type = src.type;
3523
+
3524
+ // Events bubbling up the document may have been marked as prevented
3525
+ // by a handler lower down the tree; reflect the correct value.
3526
+ this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
3527
+ src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
3528
+
3529
+ // Event type
3530
+ } else {
3531
+ this.type = src;
3532
+ }
3533
+
3534
+ // Put explicitly provided properties onto the event object
3535
+ if ( props ) {
3536
+ jQuery.extend( this, props );
3537
+ }
3538
+
3539
+ // Create a timestamp if incoming event doesn't have one
3540
+ this.timeStamp = src && src.timeStamp || jQuery.now();
3541
+
3542
+ // Mark it as fixed
3543
+ this[ jQuery.expando ] = true;
3544
+ };
3545
+
3546
+ function returnFalse() {
3547
+ return false;
3548
+ }
3549
+ function returnTrue() {
3550
+ return true;
3551
+ }
3552
+
3553
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3554
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3555
+ jQuery.Event.prototype = {
3556
+ preventDefault: function() {
3557
+ this.isDefaultPrevented = returnTrue;
3558
+
3559
+ var e = this.originalEvent;
3560
+ if ( !e ) {
3561
+ return;
3562
+ }
3563
+
3564
+ // if preventDefault exists run it on the original event
3565
+ if ( e.preventDefault ) {
3566
+ e.preventDefault();
3567
+
3568
+ // otherwise set the returnValue property of the original event to false (IE)
3569
+ } else {
3570
+ e.returnValue = false;
3571
+ }
3572
+ },
3573
+ stopPropagation: function() {
3574
+ this.isPropagationStopped = returnTrue;
3575
+
3576
+ var e = this.originalEvent;
3577
+ if ( !e ) {
3578
+ return;
3579
+ }
3580
+ // if stopPropagation exists run it on the original event
3581
+ if ( e.stopPropagation ) {
3582
+ e.stopPropagation();
3583
+ }
3584
+ // otherwise set the cancelBubble property of the original event to true (IE)
3585
+ e.cancelBubble = true;
3586
+ },
3587
+ stopImmediatePropagation: function() {
3588
+ this.isImmediatePropagationStopped = returnTrue;
3589
+ this.stopPropagation();
3590
+ },
3591
+ isDefaultPrevented: returnFalse,
3592
+ isPropagationStopped: returnFalse,
3593
+ isImmediatePropagationStopped: returnFalse
3594
+ };
3595
+
3596
+ // Create mouseenter/leave events using mouseover/out and event-time checks
3597
+ jQuery.each({
3598
+ mouseenter: "mouseover",
3599
+ mouseleave: "mouseout"
3600
+ }, function( orig, fix ) {
3601
+ jQuery.event.special[ orig ] = {
3602
+ delegateType: fix,
3603
+ bindType: fix,
3604
+
3605
+ handle: function( event ) {
3606
+ var target = this,
3607
+ related = event.relatedTarget,
3608
+ handleObj = event.handleObj,
3609
+ selector = handleObj.selector,
3610
+ ret;
3611
+
3612
+ // For mousenter/leave call the handler if related is outside the target.
3613
+ // NB: No relatedTarget if the mouse left/entered the browser window
3614
+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3615
+ event.type = handleObj.origType;
3616
+ ret = handleObj.handler.apply( this, arguments );
3617
+ event.type = fix;
3618
+ }
3619
+ return ret;
3620
+ }
3621
+ };
3622
+ });
3623
+
3624
+ // IE submit delegation
3625
+ if ( !jQuery.support.submitBubbles ) {
3626
+
3627
+ jQuery.event.special.submit = {
3628
+ setup: function() {
3629
+ // Only need this for delegated form submit events
3630
+ if ( jQuery.nodeName( this, "form" ) ) {
3631
+ return false;
3632
+ }
3633
+
3634
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
3635
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3636
+ // Node name check avoids a VML-related crash in IE (#9807)
3637
+ var elem = e.target,
3638
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3639
+ if ( form && !form._submit_attached ) {
3640
+ jQuery.event.add( form, "submit._submit", function( event ) {
3641
+ event._submit_bubble = true;
3642
+ });
3643
+ form._submit_attached = true;
3644
+ }
3645
+ });
3646
+ // return undefined since we don't need an event listener
3647
+ },
3648
+
3649
+ postDispatch: function( event ) {
3650
+ // If form was submitted by the user, bubble the event up the tree
3651
+ if ( event._submit_bubble ) {
3652
+ delete event._submit_bubble;
3653
+ if ( this.parentNode && !event.isTrigger ) {
3654
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
3655
+ }
3656
+ }
3657
+ },
3658
+
3659
+ teardown: function() {
3660
+ // Only need this for delegated form submit events
3661
+ if ( jQuery.nodeName( this, "form" ) ) {
3662
+ return false;
3663
+ }
3664
+
3665
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3666
+ jQuery.event.remove( this, "._submit" );
3667
+ }
3668
+ };
3669
+ }
3670
+
3671
+ // IE change delegation and checkbox/radio fix
3672
+ if ( !jQuery.support.changeBubbles ) {
3673
+
3674
+ jQuery.event.special.change = {
3675
+
3676
+ setup: function() {
3677
+
3678
+ if ( rformElems.test( this.nodeName ) ) {
3679
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
3680
+ // after a propertychange. Eat the blur-change in special.change.handle.
3681
+ // This still fires onchange a second time for check/radio after blur.
3682
+ if ( this.type === "checkbox" || this.type === "radio" ) {
3683
+ jQuery.event.add( this, "propertychange._change", function( event ) {
3684
+ if ( event.originalEvent.propertyName === "checked" ) {
3685
+ this._just_changed = true;
3686
+ }
3687
+ });
3688
+ jQuery.event.add( this, "click._change", function( event ) {
3689
+ if ( this._just_changed && !event.isTrigger ) {
3690
+ this._just_changed = false;
3691
+ jQuery.event.simulate( "change", this, event, true );
3692
+ }
3693
+ });
3694
+ }
3695
+ return false;
3696
+ }
3697
+ // Delegated event; lazy-add a change handler on descendant inputs
3698
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
3699
+ var elem = e.target;
3700
+
3701
+ if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3702
+ jQuery.event.add( elem, "change._change", function( event ) {
3703
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3704
+ jQuery.event.simulate( "change", this.parentNode, event, true );
3705
+ }
3706
+ });
3707
+ elem._change_attached = true;
3708
+ }
3709
+ });
3710
+ },
3711
+
3712
+ handle: function( event ) {
3713
+ var elem = event.target;
3714
+
3715
+ // Swallow native change events from checkbox/radio, we already triggered them above
3716
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3717
+ return event.handleObj.handler.apply( this, arguments );
3718
+ }
3719
+ },
3720
+
3721
+ teardown: function() {
3722
+ jQuery.event.remove( this, "._change" );
3723
+
3724
+ return rformElems.test( this.nodeName );
3725
+ }
3726
+ };
3727
+ }
3728
+
3729
+ // Create "bubbling" focus and blur events
3730
+ if ( !jQuery.support.focusinBubbles ) {
3731
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3732
+
3733
+ // Attach a single capturing handler while someone wants focusin/focusout
3734
+ var attaches = 0,
3735
+ handler = function( event ) {
3736
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
3737
+ };
3738
+
3739
+ jQuery.event.special[ fix ] = {
3740
+ setup: function() {
3741
+ if ( attaches++ === 0 ) {
3742
+ document.addEventListener( orig, handler, true );
3743
+ }
3744
+ },
3745
+ teardown: function() {
3746
+ if ( --attaches === 0 ) {
3747
+ document.removeEventListener( orig, handler, true );
3748
+ }
3749
+ }
3750
+ };
3751
+ });
3752
+ }
3753
+
3754
+ jQuery.fn.extend({
3755
+
3756
+ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3757
+ var origFn, type;
3758
+
3759
+ // Types can be a map of types/handlers
3760
+ if ( typeof types === "object" ) {
3761
+ // ( types-Object, selector, data )
3762
+ if ( typeof selector !== "string" ) { // && selector != null
3763
+ // ( types-Object, data )
3764
+ data = data || selector;
3765
+ selector = undefined;
3766
+ }
3767
+ for ( type in types ) {
3768
+ this.on( type, selector, data, types[ type ], one );
3769
+ }
3770
+ return this;
3771
+ }
3772
+
3773
+ if ( data == null && fn == null ) {
3774
+ // ( types, fn )
3775
+ fn = selector;
3776
+ data = selector = undefined;
3777
+ } else if ( fn == null ) {
3778
+ if ( typeof selector === "string" ) {
3779
+ // ( types, selector, fn )
3780
+ fn = data;
3781
+ data = undefined;
3782
+ } else {
3783
+ // ( types, data, fn )
3784
+ fn = data;
3785
+ data = selector;
3786
+ selector = undefined;
3787
+ }
3788
+ }
3789
+ if ( fn === false ) {
3790
+ fn = returnFalse;
3791
+ } else if ( !fn ) {
3792
+ return this;
3793
+ }
3794
+
3795
+ if ( one === 1 ) {
3796
+ origFn = fn;
3797
+ fn = function( event ) {
3798
+ // Can use an empty set, since event contains the info
3799
+ jQuery().off( event );
3800
+ return origFn.apply( this, arguments );
3801
+ };
3802
+ // Use same guid so caller can remove using origFn
3803
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3804
+ }
3805
+ return this.each( function() {
3806
+ jQuery.event.add( this, types, fn, data, selector );
3807
+ });
3808
+ },
3809
+ one: function( types, selector, data, fn ) {
3810
+ return this.on( types, selector, data, fn, 1 );
3811
+ },
3812
+ off: function( types, selector, fn ) {
3813
+ if ( types && types.preventDefault && types.handleObj ) {
3814
+ // ( event ) dispatched jQuery.Event
3815
+ var handleObj = types.handleObj;
3816
+ jQuery( types.delegateTarget ).off(
3817
+ handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
3818
+ handleObj.selector,
3819
+ handleObj.handler
3820
+ );
3821
+ return this;
3822
+ }
3823
+ if ( typeof types === "object" ) {
3824
+ // ( types-object [, selector] )
3825
+ for ( var type in types ) {
3826
+ this.off( type, selector, types[ type ] );
3827
+ }
3828
+ return this;
3829
+ }
3830
+ if ( selector === false || typeof selector === "function" ) {
3831
+ // ( types [, fn] )
3832
+ fn = selector;
3833
+ selector = undefined;
3834
+ }
3835
+ if ( fn === false ) {
3836
+ fn = returnFalse;
3837
+ }
3838
+ return this.each(function() {
3839
+ jQuery.event.remove( this, types, fn, selector );
3840
+ });
3841
+ },
3842
+
3843
+ bind: function( types, data, fn ) {
3844
+ return this.on( types, null, data, fn );
3845
+ },
3846
+ unbind: function( types, fn ) {
3847
+ return this.off( types, null, fn );
3848
+ },
3849
+
3850
+ live: function( types, data, fn ) {
3851
+ jQuery( this.context ).on( types, this.selector, data, fn );
3852
+ return this;
3853
+ },
3854
+ die: function( types, fn ) {
3855
+ jQuery( this.context ).off( types, this.selector || "**", fn );
3856
+ return this;
3857
+ },
3858
+
3859
+ delegate: function( selector, types, data, fn ) {
3860
+ return this.on( types, selector, data, fn );
3861
+ },
3862
+ undelegate: function( selector, types, fn ) {
3863
+ // ( namespace ) or ( selector, types [, fn] )
3864
+ return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3865
+ },
3866
+
3867
+ trigger: function( type, data ) {
3868
+ return this.each(function() {
3869
+ jQuery.event.trigger( type, data, this );
3870
+ });
3871
+ },
3872
+ triggerHandler: function( type, data ) {
3873
+ if ( this[0] ) {
3874
+ return jQuery.event.trigger( type, data, this[0], true );
3875
+ }
3876
+ },
3877
+
3878
+ toggle: function( fn ) {
3879
+ // Save reference to arguments for access in closure
3880
+ var args = arguments,
3881
+ guid = fn.guid || jQuery.guid++,
3882
+ i = 0,
3883
+ toggler = function( event ) {
3884
+ // Figure out which function to execute
3885
+ var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3886
+ jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3887
+
3888
+ // Make sure that clicks stop
3889
+ event.preventDefault();
3890
+
3891
+ // and execute the function
3892
+ return args[ lastToggle ].apply( this, arguments ) || false;
3893
+ };
3894
+
3895
+ // link all the functions, so any of them can unbind this click handler
3896
+ toggler.guid = guid;
3897
+ while ( i < args.length ) {
3898
+ args[ i++ ].guid = guid;
3899
+ }
3900
+
3901
+ return this.click( toggler );
3902
+ },
3903
+
3904
+ hover: function( fnOver, fnOut ) {
3905
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3906
+ }
3907
+ });
3908
+
3909
+ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3910
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3911
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3912
+
3913
+ // Handle event binding
3914
+ jQuery.fn[ name ] = function( data, fn ) {
3915
+ if ( fn == null ) {
3916
+ fn = data;
3917
+ data = null;
3918
+ }
3919
+
3920
+ return arguments.length > 0 ?
3921
+ this.on( name, null, data, fn ) :
3922
+ this.trigger( name );
3923
+ };
3924
+
3925
+ if ( jQuery.attrFn ) {
3926
+ jQuery.attrFn[ name ] = true;
3927
+ }
3928
+
3929
+ if ( rkeyEvent.test( name ) ) {
3930
+ jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
3931
+ }
3932
+
3933
+ if ( rmouseEvent.test( name ) ) {
3934
+ jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
3935
+ }
3936
+ });
3937
+
3938
+
3939
+
3940
+ /*!
3941
+ * Sizzle CSS Selector Engine
3942
+ * Copyright 2011, The Dojo Foundation
3943
+ * Released under the MIT, BSD, and GPL Licenses.
3944
+ * More information: http://sizzlejs.com/
3945
+ */
3946
+ (function(){
3947
+
3948
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3949
+ expando = "sizcache" + (Math.random() + '').replace('.', ''),
3950
+ done = 0,
3951
+ toString = Object.prototype.toString,
3952
+ hasDuplicate = false,
3953
+ baseHasDuplicate = true,
3954
+ rBackslash = /\\/g,
3955
+ rReturn = /\r\n/g,
3956
+ rNonWord = /\W/;
3957
+
3958
+ // Here we check if the JavaScript engine is using some sort of
3959
+ // optimization where it does not always call our comparision
3960
+ // function. If that is the case, discard the hasDuplicate value.
3961
+ // Thus far that includes Google Chrome.
3962
+ [0, 0].sort(function() {
3963
+ baseHasDuplicate = false;
3964
+ return 0;
3965
+ });
3966
+
3967
+ var Sizzle = function( selector, context, results, seed ) {
3968
+ results = results || [];
3969
+ context = context || document;
3970
+
3971
+ var origContext = context;
3972
+
3973
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3974
+ return [];
3975
+ }
3976
+
3977
+ if ( !selector || typeof selector !== "string" ) {
3978
+ return results;
3979
+ }
3980
+
3981
+ var m, set, checkSet, extra, ret, cur, pop, i,
3982
+ prune = true,
3983
+ contextXML = Sizzle.isXML( context ),
3984
+ parts = [],
3985
+ soFar = selector;
3986
+
3987
+ // Reset the position of the chunker regexp (start from head)
3988
+ do {
3989
+ chunker.exec( "" );
3990
+ m = chunker.exec( soFar );
3991
+
3992
+ if ( m ) {
3993
+ soFar = m[3];
3994
+
3995
+ parts.push( m[1] );
3996
+
3997
+ if ( m[2] ) {
3998
+ extra = m[3];
3999
+ break;
4000
+ }
4001
+ }
4002
+ } while ( m );
4003
+
4004
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
4005
+
4006
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4007
+ set = posProcess( parts[0] + parts[1], context, seed );
4008
+
4009
+ } else {
4010
+ set = Expr.relative[ parts[0] ] ?
4011
+ [ context ] :
4012
+ Sizzle( parts.shift(), context );
4013
+
4014
+ while ( parts.length ) {
4015
+ selector = parts.shift();
4016
+
4017
+ if ( Expr.relative[ selector ] ) {
4018
+ selector += parts.shift();
4019
+ }
4020
+
4021
+ set = posProcess( selector, set, seed );
4022
+ }
4023
+ }
4024
+
4025
+ } else {
4026
+ // Take a shortcut and set the context if the root selector is an ID
4027
+ // (but not if it'll be faster if the inner selector is an ID)
4028
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4029
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4030
+
4031
+ ret = Sizzle.find( parts.shift(), context, contextXML );
4032
+ context = ret.expr ?
4033
+ Sizzle.filter( ret.expr, ret.set )[0] :
4034
+ ret.set[0];
4035
+ }
4036
+
4037
+ if ( context ) {
4038
+ ret = seed ?
4039
+ { expr: parts.pop(), set: makeArray(seed) } :
4040
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4041
+
4042
+ set = ret.expr ?
4043
+ Sizzle.filter( ret.expr, ret.set ) :
4044
+ ret.set;
4045
+
4046
+ if ( parts.length > 0 ) {
4047
+ checkSet = makeArray( set );
4048
+
4049
+ } else {
4050
+ prune = false;
4051
+ }
4052
+
4053
+ while ( parts.length ) {
4054
+ cur = parts.pop();
4055
+ pop = cur;
4056
+
4057
+ if ( !Expr.relative[ cur ] ) {
4058
+ cur = "";
4059
+ } else {
4060
+ pop = parts.pop();
4061
+ }
4062
+
4063
+ if ( pop == null ) {
4064
+ pop = context;
4065
+ }
4066
+
4067
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
4068
+ }
4069
+
4070
+ } else {
4071
+ checkSet = parts = [];
4072
+ }
4073
+ }
4074
+
4075
+ if ( !checkSet ) {
4076
+ checkSet = set;
4077
+ }
4078
+
4079
+ if ( !checkSet ) {
4080
+ Sizzle.error( cur || selector );
4081
+ }
4082
+
4083
+ if ( toString.call(checkSet) === "[object Array]" ) {
4084
+ if ( !prune ) {
4085
+ results.push.apply( results, checkSet );
4086
+
4087
+ } else if ( context && context.nodeType === 1 ) {
4088
+ for ( i = 0; checkSet[i] != null; i++ ) {
4089
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4090
+ results.push( set[i] );
4091
+ }
4092
+ }
4093
+
4094
+ } else {
4095
+ for ( i = 0; checkSet[i] != null; i++ ) {
4096
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4097
+ results.push( set[i] );
4098
+ }
4099
+ }
4100
+ }
4101
+
4102
+ } else {
4103
+ makeArray( checkSet, results );
4104
+ }
4105
+
4106
+ if ( extra ) {
4107
+ Sizzle( extra, origContext, results, seed );
4108
+ Sizzle.uniqueSort( results );
4109
+ }
4110
+
4111
+ return results;
4112
+ };
4113
+
4114
+ Sizzle.uniqueSort = function( results ) {
4115
+ if ( sortOrder ) {
4116
+ hasDuplicate = baseHasDuplicate;
4117
+ results.sort( sortOrder );
4118
+
4119
+ if ( hasDuplicate ) {
4120
+ for ( var i = 1; i < results.length; i++ ) {
4121
+ if ( results[i] === results[ i - 1 ] ) {
4122
+ results.splice( i--, 1 );
4123
+ }
4124
+ }
4125
+ }
4126
+ }
4127
+
4128
+ return results;
4129
+ };
4130
+
4131
+ Sizzle.matches = function( expr, set ) {
4132
+ return Sizzle( expr, null, null, set );
4133
+ };
4134
+
4135
+ Sizzle.matchesSelector = function( node, expr ) {
4136
+ return Sizzle( expr, null, null, [node] ).length > 0;
4137
+ };
4138
+
4139
+ Sizzle.find = function( expr, context, isXML ) {
4140
+ var set, i, len, match, type, left;
4141
+
4142
+ if ( !expr ) {
4143
+ return [];
4144
+ }
4145
+
4146
+ for ( i = 0, len = Expr.order.length; i < len; i++ ) {
4147
+ type = Expr.order[i];
4148
+
4149
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4150
+ left = match[1];
4151
+ match.splice( 1, 1 );
4152
+
4153
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
4154
+ match[1] = (match[1] || "").replace( rBackslash, "" );
4155
+ set = Expr.find[ type ]( match, context, isXML );
4156
+
4157
+ if ( set != null ) {
4158
+ expr = expr.replace( Expr.match[ type ], "" );
4159
+ break;
4160
+ }
4161
+ }
4162
+ }
4163
+ }
4164
+
4165
+ if ( !set ) {
4166
+ set = typeof context.getElementsByTagName !== "undefined" ?
4167
+ context.getElementsByTagName( "*" ) :
4168
+ [];
4169
+ }
4170
+
4171
+ return { set: set, expr: expr };
4172
+ };
4173
+
4174
+ Sizzle.filter = function( expr, set, inplace, not ) {
4175
+ var match, anyFound,
4176
+ type, found, item, filter, left,
4177
+ i, pass,
4178
+ old = expr,
4179
+ result = [],
4180
+ curLoop = set,
4181
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4182
+
4183
+ while ( expr && set.length ) {
4184
+ for ( type in Expr.filter ) {
4185
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4186
+ filter = Expr.filter[ type ];
4187
+ left = match[1];
4188
+
4189
+ anyFound = false;
4190
+
4191
+ match.splice(1,1);
4192
+
4193
+ if ( left.substr( left.length - 1 ) === "\\" ) {
4194
+ continue;
4195
+ }
4196
+
4197
+ if ( curLoop === result ) {
4198
+ result = [];
4199
+ }
4200
+
4201
+ if ( Expr.preFilter[ type ] ) {
4202
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4203
+
4204
+ if ( !match ) {
4205
+ anyFound = found = true;
4206
+
4207
+ } else if ( match === true ) {
4208
+ continue;
4209
+ }
4210
+ }
4211
+
4212
+ if ( match ) {
4213
+ for ( i = 0; (item = curLoop[i]) != null; i++ ) {
4214
+ if ( item ) {
4215
+ found = filter( item, match, i, curLoop );
4216
+ pass = not ^ found;
4217
+
4218
+ if ( inplace && found != null ) {
4219
+ if ( pass ) {
4220
+ anyFound = true;
4221
+
4222
+ } else {
4223
+ curLoop[i] = false;
4224
+ }
4225
+
4226
+ } else if ( pass ) {
4227
+ result.push( item );
4228
+ anyFound = true;
4229
+ }
4230
+ }
4231
+ }
4232
+ }
4233
+
4234
+ if ( found !== undefined ) {
4235
+ if ( !inplace ) {
4236
+ curLoop = result;
4237
+ }
4238
+
4239
+ expr = expr.replace( Expr.match[ type ], "" );
4240
+
4241
+ if ( !anyFound ) {
4242
+ return [];
4243
+ }
4244
+
4245
+ break;
4246
+ }
4247
+ }
4248
+ }
4249
+
4250
+ // Improper expression
4251
+ if ( expr === old ) {
4252
+ if ( anyFound == null ) {
4253
+ Sizzle.error( expr );
4254
+
4255
+ } else {
4256
+ break;
4257
+ }
4258
+ }
4259
+
4260
+ old = expr;
4261
+ }
4262
+
4263
+ return curLoop;
4264
+ };
4265
+
4266
+ Sizzle.error = function( msg ) {
4267
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
4268
+ };
4269
+
4270
+ /**
4271
+ * Utility function for retreiving the text value of an array of DOM nodes
4272
+ * @param {Array|Element} elem
4273
+ */
4274
+ var getText = Sizzle.getText = function( elem ) {
4275
+ var i, node,
4276
+ nodeType = elem.nodeType,
4277
+ ret = "";
4278
+
4279
+ if ( nodeType ) {
4280
+ if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
4281
+ // Use textContent || innerText for elements
4282
+ if ( typeof elem.textContent === 'string' ) {
4283
+ return elem.textContent;
4284
+ } else if ( typeof elem.innerText === 'string' ) {
4285
+ // Replace IE's carriage returns
4286
+ return elem.innerText.replace( rReturn, '' );
4287
+ } else {
4288
+ // Traverse it's children
4289
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
4290
+ ret += getText( elem );
4291
+ }
4292
+ }
4293
+ } else if ( nodeType === 3 || nodeType === 4 ) {
4294
+ return elem.nodeValue;
4295
+ }
4296
+ } else {
4297
+
4298
+ // If no nodeType, this is expected to be an array
4299
+ for ( i = 0; (node = elem[i]); i++ ) {
4300
+ // Do not traverse comment nodes
4301
+ if ( node.nodeType !== 8 ) {
4302
+ ret += getText( node );
4303
+ }
4304
+ }
4305
+ }
4306
+ return ret;
4307
+ };
4308
+
4309
+ var Expr = Sizzle.selectors = {
4310
+ order: [ "ID", "NAME", "TAG" ],
4311
+
4312
+ match: {
4313
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4314
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4315
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4316
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4317
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4318
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4319
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4320
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4321
+ },
4322
+
4323
+ leftMatch: {},
4324
+
4325
+ attrMap: {
4326
+ "class": "className",
4327
+ "for": "htmlFor"
4328
+ },
4329
+
4330
+ attrHandle: {
4331
+ href: function( elem ) {
4332
+ return elem.getAttribute( "href" );
4333
+ },
4334
+ type: function( elem ) {
4335
+ return elem.getAttribute( "type" );
4336
+ }
4337
+ },
4338
+
4339
+ relative: {
4340
+ "+": function(checkSet, part){
4341
+ var isPartStr = typeof part === "string",
4342
+ isTag = isPartStr && !rNonWord.test( part ),
4343
+ isPartStrNotTag = isPartStr && !isTag;
4344
+
4345
+ if ( isTag ) {
4346
+ part = part.toLowerCase();
4347
+ }
4348
+
4349
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4350
+ if ( (elem = checkSet[i]) ) {
4351
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4352
+
4353
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4354
+ elem || false :
4355
+ elem === part;
4356
+ }
4357
+ }
4358
+
4359
+ if ( isPartStrNotTag ) {
4360
+ Sizzle.filter( part, checkSet, true );
4361
+ }
4362
+ },
4363
+
4364
+ ">": function( checkSet, part ) {
4365
+ var elem,
4366
+ isPartStr = typeof part === "string",
4367
+ i = 0,
4368
+ l = checkSet.length;
4369
+
4370
+ if ( isPartStr && !rNonWord.test( part ) ) {
4371
+ part = part.toLowerCase();
4372
+
4373
+ for ( ; i < l; i++ ) {
4374
+ elem = checkSet[i];
4375
+
4376
+ if ( elem ) {
4377
+ var parent = elem.parentNode;
4378
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4379
+ }
4380
+ }
4381
+
4382
+ } else {
4383
+ for ( ; i < l; i++ ) {
4384
+ elem = checkSet[i];
4385
+
4386
+ if ( elem ) {
4387
+ checkSet[i] = isPartStr ?
4388
+ elem.parentNode :
4389
+ elem.parentNode === part;
4390
+ }
4391
+ }
4392
+
4393
+ if ( isPartStr ) {
4394
+ Sizzle.filter( part, checkSet, true );
4395
+ }
4396
+ }
4397
+ },
4398
+
4399
+ "": function(checkSet, part, isXML){
4400
+ var nodeCheck,
4401
+ doneName = done++,
4402
+ checkFn = dirCheck;
4403
+
4404
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
4405
+ part = part.toLowerCase();
4406
+ nodeCheck = part;
4407
+ checkFn = dirNodeCheck;
4408
+ }
4409
+
4410
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4411
+ },
4412
+
4413
+ "~": function( checkSet, part, isXML ) {
4414
+ var nodeCheck,
4415
+ doneName = done++,
4416
+ checkFn = dirCheck;
4417
+
4418
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
4419
+ part = part.toLowerCase();
4420
+ nodeCheck = part;
4421
+ checkFn = dirNodeCheck;
4422
+ }
4423
+
4424
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4425
+ }
4426
+ },
4427
+
4428
+ find: {
4429
+ ID: function( match, context, isXML ) {
4430
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
4431
+ var m = context.getElementById(match[1]);
4432
+ // Check parentNode to catch when Blackberry 4.6 returns
4433
+ // nodes that are no longer in the document #6963
4434
+ return m && m.parentNode ? [m] : [];
4435
+ }
4436
+ },
4437
+
4438
+ NAME: function( match, context ) {
4439
+ if ( typeof context.getElementsByName !== "undefined" ) {
4440
+ var ret = [],
4441
+ results = context.getElementsByName( match[1] );
4442
+
4443
+ for ( var i = 0, l = results.length; i < l; i++ ) {
4444
+ if ( results[i].getAttribute("name") === match[1] ) {
4445
+ ret.push( results[i] );
4446
+ }
4447
+ }
4448
+
4449
+ return ret.length === 0 ? null : ret;
4450
+ }
4451
+ },
4452
+
4453
+ TAG: function( match, context ) {
4454
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
4455
+ return context.getElementsByTagName( match[1] );
4456
+ }
4457
+ }
4458
+ },
4459
+ preFilter: {
4460
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4461
+ match = " " + match[1].replace( rBackslash, "" ) + " ";
4462
+
4463
+ if ( isXML ) {
4464
+ return match;
4465
+ }
4466
+
4467
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4468
+ if ( elem ) {
4469
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4470
+ if ( !inplace ) {
4471
+ result.push( elem );
4472
+ }
4473
+
4474
+ } else if ( inplace ) {
4475
+ curLoop[i] = false;
4476
+ }
4477
+ }
4478
+ }
4479
+
4480
+ return false;
4481
+ },
4482
+
4483
+ ID: function( match ) {
4484
+ return match[1].replace( rBackslash, "" );
4485
+ },
4486
+
4487
+ TAG: function( match, curLoop ) {
4488
+ return match[1].replace( rBackslash, "" ).toLowerCase();
4489
+ },
4490
+
4491
+ CHILD: function( match ) {
4492
+ if ( match[1] === "nth" ) {
4493
+ if ( !match[2] ) {
4494
+ Sizzle.error( match[0] );
4495
+ }
4496
+
4497
+ match[2] = match[2].replace(/^\+|\s*/g, '');
4498
+
4499
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4500
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4501
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4502
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4503
+
4504
+ // calculate the numbers (first)n+(last) including if they are negative
4505
+ match[2] = (test[1] + (test[2] || 1)) - 0;
4506
+ match[3] = test[3] - 0;
4507
+ }
4508
+ else if ( match[2] ) {
4509
+ Sizzle.error( match[0] );
4510
+ }
4511
+
4512
+ // TODO: Move to normal caching system
4513
+ match[0] = done++;
4514
+
4515
+ return match;
4516
+ },
4517
+
4518
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4519
+ var name = match[1] = match[1].replace( rBackslash, "" );
4520
+
4521
+ if ( !isXML && Expr.attrMap[name] ) {
4522
+ match[1] = Expr.attrMap[name];
4523
+ }
4524
+
4525
+ // Handle if an un-quoted value was used
4526
+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4527
+
4528
+ if ( match[2] === "~=" ) {
4529
+ match[4] = " " + match[4] + " ";
4530
+ }
4531
+
4532
+ return match;
4533
+ },
4534
+
4535
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
4536
+ if ( match[1] === "not" ) {
4537
+ // If we're dealing with a complex expression, or a simple one
4538
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4539
+ match[3] = Sizzle(match[3], null, null, curLoop);
4540
+
4541
+ } else {
4542
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4543
+
4544
+ if ( !inplace ) {
4545
+ result.push.apply( result, ret );
4546
+ }
4547
+
4548
+ return false;
4549
+ }
4550
+
4551
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4552
+ return true;
4553
+ }
4554
+
4555
+ return match;
4556
+ },
4557
+
4558
+ POS: function( match ) {
4559
+ match.unshift( true );
4560
+
4561
+ return match;
4562
+ }
4563
+ },
4564
+
4565
+ filters: {
4566
+ enabled: function( elem ) {
4567
+ return elem.disabled === false && elem.type !== "hidden";
4568
+ },
4569
+
4570
+ disabled: function( elem ) {
4571
+ return elem.disabled === true;
4572
+ },
4573
+
4574
+ checked: function( elem ) {
4575
+ return elem.checked === true;
4576
+ },
4577
+
4578
+ selected: function( elem ) {
4579
+ // Accessing this property makes selected-by-default
4580
+ // options in Safari work properly
4581
+ if ( elem.parentNode ) {
4582
+ elem.parentNode.selectedIndex;
4583
+ }
4584
+
4585
+ return elem.selected === true;
4586
+ },
4587
+
4588
+ parent: function( elem ) {
4589
+ return !!elem.firstChild;
4590
+ },
4591
+
4592
+ empty: function( elem ) {
4593
+ return !elem.firstChild;
4594
+ },
4595
+
4596
+ has: function( elem, i, match ) {
4597
+ return !!Sizzle( match[3], elem ).length;
4598
+ },
4599
+
4600
+ header: function( elem ) {
4601
+ return (/h\d/i).test( elem.nodeName );
4602
+ },
4603
+
4604
+ text: function( elem ) {
4605
+ var attr = elem.getAttribute( "type" ), type = elem.type;
4606
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
4607
+ // use getAttribute instead to test this case
4608
+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4609
+ },
4610
+
4611
+ radio: function( elem ) {
4612
+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4613
+ },
4614
+
4615
+ checkbox: function( elem ) {
4616
+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4617
+ },
4618
+
4619
+ file: function( elem ) {
4620
+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4621
+ },
4622
+
4623
+ password: function( elem ) {
4624
+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4625
+ },
4626
+
4627
+ submit: function( elem ) {
4628
+ var name = elem.nodeName.toLowerCase();
4629
+ return (name === "input" || name === "button") && "submit" === elem.type;
4630
+ },
4631
+
4632
+ image: function( elem ) {
4633
+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4634
+ },
4635
+
4636
+ reset: function( elem ) {
4637
+ var name = elem.nodeName.toLowerCase();
4638
+ return (name === "input" || name === "button") && "reset" === elem.type;
4639
+ },
4640
+
4641
+ button: function( elem ) {
4642
+ var name = elem.nodeName.toLowerCase();
4643
+ return name === "input" && "button" === elem.type || name === "button";
4644
+ },
4645
+
4646
+ input: function( elem ) {
4647
+ return (/input|select|textarea|button/i).test( elem.nodeName );
4648
+ },
4649
+
4650
+ focus: function( elem ) {
4651
+ return elem === elem.ownerDocument.activeElement;
4652
+ }
4653
+ },
4654
+ setFilters: {
4655
+ first: function( elem, i ) {
4656
+ return i === 0;
4657
+ },
4658
+
4659
+ last: function( elem, i, match, array ) {
4660
+ return i === array.length - 1;
4661
+ },
4662
+
4663
+ even: function( elem, i ) {
4664
+ return i % 2 === 0;
4665
+ },
4666
+
4667
+ odd: function( elem, i ) {
4668
+ return i % 2 === 1;
4669
+ },
4670
+
4671
+ lt: function( elem, i, match ) {
4672
+ return i < match[3] - 0;
4673
+ },
4674
+
4675
+ gt: function( elem, i, match ) {
4676
+ return i > match[3] - 0;
4677
+ },
4678
+
4679
+ nth: function( elem, i, match ) {
4680
+ return match[3] - 0 === i;
4681
+ },
4682
+
4683
+ eq: function( elem, i, match ) {
4684
+ return match[3] - 0 === i;
4685
+ }
4686
+ },
4687
+ filter: {
4688
+ PSEUDO: function( elem, match, i, array ) {
4689
+ var name = match[1],
4690
+ filter = Expr.filters[ name ];
4691
+
4692
+ if ( filter ) {
4693
+ return filter( elem, i, match, array );
4694
+
4695
+ } else if ( name === "contains" ) {
4696
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
4697
+
4698
+ } else if ( name === "not" ) {
4699
+ var not = match[3];
4700
+
4701
+ for ( var j = 0, l = not.length; j < l; j++ ) {
4702
+ if ( not[j] === elem ) {
4703
+ return false;
4704
+ }
4705
+ }
4706
+
4707
+ return true;
4708
+
4709
+ } else {
4710
+ Sizzle.error( name );
4711
+ }
4712
+ },
4713
+
4714
+ CHILD: function( elem, match ) {
4715
+ var first, last,
4716
+ doneName, parent, cache,
4717
+ count, diff,
4718
+ type = match[1],
4719
+ node = elem;
4720
+
4721
+ switch ( type ) {
4722
+ case "only":
4723
+ case "first":
4724
+ while ( (node = node.previousSibling) ) {
4725
+ if ( node.nodeType === 1 ) {
4726
+ return false;
4727
+ }
4728
+ }
4729
+
4730
+ if ( type === "first" ) {
4731
+ return true;
4732
+ }
4733
+
4734
+ node = elem;
4735
+
4736
+ /* falls through */
4737
+ case "last":
4738
+ while ( (node = node.nextSibling) ) {
4739
+ if ( node.nodeType === 1 ) {
4740
+ return false;
4741
+ }
4742
+ }
4743
+
4744
+ return true;
4745
+
4746
+ case "nth":
4747
+ first = match[2];
4748
+ last = match[3];
4749
+
4750
+ if ( first === 1 && last === 0 ) {
4751
+ return true;
4752
+ }
4753
+
4754
+ doneName = match[0];
4755
+ parent = elem.parentNode;
4756
+
4757
+ if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
4758
+ count = 0;
4759
+
4760
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
4761
+ if ( node.nodeType === 1 ) {
4762
+ node.nodeIndex = ++count;
4763
+ }
4764
+ }
4765
+
4766
+ parent[ expando ] = doneName;
4767
+ }
4768
+
4769
+ diff = elem.nodeIndex - last;
4770
+
4771
+ if ( first === 0 ) {
4772
+ return diff === 0;
4773
+
4774
+ } else {
4775
+ return ( diff % first === 0 && diff / first >= 0 );
4776
+ }
4777
+ }
4778
+ },
4779
+
4780
+ ID: function( elem, match ) {
4781
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
4782
+ },
4783
+
4784
+ TAG: function( elem, match ) {
4785
+ return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
4786
+ },
4787
+
4788
+ CLASS: function( elem, match ) {
4789
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
4790
+ .indexOf( match ) > -1;
4791
+ },
4792
+
4793
+ ATTR: function( elem, match ) {
4794
+ var name = match[1],
4795
+ result = Sizzle.attr ?
4796
+ Sizzle.attr( elem, name ) :
4797
+ Expr.attrHandle[ name ] ?
4798
+ Expr.attrHandle[ name ]( elem ) :
4799
+ elem[ name ] != null ?
4800
+ elem[ name ] :
4801
+ elem.getAttribute( name ),
4802
+ value = result + "",
4803
+ type = match[2],
4804
+ check = match[4];
4805
+
4806
+ return result == null ?
4807
+ type === "!=" :
4808
+ !type && Sizzle.attr ?
4809
+ result != null :
4810
+ type === "=" ?
4811
+ value === check :
4812
+ type === "*=" ?
4813
+ value.indexOf(check) >= 0 :
4814
+ type === "~=" ?
4815
+ (" " + value + " ").indexOf(check) >= 0 :
4816
+ !check ?
4817
+ value && result !== false :
4818
+ type === "!=" ?
4819
+ value !== check :
4820
+ type === "^=" ?
4821
+ value.indexOf(check) === 0 :
4822
+ type === "$=" ?
4823
+ value.substr(value.length - check.length) === check :
4824
+ type === "|=" ?
4825
+ value === check || value.substr(0, check.length + 1) === check + "-" :
4826
+ false;
4827
+ },
4828
+
4829
+ POS: function( elem, match, i, array ) {
4830
+ var name = match[2],
4831
+ filter = Expr.setFilters[ name ];
4832
+
4833
+ if ( filter ) {
4834
+ return filter( elem, i, match, array );
4835
+ }
4836
+ }
4837
+ }
4838
+ };
4839
+
4840
+ var origPOS = Expr.match.POS,
4841
+ fescape = function(all, num){
4842
+ return "\\" + (num - 0 + 1);
4843
+ };
4844
+
4845
+ for ( var type in Expr.match ) {
4846
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4847
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4848
+ }
4849
+ // Expose origPOS
4850
+ // "global" as in regardless of relation to brackets/parens
4851
+ Expr.match.globalPOS = origPOS;
4852
+
4853
+ var makeArray = function( array, results ) {
4854
+ array = Array.prototype.slice.call( array, 0 );
4855
+
4856
+ if ( results ) {
4857
+ results.push.apply( results, array );
4858
+ return results;
4859
+ }
4860
+
4861
+ return array;
4862
+ };
4863
+
4864
+ // Perform a simple check to determine if the browser is capable of
4865
+ // converting a NodeList to an array using builtin methods.
4866
+ // Also verifies that the returned array holds DOM nodes
4867
+ // (which is not the case in the Blackberry browser)
4868
+ try {
4869
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4870
+
4871
+ // Provide a fallback method if it does not work
4872
+ } catch( e ) {
4873
+ makeArray = function( array, results ) {
4874
+ var i = 0,
4875
+ ret = results || [];
4876
+
4877
+ if ( toString.call(array) === "[object Array]" ) {
4878
+ Array.prototype.push.apply( ret, array );
4879
+
4880
+ } else {
4881
+ if ( typeof array.length === "number" ) {
4882
+ for ( var l = array.length; i < l; i++ ) {
4883
+ ret.push( array[i] );
4884
+ }
4885
+
4886
+ } else {
4887
+ for ( ; array[i]; i++ ) {
4888
+ ret.push( array[i] );
4889
+ }
4890
+ }
4891
+ }
4892
+
4893
+ return ret;
4894
+ };
4895
+ }
4896
+
4897
+ var sortOrder, siblingCheck;
4898
+
4899
+ if ( document.documentElement.compareDocumentPosition ) {
4900
+ sortOrder = function( a, b ) {
4901
+ if ( a === b ) {
4902
+ hasDuplicate = true;
4903
+ return 0;
4904
+ }
4905
+
4906
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4907
+ return a.compareDocumentPosition ? -1 : 1;
4908
+ }
4909
+
4910
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4911
+ };
4912
+
4913
+ } else {
4914
+ sortOrder = function( a, b ) {
4915
+ // The nodes are identical, we can exit early
4916
+ if ( a === b ) {
4917
+ hasDuplicate = true;
4918
+ return 0;
4919
+
4920
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
4921
+ } else if ( a.sourceIndex && b.sourceIndex ) {
4922
+ return a.sourceIndex - b.sourceIndex;
4923
+ }
4924
+
4925
+ var al, bl,
4926
+ ap = [],
4927
+ bp = [],
4928
+ aup = a.parentNode,
4929
+ bup = b.parentNode,
4930
+ cur = aup;
4931
+
4932
+ // If the nodes are siblings (or identical) we can do a quick check
4933
+ if ( aup === bup ) {
4934
+ return siblingCheck( a, b );
4935
+
4936
+ // If no parents were found then the nodes are disconnected
4937
+ } else if ( !aup ) {
4938
+ return -1;
4939
+
4940
+ } else if ( !bup ) {
4941
+ return 1;
4942
+ }
4943
+
4944
+ // Otherwise they're somewhere else in the tree so we need
4945
+ // to build up a full list of the parentNodes for comparison
4946
+ while ( cur ) {
4947
+ ap.unshift( cur );
4948
+ cur = cur.parentNode;
4949
+ }
4950
+
4951
+ cur = bup;
4952
+
4953
+ while ( cur ) {
4954
+ bp.unshift( cur );
4955
+ cur = cur.parentNode;
4956
+ }
4957
+
4958
+ al = ap.length;
4959
+ bl = bp.length;
4960
+
4961
+ // Start walking down the tree looking for a discrepancy
4962
+ for ( var i = 0; i < al && i < bl; i++ ) {
4963
+ if ( ap[i] !== bp[i] ) {
4964
+ return siblingCheck( ap[i], bp[i] );
4965
+ }
4966
+ }
4967
+
4968
+ // We ended someplace up the tree so do a sibling check
4969
+ return i === al ?
4970
+ siblingCheck( a, bp[i], -1 ) :
4971
+ siblingCheck( ap[i], b, 1 );
4972
+ };
4973
+
4974
+ siblingCheck = function( a, b, ret ) {
4975
+ if ( a === b ) {
4976
+ return ret;
4977
+ }
4978
+
4979
+ var cur = a.nextSibling;
4980
+
4981
+ while ( cur ) {
4982
+ if ( cur === b ) {
4983
+ return -1;
4984
+ }
4985
+
4986
+ cur = cur.nextSibling;
4987
+ }
4988
+
4989
+ return 1;
4990
+ };
4991
+ }
4992
+
4993
+ // Check to see if the browser returns elements by name when
4994
+ // querying by getElementById (and provide a workaround)
4995
+ (function(){
4996
+ // We're going to inject a fake input element with a specified name
4997
+ var form = document.createElement("div"),
4998
+ id = "script" + (new Date()).getTime(),
4999
+ root = document.documentElement;
5000
+
5001
+ form.innerHTML = "<a name='" + id + "'/>";
5002
+
5003
+ // Inject it into the root element, check its status, and remove it quickly
5004
+ root.insertBefore( form, root.firstChild );
5005
+
5006
+ // The workaround has to do additional checks after a getElementById
5007
+ // Which slows things down for other browsers (hence the branching)
5008
+ if ( document.getElementById( id ) ) {
5009
+ Expr.find.ID = function( match, context, isXML ) {
5010
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
5011
+ var m = context.getElementById(match[1]);
5012
+
5013
+ return m ?
5014
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
5015
+ [m] :
5016
+ undefined :
5017
+ [];
5018
+ }
5019
+ };
5020
+
5021
+ Expr.filter.ID = function( elem, match ) {
5022
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
5023
+
5024
+ return elem.nodeType === 1 && node && node.nodeValue === match;
5025
+ };
5026
+ }
5027
+
5028
+ root.removeChild( form );
5029
+
5030
+ // release memory in IE
5031
+ root = form = null;
5032
+ })();
5033
+
5034
+ (function(){
5035
+ // Check to see if the browser returns only elements
5036
+ // when doing getElementsByTagName("*")
5037
+
5038
+ // Create a fake element
5039
+ var div = document.createElement("div");
5040
+ div.appendChild( document.createComment("") );
5041
+
5042
+ // Make sure no comments are found
5043
+ if ( div.getElementsByTagName("*").length > 0 ) {
5044
+ Expr.find.TAG = function( match, context ) {
5045
+ var results = context.getElementsByTagName( match[1] );
5046
+
5047
+ // Filter out possible comments
5048
+ if ( match[1] === "*" ) {
5049
+ var tmp = [];
5050
+
5051
+ for ( var i = 0; results[i]; i++ ) {
5052
+ if ( results[i].nodeType === 1 ) {
5053
+ tmp.push( results[i] );
5054
+ }
5055
+ }
5056
+
5057
+ results = tmp;
5058
+ }
5059
+
5060
+ return results;
5061
+ };
5062
+ }
5063
+
5064
+ // Check to see if an attribute returns normalized href attributes
5065
+ div.innerHTML = "<a href='#'></a>";
5066
+
5067
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5068
+ div.firstChild.getAttribute("href") !== "#" ) {
5069
+
5070
+ Expr.attrHandle.href = function( elem ) {
5071
+ return elem.getAttribute( "href", 2 );
5072
+ };
5073
+ }
5074
+
5075
+ // release memory in IE
5076
+ div = null;
5077
+ })();
5078
+
5079
+ if ( document.querySelectorAll ) {
5080
+ (function(){
5081
+ var oldSizzle = Sizzle,
5082
+ div = document.createElement("div"),
5083
+ id = "__sizzle__";
5084
+
5085
+ div.innerHTML = "<p class='TEST'></p>";
5086
+
5087
+ // Safari can't handle uppercase or unicode characters when
5088
+ // in quirks mode.
5089
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5090
+ return;
5091
+ }
5092
+
5093
+ Sizzle = function( query, context, extra, seed ) {
5094
+ context = context || document;
5095
+
5096
+ // Only use querySelectorAll on non-XML documents
5097
+ // (ID selectors don't work in non-HTML documents)
5098
+ if ( !seed && !Sizzle.isXML(context) ) {
5099
+ // See if we find a selector to speed up
5100
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5101
+
5102
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5103
+ // Speed-up: Sizzle("TAG")
5104
+ if ( match[1] ) {
5105
+ return makeArray( context.getElementsByTagName( query ), extra );
5106
+
5107
+ // Speed-up: Sizzle(".CLASS")
5108
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5109
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
5110
+ }
5111
+ }
5112
+
5113
+ if ( context.nodeType === 9 ) {
5114
+ // Speed-up: Sizzle("body")
5115
+ // The body element only exists once, optimize finding it
5116
+ if ( query === "body" && context.body ) {
5117
+ return makeArray( [ context.body ], extra );
5118
+
5119
+ // Speed-up: Sizzle("#ID")
5120
+ } else if ( match && match[3] ) {
5121
+ var elem = context.getElementById( match[3] );
5122
+
5123
+ // Check parentNode to catch when Blackberry 4.6 returns
5124
+ // nodes that are no longer in the document #6963
5125
+ if ( elem && elem.parentNode ) {
5126
+ // Handle the case where IE and Opera return items
5127
+ // by name instead of ID
5128
+ if ( elem.id === match[3] ) {
5129
+ return makeArray( [ elem ], extra );
5130
+ }
5131
+
5132
+ } else {
5133
+ return makeArray( [], extra );
5134
+ }
5135
+ }
5136
+
5137
+ try {
5138
+ return makeArray( context.querySelectorAll(query), extra );
5139
+ } catch(qsaError) {}
5140
+
5141
+ // qSA works strangely on Element-rooted queries
5142
+ // We can work around this by specifying an extra ID on the root
5143
+ // and working up from there (Thanks to Andrew Dupont for the technique)
5144
+ // IE 8 doesn't work on object elements
5145
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5146
+ var oldContext = context,
5147
+ old = context.getAttribute( "id" ),
5148
+ nid = old || id,
5149
+ hasParent = context.parentNode,
5150
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
5151
+
5152
+ if ( !old ) {
5153
+ context.setAttribute( "id", nid );
5154
+ } else {
5155
+ nid = nid.replace( /'/g, "\\$&" );
5156
+ }
5157
+ if ( relativeHierarchySelector && hasParent ) {
5158
+ context = context.parentNode;
5159
+ }
5160
+
5161
+ try {
5162
+ if ( !relativeHierarchySelector || hasParent ) {
5163
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5164
+ }
5165
+
5166
+ } catch(pseudoError) {
5167
+ } finally {
5168
+ if ( !old ) {
5169
+ oldContext.removeAttribute( "id" );
5170
+ }
5171
+ }
5172
+ }
5173
+ }
5174
+
5175
+ return oldSizzle(query, context, extra, seed);
5176
+ };
5177
+
5178
+ for ( var prop in oldSizzle ) {
5179
+ Sizzle[ prop ] = oldSizzle[ prop ];
5180
+ }
5181
+
5182
+ // release memory in IE
5183
+ div = null;
5184
+ })();
5185
+ }
5186
+
5187
+ (function(){
5188
+ var html = document.documentElement,
5189
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5190
+
5191
+ if ( matches ) {
5192
+ // Check to see if it's possible to do matchesSelector
5193
+ // on a disconnected node (IE 9 fails this)
5194
+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5195
+ pseudoWorks = false;
5196
+
5197
+ try {
5198
+ // This should fail with an exception
5199
+ // Gecko does not error, returns false instead
5200
+ matches.call( document.documentElement, "[test!='']:sizzle" );
5201
+
5202
+ } catch( pseudoError ) {
5203
+ pseudoWorks = true;
5204
+ }
5205
+
5206
+ Sizzle.matchesSelector = function( node, expr ) {
5207
+ // Make sure that attribute selectors are quoted
5208
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5209
+
5210
+ if ( !Sizzle.isXML( node ) ) {
5211
+ try {
5212
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5213
+ var ret = matches.call( node, expr );
5214
+
5215
+ // IE 9's matchesSelector returns false on disconnected nodes
5216
+ if ( ret || !disconnectedMatch ||
5217
+ // As well, disconnected nodes are said to be in a document
5218
+ // fragment in IE 9, so check for that
5219
+ node.document && node.document.nodeType !== 11 ) {
5220
+ return ret;
5221
+ }
5222
+ }
5223
+ } catch(e) {}
5224
+ }
5225
+
5226
+ return Sizzle(expr, null, null, [node]).length > 0;
5227
+ };
5228
+ }
5229
+ })();
5230
+
5231
+ (function(){
5232
+ var div = document.createElement("div");
5233
+
5234
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5235
+
5236
+ // Opera can't find a second classname (in 9.6)
5237
+ // Also, make sure that getElementsByClassName actually exists
5238
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5239
+ return;
5240
+ }
5241
+
5242
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
5243
+ div.lastChild.className = "e";
5244
+
5245
+ if ( div.getElementsByClassName("e").length === 1 ) {
5246
+ return;
5247
+ }
5248
+
5249
+ Expr.order.splice(1, 0, "CLASS");
5250
+ Expr.find.CLASS = function( match, context, isXML ) {
5251
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5252
+ return context.getElementsByClassName(match[1]);
5253
+ }
5254
+ };
5255
+
5256
+ // release memory in IE
5257
+ div = null;
5258
+ })();
5259
+
5260
+ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5261
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5262
+ var elem = checkSet[i];
5263
+
5264
+ if ( elem ) {
5265
+ var match = false;
5266
+
5267
+ elem = elem[dir];
5268
+
5269
+ while ( elem ) {
5270
+ if ( elem[ expando ] === doneName ) {
5271
+ match = checkSet[elem.sizset];
5272
+ break;
5273
+ }
5274
+
5275
+ if ( elem.nodeType === 1 && !isXML ){
5276
+ elem[ expando ] = doneName;
5277
+ elem.sizset = i;
5278
+ }
5279
+
5280
+ if ( elem.nodeName.toLowerCase() === cur ) {
5281
+ match = elem;
5282
+ break;
5283
+ }
5284
+
5285
+ elem = elem[dir];
5286
+ }
5287
+
5288
+ checkSet[i] = match;
5289
+ }
5290
+ }
5291
+ }
5292
+
5293
+ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5294
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5295
+ var elem = checkSet[i];
5296
+
5297
+ if ( elem ) {
5298
+ var match = false;
5299
+
5300
+ elem = elem[dir];
5301
+
5302
+ while ( elem ) {
5303
+ if ( elem[ expando ] === doneName ) {
5304
+ match = checkSet[elem.sizset];
5305
+ break;
5306
+ }
5307
+
5308
+ if ( elem.nodeType === 1 ) {
5309
+ if ( !isXML ) {
5310
+ elem[ expando ] = doneName;
5311
+ elem.sizset = i;
5312
+ }
5313
+
5314
+ if ( typeof cur !== "string" ) {
5315
+ if ( elem === cur ) {
5316
+ match = true;
5317
+ break;
5318
+ }
5319
+
5320
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5321
+ match = elem;
5322
+ break;
5323
+ }
5324
+ }
5325
+
5326
+ elem = elem[dir];
5327
+ }
5328
+
5329
+ checkSet[i] = match;
5330
+ }
5331
+ }
5332
+ }
5333
+
5334
+ if ( document.documentElement.contains ) {
5335
+ Sizzle.contains = function( a, b ) {
5336
+ return a !== b && (a.contains ? a.contains(b) : true);
5337
+ };
5338
+
5339
+ } else if ( document.documentElement.compareDocumentPosition ) {
5340
+ Sizzle.contains = function( a, b ) {
5341
+ return !!(a.compareDocumentPosition(b) & 16);
5342
+ };
5343
+
5344
+ } else {
5345
+ Sizzle.contains = function() {
5346
+ return false;
5347
+ };
5348
+ }
5349
+
5350
+ Sizzle.isXML = function( elem ) {
5351
+ // documentElement is verified for cases where it doesn't yet exist
5352
+ // (such as loading iframes in IE - #4833)
5353
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5354
+
5355
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
5356
+ };
5357
+
5358
+ var posProcess = function( selector, context, seed ) {
5359
+ var match,
5360
+ tmpSet = [],
5361
+ later = "",
5362
+ root = context.nodeType ? [context] : context;
5363
+
5364
+ // Position selectors must be done after the filter
5365
+ // And so must :not(positional) so we move all PSEUDOs to the end
5366
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5367
+ later += match[0];
5368
+ selector = selector.replace( Expr.match.PSEUDO, "" );
5369
+ }
5370
+
5371
+ selector = Expr.relative[selector] ? selector + "*" : selector;
5372
+
5373
+ for ( var i = 0, l = root.length; i < l; i++ ) {
5374
+ Sizzle( selector, root[i], tmpSet, seed );
5375
+ }
5376
+
5377
+ return Sizzle.filter( later, tmpSet );
5378
+ };
5379
+
5380
+ // EXPOSE
5381
+ // Override sizzle attribute retrieval
5382
+ Sizzle.attr = jQuery.attr;
5383
+ Sizzle.selectors.attrMap = {};
5384
+ jQuery.find = Sizzle;
5385
+ jQuery.expr = Sizzle.selectors;
5386
+ jQuery.expr[":"] = jQuery.expr.filters;
5387
+ jQuery.unique = Sizzle.uniqueSort;
5388
+ jQuery.text = Sizzle.getText;
5389
+ jQuery.isXMLDoc = Sizzle.isXML;
5390
+ jQuery.contains = Sizzle.contains;
5391
+
5392
+
5393
+ })();
5394
+
5395
+
5396
+ var runtil = /Until$/,
5397
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5398
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
5399
+ rmultiselector = /,/,
5400
+ isSimple = /^.[^:#\[\.,]*$/,
5401
+ slice = Array.prototype.slice,
5402
+ POS = jQuery.expr.match.globalPOS,
5403
+ // methods guaranteed to produce a unique set when starting from a unique set
5404
+ guaranteedUnique = {
5405
+ children: true,
5406
+ contents: true,
5407
+ next: true,
5408
+ prev: true
5409
+ };
5410
+
5411
+ jQuery.fn.extend({
5412
+ find: function( selector ) {
5413
+ var self = this,
5414
+ i, l;
5415
+
5416
+ if ( typeof selector !== "string" ) {
5417
+ return jQuery( selector ).filter(function() {
5418
+ for ( i = 0, l = self.length; i < l; i++ ) {
5419
+ if ( jQuery.contains( self[ i ], this ) ) {
5420
+ return true;
5421
+ }
5422
+ }
5423
+ });
5424
+ }
5425
+
5426
+ var ret = this.pushStack( "", "find", selector ),
5427
+ length, n, r;
5428
+
5429
+ for ( i = 0, l = this.length; i < l; i++ ) {
5430
+ length = ret.length;
5431
+ jQuery.find( selector, this[i], ret );
5432
+
5433
+ if ( i > 0 ) {
5434
+ // Make sure that the results are unique
5435
+ for ( n = length; n < ret.length; n++ ) {
5436
+ for ( r = 0; r < length; r++ ) {
5437
+ if ( ret[r] === ret[n] ) {
5438
+ ret.splice(n--, 1);
5439
+ break;
5440
+ }
5441
+ }
5442
+ }
5443
+ }
5444
+ }
5445
+
5446
+ return ret;
5447
+ },
5448
+
5449
+ has: function( target ) {
5450
+ var targets = jQuery( target );
5451
+ return this.filter(function() {
5452
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
5453
+ if ( jQuery.contains( this, targets[i] ) ) {
5454
+ return true;
5455
+ }
5456
+ }
5457
+ });
5458
+ },
5459
+
5460
+ not: function( selector ) {
5461
+ return this.pushStack( winnow(this, selector, false), "not", selector);
5462
+ },
5463
+
5464
+ filter: function( selector ) {
5465
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
5466
+ },
5467
+
5468
+ is: function( selector ) {
5469
+ return !!selector && (
5470
+ typeof selector === "string" ?
5471
+ // If this is a positional selector, check membership in the returned set
5472
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
5473
+ POS.test( selector ) ?
5474
+ jQuery( selector, this.context ).index( this[0] ) >= 0 :
5475
+ jQuery.filter( selector, this ).length > 0 :
5476
+ this.filter( selector ).length > 0 );
5477
+ },
5478
+
5479
+ closest: function( selectors, context ) {
5480
+ var ret = [], i, l, cur = this[0];
5481
+
5482
+ // Array (deprecated as of jQuery 1.7)
5483
+ if ( jQuery.isArray( selectors ) ) {
5484
+ var level = 1;
5485
+
5486
+ while ( cur && cur.ownerDocument && cur !== context ) {
5487
+ for ( i = 0; i < selectors.length; i++ ) {
5488
+
5489
+ if ( jQuery( cur ).is( selectors[ i ] ) ) {
5490
+ ret.push({ selector: selectors[ i ], elem: cur, level: level });
5491
+ }
5492
+ }
5493
+
5494
+ cur = cur.parentNode;
5495
+ level++;
5496
+ }
5497
+
5498
+ return ret;
5499
+ }
5500
+
5501
+ // String
5502
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5503
+ jQuery( selectors, context || this.context ) :
5504
+ 0;
5505
+
5506
+ for ( i = 0, l = this.length; i < l; i++ ) {
5507
+ cur = this[i];
5508
+
5509
+ while ( cur ) {
5510
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5511
+ ret.push( cur );
5512
+ break;
5513
+
5514
+ } else {
5515
+ cur = cur.parentNode;
5516
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5517
+ break;
5518
+ }
5519
+ }
5520
+ }
5521
+ }
5522
+
5523
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5524
+
5525
+ return this.pushStack( ret, "closest", selectors );
5526
+ },
5527
+
5528
+ // Determine the position of an element within
5529
+ // the matched set of elements
5530
+ index: function( elem ) {
5531
+
5532
+ // No argument, return index in parent
5533
+ if ( !elem ) {
5534
+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5535
+ }
5536
+
5537
+ // index in selector
5538
+ if ( typeof elem === "string" ) {
5539
+ return jQuery.inArray( this[0], jQuery( elem ) );
5540
+ }
5541
+
5542
+ // Locate the position of the desired element
5543
+ return jQuery.inArray(
5544
+ // If it receives a jQuery object, the first element is used
5545
+ elem.jquery ? elem[0] : elem, this );
5546
+ },
5547
+
5548
+ add: function( selector, context ) {
5549
+ var set = typeof selector === "string" ?
5550
+ jQuery( selector, context ) :
5551
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5552
+ all = jQuery.merge( this.get(), set );
5553
+
5554
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5555
+ all :
5556
+ jQuery.unique( all ) );
5557
+ },
5558
+
5559
+ andSelf: function() {
5560
+ return this.add( this.prevObject );
5561
+ }
5562
+ });
5563
+
5564
+ // A painfully simple check to see if an element is disconnected
5565
+ // from a document (should be improved, where feasible).
5566
+ function isDisconnected( node ) {
5567
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
5568
+ }
5569
+
5570
+ jQuery.each({
5571
+ parent: function( elem ) {
5572
+ var parent = elem.parentNode;
5573
+ return parent && parent.nodeType !== 11 ? parent : null;
5574
+ },
5575
+ parents: function( elem ) {
5576
+ return jQuery.dir( elem, "parentNode" );
5577
+ },
5578
+ parentsUntil: function( elem, i, until ) {
5579
+ return jQuery.dir( elem, "parentNode", until );
5580
+ },
5581
+ next: function( elem ) {
5582
+ return jQuery.nth( elem, 2, "nextSibling" );
5583
+ },
5584
+ prev: function( elem ) {
5585
+ return jQuery.nth( elem, 2, "previousSibling" );
5586
+ },
5587
+ nextAll: function( elem ) {
5588
+ return jQuery.dir( elem, "nextSibling" );
5589
+ },
5590
+ prevAll: function( elem ) {
5591
+ return jQuery.dir( elem, "previousSibling" );
5592
+ },
5593
+ nextUntil: function( elem, i, until ) {
5594
+ return jQuery.dir( elem, "nextSibling", until );
5595
+ },
5596
+ prevUntil: function( elem, i, until ) {
5597
+ return jQuery.dir( elem, "previousSibling", until );
5598
+ },
5599
+ siblings: function( elem ) {
5600
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5601
+ },
5602
+ children: function( elem ) {
5603
+ return jQuery.sibling( elem.firstChild );
5604
+ },
5605
+ contents: function( elem ) {
5606
+ return jQuery.nodeName( elem, "iframe" ) ?
5607
+ elem.contentDocument || elem.contentWindow.document :
5608
+ jQuery.makeArray( elem.childNodes );
5609
+ }
5610
+ }, function( name, fn ) {
5611
+ jQuery.fn[ name ] = function( until, selector ) {
5612
+ var ret = jQuery.map( this, fn, until );
5613
+
5614
+ if ( !runtil.test( name ) ) {
5615
+ selector = until;
5616
+ }
5617
+
5618
+ if ( selector && typeof selector === "string" ) {
5619
+ ret = jQuery.filter( selector, ret );
5620
+ }
5621
+
5622
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5623
+
5624
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5625
+ ret = ret.reverse();
5626
+ }
5627
+
5628
+ return this.pushStack( ret, name, slice.call( arguments ).join(",") );
5629
+ };
5630
+ });
5631
+
5632
+ jQuery.extend({
5633
+ filter: function( expr, elems, not ) {
5634
+ if ( not ) {
5635
+ expr = ":not(" + expr + ")";
5636
+ }
5637
+
5638
+ return elems.length === 1 ?
5639
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5640
+ jQuery.find.matches(expr, elems);
5641
+ },
5642
+
5643
+ dir: function( elem, dir, until ) {
5644
+ var matched = [],
5645
+ cur = elem[ dir ];
5646
+
5647
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5648
+ if ( cur.nodeType === 1 ) {
5649
+ matched.push( cur );
5650
+ }
5651
+ cur = cur[dir];
5652
+ }
5653
+ return matched;
5654
+ },
5655
+
5656
+ nth: function( cur, result, dir, elem ) {
5657
+ result = result || 1;
5658
+ var num = 0;
5659
+
5660
+ for ( ; cur; cur = cur[dir] ) {
5661
+ if ( cur.nodeType === 1 && ++num === result ) {
5662
+ break;
5663
+ }
5664
+ }
5665
+
5666
+ return cur;
5667
+ },
5668
+
5669
+ sibling: function( n, elem ) {
5670
+ var r = [];
5671
+
5672
+ for ( ; n; n = n.nextSibling ) {
5673
+ if ( n.nodeType === 1 && n !== elem ) {
5674
+ r.push( n );
5675
+ }
5676
+ }
5677
+
5678
+ return r;
5679
+ }
5680
+ });
5681
+
5682
+ // Implement the identical functionality for filter and not
5683
+ function winnow( elements, qualifier, keep ) {
5684
+
5685
+ // Can't pass null or undefined to indexOf in Firefox 4
5686
+ // Set to 0 to skip string check
5687
+ qualifier = qualifier || 0;
5688
+
5689
+ if ( jQuery.isFunction( qualifier ) ) {
5690
+ return jQuery.grep(elements, function( elem, i ) {
5691
+ var retVal = !!qualifier.call( elem, i, elem );
5692
+ return retVal === keep;
5693
+ });
5694
+
5695
+ } else if ( qualifier.nodeType ) {
5696
+ return jQuery.grep(elements, function( elem, i ) {
5697
+ return ( elem === qualifier ) === keep;
5698
+ });
5699
+
5700
+ } else if ( typeof qualifier === "string" ) {
5701
+ var filtered = jQuery.grep(elements, function( elem ) {
5702
+ return elem.nodeType === 1;
5703
+ });
5704
+
5705
+ if ( isSimple.test( qualifier ) ) {
5706
+ return jQuery.filter(qualifier, filtered, !keep);
5707
+ } else {
5708
+ qualifier = jQuery.filter( qualifier, filtered );
5709
+ }
5710
+ }
5711
+
5712
+ return jQuery.grep(elements, function( elem, i ) {
5713
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
5714
+ });
5715
+ }
5716
+
5717
+
5718
+
5719
+
5720
+ function createSafeFragment( document ) {
5721
+ var list = nodeNames.split( "|" ),
5722
+ safeFrag = document.createDocumentFragment();
5723
+
5724
+ if ( safeFrag.createElement ) {
5725
+ while ( list.length ) {
5726
+ safeFrag.createElement(
5727
+ list.pop()
5728
+ );
5729
+ }
5730
+ }
5731
+ return safeFrag;
5732
+ }
5733
+
5734
+ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5735
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5736
+ rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5737
+ rleadingWhitespace = /^\s+/,
5738
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5739
+ rtagName = /<([\w:]+)/,
5740
+ rtbody = /<tbody/i,
5741
+ rhtml = /<|&#?\w+;/,
5742
+ rnoInnerhtml = /<(?:script|style)/i,
5743
+ rnocache = /<(?:script|object|embed|option|style)/i,
5744
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5745
+ // checked="checked" or checked
5746
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5747
+ rscriptType = /\/(java|ecma)script/i,
5748
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5749
+ wrapMap = {
5750
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
5751
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
5752
+ thead: [ 1, "<table>", "</table>" ],
5753
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5754
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5755
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5756
+ area: [ 1, "<map>", "</map>" ],
5757
+ _default: [ 0, "", "" ]
5758
+ },
5759
+ safeFragment = createSafeFragment( document );
5760
+
5761
+ wrapMap.optgroup = wrapMap.option;
5762
+ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5763
+ wrapMap.th = wrapMap.td;
5764
+
5765
+ // IE can't serialize <link> and <script> tags normally
5766
+ if ( !jQuery.support.htmlSerialize ) {
5767
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
5768
+ }
5769
+
5770
+ jQuery.fn.extend({
5771
+ text: function( value ) {
5772
+ return jQuery.access( this, function( value ) {
5773
+ return value === undefined ?
5774
+ jQuery.text( this ) :
5775
+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5776
+ }, null, value, arguments.length );
5777
+ },
5778
+
5779
+ wrapAll: function( html ) {
5780
+ if ( jQuery.isFunction( html ) ) {
5781
+ return this.each(function(i) {
5782
+ jQuery(this).wrapAll( html.call(this, i) );
5783
+ });
5784
+ }
5785
+
5786
+ if ( this[0] ) {
5787
+ // The elements to wrap the target around
5788
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5789
+
5790
+ if ( this[0].parentNode ) {
5791
+ wrap.insertBefore( this[0] );
5792
+ }
5793
+
5794
+ wrap.map(function() {
5795
+ var elem = this;
5796
+
5797
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5798
+ elem = elem.firstChild;
5799
+ }
5800
+
5801
+ return elem;
5802
+ }).append( this );
5803
+ }
5804
+
5805
+ return this;
5806
+ },
5807
+
5808
+ wrapInner: function( html ) {
5809
+ if ( jQuery.isFunction( html ) ) {
5810
+ return this.each(function(i) {
5811
+ jQuery(this).wrapInner( html.call(this, i) );
5812
+ });
5813
+ }
5814
+
5815
+ return this.each(function() {
5816
+ var self = jQuery( this ),
5817
+ contents = self.contents();
5818
+
5819
+ if ( contents.length ) {
5820
+ contents.wrapAll( html );
5821
+
5822
+ } else {
5823
+ self.append( html );
5824
+ }
5825
+ });
5826
+ },
5827
+
5828
+ wrap: function( html ) {
5829
+ var isFunction = jQuery.isFunction( html );
5830
+
5831
+ return this.each(function(i) {
5832
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
5833
+ });
5834
+ },
5835
+
5836
+ unwrap: function() {
5837
+ return this.parent().each(function() {
5838
+ if ( !jQuery.nodeName( this, "body" ) ) {
5839
+ jQuery( this ).replaceWith( this.childNodes );
5840
+ }
5841
+ }).end();
5842
+ },
5843
+
5844
+ append: function() {
5845
+ return this.domManip(arguments, true, function( elem ) {
5846
+ if ( this.nodeType === 1 ) {
5847
+ this.appendChild( elem );
5848
+ }
5849
+ });
5850
+ },
5851
+
5852
+ prepend: function() {
5853
+ return this.domManip(arguments, true, function( elem ) {
5854
+ if ( this.nodeType === 1 ) {
5855
+ this.insertBefore( elem, this.firstChild );
5856
+ }
5857
+ });
5858
+ },
5859
+
5860
+ before: function() {
5861
+ if ( this[0] && this[0].parentNode ) {
5862
+ return this.domManip(arguments, false, function( elem ) {
5863
+ this.parentNode.insertBefore( elem, this );
5864
+ });
5865
+ } else if ( arguments.length ) {
5866
+ var set = jQuery.clean( arguments );
5867
+ set.push.apply( set, this.toArray() );
5868
+ return this.pushStack( set, "before", arguments );
5869
+ }
5870
+ },
5871
+
5872
+ after: function() {
5873
+ if ( this[0] && this[0].parentNode ) {
5874
+ return this.domManip(arguments, false, function( elem ) {
5875
+ this.parentNode.insertBefore( elem, this.nextSibling );
5876
+ });
5877
+ } else if ( arguments.length ) {
5878
+ var set = this.pushStack( this, "after", arguments );
5879
+ set.push.apply( set, jQuery.clean(arguments) );
5880
+ return set;
5881
+ }
5882
+ },
5883
+
5884
+ // keepData is for internal use only--do not document
5885
+ remove: function( selector, keepData ) {
5886
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5887
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5888
+ if ( !keepData && elem.nodeType === 1 ) {
5889
+ jQuery.cleanData( elem.getElementsByTagName("*") );
5890
+ jQuery.cleanData( [ elem ] );
5891
+ }
5892
+
5893
+ if ( elem.parentNode ) {
5894
+ elem.parentNode.removeChild( elem );
5895
+ }
5896
+ }
5897
+ }
5898
+
5899
+ return this;
5900
+ },
5901
+
5902
+ empty: function() {
5903
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5904
+ // Remove element nodes and prevent memory leaks
5905
+ if ( elem.nodeType === 1 ) {
5906
+ jQuery.cleanData( elem.getElementsByTagName("*") );
5907
+ }
5908
+
5909
+ // Remove any remaining nodes
5910
+ while ( elem.firstChild ) {
5911
+ elem.removeChild( elem.firstChild );
5912
+ }
5913
+ }
5914
+
5915
+ return this;
5916
+ },
5917
+
5918
+ clone: function( dataAndEvents, deepDataAndEvents ) {
5919
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5920
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5921
+
5922
+ return this.map( function () {
5923
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5924
+ });
5925
+ },
5926
+
5927
+ html: function( value ) {
5928
+ return jQuery.access( this, function( value ) {
5929
+ var elem = this[0] || {},
5930
+ i = 0,
5931
+ l = this.length;
5932
+
5933
+ if ( value === undefined ) {
5934
+ return elem.nodeType === 1 ?
5935
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
5936
+ null;
5937
+ }
5938
+
5939
+
5940
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5941
+ ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5942
+ !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
5943
+
5944
+ value = value.replace( rxhtmlTag, "<$1></$2>" );
5945
+
5946
+ try {
5947
+ for (; i < l; i++ ) {
5948
+ // Remove element nodes and prevent memory leaks
5949
+ elem = this[i] || {};
5950
+ if ( elem.nodeType === 1 ) {
5951
+ jQuery.cleanData( elem.getElementsByTagName( "*" ) );
5952
+ elem.innerHTML = value;
5953
+ }
5954
+ }
5955
+
5956
+ elem = 0;
5957
+
5958
+ // If using innerHTML throws an exception, use the fallback method
5959
+ } catch(e) {}
5960
+ }
5961
+
5962
+ if ( elem ) {
5963
+ this.empty().append( value );
5964
+ }
5965
+ }, null, value, arguments.length );
5966
+ },
5967
+
5968
+ replaceWith: function( value ) {
5969
+ if ( this[0] && this[0].parentNode ) {
5970
+ // Make sure that the elements are removed from the DOM before they are inserted
5971
+ // this can help fix replacing a parent with child elements
5972
+ if ( jQuery.isFunction( value ) ) {
5973
+ return this.each(function(i) {
5974
+ var self = jQuery(this), old = self.html();
5975
+ self.replaceWith( value.call( this, i, old ) );
5976
+ });
5977
+ }
5978
+
5979
+ if ( typeof value !== "string" ) {
5980
+ value = jQuery( value ).detach();
5981
+ }
5982
+
5983
+ return this.each(function() {
5984
+ var next = this.nextSibling,
5985
+ parent = this.parentNode;
5986
+
5987
+ jQuery( this ).remove();
5988
+
5989
+ if ( next ) {
5990
+ jQuery(next).before( value );
5991
+ } else {
5992
+ jQuery(parent).append( value );
5993
+ }
5994
+ });
5995
+ } else {
5996
+ return this.length ?
5997
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5998
+ this;
5999
+ }
6000
+ },
6001
+
6002
+ detach: function( selector ) {
6003
+ return this.remove( selector, true );
6004
+ },
6005
+
6006
+ domManip: function( args, table, callback ) {
6007
+ var results, first, fragment, parent,
6008
+ value = args[0],
6009
+ scripts = [];
6010
+
6011
+ // We can't cloneNode fragments that contain checked, in WebKit
6012
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
6013
+ return this.each(function() {
6014
+ jQuery(this).domManip( args, table, callback, true );
6015
+ });
6016
+ }
6017
+
6018
+ if ( jQuery.isFunction(value) ) {
6019
+ return this.each(function(i) {
6020
+ var self = jQuery(this);
6021
+ args[0] = value.call(this, i, table ? self.html() : undefined);
6022
+ self.domManip( args, table, callback );
6023
+ });
6024
+ }
6025
+
6026
+ if ( this[0] ) {
6027
+ parent = value && value.parentNode;
6028
+
6029
+ // If we're in a fragment, just use that instead of building a new one
6030
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6031
+ results = { fragment: parent };
6032
+
6033
+ } else {
6034
+ results = jQuery.buildFragment( args, this, scripts );
6035
+ }
6036
+
6037
+ fragment = results.fragment;
6038
+
6039
+ if ( fragment.childNodes.length === 1 ) {
6040
+ first = fragment = fragment.firstChild;
6041
+ } else {
6042
+ first = fragment.firstChild;
6043
+ }
6044
+
6045
+ if ( first ) {
6046
+ table = table && jQuery.nodeName( first, "tr" );
6047
+
6048
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6049
+ callback.call(
6050
+ table ?
6051
+ root(this[i], first) :
6052
+ this[i],
6053
+ // Make sure that we do not leak memory by inadvertently discarding
6054
+ // the original fragment (which might have attached data) instead of
6055
+ // using it; in addition, use the original fragment object for the last
6056
+ // item instead of first because it can end up being emptied incorrectly
6057
+ // in certain situations (Bug #8070).
6058
+ // Fragments from the fragment cache must always be cloned and never used
6059
+ // in place.
6060
+ results.cacheable || ( l > 1 && i < lastIndex ) ?
6061
+ jQuery.clone( fragment, true, true ) :
6062
+ fragment
6063
+ );
6064
+ }
6065
+ }
6066
+
6067
+ if ( scripts.length ) {
6068
+ jQuery.each( scripts, function( i, elem ) {
6069
+ if ( elem.src ) {
6070
+ jQuery.ajax({
6071
+ type: "GET",
6072
+ global: false,
6073
+ url: elem.src,
6074
+ async: false,
6075
+ dataType: "script"
6076
+ });
6077
+ } else {
6078
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6079
+ }
6080
+
6081
+ if ( elem.parentNode ) {
6082
+ elem.parentNode.removeChild( elem );
6083
+ }
6084
+ });
6085
+ }
6086
+ }
6087
+
6088
+ return this;
6089
+ }
6090
+ });
6091
+
6092
+ function root( elem, cur ) {
6093
+ return jQuery.nodeName(elem, "table") ?
6094
+ (elem.getElementsByTagName("tbody")[0] ||
6095
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6096
+ elem;
6097
+ }
6098
+
6099
+ function cloneCopyEvent( src, dest ) {
6100
+
6101
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6102
+ return;
6103
+ }
6104
+
6105
+ var type, i, l,
6106
+ oldData = jQuery._data( src ),
6107
+ curData = jQuery._data( dest, oldData ),
6108
+ events = oldData.events;
6109
+
6110
+ if ( events ) {
6111
+ delete curData.handle;
6112
+ curData.events = {};
6113
+
6114
+ for ( type in events ) {
6115
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6116
+ jQuery.event.add( dest, type, events[ type ][ i ] );
6117
+ }
6118
+ }
6119
+ }
6120
+
6121
+ // make the cloned public data object a copy from the original
6122
+ if ( curData.data ) {
6123
+ curData.data = jQuery.extend( {}, curData.data );
6124
+ }
6125
+ }
6126
+
6127
+ function cloneFixAttributes( src, dest ) {
6128
+ var nodeName;
6129
+
6130
+ // We do not need to do anything for non-Elements
6131
+ if ( dest.nodeType !== 1 ) {
6132
+ return;
6133
+ }
6134
+
6135
+ // clearAttributes removes the attributes, which we don't want,
6136
+ // but also removes the attachEvent events, which we *do* want
6137
+ if ( dest.clearAttributes ) {
6138
+ dest.clearAttributes();
6139
+ }
6140
+
6141
+ // mergeAttributes, in contrast, only merges back on the
6142
+ // original attributes, not the events
6143
+ if ( dest.mergeAttributes ) {
6144
+ dest.mergeAttributes( src );
6145
+ }
6146
+
6147
+ nodeName = dest.nodeName.toLowerCase();
6148
+
6149
+ // IE6-8 fail to clone children inside object elements that use
6150
+ // the proprietary classid attribute value (rather than the type
6151
+ // attribute) to identify the type of content to display
6152
+ if ( nodeName === "object" ) {
6153
+ dest.outerHTML = src.outerHTML;
6154
+
6155
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6156
+ // IE6-8 fails to persist the checked state of a cloned checkbox
6157
+ // or radio button. Worse, IE6-7 fail to give the cloned element
6158
+ // a checked appearance if the defaultChecked value isn't also set
6159
+ if ( src.checked ) {
6160
+ dest.defaultChecked = dest.checked = src.checked;
6161
+ }
6162
+
6163
+ // IE6-7 get confused and end up setting the value of a cloned
6164
+ // checkbox/radio button to an empty string instead of "on"
6165
+ if ( dest.value !== src.value ) {
6166
+ dest.value = src.value;
6167
+ }
6168
+
6169
+ // IE6-8 fails to return the selected option to the default selected
6170
+ // state when cloning options
6171
+ } else if ( nodeName === "option" ) {
6172
+ dest.selected = src.defaultSelected;
6173
+
6174
+ // IE6-8 fails to set the defaultValue to the correct value when
6175
+ // cloning other types of input fields
6176
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
6177
+ dest.defaultValue = src.defaultValue;
6178
+
6179
+ // IE blanks contents when cloning scripts
6180
+ } else if ( nodeName === "script" && dest.text !== src.text ) {
6181
+ dest.text = src.text;
6182
+ }
6183
+
6184
+ // Event data gets referenced instead of copied if the expando
6185
+ // gets copied too
6186
+ dest.removeAttribute( jQuery.expando );
6187
+
6188
+ // Clear flags for bubbling special change/submit events, they must
6189
+ // be reattached when the newly cloned events are first activated
6190
+ dest.removeAttribute( "_submit_attached" );
6191
+ dest.removeAttribute( "_change_attached" );
6192
+ }
6193
+
6194
+ jQuery.buildFragment = function( args, nodes, scripts ) {
6195
+ var fragment, cacheable, cacheresults, doc,
6196
+ first = args[ 0 ];
6197
+
6198
+ // nodes may contain either an explicit document object,
6199
+ // a jQuery collection or context object.
6200
+ // If nodes[0] contains a valid object to assign to doc
6201
+ if ( nodes && nodes[0] ) {
6202
+ doc = nodes[0].ownerDocument || nodes[0];
6203
+ }
6204
+
6205
+ // Ensure that an attr object doesn't incorrectly stand in as a document object
6206
+ // Chrome and Firefox seem to allow this to occur and will throw exception
6207
+ // Fixes #8950
6208
+ if ( !doc.createDocumentFragment ) {
6209
+ doc = document;
6210
+ }
6211
+
6212
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6213
+ // Cloning options loses the selected state, so don't cache them
6214
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6215
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6216
+ // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
6217
+ if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
6218
+ first.charAt(0) === "<" && !rnocache.test( first ) &&
6219
+ (jQuery.support.checkClone || !rchecked.test( first )) &&
6220
+ (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
6221
+
6222
+ cacheable = true;
6223
+
6224
+ cacheresults = jQuery.fragments[ first ];
6225
+ if ( cacheresults && cacheresults !== 1 ) {
6226
+ fragment = cacheresults;
6227
+ }
6228
+ }
6229
+
6230
+ if ( !fragment ) {
6231
+ fragment = doc.createDocumentFragment();
6232
+ jQuery.clean( args, doc, fragment, scripts );
6233
+ }
6234
+
6235
+ if ( cacheable ) {
6236
+ jQuery.fragments[ first ] = cacheresults ? fragment : 1;
6237
+ }
6238
+
6239
+ return { fragment: fragment, cacheable: cacheable };
6240
+ };
6241
+
6242
+ jQuery.fragments = {};
6243
+
6244
+ jQuery.each({
6245
+ appendTo: "append",
6246
+ prependTo: "prepend",
6247
+ insertBefore: "before",
6248
+ insertAfter: "after",
6249
+ replaceAll: "replaceWith"
6250
+ }, function( name, original ) {
6251
+ jQuery.fn[ name ] = function( selector ) {
6252
+ var ret = [],
6253
+ insert = jQuery( selector ),
6254
+ parent = this.length === 1 && this[0].parentNode;
6255
+
6256
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6257
+ insert[ original ]( this[0] );
6258
+ return this;
6259
+
6260
+ } else {
6261
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
6262
+ var elems = ( i > 0 ? this.clone(true) : this ).get();
6263
+ jQuery( insert[i] )[ original ]( elems );
6264
+ ret = ret.concat( elems );
6265
+ }
6266
+
6267
+ return this.pushStack( ret, name, insert.selector );
6268
+ }
6269
+ };
6270
+ });
6271
+
6272
+ function getAll( elem ) {
6273
+ if ( typeof elem.getElementsByTagName !== "undefined" ) {
6274
+ return elem.getElementsByTagName( "*" );
6275
+
6276
+ } else if ( typeof elem.querySelectorAll !== "undefined" ) {
6277
+ return elem.querySelectorAll( "*" );
6278
+
6279
+ } else {
6280
+ return [];
6281
+ }
6282
+ }
6283
+
6284
+ // Used in clean, fixes the defaultChecked property
6285
+ function fixDefaultChecked( elem ) {
6286
+ if ( elem.type === "checkbox" || elem.type === "radio" ) {
6287
+ elem.defaultChecked = elem.checked;
6288
+ }
6289
+ }
6290
+ // Finds all inputs and passes them to fixDefaultChecked
6291
+ function findInputs( elem ) {
6292
+ var nodeName = ( elem.nodeName || "" ).toLowerCase();
6293
+ if ( nodeName === "input" ) {
6294
+ fixDefaultChecked( elem );
6295
+ // Skip scripts, get other children
6296
+ } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
6297
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6298
+ }
6299
+ }
6300
+
6301
+ // Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
6302
+ function shimCloneNode( elem ) {
6303
+ var div = document.createElement( "div" );
6304
+ safeFragment.appendChild( div );
6305
+
6306
+ div.innerHTML = elem.outerHTML;
6307
+ return div.firstChild;
6308
+ }
6309
+
6310
+ jQuery.extend({
6311
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6312
+ var srcElements,
6313
+ destElements,
6314
+ i,
6315
+ // IE<=8 does not properly clone detached, unknown element nodes
6316
+ clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?
6317
+ elem.cloneNode( true ) :
6318
+ shimCloneNode( elem );
6319
+
6320
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6321
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6322
+ // IE copies events bound via attachEvent when using cloneNode.
6323
+ // Calling detachEvent on the clone will also remove the events
6324
+ // from the original. In order to get around this, we use some
6325
+ // proprietary methods to clear the events. Thanks to MooTools
6326
+ // guys for this hotness.
6327
+
6328
+ cloneFixAttributes( elem, clone );
6329
+
6330
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
6331
+ srcElements = getAll( elem );
6332
+ destElements = getAll( clone );
6333
+
6334
+ // Weird iteration because IE will replace the length property
6335
+ // with an element if you are cloning the body and one of the
6336
+ // elements on the page has a name or id of "length"
6337
+ for ( i = 0; srcElements[i]; ++i ) {
6338
+ // Ensure that the destination node is not null; Fixes #9587
6339
+ if ( destElements[i] ) {
6340
+ cloneFixAttributes( srcElements[i], destElements[i] );
6341
+ }
6342
+ }
6343
+ }
6344
+
6345
+ // Copy the events from the original to the clone
6346
+ if ( dataAndEvents ) {
6347
+ cloneCopyEvent( elem, clone );
6348
+
6349
+ if ( deepDataAndEvents ) {
6350
+ srcElements = getAll( elem );
6351
+ destElements = getAll( clone );
6352
+
6353
+ for ( i = 0; srcElements[i]; ++i ) {
6354
+ cloneCopyEvent( srcElements[i], destElements[i] );
6355
+ }
6356
+ }
6357
+ }
6358
+
6359
+ srcElements = destElements = null;
6360
+
6361
+ // Return the cloned set
6362
+ return clone;
6363
+ },
6364
+
6365
+ clean: function( elems, context, fragment, scripts ) {
6366
+ var checkScriptType, script, j,
6367
+ ret = [];
6368
+
6369
+ context = context || document;
6370
+
6371
+ // !context.createElement fails in IE with an error but returns typeof 'object'
6372
+ if ( typeof context.createElement === "undefined" ) {
6373
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6374
+ }
6375
+
6376
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6377
+ if ( typeof elem === "number" ) {
6378
+ elem += "";
6379
+ }
6380
+
6381
+ if ( !elem ) {
6382
+ continue;
6383
+ }
6384
+
6385
+ // Convert html string into DOM nodes
6386
+ if ( typeof elem === "string" ) {
6387
+ if ( !rhtml.test( elem ) ) {
6388
+ elem = context.createTextNode( elem );
6389
+ } else {
6390
+ // Fix "XHTML"-style tags in all browsers
6391
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
6392
+
6393
+ // Trim whitespace, otherwise indexOf won't work as expected
6394
+ var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
6395
+ wrap = wrapMap[ tag ] || wrapMap._default,
6396
+ depth = wrap[0],
6397
+ div = context.createElement("div"),
6398
+ safeChildNodes = safeFragment.childNodes,
6399
+ remove;
6400
+
6401
+ // Append wrapper element to unknown element safe doc fragment
6402
+ if ( context === document ) {
6403
+ // Use the fragment we've already created for this document
6404
+ safeFragment.appendChild( div );
6405
+ } else {
6406
+ // Use a fragment created with the owner document
6407
+ createSafeFragment( context ).appendChild( div );
6408
+ }
6409
+
6410
+ // Go to html and back, then peel off extra wrappers
6411
+ div.innerHTML = wrap[1] + elem + wrap[2];
6412
+
6413
+ // Move to the right depth
6414
+ while ( depth-- ) {
6415
+ div = div.lastChild;
6416
+ }
6417
+
6418
+ // Remove IE's autoinserted <tbody> from table fragments
6419
+ if ( !jQuery.support.tbody ) {
6420
+
6421
+ // String was a <table>, *may* have spurious <tbody>
6422
+ var hasBody = rtbody.test(elem),
6423
+ tbody = tag === "table" && !hasBody ?
6424
+ div.firstChild && div.firstChild.childNodes :
6425
+
6426
+ // String was a bare <thead> or <tfoot>
6427
+ wrap[1] === "<table>" && !hasBody ?
6428
+ div.childNodes :
6429
+ [];
6430
+
6431
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
6432
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6433
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
6434
+ }
6435
+ }
6436
+ }
6437
+
6438
+ // IE completely kills leading whitespace when innerHTML is used
6439
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6440
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6441
+ }
6442
+
6443
+ elem = div.childNodes;
6444
+
6445
+ // Clear elements from DocumentFragment (safeFragment or otherwise)
6446
+ // to avoid hoarding elements. Fixes #11356
6447
+ if ( div ) {
6448
+ div.parentNode.removeChild( div );
6449
+
6450
+ // Guard against -1 index exceptions in FF3.6
6451
+ if ( safeChildNodes.length > 0 ) {
6452
+ remove = safeChildNodes[ safeChildNodes.length - 1 ];
6453
+
6454
+ if ( remove && remove.parentNode ) {
6455
+ remove.parentNode.removeChild( remove );
6456
+ }
6457
+ }
6458
+ }
6459
+ }
6460
+ }
6461
+
6462
+ // Resets defaultChecked for any radios and checkboxes
6463
+ // about to be appended to the DOM in IE 6/7 (#8060)
6464
+ var len;
6465
+ if ( !jQuery.support.appendChecked ) {
6466
+ if ( elem[0] && typeof (len = elem.length) === "number" ) {
6467
+ for ( j = 0; j < len; j++ ) {
6468
+ findInputs( elem[j] );
6469
+ }
6470
+ } else {
6471
+ findInputs( elem );
6472
+ }
6473
+ }
6474
+
6475
+ if ( elem.nodeType ) {
6476
+ ret.push( elem );
6477
+ } else {
6478
+ ret = jQuery.merge( ret, elem );
6479
+ }
6480
+ }
6481
+
6482
+ if ( fragment ) {
6483
+ checkScriptType = function( elem ) {
6484
+ return !elem.type || rscriptType.test( elem.type );
6485
+ };
6486
+ for ( i = 0; ret[i]; i++ ) {
6487
+ script = ret[i];
6488
+ if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {
6489
+ scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );
6490
+
6491
+ } else {
6492
+ if ( script.nodeType === 1 ) {
6493
+ var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType );
6494
+
6495
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6496
+ }
6497
+ fragment.appendChild( script );
6498
+ }
6499
+ }
6500
+ }
6501
+
6502
+ return ret;
6503
+ },
6504
+
6505
+ cleanData: function( elems ) {
6506
+ var data, id,
6507
+ cache = jQuery.cache,
6508
+ special = jQuery.event.special,
6509
+ deleteExpando = jQuery.support.deleteExpando;
6510
+
6511
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6512
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6513
+ continue;
6514
+ }
6515
+
6516
+ id = elem[ jQuery.expando ];
6517
+
6518
+ if ( id ) {
6519
+ data = cache[ id ];
6520
+
6521
+ if ( data && data.events ) {
6522
+ for ( var type in data.events ) {
6523
+ if ( special[ type ] ) {
6524
+ jQuery.event.remove( elem, type );
6525
+
6526
+ // This is a shortcut to avoid jQuery.event.remove's overhead
6527
+ } else {
6528
+ jQuery.removeEvent( elem, type, data.handle );
6529
+ }
6530
+ }
6531
+
6532
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6533
+ if ( data.handle ) {
6534
+ data.handle.elem = null;
6535
+ }
6536
+ }
6537
+
6538
+ if ( deleteExpando ) {
6539
+ delete elem[ jQuery.expando ];
6540
+
6541
+ } else if ( elem.removeAttribute ) {
6542
+ elem.removeAttribute( jQuery.expando );
6543
+ }
6544
+
6545
+ delete cache[ id ];
6546
+ }
6547
+ }
6548
+ }
6549
+ });
6550
+
6551
+
6552
+
6553
+
6554
+ var ralpha = /alpha\([^)]*\)/i,
6555
+ ropacity = /opacity=([^)]*)/,
6556
+ // fixed for IE9, see #8346
6557
+ rupper = /([A-Z]|^ms)/g,
6558
+ rnum = /^[\-+]?(?:\d*\.)?\d+$/i,
6559
+ rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
6560
+ rrelNum = /^([\-+])=([\-+.\de]+)/,
6561
+ rmargin = /^margin/,
6562
+
6563
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6564
+
6565
+ // order is important!
6566
+ cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6567
+
6568
+ curCSS,
6569
+
6570
+ getComputedStyle,
6571
+ currentStyle;
6572
+
6573
+ jQuery.fn.css = function( name, value ) {
6574
+ return jQuery.access( this, function( elem, name, value ) {
6575
+ return value !== undefined ?
6576
+ jQuery.style( elem, name, value ) :
6577
+ jQuery.css( elem, name );
6578
+ }, name, value, arguments.length > 1 );
6579
+ };
6580
+
6581
+ jQuery.extend({
6582
+ // Add in style property hooks for overriding the default
6583
+ // behavior of getting and setting a style property
6584
+ cssHooks: {
6585
+ opacity: {
6586
+ get: function( elem, computed ) {
6587
+ if ( computed ) {
6588
+ // We should always get a number back from opacity
6589
+ var ret = curCSS( elem, "opacity" );
6590
+ return ret === "" ? "1" : ret;
6591
+
6592
+ } else {
6593
+ return elem.style.opacity;
6594
+ }
6595
+ }
6596
+ }
6597
+ },
6598
+
6599
+ // Exclude the following css properties to add px
6600
+ cssNumber: {
6601
+ "fillOpacity": true,
6602
+ "fontWeight": true,
6603
+ "lineHeight": true,
6604
+ "opacity": true,
6605
+ "orphans": true,
6606
+ "widows": true,
6607
+ "zIndex": true,
6608
+ "zoom": true
6609
+ },
6610
+
6611
+ // Add in properties whose names you wish to fix before
6612
+ // setting or getting the value
6613
+ cssProps: {
6614
+ // normalize float css property
6615
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6616
+ },
6617
+
6618
+ // Get and set the style property on a DOM Node
6619
+ style: function( elem, name, value, extra ) {
6620
+ // Don't set styles on text and comment nodes
6621
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6622
+ return;
6623
+ }
6624
+
6625
+ // Make sure that we're working with the right name
6626
+ var ret, type, origName = jQuery.camelCase( name ),
6627
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
6628
+
6629
+ name = jQuery.cssProps[ origName ] || origName;
6630
+
6631
+ // Check if we're setting a value
6632
+ if ( value !== undefined ) {
6633
+ type = typeof value;
6634
+
6635
+ // convert relative number strings (+= or -=) to relative numbers. #7345
6636
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6637
+ value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6638
+ // Fixes bug #9237
6639
+ type = "number";
6640
+ }
6641
+
6642
+ // Make sure that NaN and null values aren't set. See: #7116
6643
+ if ( value == null || type === "number" && isNaN( value ) ) {
6644
+ return;
6645
+ }
6646
+
6647
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
6648
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6649
+ value += "px";
6650
+ }
6651
+
6652
+ // If a hook was provided, use that value, otherwise just set the specified value
6653
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6654
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6655
+ // Fixes bug #5509
6656
+ try {
6657
+ style[ name ] = value;
6658
+ } catch(e) {}
6659
+ }
6660
+
6661
+ } else {
6662
+ // If a hook was provided get the non-computed value from there
6663
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6664
+ return ret;
6665
+ }
6666
+
6667
+ // Otherwise just get the value from the style object
6668
+ return style[ name ];
6669
+ }
6670
+ },
6671
+
6672
+ css: function( elem, name, extra ) {
6673
+ var ret, hooks;
6674
+
6675
+ // Make sure that we're working with the right name
6676
+ name = jQuery.camelCase( name );
6677
+ hooks = jQuery.cssHooks[ name ];
6678
+ name = jQuery.cssProps[ name ] || name;
6679
+
6680
+ // cssFloat needs a special treatment
6681
+ if ( name === "cssFloat" ) {
6682
+ name = "float";
6683
+ }
6684
+
6685
+ // If a hook was provided get the computed value from there
6686
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6687
+ return ret;
6688
+
6689
+ // Otherwise, if a way to get the computed value exists, use that
6690
+ } else if ( curCSS ) {
6691
+ return curCSS( elem, name );
6692
+ }
6693
+ },
6694
+
6695
+ // A method for quickly swapping in/out CSS properties to get correct calculations
6696
+ swap: function( elem, options, callback ) {
6697
+ var old = {},
6698
+ ret, name;
6699
+
6700
+ // Remember the old values, and insert the new ones
6701
+ for ( name in options ) {
6702
+ old[ name ] = elem.style[ name ];
6703
+ elem.style[ name ] = options[ name ];
6704
+ }
6705
+
6706
+ ret = callback.call( elem );
6707
+
6708
+ // Revert the old values
6709
+ for ( name in options ) {
6710
+ elem.style[ name ] = old[ name ];
6711
+ }
6712
+
6713
+ return ret;
6714
+ }
6715
+ });
6716
+
6717
+ // DEPRECATED in 1.3, Use jQuery.css() instead
6718
+ jQuery.curCSS = jQuery.css;
6719
+
6720
+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
6721
+ getComputedStyle = function( elem, name ) {
6722
+ var ret, defaultView, computedStyle, width,
6723
+ style = elem.style;
6724
+
6725
+ name = name.replace( rupper, "-$1" ).toLowerCase();
6726
+
6727
+ if ( (defaultView = elem.ownerDocument.defaultView) &&
6728
+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6729
+
6730
+ ret = computedStyle.getPropertyValue( name );
6731
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6732
+ ret = jQuery.style( elem, name );
6733
+ }
6734
+ }
6735
+
6736
+ // A tribute to the "awesome hack by Dean Edwards"
6737
+ // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins
6738
+ // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6739
+ if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {
6740
+ width = style.width;
6741
+ style.width = ret;
6742
+ ret = computedStyle.width;
6743
+ style.width = width;
6744
+ }
6745
+
6746
+ return ret;
6747
+ };
6748
+ }
6749
+
6750
+ if ( document.documentElement.currentStyle ) {
6751
+ currentStyle = function( elem, name ) {
6752
+ var left, rsLeft, uncomputed,
6753
+ ret = elem.currentStyle && elem.currentStyle[ name ],
6754
+ style = elem.style;
6755
+
6756
+ // Avoid setting ret to empty string here
6757
+ // so we don't default to auto
6758
+ if ( ret == null && style && (uncomputed = style[ name ]) ) {
6759
+ ret = uncomputed;
6760
+ }
6761
+
6762
+ // From the awesome hack by Dean Edwards
6763
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6764
+
6765
+ // If we're not dealing with a regular pixel number
6766
+ // but a number that has a weird ending, we need to convert it to pixels
6767
+ if ( rnumnonpx.test( ret ) ) {
6768
+
6769
+ // Remember the original values
6770
+ left = style.left;
6771
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
6772
+
6773
+ // Put in the new values to get a computed value out
6774
+ if ( rsLeft ) {
6775
+ elem.runtimeStyle.left = elem.currentStyle.left;
6776
+ }
6777
+ style.left = name === "fontSize" ? "1em" : ret;
6778
+ ret = style.pixelLeft + "px";
6779
+
6780
+ // Revert the changed values
6781
+ style.left = left;
6782
+ if ( rsLeft ) {
6783
+ elem.runtimeStyle.left = rsLeft;
6784
+ }
6785
+ }
6786
+
6787
+ return ret === "" ? "auto" : ret;
6788
+ };
6789
+ }
6790
+
6791
+ curCSS = getComputedStyle || currentStyle;
6792
+
6793
+ function getWidthOrHeight( elem, name, extra ) {
6794
+
6795
+ // Start with offset property
6796
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6797
+ i = name === "width" ? 1 : 0,
6798
+ len = 4;
6799
+
6800
+ if ( val > 0 ) {
6801
+ if ( extra !== "border" ) {
6802
+ for ( ; i < len; i += 2 ) {
6803
+ if ( !extra ) {
6804
+ val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
6805
+ }
6806
+ if ( extra === "margin" ) {
6807
+ val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
6808
+ } else {
6809
+ val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6810
+ }
6811
+ }
6812
+ }
6813
+
6814
+ return val + "px";
6815
+ }
6816
+
6817
+ // Fall back to computed then uncomputed css if necessary
6818
+ val = curCSS( elem, name );
6819
+ if ( val < 0 || val == null ) {
6820
+ val = elem.style[ name ];
6821
+ }
6822
+
6823
+ // Computed unit is not pixels. Stop here and return.
6824
+ if ( rnumnonpx.test(val) ) {
6825
+ return val;
6826
+ }
6827
+
6828
+ // Normalize "", auto, and prepare for extra
6829
+ val = parseFloat( val ) || 0;
6830
+
6831
+ // Add padding, border, margin
6832
+ if ( extra ) {
6833
+ for ( ; i < len; i += 2 ) {
6834
+ val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
6835
+ if ( extra !== "padding" ) {
6836
+ val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
6837
+ }
6838
+ if ( extra === "margin" ) {
6839
+ val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
6840
+ }
6841
+ }
6842
+ }
6843
+
6844
+ return val + "px";
6845
+ }
6846
+
6847
+ jQuery.each([ "height", "width" ], function( i, name ) {
6848
+ jQuery.cssHooks[ name ] = {
6849
+ get: function( elem, computed, extra ) {
6850
+ if ( computed ) {
6851
+ if ( elem.offsetWidth !== 0 ) {
6852
+ return getWidthOrHeight( elem, name, extra );
6853
+ } else {
6854
+ return jQuery.swap( elem, cssShow, function() {
6855
+ return getWidthOrHeight( elem, name, extra );
6856
+ });
6857
+ }
6858
+ }
6859
+ },
6860
+
6861
+ set: function( elem, value ) {
6862
+ return rnum.test( value ) ?
6863
+ value + "px" :
6864
+ value;
6865
+ }
6866
+ };
6867
+ });
6868
+
6869
+ if ( !jQuery.support.opacity ) {
6870
+ jQuery.cssHooks.opacity = {
6871
+ get: function( elem, computed ) {
6872
+ // IE uses filters for opacity
6873
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6874
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6875
+ computed ? "1" : "";
6876
+ },
6877
+
6878
+ set: function( elem, value ) {
6879
+ var style = elem.style,
6880
+ currentStyle = elem.currentStyle,
6881
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6882
+ filter = currentStyle && currentStyle.filter || style.filter || "";
6883
+
6884
+ // IE has trouble with opacity if it does not have layout
6885
+ // Force it by setting the zoom level
6886
+ style.zoom = 1;
6887
+
6888
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6889
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6890
+
6891
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6892
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
6893
+ // style.removeAttribute is IE Only, but so apparently is this code path...
6894
+ style.removeAttribute( "filter" );
6895
+
6896
+ // if there there is no filter style applied in a css rule, we are done
6897
+ if ( currentStyle && !currentStyle.filter ) {
6898
+ return;
6899
+ }
6900
+ }
6901
+
6902
+ // otherwise, set new filter values
6903
+ style.filter = ralpha.test( filter ) ?
6904
+ filter.replace( ralpha, opacity ) :
6905
+ filter + " " + opacity;
6906
+ }
6907
+ };
6908
+ }
6909
+
6910
+ jQuery(function() {
6911
+ // This hook cannot be added until DOM ready because the support test
6912
+ // for it is not run until after DOM ready
6913
+ if ( !jQuery.support.reliableMarginRight ) {
6914
+ jQuery.cssHooks.marginRight = {
6915
+ get: function( elem, computed ) {
6916
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6917
+ // Work around by temporarily setting element display to inline-block
6918
+ return jQuery.swap( elem, { "display": "inline-block" }, function() {
6919
+ if ( computed ) {
6920
+ return curCSS( elem, "margin-right" );
6921
+ } else {
6922
+ return elem.style.marginRight;
6923
+ }
6924
+ });
6925
+ }
6926
+ };
6927
+ }
6928
+ });
6929
+
6930
+ if ( jQuery.expr && jQuery.expr.filters ) {
6931
+ jQuery.expr.filters.hidden = function( elem ) {
6932
+ var width = elem.offsetWidth,
6933
+ height = elem.offsetHeight;
6934
+
6935
+ return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
6936
+ };
6937
+
6938
+ jQuery.expr.filters.visible = function( elem ) {
6939
+ return !jQuery.expr.filters.hidden( elem );
6940
+ };
6941
+ }
6942
+
6943
+ // These hooks are used by animate to expand properties
6944
+ jQuery.each({
6945
+ margin: "",
6946
+ padding: "",
6947
+ border: "Width"
6948
+ }, function( prefix, suffix ) {
6949
+
6950
+ jQuery.cssHooks[ prefix + suffix ] = {
6951
+ expand: function( value ) {
6952
+ var i,
6953
+
6954
+ // assumes a single number if not a string
6955
+ parts = typeof value === "string" ? value.split(" ") : [ value ],
6956
+ expanded = {};
6957
+
6958
+ for ( i = 0; i < 4; i++ ) {
6959
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
6960
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6961
+ }
6962
+
6963
+ return expanded;
6964
+ }
6965
+ };
6966
+ });
6967
+
6968
+
6969
+
6970
+
6971
+ var r20 = /%20/g,
6972
+ rbracket = /\[\]$/,
6973
+ rCRLF = /\r?\n/g,
6974
+ rhash = /#.*$/,
6975
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6976
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6977
+ // #7653, #8125, #8152: local protocol detection
6978
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6979
+ rnoContent = /^(?:GET|HEAD)$/,
6980
+ rprotocol = /^\/\//,
6981
+ rquery = /\?/,
6982
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6983
+ rselectTextarea = /^(?:select|textarea)/i,
6984
+ rspacesAjax = /\s+/,
6985
+ rts = /([?&])_=[^&]*/,
6986
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6987
+
6988
+ // Keep a copy of the old load method
6989
+ _load = jQuery.fn.load,
6990
+
6991
+ /* Prefilters
6992
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6993
+ * 2) These are called:
6994
+ * - BEFORE asking for a transport
6995
+ * - AFTER param serialization (s.data is a string if s.processData is true)
6996
+ * 3) key is the dataType
6997
+ * 4) the catchall symbol "*" can be used
6998
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6999
+ */
7000
+ prefilters = {},
7001
+
7002
+ /* Transports bindings
7003
+ * 1) key is the dataType
7004
+ * 2) the catchall symbol "*" can be used
7005
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
7006
+ */
7007
+ transports = {},
7008
+
7009
+ // Document location
7010
+ ajaxLocation,
7011
+
7012
+ // Document location segments
7013
+ ajaxLocParts,
7014
+
7015
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7016
+ allTypes = ["*/"] + ["*"];
7017
+
7018
+ // #8138, IE may throw an exception when accessing
7019
+ // a field from window.location if document.domain has been set
7020
+ try {
7021
+ ajaxLocation = location.href;
7022
+ } catch( e ) {
7023
+ // Use the href attribute of an A element
7024
+ // since IE will modify it given document.location
7025
+ ajaxLocation = document.createElement( "a" );
7026
+ ajaxLocation.href = "";
7027
+ ajaxLocation = ajaxLocation.href;
7028
+ }
7029
+
7030
+ // Segment location into parts
7031
+ ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7032
+
7033
+ // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7034
+ function addToPrefiltersOrTransports( structure ) {
7035
+
7036
+ // dataTypeExpression is optional and defaults to "*"
7037
+ return function( dataTypeExpression, func ) {
7038
+
7039
+ if ( typeof dataTypeExpression !== "string" ) {
7040
+ func = dataTypeExpression;
7041
+ dataTypeExpression = "*";
7042
+ }
7043
+
7044
+ if ( jQuery.isFunction( func ) ) {
7045
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
7046
+ i = 0,
7047
+ length = dataTypes.length,
7048
+ dataType,
7049
+ list,
7050
+ placeBefore;
7051
+
7052
+ // For each dataType in the dataTypeExpression
7053
+ for ( ; i < length; i++ ) {
7054
+ dataType = dataTypes[ i ];
7055
+ // We control if we're asked to add before
7056
+ // any existing element
7057
+ placeBefore = /^\+/.test( dataType );
7058
+ if ( placeBefore ) {
7059
+ dataType = dataType.substr( 1 ) || "*";
7060
+ }
7061
+ list = structure[ dataType ] = structure[ dataType ] || [];
7062
+ // then we add to the structure accordingly
7063
+ list[ placeBefore ? "unshift" : "push" ]( func );
7064
+ }
7065
+ }
7066
+ };
7067
+ }
7068
+
7069
+ // Base inspection function for prefilters and transports
7070
+ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7071
+ dataType /* internal */, inspected /* internal */ ) {
7072
+
7073
+ dataType = dataType || options.dataTypes[ 0 ];
7074
+ inspected = inspected || {};
7075
+
7076
+ inspected[ dataType ] = true;
7077
+
7078
+ var list = structure[ dataType ],
7079
+ i = 0,
7080
+ length = list ? list.length : 0,
7081
+ executeOnly = ( structure === prefilters ),
7082
+ selection;
7083
+
7084
+ for ( ; i < length && ( executeOnly || !selection ); i++ ) {
7085
+ selection = list[ i ]( options, originalOptions, jqXHR );
7086
+ // If we got redirected to another dataType
7087
+ // we try there if executing only and not done already
7088
+ if ( typeof selection === "string" ) {
7089
+ if ( !executeOnly || inspected[ selection ] ) {
7090
+ selection = undefined;
7091
+ } else {
7092
+ options.dataTypes.unshift( selection );
7093
+ selection = inspectPrefiltersOrTransports(
7094
+ structure, options, originalOptions, jqXHR, selection, inspected );
7095
+ }
7096
+ }
7097
+ }
7098
+ // If we're only executing or nothing was selected
7099
+ // we try the catchall dataType if not done already
7100
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7101
+ selection = inspectPrefiltersOrTransports(
7102
+ structure, options, originalOptions, jqXHR, "*", inspected );
7103
+ }
7104
+ // unnecessary when only executing (prefilters)
7105
+ // but it'll be ignored by the caller in that case
7106
+ return selection;
7107
+ }
7108
+
7109
+ // A special extend for ajax options
7110
+ // that takes "flat" options (not to be deep extended)
7111
+ // Fixes #9887
7112
+ function ajaxExtend( target, src ) {
7113
+ var key, deep,
7114
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
7115
+ for ( key in src ) {
7116
+ if ( src[ key ] !== undefined ) {
7117
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
7118
+ }
7119
+ }
7120
+ if ( deep ) {
7121
+ jQuery.extend( true, target, deep );
7122
+ }
7123
+ }
7124
+
7125
+ jQuery.fn.extend({
7126
+ load: function( url, params, callback ) {
7127
+ if ( typeof url !== "string" && _load ) {
7128
+ return _load.apply( this, arguments );
7129
+
7130
+ // Don't do a request if no elements are being requested
7131
+ } else if ( !this.length ) {
7132
+ return this;
7133
+ }
7134
+
7135
+ var off = url.indexOf( " " );
7136
+ if ( off >= 0 ) {
7137
+ var selector = url.slice( off, url.length );
7138
+ url = url.slice( 0, off );
7139
+ }
7140
+
7141
+ // Default to a GET request
7142
+ var type = "GET";
7143
+
7144
+ // If the second parameter was provided
7145
+ if ( params ) {
7146
+ // If it's a function
7147
+ if ( jQuery.isFunction( params ) ) {
7148
+ // We assume that it's the callback
7149
+ callback = params;
7150
+ params = undefined;
7151
+
7152
+ // Otherwise, build a param string
7153
+ } else if ( typeof params === "object" ) {
7154
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7155
+ type = "POST";
7156
+ }
7157
+ }
7158
+
7159
+ var self = this;
7160
+
7161
+ // Request the remote document
7162
+ jQuery.ajax({
7163
+ url: url,
7164
+ type: type,
7165
+ dataType: "html",
7166
+ data: params,
7167
+ // Complete callback (responseText is used internally)
7168
+ complete: function( jqXHR, status, responseText ) {
7169
+ // Store the response as specified by the jqXHR object
7170
+ responseText = jqXHR.responseText;
7171
+ // If successful, inject the HTML into all the matched elements
7172
+ if ( jqXHR.isResolved() ) {
7173
+ // #4825: Get the actual response in case
7174
+ // a dataFilter is present in ajaxSettings
7175
+ jqXHR.done(function( r ) {
7176
+ responseText = r;
7177
+ });
7178
+ // See if a selector was specified
7179
+ self.html( selector ?
7180
+ // Create a dummy div to hold the results
7181
+ jQuery("<div>")
7182
+ // inject the contents of the document in, removing the scripts
7183
+ // to avoid any 'Permission Denied' errors in IE
7184
+ .append(responseText.replace(rscript, ""))
7185
+
7186
+ // Locate the specified elements
7187
+ .find(selector) :
7188
+
7189
+ // If not, just inject the full result
7190
+ responseText );
7191
+ }
7192
+
7193
+ if ( callback ) {
7194
+ self.each( callback, [ responseText, status, jqXHR ] );
7195
+ }
7196
+ }
7197
+ });
7198
+
7199
+ return this;
7200
+ },
7201
+
7202
+ serialize: function() {
7203
+ return jQuery.param( this.serializeArray() );
7204
+ },
7205
+
7206
+ serializeArray: function() {
7207
+ return this.map(function(){
7208
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
7209
+ })
7210
+ .filter(function(){
7211
+ return this.name && !this.disabled &&
7212
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
7213
+ rinput.test( this.type ) );
7214
+ })
7215
+ .map(function( i, elem ){
7216
+ var val = jQuery( this ).val();
7217
+
7218
+ return val == null ?
7219
+ null :
7220
+ jQuery.isArray( val ) ?
7221
+ jQuery.map( val, function( val, i ){
7222
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7223
+ }) :
7224
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7225
+ }).get();
7226
+ }
7227
+ });
7228
+
7229
+ // Attach a bunch of functions for handling common AJAX events
7230
+ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7231
+ jQuery.fn[ o ] = function( f ){
7232
+ return this.on( o, f );
7233
+ };
7234
+ });
7235
+
7236
+ jQuery.each( [ "get", "post" ], function( i, method ) {
7237
+ jQuery[ method ] = function( url, data, callback, type ) {
7238
+ // shift arguments if data argument was omitted
7239
+ if ( jQuery.isFunction( data ) ) {
7240
+ type = type || callback;
7241
+ callback = data;
7242
+ data = undefined;
7243
+ }
7244
+
7245
+ return jQuery.ajax({
7246
+ type: method,
7247
+ url: url,
7248
+ data: data,
7249
+ success: callback,
7250
+ dataType: type
7251
+ });
7252
+ };
7253
+ });
7254
+
7255
+ jQuery.extend({
7256
+
7257
+ getScript: function( url, callback ) {
7258
+ return jQuery.get( url, undefined, callback, "script" );
7259
+ },
7260
+
7261
+ getJSON: function( url, data, callback ) {
7262
+ return jQuery.get( url, data, callback, "json" );
7263
+ },
7264
+
7265
+ // Creates a full fledged settings object into target
7266
+ // with both ajaxSettings and settings fields.
7267
+ // If target is omitted, writes into ajaxSettings.
7268
+ ajaxSetup: function( target, settings ) {
7269
+ if ( settings ) {
7270
+ // Building a settings object
7271
+ ajaxExtend( target, jQuery.ajaxSettings );
7272
+ } else {
7273
+ // Extending ajaxSettings
7274
+ settings = target;
7275
+ target = jQuery.ajaxSettings;
7276
+ }
7277
+ ajaxExtend( target, settings );
7278
+ return target;
7279
+ },
7280
+
7281
+ ajaxSettings: {
7282
+ url: ajaxLocation,
7283
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7284
+ global: true,
7285
+ type: "GET",
7286
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7287
+ processData: true,
7288
+ async: true,
7289
+ /*
7290
+ timeout: 0,
7291
+ data: null,
7292
+ dataType: null,
7293
+ username: null,
7294
+ password: null,
7295
+ cache: null,
7296
+ traditional: false,
7297
+ headers: {},
7298
+ */
7299
+
7300
+ accepts: {
7301
+ xml: "application/xml, text/xml",
7302
+ html: "text/html",
7303
+ text: "text/plain",
7304
+ json: "application/json, text/javascript",
7305
+ "*": allTypes
7306
+ },
7307
+
7308
+ contents: {
7309
+ xml: /xml/,
7310
+ html: /html/,
7311
+ json: /json/
7312
+ },
7313
+
7314
+ responseFields: {
7315
+ xml: "responseXML",
7316
+ text: "responseText"
7317
+ },
7318
+
7319
+ // List of data converters
7320
+ // 1) key format is "source_type destination_type" (a single space in-between)
7321
+ // 2) the catchall symbol "*" can be used for source_type
7322
+ converters: {
7323
+
7324
+ // Convert anything to text
7325
+ "* text": window.String,
7326
+
7327
+ // Text to html (true = no transformation)
7328
+ "text html": true,
7329
+
7330
+ // Evaluate text as a json expression
7331
+ "text json": jQuery.parseJSON,
7332
+
7333
+ // Parse text as xml
7334
+ "text xml": jQuery.parseXML
7335
+ },
7336
+
7337
+ // For options that shouldn't be deep extended:
7338
+ // you can add your own custom options here if
7339
+ // and when you create one that shouldn't be
7340
+ // deep extended (see ajaxExtend)
7341
+ flatOptions: {
7342
+ context: true,
7343
+ url: true
7344
+ }
7345
+ },
7346
+
7347
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7348
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
7349
+
7350
+ // Main method
7351
+ ajax: function( url, options ) {
7352
+
7353
+ // If url is an object, simulate pre-1.5 signature
7354
+ if ( typeof url === "object" ) {
7355
+ options = url;
7356
+ url = undefined;
7357
+ }
7358
+
7359
+ // Force options to be an object
7360
+ options = options || {};
7361
+
7362
+ var // Create the final options object
7363
+ s = jQuery.ajaxSetup( {}, options ),
7364
+ // Callbacks context
7365
+ callbackContext = s.context || s,
7366
+ // Context for global events
7367
+ // It's the callbackContext if one was provided in the options
7368
+ // and if it's a DOM node or a jQuery collection
7369
+ globalEventContext = callbackContext !== s &&
7370
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7371
+ jQuery( callbackContext ) : jQuery.event,
7372
+ // Deferreds
7373
+ deferred = jQuery.Deferred(),
7374
+ completeDeferred = jQuery.Callbacks( "once memory" ),
7375
+ // Status-dependent callbacks
7376
+ statusCode = s.statusCode || {},
7377
+ // ifModified key
7378
+ ifModifiedKey,
7379
+ // Headers (they are sent all at once)
7380
+ requestHeaders = {},
7381
+ requestHeadersNames = {},
7382
+ // Response headers
7383
+ responseHeadersString,
7384
+ responseHeaders,
7385
+ // transport
7386
+ transport,
7387
+ // timeout handle
7388
+ timeoutTimer,
7389
+ // Cross-domain detection vars
7390
+ parts,
7391
+ // The jqXHR state
7392
+ state = 0,
7393
+ // To know if global events are to be dispatched
7394
+ fireGlobals,
7395
+ // Loop variable
7396
+ i,
7397
+ // Fake xhr
7398
+ jqXHR = {
7399
+
7400
+ readyState: 0,
7401
+
7402
+ // Caches the header
7403
+ setRequestHeader: function( name, value ) {
7404
+ if ( !state ) {
7405
+ var lname = name.toLowerCase();
7406
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7407
+ requestHeaders[ name ] = value;
7408
+ }
7409
+ return this;
7410
+ },
7411
+
7412
+ // Raw string
7413
+ getAllResponseHeaders: function() {
7414
+ return state === 2 ? responseHeadersString : null;
7415
+ },
7416
+
7417
+ // Builds headers hashtable if needed
7418
+ getResponseHeader: function( key ) {
7419
+ var match;
7420
+ if ( state === 2 ) {
7421
+ if ( !responseHeaders ) {
7422
+ responseHeaders = {};
7423
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7424
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7425
+ }
7426
+ }
7427
+ match = responseHeaders[ key.toLowerCase() ];
7428
+ }
7429
+ return match === undefined ? null : match;
7430
+ },
7431
+
7432
+ // Overrides response content-type header
7433
+ overrideMimeType: function( type ) {
7434
+ if ( !state ) {
7435
+ s.mimeType = type;
7436
+ }
7437
+ return this;
7438
+ },
7439
+
7440
+ // Cancel the request
7441
+ abort: function( statusText ) {
7442
+ statusText = statusText || "abort";
7443
+ if ( transport ) {
7444
+ transport.abort( statusText );
7445
+ }
7446
+ done( 0, statusText );
7447
+ return this;
7448
+ }
7449
+ };
7450
+
7451
+ // Callback for when everything is done
7452
+ // It is defined here because jslint complains if it is declared
7453
+ // at the end of the function (which would be more logical and readable)
7454
+ function done( status, nativeStatusText, responses, headers ) {
7455
+
7456
+ // Called once
7457
+ if ( state === 2 ) {
7458
+ return;
7459
+ }
7460
+
7461
+ // State is "done" now
7462
+ state = 2;
7463
+
7464
+ // Clear timeout if it exists
7465
+ if ( timeoutTimer ) {
7466
+ clearTimeout( timeoutTimer );
7467
+ }
7468
+
7469
+ // Dereference transport for early garbage collection
7470
+ // (no matter how long the jqXHR object will be used)
7471
+ transport = undefined;
7472
+
7473
+ // Cache response headers
7474
+ responseHeadersString = headers || "";
7475
+
7476
+ // Set readyState
7477
+ jqXHR.readyState = status > 0 ? 4 : 0;
7478
+
7479
+ var isSuccess,
7480
+ success,
7481
+ error,
7482
+ statusText = nativeStatusText,
7483
+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7484
+ lastModified,
7485
+ etag;
7486
+
7487
+ // If successful, handle type chaining
7488
+ if ( status >= 200 && status < 300 || status === 304 ) {
7489
+
7490
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7491
+ if ( s.ifModified ) {
7492
+
7493
+ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7494
+ jQuery.lastModified[ ifModifiedKey ] = lastModified;
7495
+ }
7496
+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7497
+ jQuery.etag[ ifModifiedKey ] = etag;
7498
+ }
7499
+ }
7500
+
7501
+ // If not modified
7502
+ if ( status === 304 ) {
7503
+
7504
+ statusText = "notmodified";
7505
+ isSuccess = true;
7506
+
7507
+ // If we have data
7508
+ } else {
7509
+
7510
+ try {
7511
+ success = ajaxConvert( s, response );
7512
+ statusText = "success";
7513
+ isSuccess = true;
7514
+ } catch(e) {
7515
+ // We have a parsererror
7516
+ statusText = "parsererror";
7517
+ error = e;
7518
+ }
7519
+ }
7520
+ } else {
7521
+ // We extract error from statusText
7522
+ // then normalize statusText and status for non-aborts
7523
+ error = statusText;
7524
+ if ( !statusText || status ) {
7525
+ statusText = "error";
7526
+ if ( status < 0 ) {
7527
+ status = 0;
7528
+ }
7529
+ }
7530
+ }
7531
+
7532
+ // Set data for the fake xhr object
7533
+ jqXHR.status = status;
7534
+ jqXHR.statusText = "" + ( nativeStatusText || statusText );
7535
+
7536
+ // Success/Error
7537
+ if ( isSuccess ) {
7538
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7539
+ } else {
7540
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7541
+ }
7542
+
7543
+ // Status-dependent callbacks
7544
+ jqXHR.statusCode( statusCode );
7545
+ statusCode = undefined;
7546
+
7547
+ if ( fireGlobals ) {
7548
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7549
+ [ jqXHR, s, isSuccess ? success : error ] );
7550
+ }
7551
+
7552
+ // Complete
7553
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7554
+
7555
+ if ( fireGlobals ) {
7556
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7557
+ // Handle the global AJAX counter
7558
+ if ( !( --jQuery.active ) ) {
7559
+ jQuery.event.trigger( "ajaxStop" );
7560
+ }
7561
+ }
7562
+ }
7563
+
7564
+ // Attach deferreds
7565
+ deferred.promise( jqXHR );
7566
+ jqXHR.success = jqXHR.done;
7567
+ jqXHR.error = jqXHR.fail;
7568
+ jqXHR.complete = completeDeferred.add;
7569
+
7570
+ // Status-dependent callbacks
7571
+ jqXHR.statusCode = function( map ) {
7572
+ if ( map ) {
7573
+ var tmp;
7574
+ if ( state < 2 ) {
7575
+ for ( tmp in map ) {
7576
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7577
+ }
7578
+ } else {
7579
+ tmp = map[ jqXHR.status ];
7580
+ jqXHR.then( tmp, tmp );
7581
+ }
7582
+ }
7583
+ return this;
7584
+ };
7585
+
7586
+ // Remove hash character (#7531: and string promotion)
7587
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7588
+ // We also use the url parameter if available
7589
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7590
+
7591
+ // Extract dataTypes list
7592
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7593
+
7594
+ // Determine if a cross-domain request is in order
7595
+ if ( s.crossDomain == null ) {
7596
+ parts = rurl.exec( s.url.toLowerCase() );
7597
+ s.crossDomain = !!( parts &&
7598
+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7599
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7600
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7601
+ );
7602
+ }
7603
+
7604
+ // Convert data if not already a string
7605
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
7606
+ s.data = jQuery.param( s.data, s.traditional );
7607
+ }
7608
+
7609
+ // Apply prefilters
7610
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7611
+
7612
+ // If request was aborted inside a prefilter, stop there
7613
+ if ( state === 2 ) {
7614
+ return false;
7615
+ }
7616
+
7617
+ // We can fire global events as of now if asked to
7618
+ fireGlobals = s.global;
7619
+
7620
+ // Uppercase the type
7621
+ s.type = s.type.toUpperCase();
7622
+
7623
+ // Determine if request has content
7624
+ s.hasContent = !rnoContent.test( s.type );
7625
+
7626
+ // Watch for a new set of requests
7627
+ if ( fireGlobals && jQuery.active++ === 0 ) {
7628
+ jQuery.event.trigger( "ajaxStart" );
7629
+ }
7630
+
7631
+ // More options handling for requests with no content
7632
+ if ( !s.hasContent ) {
7633
+
7634
+ // If data is available, append data to url
7635
+ if ( s.data ) {
7636
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7637
+ // #9682: remove data so that it's not used in an eventual retry
7638
+ delete s.data;
7639
+ }
7640
+
7641
+ // Get ifModifiedKey before adding the anti-cache parameter
7642
+ ifModifiedKey = s.url;
7643
+
7644
+ // Add anti-cache in url if needed
7645
+ if ( s.cache === false ) {
7646
+
7647
+ var ts = jQuery.now(),
7648
+ // try replacing _= if it is there
7649
+ ret = s.url.replace( rts, "$1_=" + ts );
7650
+
7651
+ // if nothing was replaced, add timestamp to the end
7652
+ s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7653
+ }
7654
+ }
7655
+
7656
+ // Set the correct header, if data is being sent
7657
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7658
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
7659
+ }
7660
+
7661
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7662
+ if ( s.ifModified ) {
7663
+ ifModifiedKey = ifModifiedKey || s.url;
7664
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
7665
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7666
+ }
7667
+ if ( jQuery.etag[ ifModifiedKey ] ) {
7668
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7669
+ }
7670
+ }
7671
+
7672
+ // Set the Accepts header for the server, depending on the dataType
7673
+ jqXHR.setRequestHeader(
7674
+ "Accept",
7675
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7676
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7677
+ s.accepts[ "*" ]
7678
+ );
7679
+
7680
+ // Check for headers option
7681
+ for ( i in s.headers ) {
7682
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
7683
+ }
7684
+
7685
+ // Allow custom headers/mimetypes and early abort
7686
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7687
+ // Abort if not done already
7688
+ jqXHR.abort();
7689
+ return false;
7690
+
7691
+ }
7692
+
7693
+ // Install callbacks on deferreds
7694
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
7695
+ jqXHR[ i ]( s[ i ] );
7696
+ }
7697
+
7698
+ // Get transport
7699
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7700
+
7701
+ // If no transport, we auto-abort
7702
+ if ( !transport ) {
7703
+ done( -1, "No Transport" );
7704
+ } else {
7705
+ jqXHR.readyState = 1;
7706
+ // Send global event
7707
+ if ( fireGlobals ) {
7708
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7709
+ }
7710
+ // Timeout
7711
+ if ( s.async && s.timeout > 0 ) {
7712
+ timeoutTimer = setTimeout( function(){
7713
+ jqXHR.abort( "timeout" );
7714
+ }, s.timeout );
7715
+ }
7716
+
7717
+ try {
7718
+ state = 1;
7719
+ transport.send( requestHeaders, done );
7720
+ } catch (e) {
7721
+ // Propagate exception as error if not done
7722
+ if ( state < 2 ) {
7723
+ done( -1, e );
7724
+ // Simply rethrow otherwise
7725
+ } else {
7726
+ throw e;
7727
+ }
7728
+ }
7729
+ }
7730
+
7731
+ return jqXHR;
7732
+ },
7733
+
7734
+ // Serialize an array of form elements or a set of
7735
+ // key/values into a query string
7736
+ param: function( a, traditional ) {
7737
+ var s = [],
7738
+ add = function( key, value ) {
7739
+ // If value is a function, invoke it and return its value
7740
+ value = jQuery.isFunction( value ) ? value() : value;
7741
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7742
+ };
7743
+
7744
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
7745
+ if ( traditional === undefined ) {
7746
+ traditional = jQuery.ajaxSettings.traditional;
7747
+ }
7748
+
7749
+ // If an array was passed in, assume that it is an array of form elements.
7750
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7751
+ // Serialize the form elements
7752
+ jQuery.each( a, function() {
7753
+ add( this.name, this.value );
7754
+ });
7755
+
7756
+ } else {
7757
+ // If traditional, encode the "old" way (the way 1.3.2 or older
7758
+ // did it), otherwise encode params recursively.
7759
+ for ( var prefix in a ) {
7760
+ buildParams( prefix, a[ prefix ], traditional, add );
7761
+ }
7762
+ }
7763
+
7764
+ // Return the resulting serialization
7765
+ return s.join( "&" ).replace( r20, "+" );
7766
+ }
7767
+ });
7768
+
7769
+ function buildParams( prefix, obj, traditional, add ) {
7770
+ if ( jQuery.isArray( obj ) ) {
7771
+ // Serialize array item.
7772
+ jQuery.each( obj, function( i, v ) {
7773
+ if ( traditional || rbracket.test( prefix ) ) {
7774
+ // Treat each array item as a scalar.
7775
+ add( prefix, v );
7776
+
7777
+ } else {
7778
+ // If array item is non-scalar (array or object), encode its
7779
+ // numeric index to resolve deserialization ambiguity issues.
7780
+ // Note that rack (as of 1.0.0) can't currently deserialize
7781
+ // nested arrays properly, and attempting to do so may cause
7782
+ // a server error. Possible fixes are to modify rack's
7783
+ // deserialization algorithm or to provide an option or flag
7784
+ // to force array serialization to be shallow.
7785
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
7786
+ }
7787
+ });
7788
+
7789
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
7790
+ // Serialize object item.
7791
+ for ( var name in obj ) {
7792
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7793
+ }
7794
+
7795
+ } else {
7796
+ // Serialize scalar item.
7797
+ add( prefix, obj );
7798
+ }
7799
+ }
7800
+
7801
+ // This is still on the jQuery object... for now
7802
+ // Want to move this to jQuery.ajax some day
7803
+ jQuery.extend({
7804
+
7805
+ // Counter for holding the number of active queries
7806
+ active: 0,
7807
+
7808
+ // Last-Modified header cache for next request
7809
+ lastModified: {},
7810
+ etag: {}
7811
+
7812
+ });
7813
+
7814
+ /* Handles responses to an ajax request:
7815
+ * - sets all responseXXX fields accordingly
7816
+ * - finds the right dataType (mediates between content-type and expected dataType)
7817
+ * - returns the corresponding response
7818
+ */
7819
+ function ajaxHandleResponses( s, jqXHR, responses ) {
7820
+
7821
+ var contents = s.contents,
7822
+ dataTypes = s.dataTypes,
7823
+ responseFields = s.responseFields,
7824
+ ct,
7825
+ type,
7826
+ finalDataType,
7827
+ firstDataType;
7828
+
7829
+ // Fill responseXXX fields
7830
+ for ( type in responseFields ) {
7831
+ if ( type in responses ) {
7832
+ jqXHR[ responseFields[type] ] = responses[ type ];
7833
+ }
7834
+ }
7835
+
7836
+ // Remove auto dataType and get content-type in the process
7837
+ while( dataTypes[ 0 ] === "*" ) {
7838
+ dataTypes.shift();
7839
+ if ( ct === undefined ) {
7840
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7841
+ }
7842
+ }
7843
+
7844
+ // Check if we're dealing with a known content-type
7845
+ if ( ct ) {
7846
+ for ( type in contents ) {
7847
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
7848
+ dataTypes.unshift( type );
7849
+ break;
7850
+ }
7851
+ }
7852
+ }
7853
+
7854
+ // Check to see if we have a response for the expected dataType
7855
+ if ( dataTypes[ 0 ] in responses ) {
7856
+ finalDataType = dataTypes[ 0 ];
7857
+ } else {
7858
+ // Try convertible dataTypes
7859
+ for ( type in responses ) {
7860
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7861
+ finalDataType = type;
7862
+ break;
7863
+ }
7864
+ if ( !firstDataType ) {
7865
+ firstDataType = type;
7866
+ }
7867
+ }
7868
+ // Or just use first one
7869
+ finalDataType = finalDataType || firstDataType;
7870
+ }
7871
+
7872
+ // If we found a dataType
7873
+ // We add the dataType to the list if needed
7874
+ // and return the corresponding response
7875
+ if ( finalDataType ) {
7876
+ if ( finalDataType !== dataTypes[ 0 ] ) {
7877
+ dataTypes.unshift( finalDataType );
7878
+ }
7879
+ return responses[ finalDataType ];
7880
+ }
7881
+ }
7882
+
7883
+ // Chain conversions given the request and the original response
7884
+ function ajaxConvert( s, response ) {
7885
+
7886
+ // Apply the dataFilter if provided
7887
+ if ( s.dataFilter ) {
7888
+ response = s.dataFilter( response, s.dataType );
7889
+ }
7890
+
7891
+ var dataTypes = s.dataTypes,
7892
+ converters = {},
7893
+ i,
7894
+ key,
7895
+ length = dataTypes.length,
7896
+ tmp,
7897
+ // Current and previous dataTypes
7898
+ current = dataTypes[ 0 ],
7899
+ prev,
7900
+ // Conversion expression
7901
+ conversion,
7902
+ // Conversion function
7903
+ conv,
7904
+ // Conversion functions (transitive conversion)
7905
+ conv1,
7906
+ conv2;
7907
+
7908
+ // For each dataType in the chain
7909
+ for ( i = 1; i < length; i++ ) {
7910
+
7911
+ // Create converters map
7912
+ // with lowercased keys
7913
+ if ( i === 1 ) {
7914
+ for ( key in s.converters ) {
7915
+ if ( typeof key === "string" ) {
7916
+ converters[ key.toLowerCase() ] = s.converters[ key ];
7917
+ }
7918
+ }
7919
+ }
7920
+
7921
+ // Get the dataTypes
7922
+ prev = current;
7923
+ current = dataTypes[ i ];
7924
+
7925
+ // If current is auto dataType, update it to prev
7926
+ if ( current === "*" ) {
7927
+ current = prev;
7928
+ // If no auto and dataTypes are actually different
7929
+ } else if ( prev !== "*" && prev !== current ) {
7930
+
7931
+ // Get the converter
7932
+ conversion = prev + " " + current;
7933
+ conv = converters[ conversion ] || converters[ "* " + current ];
7934
+
7935
+ // If there is no direct converter, search transitively
7936
+ if ( !conv ) {
7937
+ conv2 = undefined;
7938
+ for ( conv1 in converters ) {
7939
+ tmp = conv1.split( " " );
7940
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7941
+ conv2 = converters[ tmp[1] + " " + current ];
7942
+ if ( conv2 ) {
7943
+ conv1 = converters[ conv1 ];
7944
+ if ( conv1 === true ) {
7945
+ conv = conv2;
7946
+ } else if ( conv2 === true ) {
7947
+ conv = conv1;
7948
+ }
7949
+ break;
7950
+ }
7951
+ }
7952
+ }
7953
+ }
7954
+ // If we found no converter, dispatch an error
7955
+ if ( !( conv || conv2 ) ) {
7956
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7957
+ }
7958
+ // If found converter is not an equivalence
7959
+ if ( conv !== true ) {
7960
+ // Convert with 1 or 2 converters accordingly
7961
+ response = conv ? conv( response ) : conv2( conv1(response) );
7962
+ }
7963
+ }
7964
+ }
7965
+ return response;
7966
+ }
7967
+
7968
+
7969
+
7970
+
7971
+ var jsc = jQuery.now(),
7972
+ jsre = /(\=)\?(&|$)|\?\?/i;
7973
+
7974
+ // Default jsonp settings
7975
+ jQuery.ajaxSetup({
7976
+ jsonp: "callback",
7977
+ jsonpCallback: function() {
7978
+ return jQuery.expando + "_" + ( jsc++ );
7979
+ }
7980
+ });
7981
+
7982
+ // Detect, normalize options and install callbacks for jsonp requests
7983
+ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7984
+
7985
+ var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );
7986
+
7987
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
7988
+ s.jsonp !== false && ( jsre.test( s.url ) ||
7989
+ inspectData && jsre.test( s.data ) ) ) {
7990
+
7991
+ var responseContainer,
7992
+ jsonpCallback = s.jsonpCallback =
7993
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7994
+ previous = window[ jsonpCallback ],
7995
+ url = s.url,
7996
+ data = s.data,
7997
+ replace = "$1" + jsonpCallback + "$2";
7998
+
7999
+ if ( s.jsonp !== false ) {
8000
+ url = url.replace( jsre, replace );
8001
+ if ( s.url === url ) {
8002
+ if ( inspectData ) {
8003
+ data = data.replace( jsre, replace );
8004
+ }
8005
+ if ( s.data === data ) {
8006
+ // Add callback manually
8007
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
8008
+ }
8009
+ }
8010
+ }
8011
+
8012
+ s.url = url;
8013
+ s.data = data;
8014
+
8015
+ // Install callback
8016
+ window[ jsonpCallback ] = function( response ) {
8017
+ responseContainer = [ response ];
8018
+ };
8019
+
8020
+ // Clean-up function
8021
+ jqXHR.always(function() {
8022
+ // Set callback back to previous value
8023
+ window[ jsonpCallback ] = previous;
8024
+ // Call if it was a function and we have a response
8025
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
8026
+ window[ jsonpCallback ]( responseContainer[ 0 ] );
8027
+ }
8028
+ });
8029
+
8030
+ // Use data converter to retrieve json after script execution
8031
+ s.converters["script json"] = function() {
8032
+ if ( !responseContainer ) {
8033
+ jQuery.error( jsonpCallback + " was not called" );
8034
+ }
8035
+ return responseContainer[ 0 ];
8036
+ };
8037
+
8038
+ // force json dataType
8039
+ s.dataTypes[ 0 ] = "json";
8040
+
8041
+ // Delegate to script
8042
+ return "script";
8043
+ }
8044
+ });
8045
+
8046
+
8047
+
8048
+
8049
+ // Install script dataType
8050
+ jQuery.ajaxSetup({
8051
+ accepts: {
8052
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8053
+ },
8054
+ contents: {
8055
+ script: /javascript|ecmascript/
8056
+ },
8057
+ converters: {
8058
+ "text script": function( text ) {
8059
+ jQuery.globalEval( text );
8060
+ return text;
8061
+ }
8062
+ }
8063
+ });
8064
+
8065
+ // Handle cache's special case and global
8066
+ jQuery.ajaxPrefilter( "script", function( s ) {
8067
+ if ( s.cache === undefined ) {
8068
+ s.cache = false;
8069
+ }
8070
+ if ( s.crossDomain ) {
8071
+ s.type = "GET";
8072
+ s.global = false;
8073
+ }
8074
+ });
8075
+
8076
+ // Bind script tag hack transport
8077
+ jQuery.ajaxTransport( "script", function(s) {
8078
+
8079
+ // This transport only deals with cross domain requests
8080
+ if ( s.crossDomain ) {
8081
+
8082
+ var script,
8083
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8084
+
8085
+ return {
8086
+
8087
+ send: function( _, callback ) {
8088
+
8089
+ script = document.createElement( "script" );
8090
+
8091
+ script.async = "async";
8092
+
8093
+ if ( s.scriptCharset ) {
8094
+ script.charset = s.scriptCharset;
8095
+ }
8096
+
8097
+ script.src = s.url;
8098
+
8099
+ // Attach handlers for all browsers
8100
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
8101
+
8102
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8103
+
8104
+ // Handle memory leak in IE
8105
+ script.onload = script.onreadystatechange = null;
8106
+
8107
+ // Remove the script
8108
+ if ( head && script.parentNode ) {
8109
+ head.removeChild( script );
8110
+ }
8111
+
8112
+ // Dereference the script
8113
+ script = undefined;
8114
+
8115
+ // Callback if not abort
8116
+ if ( !isAbort ) {
8117
+ callback( 200, "success" );
8118
+ }
8119
+ }
8120
+ };
8121
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
8122
+ // This arises when a base node is used (#2709 and #4378).
8123
+ head.insertBefore( script, head.firstChild );
8124
+ },
8125
+
8126
+ abort: function() {
8127
+ if ( script ) {
8128
+ script.onload( 0, 1 );
8129
+ }
8130
+ }
8131
+ };
8132
+ }
8133
+ });
8134
+
8135
+
8136
+
8137
+
8138
+ var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8139
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
8140
+ // Abort all pending requests
8141
+ for ( var key in xhrCallbacks ) {
8142
+ xhrCallbacks[ key ]( 0, 1 );
8143
+ }
8144
+ } : false,
8145
+ xhrId = 0,
8146
+ xhrCallbacks;
8147
+
8148
+ // Functions to create xhrs
8149
+ function createStandardXHR() {
8150
+ try {
8151
+ return new window.XMLHttpRequest();
8152
+ } catch( e ) {}
8153
+ }
8154
+
8155
+ function createActiveXHR() {
8156
+ try {
8157
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8158
+ } catch( e ) {}
8159
+ }
8160
+
8161
+ // Create the request object
8162
+ // (This is still attached to ajaxSettings for backward compatibility)
8163
+ jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8164
+ /* Microsoft failed to properly
8165
+ * implement the XMLHttpRequest in IE7 (can't request local files),
8166
+ * so we use the ActiveXObject when it is available
8167
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8168
+ * we need a fallback.
8169
+ */
8170
+ function() {
8171
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
8172
+ } :
8173
+ // For all other browsers, use the standard XMLHttpRequest object
8174
+ createStandardXHR;
8175
+
8176
+ // Determine support properties
8177
+ (function( xhr ) {
8178
+ jQuery.extend( jQuery.support, {
8179
+ ajax: !!xhr,
8180
+ cors: !!xhr && ( "withCredentials" in xhr )
8181
+ });
8182
+ })( jQuery.ajaxSettings.xhr() );
8183
+
8184
+ // Create transport if the browser can provide an xhr
8185
+ if ( jQuery.support.ajax ) {
8186
+
8187
+ jQuery.ajaxTransport(function( s ) {
8188
+ // Cross domain only allowed if supported through XMLHttpRequest
8189
+ if ( !s.crossDomain || jQuery.support.cors ) {
8190
+
8191
+ var callback;
8192
+
8193
+ return {
8194
+ send: function( headers, complete ) {
8195
+
8196
+ // Get a new xhr
8197
+ var xhr = s.xhr(),
8198
+ handle,
8199
+ i;
8200
+
8201
+ // Open the socket
8202
+ // Passing null username, generates a login popup on Opera (#2865)
8203
+ if ( s.username ) {
8204
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
8205
+ } else {
8206
+ xhr.open( s.type, s.url, s.async );
8207
+ }
8208
+
8209
+ // Apply custom fields if provided
8210
+ if ( s.xhrFields ) {
8211
+ for ( i in s.xhrFields ) {
8212
+ xhr[ i ] = s.xhrFields[ i ];
8213
+ }
8214
+ }
8215
+
8216
+ // Override mime type if needed
8217
+ if ( s.mimeType && xhr.overrideMimeType ) {
8218
+ xhr.overrideMimeType( s.mimeType );
8219
+ }
8220
+
8221
+ // X-Requested-With header
8222
+ // For cross-domain requests, seeing as conditions for a preflight are
8223
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
8224
+ // (it can always be set on a per-request basis or even using ajaxSetup)
8225
+ // For same-domain requests, won't change header if already provided.
8226
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8227
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
8228
+ }
8229
+
8230
+ // Need an extra try/catch for cross domain requests in Firefox 3
8231
+ try {
8232
+ for ( i in headers ) {
8233
+ xhr.setRequestHeader( i, headers[ i ] );
8234
+ }
8235
+ } catch( _ ) {}
8236
+
8237
+ // Do send the request
8238
+ // This may raise an exception which is actually
8239
+ // handled in jQuery.ajax (so no try/catch here)
8240
+ xhr.send( ( s.hasContent && s.data ) || null );
8241
+
8242
+ // Listener
8243
+ callback = function( _, isAbort ) {
8244
+
8245
+ var status,
8246
+ statusText,
8247
+ responseHeaders,
8248
+ responses,
8249
+ xml;
8250
+
8251
+ // Firefox throws exceptions when accessing properties
8252
+ // of an xhr when a network error occured
8253
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8254
+ try {
8255
+
8256
+ // Was never called and is aborted or complete
8257
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8258
+
8259
+ // Only called once
8260
+ callback = undefined;
8261
+
8262
+ // Do not keep as active anymore
8263
+ if ( handle ) {
8264
+ xhr.onreadystatechange = jQuery.noop;
8265
+ if ( xhrOnUnloadAbort ) {
8266
+ delete xhrCallbacks[ handle ];
8267
+ }
8268
+ }
8269
+
8270
+ // If it's an abort
8271
+ if ( isAbort ) {
8272
+ // Abort it manually if needed
8273
+ if ( xhr.readyState !== 4 ) {
8274
+ xhr.abort();
8275
+ }
8276
+ } else {
8277
+ status = xhr.status;
8278
+ responseHeaders = xhr.getAllResponseHeaders();
8279
+ responses = {};
8280
+ xml = xhr.responseXML;
8281
+
8282
+ // Construct response list
8283
+ if ( xml && xml.documentElement /* #4958 */ ) {
8284
+ responses.xml = xml;
8285
+ }
8286
+
8287
+ // When requesting binary data, IE6-9 will throw an exception
8288
+ // on any attempt to access responseText (#11426)
8289
+ try {
8290
+ responses.text = xhr.responseText;
8291
+ } catch( _ ) {
8292
+ }
8293
+
8294
+ // Firefox throws an exception when accessing
8295
+ // statusText for faulty cross-domain requests
8296
+ try {
8297
+ statusText = xhr.statusText;
8298
+ } catch( e ) {
8299
+ // We normalize with Webkit giving an empty statusText
8300
+ statusText = "";
8301
+ }
8302
+
8303
+ // Filter status for non standard behaviors
8304
+
8305
+ // If the request is local and we have data: assume a success
8306
+ // (success with no data won't get notified, that's the best we
8307
+ // can do given current implementations)
8308
+ if ( !status && s.isLocal && !s.crossDomain ) {
8309
+ status = responses.text ? 200 : 404;
8310
+ // IE - #1450: sometimes returns 1223 when it should be 204
8311
+ } else if ( status === 1223 ) {
8312
+ status = 204;
8313
+ }
8314
+ }
8315
+ }
8316
+ } catch( firefoxAccessException ) {
8317
+ if ( !isAbort ) {
8318
+ complete( -1, firefoxAccessException );
8319
+ }
8320
+ }
8321
+
8322
+ // Call complete if needed
8323
+ if ( responses ) {
8324
+ complete( status, statusText, responses, responseHeaders );
8325
+ }
8326
+ };
8327
+
8328
+ // if we're in sync mode or it's in cache
8329
+ // and has been retrieved directly (IE6 & IE7)
8330
+ // we need to manually fire the callback
8331
+ if ( !s.async || xhr.readyState === 4 ) {
8332
+ callback();
8333
+ } else {
8334
+ handle = ++xhrId;
8335
+ if ( xhrOnUnloadAbort ) {
8336
+ // Create the active xhrs callbacks list if needed
8337
+ // and attach the unload handler
8338
+ if ( !xhrCallbacks ) {
8339
+ xhrCallbacks = {};
8340
+ jQuery( window ).unload( xhrOnUnloadAbort );
8341
+ }
8342
+ // Add to list of active xhrs callbacks
8343
+ xhrCallbacks[ handle ] = callback;
8344
+ }
8345
+ xhr.onreadystatechange = callback;
8346
+ }
8347
+ },
8348
+
8349
+ abort: function() {
8350
+ if ( callback ) {
8351
+ callback(0,1);
8352
+ }
8353
+ }
8354
+ };
8355
+ }
8356
+ });
8357
+ }
8358
+
8359
+
8360
+
8361
+
8362
+ var elemdisplay = {},
8363
+ iframe, iframeDoc,
8364
+ rfxtypes = /^(?:toggle|show|hide)$/,
8365
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8366
+ timerId,
8367
+ fxAttrs = [
8368
+ // height animations
8369
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8370
+ // width animations
8371
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8372
+ // opacity animations
8373
+ [ "opacity" ]
8374
+ ],
8375
+ fxNow;
8376
+
8377
+ jQuery.fn.extend({
8378
+ show: function( speed, easing, callback ) {
8379
+ var elem, display;
8380
+
8381
+ if ( speed || speed === 0 ) {
8382
+ return this.animate( genFx("show", 3), speed, easing, callback );
8383
+
8384
+ } else {
8385
+ for ( var i = 0, j = this.length; i < j; i++ ) {
8386
+ elem = this[ i ];
8387
+
8388
+ if ( elem.style ) {
8389
+ display = elem.style.display;
8390
+
8391
+ // Reset the inline display of this element to learn if it is
8392
+ // being hidden by cascaded rules or not
8393
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8394
+ display = elem.style.display = "";
8395
+ }
8396
+
8397
+ // Set elements which have been overridden with display: none
8398
+ // in a stylesheet to whatever the default browser style is
8399
+ // for such an element
8400
+ if ( (display === "" && jQuery.css(elem, "display") === "none") ||
8401
+ !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
8402
+ jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
8403
+ }
8404
+ }
8405
+ }
8406
+
8407
+ // Set the display of most of the elements in a second loop
8408
+ // to avoid the constant reflow
8409
+ for ( i = 0; i < j; i++ ) {
8410
+ elem = this[ i ];
8411
+
8412
+ if ( elem.style ) {
8413
+ display = elem.style.display;
8414
+
8415
+ if ( display === "" || display === "none" ) {
8416
+ elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
8417
+ }
8418
+ }
8419
+ }
8420
+
8421
+ return this;
8422
+ }
8423
+ },
8424
+
8425
+ hide: function( speed, easing, callback ) {
8426
+ if ( speed || speed === 0 ) {
8427
+ return this.animate( genFx("hide", 3), speed, easing, callback);
8428
+
8429
+ } else {
8430
+ var elem, display,
8431
+ i = 0,
8432
+ j = this.length;
8433
+
8434
+ for ( ; i < j; i++ ) {
8435
+ elem = this[i];
8436
+ if ( elem.style ) {
8437
+ display = jQuery.css( elem, "display" );
8438
+
8439
+ if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
8440
+ jQuery._data( elem, "olddisplay", display );
8441
+ }
8442
+ }
8443
+ }
8444
+
8445
+ // Set the display of the elements in a second loop
8446
+ // to avoid the constant reflow
8447
+ for ( i = 0; i < j; i++ ) {
8448
+ if ( this[i].style ) {
8449
+ this[i].style.display = "none";
8450
+ }
8451
+ }
8452
+
8453
+ return this;
8454
+ }
8455
+ },
8456
+
8457
+ // Save the old toggle function
8458
+ _toggle: jQuery.fn.toggle,
8459
+
8460
+ toggle: function( fn, fn2, callback ) {
8461
+ var bool = typeof fn === "boolean";
8462
+
8463
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8464
+ this._toggle.apply( this, arguments );
8465
+
8466
+ } else if ( fn == null || bool ) {
8467
+ this.each(function() {
8468
+ var state = bool ? fn : jQuery(this).is(":hidden");
8469
+ jQuery(this)[ state ? "show" : "hide" ]();
8470
+ });
8471
+
8472
+ } else {
8473
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
8474
+ }
8475
+
8476
+ return this;
8477
+ },
8478
+
8479
+ fadeTo: function( speed, to, easing, callback ) {
8480
+ return this.filter(":hidden").css("opacity", 0).show().end()
8481
+ .animate({opacity: to}, speed, easing, callback);
8482
+ },
8483
+
8484
+ animate: function( prop, speed, easing, callback ) {
8485
+ var optall = jQuery.speed( speed, easing, callback );
8486
+
8487
+ if ( jQuery.isEmptyObject( prop ) ) {
8488
+ return this.each( optall.complete, [ false ] );
8489
+ }
8490
+
8491
+ // Do not change referenced properties as per-property easing will be lost
8492
+ prop = jQuery.extend( {}, prop );
8493
+
8494
+ function doAnimation() {
8495
+ // XXX 'this' does not always have a nodeName when running the
8496
+ // test suite
8497
+
8498
+ if ( optall.queue === false ) {
8499
+ jQuery._mark( this );
8500
+ }
8501
+
8502
+ var opt = jQuery.extend( {}, optall ),
8503
+ isElement = this.nodeType === 1,
8504
+ hidden = isElement && jQuery(this).is(":hidden"),
8505
+ name, val, p, e, hooks, replace,
8506
+ parts, start, end, unit,
8507
+ method;
8508
+
8509
+ // will store per property easing and be used to determine when an animation is complete
8510
+ opt.animatedProperties = {};
8511
+
8512
+ // first pass over propertys to expand / normalize
8513
+ for ( p in prop ) {
8514
+ name = jQuery.camelCase( p );
8515
+ if ( p !== name ) {
8516
+ prop[ name ] = prop[ p ];
8517
+ delete prop[ p ];
8518
+ }
8519
+
8520
+ if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) {
8521
+ replace = hooks.expand( prop[ name ] );
8522
+ delete prop[ name ];
8523
+
8524
+ // not quite $.extend, this wont overwrite keys already present.
8525
+ // also - reusing 'p' from above because we have the correct "name"
8526
+ for ( p in replace ) {
8527
+ if ( ! ( p in prop ) ) {
8528
+ prop[ p ] = replace[ p ];
8529
+ }
8530
+ }
8531
+ }
8532
+ }
8533
+
8534
+ for ( name in prop ) {
8535
+ val = prop[ name ];
8536
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8537
+ if ( jQuery.isArray( val ) ) {
8538
+ opt.animatedProperties[ name ] = val[ 1 ];
8539
+ val = prop[ name ] = val[ 0 ];
8540
+ } else {
8541
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8542
+ }
8543
+
8544
+ if ( val === "hide" && hidden || val === "show" && !hidden ) {
8545
+ return opt.complete.call( this );
8546
+ }
8547
+
8548
+ if ( isElement && ( name === "height" || name === "width" ) ) {
8549
+ // Make sure that nothing sneaks out
8550
+ // Record all 3 overflow attributes because IE does not
8551
+ // change the overflow attribute when overflowX and
8552
+ // overflowY are set to the same value
8553
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8554
+
8555
+ // Set display property to inline-block for height/width
8556
+ // animations on inline elements that are having width/height animated
8557
+ if ( jQuery.css( this, "display" ) === "inline" &&
8558
+ jQuery.css( this, "float" ) === "none" ) {
8559
+
8560
+ // inline-level elements accept inline-block;
8561
+ // block-level elements need to be inline with layout
8562
+ if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
8563
+ this.style.display = "inline-block";
8564
+
8565
+ } else {
8566
+ this.style.zoom = 1;
8567
+ }
8568
+ }
8569
+ }
8570
+ }
8571
+
8572
+ if ( opt.overflow != null ) {
8573
+ this.style.overflow = "hidden";
8574
+ }
8575
+
8576
+ for ( p in prop ) {
8577
+ e = new jQuery.fx( this, opt, p );
8578
+ val = prop[ p ];
8579
+
8580
+ if ( rfxtypes.test( val ) ) {
8581
+
8582
+ // Tracks whether to show or hide based on private
8583
+ // data attached to the element
8584
+ method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
8585
+ if ( method ) {
8586
+ jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
8587
+ e[ method ]();
8588
+ } else {
8589
+ e[ val ]();
8590
+ }
8591
+
8592
+ } else {
8593
+ parts = rfxnum.exec( val );
8594
+ start = e.cur();
8595
+
8596
+ if ( parts ) {
8597
+ end = parseFloat( parts[2] );
8598
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8599
+
8600
+ // We need to compute starting value
8601
+ if ( unit !== "px" ) {
8602
+ jQuery.style( this, p, (end || 1) + unit);
8603
+ start = ( (end || 1) / e.cur() ) * start;
8604
+ jQuery.style( this, p, start + unit);
8605
+ }
8606
+
8607
+ // If a +=/-= token was provided, we're doing a relative animation
8608
+ if ( parts[1] ) {
8609
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8610
+ }
8611
+
8612
+ e.custom( start, end, unit );
8613
+
8614
+ } else {
8615
+ e.custom( start, val, "" );
8616
+ }
8617
+ }
8618
+ }
8619
+
8620
+ // For JS strict compliance
8621
+ return true;
8622
+ }
8623
+
8624
+ return optall.queue === false ?
8625
+ this.each( doAnimation ) :
8626
+ this.queue( optall.queue, doAnimation );
8627
+ },
8628
+
8629
+ stop: function( type, clearQueue, gotoEnd ) {
8630
+ if ( typeof type !== "string" ) {
8631
+ gotoEnd = clearQueue;
8632
+ clearQueue = type;
8633
+ type = undefined;
8634
+ }
8635
+ if ( clearQueue && type !== false ) {
8636
+ this.queue( type || "fx", [] );
8637
+ }
8638
+
8639
+ return this.each(function() {
8640
+ var index,
8641
+ hadTimers = false,
8642
+ timers = jQuery.timers,
8643
+ data = jQuery._data( this );
8644
+
8645
+ // clear marker counters if we know they won't be
8646
+ if ( !gotoEnd ) {
8647
+ jQuery._unmark( true, this );
8648
+ }
8649
+
8650
+ function stopQueue( elem, data, index ) {
8651
+ var hooks = data[ index ];
8652
+ jQuery.removeData( elem, index, true );
8653
+ hooks.stop( gotoEnd );
8654
+ }
8655
+
8656
+ if ( type == null ) {
8657
+ for ( index in data ) {
8658
+ if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {
8659
+ stopQueue( this, data, index );
8660
+ }
8661
+ }
8662
+ } else if ( data[ index = type + ".run" ] && data[ index ].stop ){
8663
+ stopQueue( this, data, index );
8664
+ }
8665
+
8666
+ for ( index = timers.length; index--; ) {
8667
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
8668
+ if ( gotoEnd ) {
8669
+
8670
+ // force the next step to be the last
8671
+ timers[ index ]( true );
8672
+ } else {
8673
+ timers[ index ].saveState();
8674
+ }
8675
+ hadTimers = true;
8676
+ timers.splice( index, 1 );
8677
+ }
8678
+ }
8679
+
8680
+ // start the next in the queue if the last step wasn't forced
8681
+ // timers currently will call their complete callbacks, which will dequeue
8682
+ // but only if they were gotoEnd
8683
+ if ( !( gotoEnd && hadTimers ) ) {
8684
+ jQuery.dequeue( this, type );
8685
+ }
8686
+ });
8687
+ }
8688
+
8689
+ });
8690
+
8691
+ // Animations created synchronously will run synchronously
8692
+ function createFxNow() {
8693
+ setTimeout( clearFxNow, 0 );
8694
+ return ( fxNow = jQuery.now() );
8695
+ }
8696
+
8697
+ function clearFxNow() {
8698
+ fxNow = undefined;
8699
+ }
8700
+
8701
+ // Generate parameters to create a standard animation
8702
+ function genFx( type, num ) {
8703
+ var obj = {};
8704
+
8705
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
8706
+ obj[ this ] = type;
8707
+ });
8708
+
8709
+ return obj;
8710
+ }
8711
+
8712
+ // Generate shortcuts for custom animations
8713
+ jQuery.each({
8714
+ slideDown: genFx( "show", 1 ),
8715
+ slideUp: genFx( "hide", 1 ),
8716
+ slideToggle: genFx( "toggle", 1 ),
8717
+ fadeIn: { opacity: "show" },
8718
+ fadeOut: { opacity: "hide" },
8719
+ fadeToggle: { opacity: "toggle" }
8720
+ }, function( name, props ) {
8721
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
8722
+ return this.animate( props, speed, easing, callback );
8723
+ };
8724
+ });
8725
+
8726
+ jQuery.extend({
8727
+ speed: function( speed, easing, fn ) {
8728
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8729
+ complete: fn || !fn && easing ||
8730
+ jQuery.isFunction( speed ) && speed,
8731
+ duration: speed,
8732
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8733
+ };
8734
+
8735
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8736
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8737
+
8738
+ // normalize opt.queue - true/undefined/null -> "fx"
8739
+ if ( opt.queue == null || opt.queue === true ) {
8740
+ opt.queue = "fx";
8741
+ }
8742
+
8743
+ // Queueing
8744
+ opt.old = opt.complete;
8745
+
8746
+ opt.complete = function( noUnmark ) {
8747
+ if ( jQuery.isFunction( opt.old ) ) {
8748
+ opt.old.call( this );
8749
+ }
8750
+
8751
+ if ( opt.queue ) {
8752
+ jQuery.dequeue( this, opt.queue );
8753
+ } else if ( noUnmark !== false ) {
8754
+ jQuery._unmark( this );
8755
+ }
8756
+ };
8757
+
8758
+ return opt;
8759
+ },
8760
+
8761
+ easing: {
8762
+ linear: function( p ) {
8763
+ return p;
8764
+ },
8765
+ swing: function( p ) {
8766
+ return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;
8767
+ }
8768
+ },
8769
+
8770
+ timers: [],
8771
+
8772
+ fx: function( elem, options, prop ) {
8773
+ this.options = options;
8774
+ this.elem = elem;
8775
+ this.prop = prop;
8776
+
8777
+ options.orig = options.orig || {};
8778
+ }
8779
+
8780
+ });
8781
+
8782
+ jQuery.fx.prototype = {
8783
+ // Simple function for setting a style value
8784
+ update: function() {
8785
+ if ( this.options.step ) {
8786
+ this.options.step.call( this.elem, this.now, this );
8787
+ }
8788
+
8789
+ ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
8790
+ },
8791
+
8792
+ // Get the current size
8793
+ cur: function() {
8794
+ if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
8795
+ return this.elem[ this.prop ];
8796
+ }
8797
+
8798
+ var parsed,
8799
+ r = jQuery.css( this.elem, this.prop );
8800
+ // Empty strings, null, undefined and "auto" are converted to 0,
8801
+ // complex values such as "rotate(1rad)" are returned as is,
8802
+ // simple values such as "10px" are parsed to Float.
8803
+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8804
+ },
8805
+
8806
+ // Start an animation from one number to another
8807
+ custom: function( from, to, unit ) {
8808
+ var self = this,
8809
+ fx = jQuery.fx;
8810
+
8811
+ this.startTime = fxNow || createFxNow();
8812
+ this.end = to;
8813
+ this.now = this.start = from;
8814
+ this.pos = this.state = 0;
8815
+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8816
+
8817
+ function t( gotoEnd ) {
8818
+ return self.step( gotoEnd );
8819
+ }
8820
+
8821
+ t.queue = this.options.queue;
8822
+ t.elem = this.elem;
8823
+ t.saveState = function() {
8824
+ if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
8825
+ if ( self.options.hide ) {
8826
+ jQuery._data( self.elem, "fxshow" + self.prop, self.start );
8827
+ } else if ( self.options.show ) {
8828
+ jQuery._data( self.elem, "fxshow" + self.prop, self.end );
8829
+ }
8830
+ }
8831
+ };
8832
+
8833
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
8834
+ timerId = setInterval( fx.tick, fx.interval );
8835
+ }
8836
+ },
8837
+
8838
+ // Simple 'show' function
8839
+ show: function() {
8840
+ var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
8841
+
8842
+ // Remember where we started, so that we can go back to it later
8843
+ this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
8844
+ this.options.show = true;
8845
+
8846
+ // Begin the animation
8847
+ // Make sure that we start at a small width/height to avoid any flash of content
8848
+ if ( dataShow !== undefined ) {
8849
+ // This show is picking up where a previous hide or show left off
8850
+ this.custom( this.cur(), dataShow );
8851
+ } else {
8852
+ this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
8853
+ }
8854
+
8855
+ // Start by showing the element
8856
+ jQuery( this.elem ).show();
8857
+ },
8858
+
8859
+ // Simple 'hide' function
8860
+ hide: function() {
8861
+ // Remember where we started, so that we can go back to it later
8862
+ this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
8863
+ this.options.hide = true;
8864
+
8865
+ // Begin the animation
8866
+ this.custom( this.cur(), 0 );
8867
+ },
8868
+
8869
+ // Each step of an animation
8870
+ step: function( gotoEnd ) {
8871
+ var p, n, complete,
8872
+ t = fxNow || createFxNow(),
8873
+ done = true,
8874
+ elem = this.elem,
8875
+ options = this.options;
8876
+
8877
+ if ( gotoEnd || t >= options.duration + this.startTime ) {
8878
+ this.now = this.end;
8879
+ this.pos = this.state = 1;
8880
+ this.update();
8881
+
8882
+ options.animatedProperties[ this.prop ] = true;
8883
+
8884
+ for ( p in options.animatedProperties ) {
8885
+ if ( options.animatedProperties[ p ] !== true ) {
8886
+ done = false;
8887
+ }
8888
+ }
8889
+
8890
+ if ( done ) {
8891
+ // Reset the overflow
8892
+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8893
+
8894
+ jQuery.each( [ "", "X", "Y" ], function( index, value ) {
8895
+ elem.style[ "overflow" + value ] = options.overflow[ index ];
8896
+ });
8897
+ }
8898
+
8899
+ // Hide the element if the "hide" operation was done
8900
+ if ( options.hide ) {
8901
+ jQuery( elem ).hide();
8902
+ }
8903
+
8904
+ // Reset the properties, if the item has been hidden or shown
8905
+ if ( options.hide || options.show ) {
8906
+ for ( p in options.animatedProperties ) {
8907
+ jQuery.style( elem, p, options.orig[ p ] );
8908
+ jQuery.removeData( elem, "fxshow" + p, true );
8909
+ // Toggle data is no longer needed
8910
+ jQuery.removeData( elem, "toggle" + p, true );
8911
+ }
8912
+ }
8913
+
8914
+ // Execute the complete function
8915
+ // in the event that the complete function throws an exception
8916
+ // we must ensure it won't be called twice. #5684
8917
+
8918
+ complete = options.complete;
8919
+ if ( complete ) {
8920
+
8921
+ options.complete = false;
8922
+ complete.call( elem );
8923
+ }
8924
+ }
8925
+
8926
+ return false;
8927
+
8928
+ } else {
8929
+ // classical easing cannot be used with an Infinity duration
8930
+ if ( options.duration == Infinity ) {
8931
+ this.now = t;
8932
+ } else {
8933
+ n = t - this.startTime;
8934
+ this.state = n / options.duration;
8935
+
8936
+ // Perform the easing function, defaults to swing
8937
+ this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
8938
+ this.now = this.start + ( (this.end - this.start) * this.pos );
8939
+ }
8940
+ // Perform the next step of the animation
8941
+ this.update();
8942
+ }
8943
+
8944
+ return true;
8945
+ }
8946
+ };
8947
+
8948
+ jQuery.extend( jQuery.fx, {
8949
+ tick: function() {
8950
+ var timer,
8951
+ timers = jQuery.timers,
8952
+ i = 0;
8953
+
8954
+ for ( ; i < timers.length; i++ ) {
8955
+ timer = timers[ i ];
8956
+ // Checks the timer has not already been removed
8957
+ if ( !timer() && timers[ i ] === timer ) {
8958
+ timers.splice( i--, 1 );
8959
+ }
8960
+ }
8961
+
8962
+ if ( !timers.length ) {
8963
+ jQuery.fx.stop();
8964
+ }
8965
+ },
8966
+
8967
+ interval: 13,
8968
+
8969
+ stop: function() {
8970
+ clearInterval( timerId );
8971
+ timerId = null;
8972
+ },
8973
+
8974
+ speeds: {
8975
+ slow: 600,
8976
+ fast: 200,
8977
+ // Default speed
8978
+ _default: 400
8979
+ },
8980
+
8981
+ step: {
8982
+ opacity: function( fx ) {
8983
+ jQuery.style( fx.elem, "opacity", fx.now );
8984
+ },
8985
+
8986
+ _default: function( fx ) {
8987
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8988
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
8989
+ } else {
8990
+ fx.elem[ fx.prop ] = fx.now;
8991
+ }
8992
+ }
8993
+ }
8994
+ });
8995
+
8996
+ // Ensure props that can't be negative don't go there on undershoot easing
8997
+ jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) {
8998
+ // exclude marginTop, marginLeft, marginBottom and marginRight from this list
8999
+ if ( prop.indexOf( "margin" ) ) {
9000
+ jQuery.fx.step[ prop ] = function( fx ) {
9001
+ jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
9002
+ };
9003
+ }
9004
+ });
9005
+
9006
+ if ( jQuery.expr && jQuery.expr.filters ) {
9007
+ jQuery.expr.filters.animated = function( elem ) {
9008
+ return jQuery.grep(jQuery.timers, function( fn ) {
9009
+ return elem === fn.elem;
9010
+ }).length;
9011
+ };
9012
+ }
9013
+
9014
+ // Try to restore the default display value of an element
9015
+ function defaultDisplay( nodeName ) {
9016
+
9017
+ if ( !elemdisplay[ nodeName ] ) {
9018
+
9019
+ var body = document.body,
9020
+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
9021
+ display = elem.css( "display" );
9022
+ elem.remove();
9023
+
9024
+ // If the simple way fails,
9025
+ // get element's real default display by attaching it to a temp iframe
9026
+ if ( display === "none" || display === "" ) {
9027
+ // No iframe to use yet, so create it
9028
+ if ( !iframe ) {
9029
+ iframe = document.createElement( "iframe" );
9030
+ iframe.frameBorder = iframe.width = iframe.height = 0;
9031
+ }
9032
+
9033
+ body.appendChild( iframe );
9034
+
9035
+ // Create a cacheable copy of the iframe document on first call.
9036
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
9037
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
9038
+ if ( !iframeDoc || !iframe.createElement ) {
9039
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
9040
+ iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );
9041
+ iframeDoc.close();
9042
+ }
9043
+
9044
+ elem = iframeDoc.createElement( nodeName );
9045
+
9046
+ iframeDoc.body.appendChild( elem );
9047
+
9048
+ display = jQuery.css( elem, "display" );
9049
+ body.removeChild( iframe );
9050
+ }
9051
+
9052
+ // Store the correct default display
9053
+ elemdisplay[ nodeName ] = display;
9054
+ }
9055
+
9056
+ return elemdisplay[ nodeName ];
9057
+ }
9058
+
9059
+
9060
+
9061
+
9062
+ var getOffset,
9063
+ rtable = /^t(?:able|d|h)$/i,
9064
+ rroot = /^(?:body|html)$/i;
9065
+
9066
+ if ( "getBoundingClientRect" in document.documentElement ) {
9067
+ getOffset = function( elem, doc, docElem, box ) {
9068
+ try {
9069
+ box = elem.getBoundingClientRect();
9070
+ } catch(e) {}
9071
+
9072
+ // Make sure we're not dealing with a disconnected DOM node
9073
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
9074
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
9075
+ }
9076
+
9077
+ var body = doc.body,
9078
+ win = getWindow( doc ),
9079
+ clientTop = docElem.clientTop || body.clientTop || 0,
9080
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
9081
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
9082
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
9083
+ top = box.top + scrollTop - clientTop,
9084
+ left = box.left + scrollLeft - clientLeft;
9085
+
9086
+ return { top: top, left: left };
9087
+ };
9088
+
9089
+ } else {
9090
+ getOffset = function( elem, doc, docElem ) {
9091
+ var computedStyle,
9092
+ offsetParent = elem.offsetParent,
9093
+ prevOffsetParent = elem,
9094
+ body = doc.body,
9095
+ defaultView = doc.defaultView,
9096
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9097
+ top = elem.offsetTop,
9098
+ left = elem.offsetLeft;
9099
+
9100
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9101
+ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9102
+ break;
9103
+ }
9104
+
9105
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9106
+ top -= elem.scrollTop;
9107
+ left -= elem.scrollLeft;
9108
+
9109
+ if ( elem === offsetParent ) {
9110
+ top += elem.offsetTop;
9111
+ left += elem.offsetLeft;
9112
+
9113
+ if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9114
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
9115
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9116
+ }
9117
+
9118
+ prevOffsetParent = offsetParent;
9119
+ offsetParent = elem.offsetParent;
9120
+ }
9121
+
9122
+ if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9123
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
9124
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9125
+ }
9126
+
9127
+ prevComputedStyle = computedStyle;
9128
+ }
9129
+
9130
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9131
+ top += body.offsetTop;
9132
+ left += body.offsetLeft;
9133
+ }
9134
+
9135
+ if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
9136
+ top += Math.max( docElem.scrollTop, body.scrollTop );
9137
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
9138
+ }
9139
+
9140
+ return { top: top, left: left };
9141
+ };
9142
+ }
9143
+
9144
+ jQuery.fn.offset = function( options ) {
9145
+ if ( arguments.length ) {
9146
+ return options === undefined ?
9147
+ this :
9148
+ this.each(function( i ) {
9149
+ jQuery.offset.setOffset( this, options, i );
9150
+ });
9151
+ }
9152
+
9153
+ var elem = this[0],
9154
+ doc = elem && elem.ownerDocument;
9155
+
9156
+ if ( !doc ) {
9157
+ return null;
9158
+ }
9159
+
9160
+ if ( elem === doc.body ) {
9161
+ return jQuery.offset.bodyOffset( elem );
9162
+ }
9163
+
9164
+ return getOffset( elem, doc, doc.documentElement );
9165
+ };
9166
+
9167
+ jQuery.offset = {
9168
+
9169
+ bodyOffset: function( body ) {
9170
+ var top = body.offsetTop,
9171
+ left = body.offsetLeft;
9172
+
9173
+ if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
9174
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9175
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9176
+ }
9177
+
9178
+ return { top: top, left: left };
9179
+ },
9180
+
9181
+ setOffset: function( elem, options, i ) {
9182
+ var position = jQuery.css( elem, "position" );
9183
+
9184
+ // set position first, in-case top/left are set even on static elem
9185
+ if ( position === "static" ) {
9186
+ elem.style.position = "relative";
9187
+ }
9188
+
9189
+ var curElem = jQuery( elem ),
9190
+ curOffset = curElem.offset(),
9191
+ curCSSTop = jQuery.css( elem, "top" ),
9192
+ curCSSLeft = jQuery.css( elem, "left" ),
9193
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9194
+ props = {}, curPosition = {}, curTop, curLeft;
9195
+
9196
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9197
+ if ( calculatePosition ) {
9198
+ curPosition = curElem.position();
9199
+ curTop = curPosition.top;
9200
+ curLeft = curPosition.left;
9201
+ } else {
9202
+ curTop = parseFloat( curCSSTop ) || 0;
9203
+ curLeft = parseFloat( curCSSLeft ) || 0;
9204
+ }
9205
+
9206
+ if ( jQuery.isFunction( options ) ) {
9207
+ options = options.call( elem, i, curOffset );
9208
+ }
9209
+
9210
+ if ( options.top != null ) {
9211
+ props.top = ( options.top - curOffset.top ) + curTop;
9212
+ }
9213
+ if ( options.left != null ) {
9214
+ props.left = ( options.left - curOffset.left ) + curLeft;
9215
+ }
9216
+
9217
+ if ( "using" in options ) {
9218
+ options.using.call( elem, props );
9219
+ } else {
9220
+ curElem.css( props );
9221
+ }
9222
+ }
9223
+ };
9224
+
9225
+
9226
+ jQuery.fn.extend({
9227
+
9228
+ position: function() {
9229
+ if ( !this[0] ) {
9230
+ return null;
9231
+ }
9232
+
9233
+ var elem = this[0],
9234
+
9235
+ // Get *real* offsetParent
9236
+ offsetParent = this.offsetParent(),
9237
+
9238
+ // Get correct offsets
9239
+ offset = this.offset(),
9240
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9241
+
9242
+ // Subtract element margins
9243
+ // note: when an element has margin: auto the offsetLeft and marginLeft
9244
+ // are the same in Safari causing offset.left to incorrectly be 0
9245
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9246
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9247
+
9248
+ // Add offsetParent borders
9249
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9250
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9251
+
9252
+ // Subtract the two offsets
9253
+ return {
9254
+ top: offset.top - parentOffset.top,
9255
+ left: offset.left - parentOffset.left
9256
+ };
9257
+ },
9258
+
9259
+ offsetParent: function() {
9260
+ return this.map(function() {
9261
+ var offsetParent = this.offsetParent || document.body;
9262
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9263
+ offsetParent = offsetParent.offsetParent;
9264
+ }
9265
+ return offsetParent;
9266
+ });
9267
+ }
9268
+ });
9269
+
9270
+
9271
+ // Create scrollLeft and scrollTop methods
9272
+ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
9273
+ var top = /Y/.test( prop );
9274
+
9275
+ jQuery.fn[ method ] = function( val ) {
9276
+ return jQuery.access( this, function( elem, method, val ) {
9277
+ var win = getWindow( elem );
9278
+
9279
+ if ( val === undefined ) {
9280
+ return win ? (prop in win) ? win[ prop ] :
9281
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
9282
+ win.document.body[ method ] :
9283
+ elem[ method ];
9284
+ }
9285
+
9286
+ if ( win ) {
9287
+ win.scrollTo(
9288
+ !top ? val : jQuery( win ).scrollLeft(),
9289
+ top ? val : jQuery( win ).scrollTop()
9290
+ );
9291
+
9292
+ } else {
9293
+ elem[ method ] = val;
9294
+ }
9295
+ }, method, val, arguments.length, null );
9296
+ };
9297
+ });
9298
+
9299
+ function getWindow( elem ) {
9300
+ return jQuery.isWindow( elem ) ?
9301
+ elem :
9302
+ elem.nodeType === 9 ?
9303
+ elem.defaultView || elem.parentWindow :
9304
+ false;
9305
+ }
9306
+
9307
+
9308
+
9309
+
9310
+ // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
9311
+ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9312
+ var clientProp = "client" + name,
9313
+ scrollProp = "scroll" + name,
9314
+ offsetProp = "offset" + name;
9315
+
9316
+ // innerHeight and innerWidth
9317
+ jQuery.fn[ "inner" + name ] = function() {
9318
+ var elem = this[0];
9319
+ return elem ?
9320
+ elem.style ?
9321
+ parseFloat( jQuery.css( elem, type, "padding" ) ) :
9322
+ this[ type ]() :
9323
+ null;
9324
+ };
9325
+
9326
+ // outerHeight and outerWidth
9327
+ jQuery.fn[ "outer" + name ] = function( margin ) {
9328
+ var elem = this[0];
9329
+ return elem ?
9330
+ elem.style ?
9331
+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9332
+ this[ type ]() :
9333
+ null;
9334
+ };
9335
+
9336
+ jQuery.fn[ type ] = function( value ) {
9337
+ return jQuery.access( this, function( elem, type, value ) {
9338
+ var doc, docElemProp, orig, ret;
9339
+
9340
+ if ( jQuery.isWindow( elem ) ) {
9341
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9342
+ doc = elem.document;
9343
+ docElemProp = doc.documentElement[ clientProp ];
9344
+ return jQuery.support.boxModel && docElemProp ||
9345
+ doc.body && doc.body[ clientProp ] || docElemProp;
9346
+ }
9347
+
9348
+ // Get document width or height
9349
+ if ( elem.nodeType === 9 ) {
9350
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9351
+ doc = elem.documentElement;
9352
+
9353
+ // when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]
9354
+ // so we can't use max, as it'll choose the incorrect offset[Width/Height]
9355
+ // instead we use the correct client[Width/Height]
9356
+ // support:IE6
9357
+ if ( doc[ clientProp ] >= doc[ scrollProp ] ) {
9358
+ return doc[ clientProp ];
9359
+ }
9360
+
9361
+ return Math.max(
9362
+ elem.body[ scrollProp ], doc[ scrollProp ],
9363
+ elem.body[ offsetProp ], doc[ offsetProp ]
9364
+ );
9365
+ }
9366
+
9367
+ // Get width or height on the element
9368
+ if ( value === undefined ) {
9369
+ orig = jQuery.css( elem, type );
9370
+ ret = parseFloat( orig );
9371
+ return jQuery.isNumeric( ret ) ? ret : orig;
9372
+ }
9373
+
9374
+ // Set the width or height on the element
9375
+ jQuery( elem ).css( type, value );
9376
+ }, type, value, arguments.length, null );
9377
+ };
9378
+ });
9379
+
9380
+
9381
+
9382
+
9383
+ // Expose jQuery to the global object
9384
+ window.jQuery = window.$ = jQuery;
9385
+
9386
+ // Expose jQuery as an AMD module, but only for AMD loaders that
9387
+ // understand the issues with loading multiple versions of jQuery
9388
+ // in a page that all might call define(). The loader will indicate
9389
+ // they have special allowances for multiple jQuery versions by
9390
+ // specifying define.amd.jQuery = true. Register as a named module,
9391
+ // since jQuery can be concatenated with other files that may use define,
9392
+ // but not use a proper concatenation script that understands anonymous
9393
+ // AMD modules. A named AMD is safest and most robust way to register.
9394
+ // Lowercase jquery is used because AMD module names are derived from
9395
+ // file names, and jQuery is normally delivered in a lowercase file name.
9396
+ // Do this after creating the global so that if an AMD module wants to call
9397
+ // noConflict to hide this version of jQuery, it will work.
9398
+ if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
9399
+ define( "jquery", [], function () { return jQuery; } );
9400
+ }
9401
+
9402
+
9403
+
9404
+ })( window );
9405
+
9406
+
9407
+ var nicnocon = jQuery.noConflict();
js/productzoom/jquery.carouFredSel-2.6.0.js ADDED
@@ -0,0 +1,804 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery carouFredSel 2.6.0
3
+ * Demo's and documentation:
4
+ * caroufredsel.frebsite.nl
5
+ *
6
+ * Copyright (c) 2010 Fred Heusschen
7
+ * www.frebsite.nl
8
+ *
9
+ * Dual licensed under the MIT and GPL licenses.
10
+ * http://en.wikipedia.org/wiki/MIT_License
11
+ * http://en.wikipedia.org/wiki/GNU_General_Public_License
12
+ */
13
+
14
+ (function($) {
15
+ $.fn.carouFredSel = function(o) {
16
+ if (this.length > 1) {
17
+ return this.each(function() {
18
+ $(this).carouFredSel(o);
19
+ });
20
+ }
21
+
22
+ this.init = function(o) {
23
+ if (typeof o != 'object') o = {};
24
+ if (typeof o.scroll == 'number') {
25
+ if (o.scroll <= 50) o.scroll = { items : o.scroll };
26
+ else o.scroll = { duration: o.scroll };
27
+ } else {
28
+ if (typeof o.scroll == 'string') o.scroll = { easing : o.scroll };
29
+ }
30
+ if (typeof o.items == 'number') o.items = { visible : o.items };
31
+ else if (typeof o.items == 'string') o.items = { width : o.items,
32
+ height : o.items };
33
+
34
+ opts = $.extend(true, {}, $.fn.carouFredSel.defaults, o);
35
+ opts.padding = getPadding(opts.padding);
36
+ opts.usePadding = (
37
+ opts.padding[0] == 0 &&
38
+ opts.padding[1] == 0 &&
39
+ opts.padding[2] == 0 &&
40
+ opts.padding[3] == 0
41
+ ) ? false : true;
42
+
43
+ direction = (opts.direction == 'up' || opts.direction == 'left') ? 'next' : 'prev';
44
+
45
+ if (opts.direction == 'right' || opts.direction == 'left') {
46
+ opts.dimentions = ['width', 'outerWidth', 'height', 'outerHeight', 'left', 'top', 'marginRight'];
47
+ } else {
48
+ opts.dimentions = ['height', 'outerHeight', 'width', 'outerWidth', 'top', 'left', 'marginBottom'];
49
+ opts.padding = [opts.padding[3], opts.padding[2], opts.padding[1], opts.padding[0]];
50
+ }
51
+
52
+ if ( !opts.items.width) opts.items.width = getItems($cfs).outerWidth(true);
53
+ if ( !opts.items.height) opts.items.height = getItems($cfs).outerHeight(true);
54
+ if (typeof opts.items.minimum != 'number') opts.items.minimum = opts.items.visible;
55
+ if (typeof opts.scroll.items != 'number') opts.scroll.items = opts.items.visible;
56
+ if (typeof opts.scroll.duration != 'number') opts.scroll.duration = 500;
57
+
58
+ opts.auto = getNaviObject(opts.auto, false, true);
59
+ opts.prev = getNaviObject(opts.prev);
60
+ opts.next = getNaviObject(opts.next);
61
+ opts.pagination = getNaviObject(opts.pagination, true);
62
+
63
+ opts.auto = $.extend({}, opts.scroll, opts.auto);
64
+ opts.prev = $.extend({}, opts.scroll, opts.prev);
65
+ opts.next = $.extend({}, opts.scroll, opts.next);
66
+ opts.pagination = $.extend({}, opts.scroll, opts.pagination);
67
+
68
+ if (typeof opts.pagination.keys != 'boolean') opts.pagination.keys = false;
69
+ if (typeof opts.pagination.anchorBuilder != 'function') opts.pagination.anchorBuilder = $.fn.carouFredSel.pageAnchorBuilder;
70
+ if (typeof opts.auto.play != 'boolean') opts.auto.play = true;
71
+ if (typeof opts.auto.nap != 'boolean') opts.auto.nap = true;
72
+ if (typeof opts.auto.delay != 'number') opts.auto.delay = 0;
73
+ if (typeof opts.auto.pauseDuration != 'number') opts.auto.pauseDuration = (opts.auto.duration < 10) ? 2500 : opts.auto.duration * 5;
74
+ }; // /init
75
+
76
+ this.build = function() {
77
+ $wrp.css({
78
+ position: 'relative',
79
+ overflow: 'hidden'
80
+ });
81
+ $cfs.data('cfs_origCss', {
82
+ width : $cfs.css('width'),
83
+ height : $cfs.css('height'),
84
+ position: $cfs.css('position'),
85
+ top : $cfs.css('top'),
86
+ left : $cfs.css('left')
87
+ }).css({
88
+ position: 'absolute'
89
+ });
90
+ if (opts.usePadding) {
91
+ getItems($cfs).each(function() {
92
+ var m = parseInt($(this).css(opts.dimentions[6]));
93
+ if (isNaN(m)) m = 0;
94
+ $(this).data('cfs_origCssMargin', m);
95
+ });
96
+ }
97
+ showNavi(opts, totalItems);
98
+ }; // /build
99
+
100
+ this.bind_events = function() {
101
+ $cfs.bind('pause', function(e, g) {
102
+ if (typeof g != 'boolean') g = false;
103
+ if (g) pausedGlobal = true;
104
+ if (autoTimeout != null) {
105
+ clearTimeout(autoTimeout);
106
+ }
107
+ if (autoInterval != null) {
108
+ clearInterval(autoInterval);
109
+ }
110
+ })
111
+ .bind('play', function(e, d, f, g) {
112
+ $cfs.trigger('pause');
113
+ if (opts.auto.play) {
114
+ if (typeof g != 'boolean') {
115
+ if (typeof f == 'boolean') g = f;
116
+ else if (typeof d == 'boolean') g = d;
117
+ else g = false;
118
+ }
119
+ if (typeof f != 'number') {
120
+ if (typeof d == 'number') f = d;
121
+ else f = 0;
122
+ }
123
+ if (d != 'prev' && d != 'next') d = direction;
124
+
125
+ if (g) pausedGlobal = false;
126
+ if (pausedGlobal) return;
127
+
128
+ autoTimeout = setTimeout(function() {
129
+ if ($cfs.is(':animated')) {
130
+ $cfs.trigger('play', d);
131
+ } else {
132
+ pauseTimePassed = 0;
133
+ $cfs.trigger(d, opts.auto);
134
+ }
135
+ }, opts.auto.pauseDuration + f - pauseTimePassed);
136
+
137
+ if (opts.auto.pauseOnHover === 'resume') {
138
+ autoInterval = setInterval(function() {
139
+ pauseTimePassed += 100;
140
+ }, 100);
141
+ }
142
+ }
143
+ })
144
+ .bind('prev', function(e, sO, nI) {
145
+ if ($cfs.is(':animated')) return false;
146
+ if (opts.items.minimum >= totalItems) return log('Not enough items: not scrolling');
147
+
148
+ if (typeof sO == 'number') nI = sO;
149
+ if (typeof sO != 'object') sO = opts.prev;
150
+ if (typeof nI != 'number') nI = sO.items;
151
+ if (typeof nI != 'number') return log('Not a valid number: not scrolling');
152
+
153
+ if (!opts.circular) {
154
+ var nulItem = totalItems - firstItem;
155
+ if (nulItem - nI < 0) {
156
+ nI = nulItem;
157
+ }
158
+ if (firstItem == 0) {
159
+ nI = 0;
160
+ }
161
+ }
162
+
163
+ firstItem += nI;
164
+ if (firstItem >= totalItems) firstItem -= totalItems;
165
+
166
+ if (!opts.circular && !opts.infinite) {
167
+ if (firstItem == 0 &&
168
+ opts.prev.button) opts.prev.button.addClass('disabled');
169
+ if (opts.next.button) opts.next.button.removeClass('disabled');
170
+ }
171
+ if (nI == 0) {
172
+ if (opts.infinite) $cfs.trigger('next', totalItems-opts.items.visible);
173
+ return false;
174
+ }
175
+
176
+ getItems($cfs, ':gt('+(totalItems-nI-1)+')').prependTo($cfs);
177
+ if (totalItems < opts.items.visible + nI) getItems($cfs, ':lt('+((opts.items.visible+nI)-totalItems)+')').clone(true).appendTo($cfs);
178
+
179
+ var c_itm = getCurrentItems($cfs, opts, nI),
180
+ l_cur = getItems($cfs, ':nth('+(nI-1)+')'),
181
+ l_old = c_itm[1].filter(':last'),
182
+ l_new = c_itm[0].filter(':last');
183
+
184
+ if (opts.usePadding) l_old.css(opts.dimentions[6], l_old.data('cfs_origCssMargin'));
185
+
186
+ var i_siz = getSizes(opts, getItems($cfs, ':lt('+nI+')')),
187
+ w_siz = mapWrapperSizes(getSizes(opts, c_itm[0], true), opts);
188
+
189
+ if (opts.usePadding) l_old.css(opts.dimentions[6], l_old.data('cfs_origCssMargin') + opts.padding[1]);
190
+
191
+ var a_cfs = {},
192
+ a_new = {},
193
+ a_cur = {},
194
+ a_dur = sO.duration;
195
+
196
+ if (a_dur == 'auto') a_dur = opts.scroll.duration / opts.scroll.items * nI;
197
+ else if (a_dur <= 0) a_dur = 0;
198
+ else if (a_dur < 10) a_dur = i_siz[0] / a_dur;
199
+
200
+ if (sO.onBefore) sO.onBefore(c_itm[1], c_itm[0], w_siz, a_dur);
201
+
202
+ if (opts.usePadding) {
203
+ var new_m = opts.padding[3];
204
+ a_cur[opts.dimentions[6]] = l_cur.data('cfs_origCssMargin');
205
+ a_new[opts.dimentions[6]] = l_new.data('cfs_origCssMargin') + opts.padding[1];
206
+
207
+ l_cur.css(opts.dimentions[6], l_cur.data('cfs_origCssMargin') + opts.padding[3]);
208
+ l_cur.stop().animate(a_cur, {
209
+ duration: a_dur,
210
+ easing : sO.easing
211
+ });
212
+ l_new.stop().animate(a_new, {
213
+ duration: a_dur,
214
+ easing : sO.easing
215
+ });
216
+ } else {
217
+ var new_m = 0;
218
+ }
219
+ a_cfs[opts.dimentions[4]] = new_m;
220
+
221
+ if ((typeof opts[opts.dimentions[0]] != 'number' && typeof opts.items[opts.dimentions[0]] != 'number') ||
222
+ (typeof opts[opts.dimentions[2]] != 'number' && typeof opts.items[opts.dimentions[2]] != 'number')
223
+ ) {
224
+ $wrp.stop().animate(w_siz, {
225
+ duration: a_dur,
226
+ easing : sO.easing
227
+ });
228
+ }
229
+ $cfs.data('cfs_numItems', nI)
230
+ .data('cfs_slideObj', sO)
231
+ .data('cfs_oldItems', c_itm[1])
232
+ .data('cfs_newItems', c_itm[0])
233
+ .data('cfs_wrapSize', w_siz)
234
+ .css(opts.dimentions[4], -i_siz[0])
235
+ .animate(a_cfs, {
236
+ duration: a_dur,
237
+ easing : sO.easing,
238
+ complete: function() {
239
+ if ($cfs.data('cfs_slideObj').onAfter) {
240
+ $cfs.data('cfs_slideObj').onAfter($cfs.data('cfs_oldItems'), $cfs.data('cfs_newItems'), $cfs.data('cfs_wrapSize'));
241
+ }
242
+ if (totalItems < opts.items.visible + $cfs.data('cfs_numItems')) {
243
+ getItems($cfs, ':gt('+(totalItems-1)+')').remove();
244
+ }
245
+ var l_itm = getItems($cfs, ':nth('+(opts.items.visible+$cfs.data('cfs_numItems')-1)+')');
246
+ if (opts.usePadding) {
247
+ l_itm.css(opts.dimentions[6], l_itm.data('cfs_origCssMargin'));
248
+ }
249
+ }
250
+ });
251
+ $cfs.trigger('updatePageStatus').trigger('play', a_dur);
252
+ })
253
+ .bind('next', function(e, sO, nI) {
254
+ if ($cfs.is(':animated')) return false;
255
+ if (opts.items.minimum >= totalItems) return log('Not enough items: not scrolling');
256
+ if (typeof sO == 'number') nI = sO;
257
+ if (typeof sO != 'object') sO = opts.next;
258
+ if (typeof nI != 'number') nI = sO.items;
259
+ if (typeof nI != 'number') return log('Not a valid number: not scrolling');
260
+
261
+ if (!opts.circular) {
262
+ if (firstItem == 0) {
263
+ if (nI > totalItems - opts.items.visible) {
264
+ nI = totalItems - opts.items.visible;
265
+ }
266
+ } else {
267
+ if (firstItem - nI < opts.items.visible) {
268
+ nI = firstItem - opts.items.visible;
269
+ }
270
+ }
271
+ }
272
+
273
+ firstItem -= nI;
274
+ if (firstItem < 0) firstItem += totalItems;
275
+
276
+ if (!opts.circular && !opts.infinite) {
277
+ if (firstItem == opts.items.visible &&
278
+ opts.next.button) opts.next.button.addClass('disabled');
279
+ if (opts.prev.button) opts.prev.button.removeClass('disabled');
280
+ }
281
+ if (nI == 0) {
282
+ if (opts.infinite) $cfs.trigger('prev', totalItems-opts.items.visible);
283
+ return false;
284
+ }
285
+
286
+ if (totalItems < opts.items.visible + nI) getItems($cfs, ':lt('+((opts.items.visible+nI)-totalItems)+')').clone(true).appendTo($cfs);
287
+
288
+ var c_itm = getCurrentItems($cfs, opts, nI),
289
+ l_cur = getItems($cfs, ':nth('+(nI-1)+')'),
290
+ l_old = c_itm[0].filter(':last'),
291
+ l_new = c_itm[1].filter(':last');
292
+
293
+ if (opts.usePadding) {
294
+ l_old.css(opts.dimentions[6], l_old.data('cfs_origCssMargin'));
295
+ l_new.css(opts.dimentions[6], l_new.data('cfs_origCssMargin'));
296
+ }
297
+
298
+ var i_siz = getSizes(opts, getItems($cfs, ':lt('+nI+')')),
299
+ w_siz = mapWrapperSizes(getSizes(opts, c_itm[1], true), opts);
300
+
301
+ if (opts.usePadding) {
302
+ l_old.css(opts.dimentions[6], l_old.data('cfs_origCssMargin') + opts.padding[1]);
303
+ l_new.css(opts.dimentions[6], l_new.data('cfs_origCssMargin') + opts.padding[1]);
304
+ }
305
+
306
+ var a_cfs = {},
307
+ a_old = {},
308
+ a_cur = {},
309
+ a_dur = sO.duration;
310
+
311
+ if (a_dur == 'auto') a_dur = opts.scroll.duration / opts.scroll.items * nI;
312
+ else if (a_dur <= 0) a_dur = 0;
313
+ else if (a_dur < 10) a_dur = i_siz[0] / a_dur;
314
+
315
+ if (sO.onBefore) sO.onBefore(c_itm[0], c_itm[1], w_siz, a_dur);
316
+
317
+ a_cfs[opts.dimentions[4]] = -i_siz[0];
318
+
319
+ if (opts.usePadding) {
320
+ a_old[opts.dimentions[6]] = l_old.data('cfs_origCssMargin');
321
+ a_cur[opts.dimentions[6]] = l_cur.data('cfs_origCssMargin') + opts.padding[3];
322
+ l_new.css(opts.dimentions[6], l_new.data('cfs_origCssMargin') + opts.padding[1]);
323
+
324
+ l_old.stop().animate(a_old, {
325
+ duration: a_dur,
326
+ easing : sO.easing
327
+ });
328
+ l_cur.stop().animate(a_cur, {
329
+ duration: a_dur,
330
+ easing : sO.easing
331
+ });
332
+ }
333
+
334
+ if ((typeof opts[opts.dimentions[0]] != 'number' && typeof opts.items[opts.dimentions[0]] != 'number') ||
335
+ (typeof opts[opts.dimentions[2]] != 'number' && typeof opts.items[opts.dimentions[2]] != 'number')
336
+ ) {
337
+ $wrp.stop().animate(w_siz, {
338
+ duration: a_dur,
339
+ easing : sO.easing
340
+ });
341
+ }
342
+ $cfs.data('cfs_numItems', nI)
343
+ .data('cfs_slideObj', sO)
344
+ .data('cfs_oldItems', c_itm[0])
345
+ .data('cfs_newItems', c_itm[1])
346
+ .data('cfs_wrapSize', w_siz)
347
+ .animate(a_cfs, {
348
+ duration: a_dur,
349
+ easing : sO.easing,
350
+ complete: function() {
351
+ if ($cfs.data('cfs_slideObj').onAfter) {
352
+ $cfs.data('cfs_slideObj').onAfter($cfs.data('cfs_oldItems'), $cfs.data('cfs_newItems'), $cfs.data('cfs_wrapSize'));
353
+ }
354
+ if (totalItems < opts.items.visible+$cfs.data('cfs_numItems')) {
355
+ getItems($cfs, ':gt('+(totalItems-1)+')').remove();
356
+ }
357
+ var org_m = (opts.usePadding) ? opts.padding[3] : 0;
358
+ $cfs.css(opts.dimentions[4], org_m);
359
+
360
+ var l_itm = getItems($cfs, ':lt('+$cfs.data('cfs_numItems')+')').appendTo($cfs).filter(':last');
361
+ if (opts.usePadding) {
362
+ l_itm.css(opts.dimentions[6], l_itm.data('cfs_origCssMargin'));
363
+ }
364
+ }
365
+ });
366
+ $cfs.trigger('updatePageStatus').trigger('play', a_dur);
367
+ })
368
+ .bind('slideTo', function(e, num, dev, org, obj) {
369
+ if ($cfs.is(':animated')) return false;
370
+
371
+ num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
372
+ if (num == 0) return false;
373
+ if (typeof obj != 'object') obj = false;
374
+
375
+ if (opts.circular) {
376
+ if (num < totalItems / 2) $cfs.trigger('next', [obj, num]);
377
+ else $cfs.trigger('prev', [obj, totalItems-num]);
378
+ } else {
379
+ if (firstItem == 0 ||
380
+ firstItem > num) $cfs.trigger('next', [obj, num]);
381
+ else $cfs.trigger('prev', [obj, totalItems-num]);
382
+ }
383
+ })
384
+ .bind('insertItem', function(e, itm, num, org, dev) {
385
+ if (typeof itm == 'object' &&
386
+ typeof itm.jquery == 'undefined') itm = $(itm);
387
+ if (typeof itm == 'string') itm = $(itm);
388
+ if (typeof itm != 'object' ||
389
+ typeof itm.jquery == 'undefined' ||
390
+ itm.length == 0) return log('Not a valid object.');
391
+
392
+ if (typeof num == 'undefined' || num == 'end') {
393
+ $cfs.append(itm);
394
+ } else {
395
+ num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
396
+ var $cit = getItems($cfs, ':nth('+num+')');
397
+
398
+ if ($cit.length) {
399
+ if (num <= firstItem) firstItem += itm.length;
400
+ $cit.before(itm);
401
+ } else {
402
+ $cfs.append(itm);
403
+ }
404
+ }
405
+ totalItems = getItems($cfs).length;
406
+ link_anchors('', '.caroufredsel', $cfs);
407
+ setSizes($cfs, opts);
408
+ showNavi(opts, totalItems);
409
+ $cfs.trigger('updatePageStatus', true);
410
+ })
411
+ .bind('removeItem', function(e, num, org, dev) {
412
+ if (typeof num == 'undefined' || num == 'end') {
413
+ getItems($cfs, ':last').remove();
414
+ } else {
415
+ num = getItemIndex(num, dev, org, firstItem, totalItems, $cfs);
416
+ var $cit = getItems($cfs, ':nth('+num+')');
417
+ if ($cit.length){
418
+ if (num < firstItem) firstItem -= $cit.length;
419
+ $cit.remove();
420
+ }
421
+ }
422
+ totalItems = getItems($cfs).length;
423
+ link_anchors('', '.caroufredsel', $cfs);
424
+ setSizes($cfs, opts);
425
+ showNavi(opts, totalItems);
426
+ $cfs.trigger('updatePageStatus', true);
427
+ })
428
+ .bind('updatePageStatus', function(e, bpa) {
429
+ if (!opts.pagination.container) return false;
430
+ if (typeof bpa == 'boolean' && bpa) {
431
+ getItems(opts.pagination.container).remove();
432
+ for (var a = 0; a < Math.ceil(totalItems/opts.items.visible); a++) {
433
+ opts.pagination.container.append(opts.pagination.anchorBuilder(a+1));
434
+ }
435
+ getItems(opts.pagination.container).unbind('click').each(function(a) {
436
+ $(this).click(function(e) {
437
+ e.preventDefault();
438
+ $cfs.trigger('slideTo', [a * opts.items.visible, 0, true, opts.pagination]);
439
+ });
440
+ });
441
+ }
442
+ var nr = (firstItem == 0) ? 0 : Math.round((totalItems-firstItem)/opts.items.visible);
443
+ getItems(opts.pagination.container).removeClass('selected').filter(':nth('+nr+')').addClass('selected');
444
+ });
445
+ }; // /bind_events
446
+
447
+ this.bind_buttons = function() {
448
+ if (opts.auto.pauseOnHover && opts.auto.play) {
449
+ $wrp.hover(
450
+ function() { $cfs.trigger('pause'); },
451
+ function() { $cfs.trigger('play'); }
452
+ );
453
+ }
454
+ if (opts.prev.button) {
455
+ opts.prev.button.click(function(e) {
456
+ $cfs.trigger('prev');
457
+ e.preventDefault();
458
+ });
459
+ if (opts.prev.pauseOnHover && opts.auto.play) {
460
+ opts.prev.button.hover(
461
+ function() { $cfs.trigger('pause'); },
462
+ function() { $cfs.trigger('play'); }
463
+ );
464
+ }
465
+ if (!opts.circular && !opts.infinite) {
466
+ opts.prev.button.addClass('disabled');
467
+ }
468
+ }
469
+ if ($.fn.mousewheel) {
470
+ if (opts.prev.mousewheel) {
471
+ $wrp.mousewheel(function(e, delta) {
472
+ if (delta > 0) {
473
+ e.preventDefault();
474
+ num = (typeof opts.prev.mousewheel == 'number') ? opts.prev.mousewheel : '';
475
+ $cfs.trigger('prev', num);
476
+ }
477
+ });
478
+ }
479
+ if (opts.next.mousewheel) {
480
+ $wrp.mousewheel(function(e, delta) {
481
+ if (delta < 0) {
482
+ e.preventDefault();
483
+ num = (typeof opts.next.mousewheel == 'number') ? opts.next.mousewheel : '';
484
+ $cfs.trigger('next', num);
485
+ }
486
+ });
487
+ }
488
+ }
489
+ if (opts.next.button) {
490
+ opts.next.button.click(function(e) {
491
+ e.preventDefault();
492
+ $cfs.trigger('next');
493
+ });
494
+ if (opts.next.pauseOnHover && opts.auto.play) {
495
+ opts.next.button.hover(
496
+ function() { $cfs.trigger('pause'); },
497
+ function() { $cfs.trigger('play'); }
498
+ )
499
+ }
500
+ }
501
+ if (opts.pagination.container) {
502
+ $cfs.trigger('updatePageStatus', true);
503
+ if (opts.pagination.pauseOnHover && opts.auto.play) {
504
+ opts.pagination.container.hover(
505
+ function() { $cfs.trigger('pause'); },
506
+ function() { $cfs.trigger('play'); }
507
+ );
508
+ }
509
+ }
510
+ if (opts.next.key || opts.prev.key) {
511
+ $(document).keyup(function(e) {
512
+ var k = e.keyCode;
513
+ if (k == opts.next.key) {
514
+ e.preventDefault();
515
+ $cfs.trigger('next');
516
+ }
517
+ if (k == opts.prev.key) {
518
+ e.preventDefault();
519
+ $cfs.trigger('prev');
520
+ }
521
+ });
522
+ }
523
+ if (opts.pagination.keys) {
524
+ $(document).keyup(function(e) {
525
+ var k = e.keyCode;
526
+ if (k >= 49 && k < 58) {
527
+ k = (k-49) * opts.items.visible;
528
+ if (k <= totalItems) {
529
+ e.preventDefault();
530
+ $cfs.trigger('slideTo', [k, 0, true, opts.pagination]);
531
+ }
532
+ }
533
+ });
534
+ }
535
+ if (opts.auto.play) {
536
+ $cfs.trigger('play', opts.auto.delay);
537
+ if ($.fn.nap && opts.auto.nap) {
538
+ $cfs.nap('pause', 'play');
539
+ }
540
+ }
541
+ }; // /bind_buttons
542
+
543
+ this.destroy = function() {
544
+ $cfs.css($cfs.data('cfs_origCss'))
545
+ .unbind('pause')
546
+ .unbind('play')
547
+ .unbind('prev')
548
+ .unbind('next')
549
+ .unbind('scrollTo')
550
+ .unbind('slideTo')
551
+ .unbind('insertItem')
552
+ .unbind('removeItem')
553
+ .unbind('updatePageStatus');
554
+
555
+ $wrp.replaceWith($cfs);
556
+ return this;
557
+ }; // /destroy
558
+
559
+ this.configuration = function(a, b) {
560
+ if (typeof a == 'undefined') return opts;
561
+ if (typeof b == 'undefined') {
562
+ var r = eval('opts.'+a);
563
+ if (typeof r == 'undefined') r = '';
564
+ return r;
565
+ }
566
+ eval('opts.'+a+' = b');
567
+ this.init(opts);
568
+ setSizes($cfs, opts);
569
+ return this;
570
+ }; // /configuration
571
+
572
+ this.link_anchors = function($c, se) {
573
+ link_anchors($c, se, $cfs);
574
+ }; // /link_anchors
575
+
576
+ var $cfs = $(this),
577
+ $wrp = $(this).wrap('<div class="caroufredsel_wrapper" />').parent(),
578
+ opts = {},
579
+ totalItems = getItems($cfs).length,
580
+ firstItem = 0,
581
+ autoTimeout = null,
582
+ autoInterval = null,
583
+ pauseTimePassed = 0,
584
+ pausedGlobal = false,
585
+ direction = 'next';
586
+
587
+ this.init(o);
588
+ this.build();
589
+ this.bind_events();
590
+ this.bind_buttons();
591
+ link_anchors('', '.caroufredsel', $cfs);
592
+ setSizes($cfs, opts);
593
+
594
+ if (opts.items.start !== 0 && opts.items.start !== false) {
595
+ var s = opts.items.start;
596
+ if (opts.items.start === true) {
597
+ s = window.location.hash;
598
+ if (!s.length) s = 0;
599
+ }
600
+ $cfs.trigger('slideTo', [s, 0, true, { duration: 0 }]);
601
+ }
602
+ return this;
603
+ };
604
+
605
+ // public
606
+ $.fn.carouFredSel.defaults = {
607
+ infinite : true,
608
+ circular : true,
609
+ direction : 'left',
610
+ padding : 0,
611
+ items : {
612
+ visible : 5,
613
+ start : 0
614
+ },
615
+ scroll : {
616
+ easing : 'swing',
617
+ pauseOnHover: false,
618
+ mousewheel : false
619
+ }
620
+ };
621
+ $.fn.carouFredSel.pageAnchorBuilder = function(nr) {
622
+ return '<a href="#"><span>'+nr+'</span></a>';
623
+ };
624
+
625
+ // private
626
+ function link_anchors($c, se, $cfs) {
627
+ if (typeof $c == 'undefined' || $c.length == 0) $c = $('body');
628
+ else if (typeof $c == 'string') $c = $($c);
629
+ if (typeof $c != 'object') return false;
630
+ if (typeof se == 'undefined') se = '';
631
+ $c.find('a'+se).each(function() {
632
+ var h = this.hash || '';
633
+ if (h.length > 0 && getItems($cfs).index($(h)) != -1) {
634
+ $(this).unbind('click').click(function(e) {
635
+ e.preventDefault();
636
+ $cfs.trigger('slideTo', h);
637
+ });
638
+ }
639
+ });
640
+ }
641
+ function showNavi(o, t) {
642
+ if (o.items.minimum >= t) {
643
+ log('Not enough items: not scrolling');
644
+ var f = 'hide';
645
+ } else {
646
+ var f = 'show';
647
+ }
648
+ if (o.prev.button) o.prev.button[f]();
649
+ if (o.next.button) o.next.button[f]();
650
+ if (o.pagination.container) o.pagination.container[f]();
651
+ }
652
+ function getKeyCode(k) {
653
+ if (k == 'right') return 39;
654
+ if (k == 'left') return 37;
655
+ if (k == 'up') return 38;
656
+ if (k == 'down') return 40;
657
+ return -1
658
+ };
659
+ function getNaviObject(obj, pagi, auto) {
660
+ if (typeof pagi != 'boolean') pagi = false;
661
+ if (typeof auto != 'boolean') auto = false;
662
+
663
+ if (typeof obj == 'undefined') obj = {};
664
+ if (typeof obj == 'string') {
665
+ var temp = getKeyCode(obj);
666
+ if (temp == -1) obj = $(obj);
667
+ else obj = temp;
668
+ }
669
+ if (pagi) {
670
+ if (typeof obj.jquery != 'undefined') obj = { container: obj };
671
+ if (typeof Object == 'boolean') obj = { keys: obj };
672
+ if (typeof obj.container == 'string') obj.container = $(obj.container);
673
+
674
+ } else if (auto) {
675
+ if (typeof obj == 'boolean') obj = { play: obj };
676
+ if (typeof obj == 'number') obj = { pauseDuration: obj };
677
+
678
+ } else {
679
+ if (typeof obj.jquery != 'undefined') obj = { button: obj };
680
+ if (typeof obj == 'number') obj = { key: obj };
681
+ if (typeof obj.button == 'string') obj.button = $(obj.button);
682
+ if (typeof obj.key == 'string') obj.key = getKeyCode(obj.key);
683
+ }
684
+ return obj;
685
+ };
686
+ function getItems(a, f) {
687
+ if (typeof f != 'string') f = '';
688
+ return $('> *'+f, a);
689
+ };
690
+ function getCurrentItems(c, o, n) {
691
+ var oi = getItems(c, ':lt('+o.items.visible+')'),
692
+ ni = getItems(c, ':lt('+(o.items.visible+n)+'):gt('+(n-1)+')');
693
+ return [oi, ni];
694
+ };
695
+ function getItemIndex(num, dev, org, firstItem, totalItems, $cfs) {
696
+ if (typeof num == 'string') {
697
+ if (isNaN(num)) num = $(num);
698
+ else num = parseInt(num);
699
+ }
700
+ if (typeof num == 'object') {
701
+ if (typeof num.jquery == 'undefined') num = $(num);
702
+ num = getItems($cfs).index(num);
703
+ if (num == -1) num = 0;
704
+ if (typeof org != 'boolean') org = false;
705
+ } else {
706
+ if (typeof org != 'boolean') org = true;
707
+ }
708
+ if (isNaN(num)) num = 0;
709
+ else num = parseInt(num);
710
+ if (isNaN(dev)) dev = 0;
711
+ else dev = parseInt(dev);
712
+
713
+ if (org) {
714
+ num += firstItem;
715
+ }
716
+ num += dev;
717
+ if (totalItems > 0) {
718
+ while (num >= totalItems) { num -= totalItems; }
719
+ while (num < 0) { num += totalItems; }
720
+ }
721
+ return num;
722
+ };
723
+ function getSizes(o, $i, wrap) {
724
+ if (typeof wrap != 'boolean') wrap = false;
725
+ var di = o.dimentions,
726
+ s1 = 0,
727
+ s2 = 0;
728
+
729
+ if (wrap && typeof o[di[0]] == 'number') s1 += o[di[0]];
730
+ else if ( typeof o.items[di[0]] == 'number') s1 += o.items[di[0]] * $i.length;
731
+ else {
732
+ $i.each(function() {
733
+ s1 += $(this)[di[1]](true);
734
+ });
735
+ }
736
+
737
+ if (wrap && typeof o[di[2]] == 'number') s2 += o[di[2]];
738
+ else if ( typeof o.items[di[2]] == 'number') s2 += o.items[di[2]];
739
+ else {
740
+ $i.each(function() {
741
+ var m = $(this)[di[3]](true);
742
+ if (s2 < m) s2 = m;
743
+ });
744
+ }
745
+ return [s1, s2];
746
+ };
747
+ function mapWrapperSizes(ws, o) {
748
+ var pad = (o.usePadding) ? o.padding : [0, 0, 0, 0];
749
+ var wra = {};
750
+ wra[o.dimentions[0]] = ws[0] + pad[1] + pad[3];
751
+ wra[o.dimentions[2]] = ws[1] + pad[0] + pad[2];
752
+ return wra;
753
+ };
754
+ function setSizes($c, o) {
755
+ var $w = $c.parent(),
756
+ $i = getItems($c),
757
+ $l = $i.filter(':nth('+(o.items.visible-1)+')'),
758
+ is = getSizes(o, $i);
759
+
760
+ $w.css(mapWrapperSizes(getSizes(o, $i.filter(':lt('+o.items.visible+')'), true), o));
761
+ if (o.usePadding) {
762
+ $l.css(o.dimentions[6], $l.data('cfs_origCssMargin') + o.padding[1]);
763
+ $c.css(o.dimentions[5], o.padding[0]);
764
+ $c.css(o.dimentions[4], o.padding[3]);
765
+ }
766
+ $c.css(o.dimentions[0], is[0]*2);
767
+ $c.css(o.dimentions[2], is[1]);
768
+ };
769
+ function getPadding(p) {
770
+ if (typeof p == 'number') p = [p];
771
+ else if (typeof p == 'string') p = p.split('px').join('').split(' ');
772
+
773
+ if (typeof p != 'object') {
774
+ log('Not a valid value, padding set to "0".');
775
+ p = [0];
776
+ }
777
+ for (i in p) {
778
+ p[i] = parseInt(p[i]);
779
+ }
780
+ switch (p.length) {
781
+ case 0:
782
+ return [0, 0, 0, 0];
783
+ case 1:
784
+ return [p[0], p[0], p[0], p[0]];
785
+ case 2:
786
+ return [p[0], p[1], p[0], p[1]];
787
+ case 3:
788
+ return [p[0], p[1], p[2], p[1]];
789
+ default:
790
+ return p;
791
+ }
792
+ };
793
+ function log(m) {
794
+ if (typeof m == 'string') m = 'carouFredSel: ' + m;
795
+ if (window.console && window.console.log) window.console.log(m);
796
+ else try { console.log(m); } catch(err) { }
797
+ return false;
798
+ };
799
+
800
+ $.fn.caroufredsel = function(o) {
801
+ this.carouFredSel(o);
802
+ };
803
+
804
+ })(jQuery);
js/productzoom/jquery.jqzoom-core.js ADDED
@@ -0,0 +1,736 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQzoom Evolution Library v2.3 - Javascript Image magnifier
3
+ * http://www.mind-projects.it
4
+ *
5
+ * Copyright 2011, Engineer Marco Renzi
6
+ * Licensed under the BSD license.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ * * Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * * Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ * * Neither the name of the organization nor the
16
+ * names of its contributors may be used to endorse or promote products
17
+ * derived from this software without specific prior written permission.
18
+ *
19
+ * Date: 03 May 2011 22:16:00
20
+ */
21
+ (function (jQuery) {
22
+ //GLOBAL VARIABLES
23
+ var isIE6 = false;//(jQuery.browser.msie && jQuery.browser.version < 7);
24
+ var body = jQuery(document.body);
25
+ var window = jQuery(window);
26
+ var jqzoompluging_disabled = false; //disabilita globalmente il plugin
27
+ jQuery.fn.jqzoom = function (options) {
28
+ return this.each(function () {
29
+ var node = this.nodeName.toLowerCase();
30
+ if (node == 'a') {
31
+ new jqzoom(this, options);
32
+ }
33
+ });
34
+ };
35
+ jqzoom = function (el, options) {
36
+ var api = null;
37
+ api = jQuery(el).data("jqzoom");
38
+ if (api) return api;
39
+ var obj = this;
40
+ var settings = jQuery.extend({}, jQuery.jqzoom.defaults, options || {});
41
+ obj.el = el;
42
+ el.rel = jQuery(el).attr('rel');
43
+ //ANCHOR ELEMENT
44
+ el.zoom_active = false;
45
+ el.zoom_disabled = false; //to disable single zoom instance
46
+ el.largeimageloading = false; //tell us if large image is loading
47
+ el.largeimageloaded = false; //tell us if large image is loaded
48
+ el.scale = {};
49
+ el.timer = null;
50
+ el.mousepos = {};
51
+ el.mouseDown = false;
52
+ jQuery(el).css({
53
+ 'outline-style': 'none',
54
+ 'text-decoration': 'none'
55
+ });
56
+ //BASE IMAGE
57
+ var img = jQuery("img:eq(0)", el);
58
+ el.title = jQuery(el).attr('title');
59
+ el.imagetitle = img.attr('title');
60
+ var zoomtitle = (jQuery.trim(el.title).length > 0) ? el.title : el.imagetitle;
61
+ var smallimage = new Smallimage(img);
62
+ var lens = new Lens();
63
+ var stage = new Stage();
64
+ var largeimage = new Largeimage();
65
+ var loader = new Loader();
66
+ //preventing default click,allowing the onclick event [exmple: lightbox]
67
+ jQuery(el).bind('click', function (e) {
68
+ e.preventDefault();
69
+ return false;
70
+ });
71
+ //setting the default zoomType if not in settings
72
+ var zoomtypes = ['standard', 'drag', 'innerzoom', 'reverse'];
73
+ if (jQuery.inArray(jQuery.trim(settings.zoomType), zoomtypes) < 0) {
74
+ settings.zoomType = 'standard';
75
+ }
76
+ jQuery.extend(obj, {
77
+ create: function () { //create the main objects
78
+ //create ZoomPad
79
+ if (jQuery(".zoomPad", el).length == 0) {
80
+ el.zoomPad = jQuery('<div/>').addClass('zoomPad');
81
+ img.wrap(el.zoomPad);
82
+ }
83
+ if(settings.zoomType == 'innerzoom'){
84
+ settings.zoomWidth = smallimage.w;
85
+ settings.zoomHeight = smallimage.h;
86
+ }
87
+ //creating ZoomPup
88
+ if (jQuery(".zoomPup", el).length == 0) {
89
+ lens.append();
90
+ }
91
+ //creating zoomWindow
92
+ if (jQuery(".zoomWindow", el).length == 0) {
93
+ stage.append();
94
+ }
95
+ //creating Preload
96
+ if (jQuery(".zoomPreload", el).length == 0) {
97
+ loader.append();
98
+ }
99
+ //preloading images
100
+ if (settings.preloadImages || settings.zoomType == 'drag' || settings.alwaysOn) {
101
+ obj.load();
102
+ }
103
+ obj.init();
104
+ },
105
+ init: function () {
106
+ //drag option
107
+ if (settings.zoomType == 'drag') {
108
+ jQuery(".zoomPad", el).mousedown(function () {
109
+ el.mouseDown = true;
110
+ });
111
+ jQuery(".zoomPad", el).mouseup(function () {
112
+ el.mouseDown = false;
113
+ });
114
+ document.body.ondragstart = function () {
115
+ return false;
116
+ };
117
+ jQuery(".zoomPad", el).css({
118
+ cursor: 'default'
119
+ });
120
+ jQuery(".zoomPup", el).css({
121
+ cursor: 'move'
122
+ });
123
+ }
124
+ if (settings.zoomType == 'innerzoom') {
125
+ jQuery(".zoomWrapper", el).css({
126
+ cursor: 'crosshair'
127
+ });
128
+ }
129
+ jQuery(".zoomPad", el).bind('mouseenter mouseover', function (event) {
130
+ img.attr('title', '');
131
+ jQuery(el).attr('title', '');
132
+ el.zoom_active = true;
133
+ //if loaded then activate else load large image
134
+ smallimage.fetchdata();
135
+ if (el.largeimageloaded) {
136
+ obj.activate(event);
137
+ } else {
138
+ obj.load();
139
+ }
140
+ });
141
+ jQuery(".zoomPad", el).bind('mouseleave', function (event) {
142
+ obj.deactivate();
143
+ });
144
+ jQuery(".zoomPad", el).bind('mousemove', function (e) {
145
+
146
+ //prevent fast mouse mevements not to fire the mouseout event
147
+ if (e.pageX > smallimage.pos.r || e.pageX < smallimage.pos.l || e.pageY < smallimage.pos.t || e.pageY > smallimage.pos.b) {
148
+ lens.setcenter();
149
+ return false;
150
+ }
151
+ el.zoom_active = true;
152
+ if (el.largeimageloaded && !jQuery('.zoomWindow', el).is(':visible')) {
153
+ obj.activate(e);
154
+ }
155
+ if (el.largeimageloaded && (settings.zoomType != 'drag' || (settings.zoomType == 'drag' && el.mouseDown))) {
156
+ lens.setposition(e);
157
+ }
158
+ });
159
+ var thumb_preload = new Array();
160
+ var i = 0;
161
+ //binding click event on thumbnails
162
+ var thumblist = new Array();
163
+ thumblist = jQuery('a').filter(function () {
164
+ var regex = new RegExp("gallery[\\s]*:[\\s]*'" + jQuery.trim(el.rel) + "'", "i");
165
+ var rel = jQuery(this).attr('rel');
166
+ if (regex.test(rel)) {
167
+ return this;
168
+ }
169
+ });
170
+ if (thumblist.length > 0) {
171
+ //getting the first to the last
172
+ var first = thumblist.splice(0, 1);
173
+ thumblist.push(first);
174
+ }
175
+ thumblist.each(function () {
176
+ //preloading thumbs
177
+ if (settings.preloadImages) {
178
+ var thumb_options = jQuery.extend({}, eval("(" + jQuery.trim(jQuery(this).attr('rel')) + ")"));
179
+ thumb_preload[i] = new Image();
180
+ thumb_preload[i].src = thumb_options.largeimage;
181
+ i++;
182
+ }
183
+ jQuery(this).click(function (e) {
184
+ if(jQuery(this).hasClass('zoomThumbActive')){
185
+ return false;
186
+ }
187
+ thumblist.each(function () {
188
+ jQuery(this).removeClass('zoomThumbActive');
189
+ });
190
+ e.preventDefault();
191
+ obj.swapimage(this);
192
+ return false;
193
+ });
194
+ });
195
+ },
196
+ load: function () {
197
+ if (el.largeimageloaded == false && el.largeimageloading == false) {
198
+ var url = jQuery(el).attr('href');
199
+ el.largeimageloading = true;
200
+ largeimage.loadimage(url);
201
+ }
202
+ },
203
+ activate: function (e) {
204
+ document.getElementById("mouse-hover-massage").style.display='none';
205
+
206
+ clearTimeout(el.timer);
207
+ //show lens and zoomWindow
208
+ lens.show();
209
+ stage.show();
210
+ },
211
+ deactivate: function (e) {
212
+ document.getElementById("mouse-hover-massage").style.display='block';
213
+ switch (settings.zoomType) {
214
+ case 'drag':
215
+ //nothing or lens.setcenter();
216
+ break;
217
+ default:
218
+ img.attr('title', el.imagetitle);
219
+ jQuery(el).attr('title', el.title);
220
+ if (settings.alwaysOn) {
221
+ lens.setcenter();
222
+ } else {
223
+ stage.hide();
224
+ lens.hide();
225
+ }
226
+ break;
227
+ }
228
+ el.zoom_active = false;
229
+ },
230
+ swapimage: function (link) {
231
+ el.largeimageloading = false;
232
+ el.largeimageloaded = false;
233
+ var options = new Object();
234
+ options = jQuery.extend({}, eval("(" + jQuery.trim(jQuery(link).attr('rel')) + ")"));
235
+ if (options.smallimage && options.largeimage) {
236
+ var smallimage = options.smallimage;
237
+ var largeimage = options.largeimage;
238
+ jQuery(link).addClass('zoomThumbActive');
239
+ jQuery(el).attr('href', largeimage);
240
+ img.attr('src', smallimage);
241
+ lens.hide();
242
+ stage.hide();
243
+ obj.load();
244
+ } else {
245
+ alert('ERROR :: Missing parameter for largeimage or smallimage.');
246
+ throw 'ERROR :: Missing parameter for largeimage or smallimage.';
247
+ }
248
+ return false;
249
+ }
250
+ });
251
+ //sometimes image is already loaded and onload will not fire
252
+ if (img[0].complete) {
253
+ //fetching data from sallimage if was previously loaded
254
+ smallimage.fetchdata();
255
+ if (jQuery(".zoomPad", el).length == 0) obj.create();
256
+ }
257
+ /*========================================================,
258
+ | Smallimage
259
+ |---------------------------------------------------------:
260
+ | Base image into the anchor element
261
+ `========================================================*/
262
+
263
+ function Smallimage(image) {
264
+ var jQueryobj = this;
265
+ this.node = image[0];
266
+ this.findborder = function () {
267
+ var bordertop = 0;
268
+ bordertop = image.css('border-top-width');
269
+ btop = '';
270
+ var borderleft = 0;
271
+ borderleft = image.css('border-left-width');
272
+ bleft = '';
273
+ if (bordertop) {
274
+ for (i = 0; i < 3; i++) {
275
+ var x = [];
276
+ x = bordertop.substr(i, 1);
277
+ if (isNaN(x) == false) {
278
+ btop = btop + '' + bordertop.substr(i, 1);
279
+ } else {
280
+ break;
281
+ }
282
+ }
283
+ }
284
+ if (borderleft) {
285
+ for (i = 0; i < 3; i++) {
286
+ if (!isNaN(borderleft.substr(i, 1))) {
287
+ bleft = bleft + borderleft.substr(i, 1)
288
+ } else {
289
+ break;
290
+ }
291
+ }
292
+ }
293
+ jQueryobj.btop = (btop.length > 0) ? eval(btop) : 0;
294
+ jQueryobj.bleft = (bleft.length > 0) ? eval(bleft) : 0;
295
+ };
296
+ this.fetchdata = function () {
297
+ jQueryobj.findborder();
298
+ jQueryobj.w = image.width();
299
+ jQueryobj.h = image.height();
300
+ jQueryobj.ow = image.outerWidth();
301
+ jQueryobj.oh = image.outerHeight();
302
+ jQueryobj.pos = image.offset();
303
+ jQueryobj.pos.l = image.offset().left + jQueryobj.bleft;
304
+ jQueryobj.pos.t = image.offset().top + jQueryobj.btop;
305
+ jQueryobj.pos.r = jQueryobj.w + jQueryobj.pos.l;
306
+ jQueryobj.pos.b = jQueryobj.h + jQueryobj.pos.t;
307
+ jQueryobj.rightlimit = image.offset().left + jQueryobj.ow;
308
+ jQueryobj.bottomlimit = image.offset().top + jQueryobj.oh;
309
+
310
+ };
311
+ this.node.onerror = function () {
312
+ alert('Problems while loading image.');
313
+ throw 'Problems while loading image.';
314
+ };
315
+ this.node.onload = function () {
316
+ jQueryobj.fetchdata();
317
+ if (jQuery(".zoomPad", el).length == 0) obj.create();
318
+ };
319
+ return jQueryobj;
320
+ };
321
+ /*========================================================,
322
+ | Loader
323
+ |---------------------------------------------------------:
324
+ | Show that the large image is loading
325
+ `========================================================*/
326
+
327
+ function Loader() {
328
+ var jQueryobj = this;
329
+ this.append = function () {
330
+ this.node = jQuery('<div/>').addClass('zoomPreload').css('visibility', 'hidden').html(settings.preloadText);
331
+ jQuery('.zoomPad', el).append(this.node);
332
+ };
333
+ this.show = function () {
334
+ this.node.top = (smallimage.oh - this.node.height()) / 2;
335
+ this.node.left = (smallimage.ow - this.node.width()) / 2;
336
+ //setting position
337
+ this.node.css({
338
+ top: this.node.top,
339
+ left: this.node.left,
340
+ position: 'absolute',
341
+ visibility: 'visible'
342
+ });
343
+ };
344
+ this.hide = function () {
345
+ this.node.css('visibility', 'hidden');
346
+ };
347
+ return this;
348
+ }
349
+ /*========================================================,
350
+ | Lens
351
+ |---------------------------------------------------------:
352
+ | Lens over the image
353
+ `========================================================*/
354
+
355
+ function Lens() {
356
+ var jQueryobj = this;
357
+ this.node = jQuery('<div/>').addClass('zoomPup');
358
+ //this.nodeimgwrapper = jQuery("<div/>").addClass('zoomPupImgWrapper');
359
+ this.append = function () {
360
+ jQuery('.zoomPad', el).append(jQuery(this.node).hide());
361
+ if (settings.zoomType == 'reverse') {
362
+ this.image = new Image();
363
+ this.image.src = smallimage.node.src; // fires off async
364
+ jQuery(this.node).empty().append(this.image);
365
+ }
366
+ };
367
+ this.setdimensions = function () {
368
+ this.node.w = (parseInt((settings.zoomWidth) / el.scale.x) > smallimage.w ) ? smallimage.w : (parseInt(settings.zoomWidth / el.scale.x));
369
+ this.node.h = (parseInt((settings.zoomHeight) / el.scale.y) > smallimage.h ) ? smallimage.h : (parseInt(settings.zoomHeight / el.scale.y));
370
+ this.node.top = (smallimage.oh - this.node.h - 2) / 2;
371
+ this.node.left = (smallimage.ow - this.node.w - 2) / 2;
372
+ //centering lens
373
+ this.node.css({
374
+ top: 0,
375
+ left: 0,
376
+ width: this.node.w + 'px',
377
+ height: this.node.h + 'px',
378
+ position: 'absolute',
379
+ display: 'none',
380
+ borderWidth: 1 + 'px'
381
+ });
382
+
383
+
384
+
385
+ if (settings.zoomType == 'reverse') {
386
+ this.image.src = smallimage.node.src;
387
+ jQuery(this.node).css({
388
+ 'opacity': 1
389
+ });
390
+
391
+ jQuery(this.image).css({
392
+ position: 'absolute',
393
+ display: 'block',
394
+ left: -(this.node.left + 1 - smallimage.bleft) + 'px',
395
+ top: -(this.node.top + 1 - smallimage.btop) + 'px'
396
+ });
397
+
398
+ }
399
+ };
400
+ this.setcenter = function () {
401
+ //calculating center position
402
+ this.node.top = (smallimage.oh - this.node.h - 2) / 2;
403
+ this.node.left = (smallimage.ow - this.node.w - 2) / 2;
404
+ //centering lens
405
+ this.node.css({
406
+ top: this.node.top,
407
+ left: this.node.left
408
+ });
409
+ if (settings.zoomType == 'reverse') {
410
+ jQuery(this.image).css({
411
+ position: 'absolute',
412
+ display: 'block',
413
+ left: -(this.node.left + 1 - smallimage.bleft) + 'px',
414
+ top: -(this.node.top + 1 - smallimage.btop) + 'px'
415
+ });
416
+
417
+ }
418
+ //centering large image
419
+ largeimage.setposition();
420
+ };
421
+ this.setposition = function (e) {
422
+ el.mousepos.x = e.pageX;
423
+ el.mousepos.y = e.pageY;
424
+ var lensleft = 0;
425
+ var lenstop = 0;
426
+
427
+ function overleft(lens) {
428
+ return el.mousepos.x - (lens.w) / 2 < smallimage.pos.l;
429
+ }
430
+
431
+ function overright(lens) {
432
+ return el.mousepos.x + (lens.w) / 2 > smallimage.pos.r;
433
+
434
+ }
435
+
436
+ function overtop(lens) {
437
+ return el.mousepos.y - (lens.h) / 2 < smallimage.pos.t;
438
+ }
439
+
440
+ function overbottom(lens) {
441
+ return el.mousepos.y + (lens.h) / 2 > smallimage.pos.b;
442
+ }
443
+
444
+ lensleft = el.mousepos.x + smallimage.bleft - smallimage.pos.l - (this.node.w + 2) / 2;
445
+ lenstop = el.mousepos.y + smallimage.btop - smallimage.pos.t - (this.node.h + 2) / 2;
446
+ if (overleft(this.node)) {
447
+ lensleft = smallimage.bleft - 1;
448
+ } else if (overright(this.node)) {
449
+ lensleft = smallimage.w + smallimage.bleft - this.node.w - 1;
450
+ }
451
+ if (overtop(this.node)) {
452
+ lenstop = smallimage.btop - 1;
453
+ } else if (overbottom(this.node)) {
454
+ lenstop = smallimage.h + smallimage.btop - this.node.h - 1;
455
+ }
456
+
457
+ this.node.left = lensleft;
458
+ this.node.top = lenstop;
459
+ this.node.css({
460
+ 'left': lensleft + 'px',
461
+ 'top': lenstop + 'px'
462
+ });
463
+ if (settings.zoomType == 'reverse') {
464
+ if (jQuery.browser.msie && jQuery.browser.version > 7) {
465
+ jQuery(this.node).empty().append(this.image);
466
+ }
467
+
468
+ jQuery(this.image).css({
469
+ position: 'absolute',
470
+ display: 'block',
471
+ left: -(this.node.left + 1 - smallimage.bleft) + 'px',
472
+ top: -(this.node.top + 1 - smallimage.btop) + 'px'
473
+ });
474
+ }
475
+
476
+ largeimage.setposition();
477
+ };
478
+ this.hide = function () {
479
+ img.css({
480
+ 'opacity': 1
481
+ });
482
+ this.node.hide();
483
+ };
484
+ this.show = function () {
485
+
486
+ if (settings.zoomType != 'innerzoom' && (settings.lens || settings.zoomType == 'drag')) {
487
+ this.node.show();
488
+ }
489
+
490
+ if (settings.zoomType == 'reverse') {
491
+ img.css({
492
+ 'opacity': settings.imageOpacity
493
+ });
494
+ }
495
+ };
496
+ this.getoffset = function () {
497
+ var o = {};
498
+ o.left = jQueryobj.node.left;
499
+ o.top = jQueryobj.node.top;
500
+ return o;
501
+ };
502
+ return this;
503
+ };
504
+ /*========================================================,
505
+ | Stage
506
+ |---------------------------------------------------------:
507
+ | Window area that contains the large image
508
+ `========================================================*/
509
+
510
+ function Stage() {
511
+ var jQueryobj = this;
512
+ this.node = jQuery("<div class='zoomWindow'><div class='zoomWrapper'><div class='zoomWrapperTitle'></div><div class='zoomWrapperImage'></div></div></div>");
513
+ this.ieframe = jQuery('<iframe class="zoomIframe" src="javascript:\'\';" marginwidth="0" marginheight="0" align="bottom" scrolling="no" frameborder="0" ></iframe>');
514
+ this.setposition = function () {
515
+ this.node.leftpos = 0;
516
+ this.node.toppos = 0;
517
+ if (settings.zoomType != 'innerzoom') {
518
+ //positioning
519
+ switch (settings.position) {
520
+ case "left":
521
+ this.node.leftpos = (smallimage.pos.l - smallimage.bleft - Math.abs(settings.xOffset) - settings.zoomWidth > 0) ? (0 - settings.zoomWidth - Math.abs(settings.xOffset)) : (smallimage.ow + Math.abs(settings.xOffset));
522
+ this.node.toppos = Math.abs(settings.yOffset);
523
+ break;
524
+ case "top":
525
+ this.node.leftpos = Math.abs(settings.xOffset);
526
+ this.node.toppos = (smallimage.pos.t - smallimage.btop - Math.abs(settings.yOffset) - settings.zoomHeight > 0) ? (0 - settings.zoomHeight - Math.abs(settings.yOffset)) : (smallimage.oh + Math.abs(settings.yOffset));
527
+ break;
528
+ case "bottom":
529
+ this.node.leftpos = Math.abs(settings.xOffset);
530
+ this.node.toppos = (smallimage.pos.t - smallimage.btop + smallimage.oh + Math.abs(settings.yOffset) + settings.zoomHeight < screen.height) ? (smallimage.oh + Math.abs(settings.yOffset)) : (0 - settings.zoomHeight - Math.abs(settings.yOffset));
531
+ break;
532
+ default:
533
+ this.node.leftpos = (smallimage.rightlimit + Math.abs(settings.xOffset) + settings.zoomWidth < screen.width) ? (smallimage.ow + Math.abs(settings.xOffset)) : (0 - settings.zoomWidth - Math.abs(settings.xOffset));
534
+ this.node.toppos = Math.abs(settings.yOffset);
535
+ break;
536
+ }
537
+ }
538
+ this.node.css({
539
+ 'left': this.node.leftpos + 'px',
540
+ 'top': this.node.toppos + 'px'
541
+ });
542
+ return this;
543
+ };
544
+ this.append = function () {
545
+ jQuery('.zoomPad', el).append(this.node);
546
+ this.node.css({
547
+ position: 'absolute',
548
+ display: 'none',
549
+ zIndex: 5001
550
+ });
551
+ if (settings.zoomType == 'innerzoom') {
552
+ this.node.css({
553
+ cursor: 'default'
554
+ });
555
+ var thickness = (smallimage.bleft == 0) ? 1 : smallimage.bleft;
556
+ jQuery('.zoomWrapper', this.node).css({
557
+ borderWidth: thickness + 'px'
558
+ });
559
+ }
560
+
561
+ jQuery('.zoomWrapper', this.node).css({
562
+ width: Math.round(settings.zoomWidth) + 'px' ,
563
+ borderWidth: thickness + 'px'
564
+ });
565
+ jQuery('.zoomWrapperImage', this.node).css({
566
+ width: '100%',
567
+ height: Math.round(settings.zoomHeight) + 'px'
568
+ });
569
+ //zoom title
570
+ jQuery('.zoomWrapperTitle', this.node).css({
571
+ width: '100%',
572
+ position: 'absolute'
573
+ });
574
+
575
+ jQuery('.zoomWrapperTitle', this.node).hide();
576
+ if (settings.title && zoomtitle.length > 0) {
577
+ jQuery('.zoomWrapperTitle', this.node).html(zoomtitle).show();
578
+ }
579
+ jQueryobj.setposition();
580
+ };
581
+ this.hide = function () {
582
+ switch (settings.hideEffect) {
583
+ case 'fadeout':
584
+ this.node.fadeOut(settings.fadeoutSpeed, function () {});
585
+ break;
586
+ default:
587
+ this.node.hide();
588
+ break;
589
+ }
590
+ this.ieframe.hide();
591
+ };
592
+ this.show = function () {
593
+ switch (settings.showEffect) {
594
+ case 'fadein':
595
+ this.node.fadeIn();
596
+ this.node.fadeIn(settings.fadeinSpeed, function () {});
597
+ break;
598
+ default:
599
+ this.node.show();
600
+ break;
601
+ }
602
+ if (isIE6 && settings.zoomType != 'innerzoom') {
603
+ this.ieframe.width = this.node.width();
604
+ this.ieframe.height = this.node.height();
605
+ this.ieframe.left = this.node.leftpos;
606
+ this.ieframe.top = this.node.toppos;
607
+ this.ieframe.css({
608
+ display: 'block',
609
+ position: "absolute",
610
+ left: this.ieframe.left,
611
+ top: this.ieframe.top,
612
+ zIndex: 99,
613
+ width: this.ieframe.width + 'px',
614
+ height: this.ieframe.height + 'px'
615
+ });
616
+ jQuery('.zoomPad', el).append(this.ieframe);
617
+ this.ieframe.show();
618
+ };
619
+ };
620
+ };
621
+ /*========================================================,
622
+ | LargeImage
623
+ |---------------------------------------------------------:
624
+ | The large detailed image
625
+ `========================================================*/
626
+
627
+ function Largeimage() {
628
+ var jQueryobj = this;
629
+ this.node = new Image();
630
+ this.loadimage = function (url) {
631
+ //showing preload
632
+ loader.show();
633
+ this.url = url;
634
+ this.node.style.position = 'absolute';
635
+ this.node.style.border = '0px';
636
+ this.node.style.display = 'none';
637
+ this.node.style.left = '-5000px';
638
+ this.node.style.top = '0px';
639
+ document.body.appendChild(this.node);
640
+ this.node.src = url; // fires off async
641
+ };
642
+ this.fetchdata = function () {
643
+ var image = jQuery(this.node);
644
+ var scale = {};
645
+ this.node.style.display = 'block';
646
+ jQueryobj.w = image.width();
647
+ jQueryobj.h = image.height();
648
+ jQueryobj.pos = image.offset();
649
+ jQueryobj.pos.l = image.offset().left;
650
+ jQueryobj.pos.t = image.offset().top;
651
+ jQueryobj.pos.r = jQueryobj.w + jQueryobj.pos.l;
652
+ jQueryobj.pos.b = jQueryobj.h + jQueryobj.pos.t;
653
+ scale.x = (jQueryobj.w / smallimage.w);
654
+ scale.y = (jQueryobj.h / smallimage.h);
655
+ el.scale = scale;
656
+ document.body.removeChild(this.node);
657
+ jQuery('.zoomWrapperImage', el).empty().append(this.node);
658
+ //setting lens dimensions;
659
+ lens.setdimensions();
660
+ };
661
+ this.node.onerror = function () {
662
+ alert('Problems while loading the big image.');
663
+ throw 'Problems while loading the big image.';
664
+ };
665
+ this.node.onload = function () {
666
+ //fetching data
667
+ jQueryobj.fetchdata();
668
+ loader.hide();
669
+ el.largeimageloading = false;
670
+ el.largeimageloaded = true;
671
+ if (settings.zoomType == 'drag' || settings.alwaysOn) {
672
+ lens.show();
673
+ stage.show();
674
+ lens.setcenter();
675
+ }
676
+ };
677
+ this.setposition = function () {
678
+ var left = -el.scale.x * (lens.getoffset().left - smallimage.bleft + 1);
679
+ var top = -el.scale.y * (lens.getoffset().top - smallimage.btop + 1);
680
+ jQuery(this.node).css({
681
+ 'left': left + 'px',
682
+ 'top': top + 'px'
683
+ });
684
+ };
685
+ return this;
686
+ };
687
+ jQuery(el).data("jqzoom", obj);
688
+ };
689
+ //es. jQuery.jqzoom.disable('#jqzoom1');
690
+ jQuery.jqzoom = {
691
+ defaults: {
692
+ zoomType: 'standard',
693
+ //innerzoom/standard/reverse/drag
694
+ zoomWidth: 350,
695
+ //zoomWindow default width
696
+ zoomHeight: 350,
697
+ //zoomWindow default height
698
+ xOffset: 10,
699
+ //zoomWindow x offset, can be negative(more on the left) or positive(more on the right)
700
+ yOffset: 0,
701
+ //zoomWindow y offset, can be negative(more on the left) or positive(more on the right)
702
+ position: "right",
703
+ //zoomWindow default position
704
+ preloadImages: true,
705
+ //image preload
706
+ preloadText: 'Loading zoom',
707
+ title: true,
708
+ lens: true,
709
+ imageOpacity: 0.4,
710
+ alwaysOn: false,
711
+ showEffect: 'show',
712
+ //show/fadein
713
+ hideEffect: 'hide',
714
+ //hide/fadeout
715
+ fadeinSpeed: 'slow',
716
+ //fast/slow/number
717
+ fadeoutSpeed: '2000' //fast/slow/number
718
+ },
719
+ disable: function (el) {
720
+ var api = jQuery(el).data('jqzoom');
721
+ api.disable();
722
+ return false;
723
+ },
724
+ enable: function (el) {
725
+ var api = jQuery(el).data('jqzoom');
726
+ api.enable();
727
+ return false;
728
+ },
729
+ disableAll: function (el) {
730
+ jqzoompluging_disabled = true;
731
+ },
732
+ enableAll: function (el) {
733
+ jqzoompluging_disabled = false;
734
+ }
735
+ };
736
+ })(jQuery);
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Inic_Productzoom</name>
4
+ <version>1.0.0.1</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>zoom on detail page</summary>
10
+ <description>zoom on detail page</description>
11
+ <notes>product zoom </notes>
12
+ <authors><author><name>indianic</name><user>indianic</user><email>enquiry@indianic.com</email></author></authors>
13
+ <date>2013-07-22</date>
14
+ <time>07:48:30</time>
15
+ <contents><target name="magecommunity"><dir name="Inic"><dir name="Productzoom"><dir name="Helper"><file name="Data.php" hash="119c5660b72cec47294b492216740dca"/></dir><dir name="etc"><file name="config.xml" hash="76f8146f7a20b12e6d25af9cd96130b8"/><file name="system.xml" hash="90fa7be8c1196cb53697a823f12d1753"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="template"><dir name="productzoom"><file name="media.phtml" hash="904257555204fc8d0ba401632ab8bd76"/></dir></dir><dir name="layout"><file name="productzoom.xml" hash="88fff5838b1a5dc8ccf74cf4158a61f4"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Inic_Productzoom.xml" hash="909cb183a6be3917e52c1481c7c52e89"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="productzoom"><file name="carosal.css" hash="61c5c318908e857204457297af5e6903"/><file name="jquery.jqzoom.css" hash="465c081ab84c0c5513ad56e63459f4e5"/></dir><dir name="img"><file name="mouse-over.png" hash="20e6208f7af2596e74f6ff390b4d2767"/><file name="next1-h.png" hash="c551a575a71d5edc1afc9def33c1449a"/><file name="next1.png" hash="f15d9ac220a82ee2865b43e66ed87daa"/><file name="prev1-h.png" hash="a8861acdfefa56e380020f69f68a668d"/><file name="prev1.png" hash="5e9f562b7622386468f17a6ea7a3fabd"/></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="productzoom"><file name="jquery-1.7.2.js" hash="cdfe1403287880f29f08b651562d6344"/><file name="jquery.carouFredSel-2.6.0.js" hash="ac920f9620bb1cd9766f6f1f0c375db9"/><file name="jquery.jqzoom-core.js" hash="8bf1605d68fd262a6cf88399dcafc8a5"/></dir></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
+ </package>
skin/frontend/default/default/img/mouse-over.png ADDED
Binary file
skin/frontend/default/default/img/next1-h.png ADDED
Binary file
skin/frontend/default/default/img/next1.png ADDED
Binary file
skin/frontend/default/default/img/prev1-h.png ADDED
Binary file
skin/frontend/default/default/img/prev1.png ADDED
Binary file
skin/frontend/default/default/productzoom/carosal.css ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*media carosal*/
2
+
3
+ .product-img-box #wrapper {
4
+ width:260px;
5
+ margin:0px 20px;
6
+ min-height: 100%;
7
+ }
8
+ .product-img-box #content {padding: 0px;}
9
+
10
+ .product-img-box .list_carousel {
11
+ margin: 0px;
12
+ width: 330px;
13
+ position:relative;
14
+ }
15
+
16
+ .product-img-box div.caroufredsel_wrapper {
17
+ width:auto !important;
18
+ }
19
+
20
+ .product-img-box .list_carousel ul {
21
+ margin: 0;
22
+ padding: 0;
23
+ list-style: none;
24
+ display: block;
25
+ }
26
+ .product-img-box .list_carousel li {
27
+
28
+ color: #666;
29
+ text-align: center;
30
+ background-color: #f2f2f2;
31
+ border:1px solid #d3d3d3;
32
+ width:72px;
33
+ height:72px;
34
+ padding: 0;
35
+ margin:0px 4px;
36
+ display: block;
37
+ float: left;
38
+ }
39
+
40
+ .product-img-box .list_carousel li img { width:72px; height:72px;}
41
+ #prev1,
42
+ #next1 {
43
+ display:inline-block;
44
+ width:11px; height:16px;
45
+ font-size:0px; line-height:0px;
46
+ overflow:hidden;
47
+ position:absolute;
48
+ margin:0px;
49
+ }
50
+
51
+ #prev1 { background:url(../img/prev1.png) no-repeat; left:-20px; top:30px;}
52
+ #next1 { background:url(../img/next1.png) no-repeat; right:-20px; top:30px;}
53
+
54
+ #prev1:hover { background:url(../img/prev1-h.png) no-repeat; left:-20px; top:30px;}
55
+ #next1:hover { background:url(../img/next1-h.png) no-repeat; right:-20px; top:30px;}
56
+
57
+ /*media carosal*/
58
+
59
+
60
+ .clearfix:before, .clearfix:after {
61
+ content: "";
62
+ display: table;
63
+ }
64
+ .clearfix:after {
65
+ clear: both;
66
+ }
67
+ .clearfix:before, .clearfix:after {
68
+ content: "";
69
+ display: table;
70
+ }
71
+ .clearfix {
72
+ }
73
+ .product-view .product-img-box {
74
+ width: 352px !important;
75
+ }
76
+ #mouse-hover-massage{
77
+ text-align:center; width: 100%; background-color:#9E9D9C; margin:0px; position:absolute; top:327px; color:#000; z-index:99999; padding:3px 0;
78
+ }
79
+ .product-view .product-shop
80
+ {
81
+ width: 250px !important;
82
+ }
83
+ #mouse-hover-massage {
84
+ background: url("../img/mouse-over.png") repeat scroll 0 0 transparent !important;
85
+ }
skin/frontend/default/default/productzoom/jquery.jqzoom.css ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .zoomPad{
2
+ position:relative;
3
+ float:left;
4
+ z-index:99;
5
+ cursor:crosshair;
6
+ }
7
+
8
+
9
+ .zoomPreload{
10
+ -moz-opacity:0.8;
11
+ opacity: 0.8;
12
+ filter: alpha(opacity = 80);
13
+ color: #333;
14
+ font-size: 12px;
15
+ font-family: Tahoma;
16
+ text-decoration: none;
17
+ border: 1px solid #CCC;
18
+ background-color: white;
19
+ padding: 8px;
20
+ text-align:center;
21
+ background-image: url(../images/zoomloader.gif);
22
+ background-repeat: no-repeat;
23
+ background-position: 43px 30px;
24
+ z-index:110;
25
+ width:90px;
26
+ height:43px;
27
+ position:absolute;
28
+ top:0px;
29
+ left:0px;
30
+ * width:100px;
31
+ * height:49px;
32
+ }
33
+
34
+
35
+ .zoomPup{
36
+ overflow:hidden;
37
+ background-color: #FFF;
38
+ -moz-opacity:0.6;
39
+ opacity: 0.6;
40
+ filter: alpha(opacity = 60);
41
+ z-index:120;
42
+ position:absolute;
43
+ border:1px solid #CCC;
44
+ z-index:101;
45
+ cursor:crosshair;
46
+ }
47
+
48
+ .zoomOverlay{
49
+ position:absolute;
50
+ left:0px;
51
+ top:0px;
52
+ background:#FFF;
53
+ /*opacity:0.5;*/
54
+ z-index:5000;
55
+ width:100%;
56
+ height:100%;
57
+ display:none;
58
+ z-index:101;
59
+ }
60
+
61
+ .zoomWindow{
62
+ position:absolute;
63
+ left:110%;
64
+ top:40px;
65
+ background:#FFF;
66
+ z-index:6000;
67
+ height:auto;
68
+ z-index:10000;
69
+ z-index:110;
70
+ }
71
+ .zoomWrapper{
72
+ position:relative;
73
+ border:1px solid #999;
74
+ z-index:110;
75
+ }
76
+ .zoomWrapperTitle{
77
+ display:block;
78
+ background:#999;
79
+ color:#FFF;
80
+ height:18px;
81
+ line-height:18px;
82
+ width:100%;
83
+ overflow:hidden;
84
+ text-align:center;
85
+ font-size:10px;
86
+ position:absolute;
87
+ top:0px;
88
+ left:0px;
89
+ z-index:120;
90
+ -moz-opacity:0.6;
91
+ opacity: 0.6;
92
+ filter: alpha(opacity = 60);
93
+ }
94
+ .zoomWrapperImage{
95
+ display:block;
96
+ position:relative;
97
+ overflow:hidden;
98
+ z-index:110;
99
+
100
+ }
101
+ .zoomWrapperImage img{
102
+ border:0px;
103
+ display:block;
104
+ position:absolute;
105
+ z-index:101;
106
+ }
107
+
108
+ .zoomIframe{
109
+ z-index: -1;
110
+ filter:alpha(opacity=0);
111
+ -moz-opacity: 0.80;
112
+ opacity: 0.80;
113
+ position:absolute;
114
+ display:block;
115
+ }
116
+
117
+ /*********************************************************
118
+ / When clicking on thumbs jqzoom will add the class
119
+ / "zoomThumbActive" on the anchor selected
120
+ /*********************************************************/