Transdirect_Shipping - Version 1.1.0

Version Notes

First version of Magento Module

Download this release

Release Info

Developer Joshua Oliver
Extension Transdirect_Shipping
Version 1.1.0
Comparing to
See all releases


Code changes from version 1.0.0 to 1.1.0

Files changed (41) hide show
  1. app/code/local/Transdirect/Ship/Block/Quotes.php +4 -4
  2. app/code/local/Transdirect/Ship/Block/Ship.php +4 -4
  3. app/code/local/Transdirect/Ship/Helper/Data.php +5 -5
  4. app/code/local/Transdirect/Ship/Model/Carrier/Transdirect.php +326 -9
  5. app/code/local/Transdirect/Ship/Model/Carrier/Transdirect_new_28-5-2014.php +0 -302
  6. app/code/local/Transdirect/Ship/Model/Carrier/bkp_26-5-2014-morning----Excellence.php +0 -260
  7. app/code/local/Transdirect/Ship/Model/Carrier/bkp_28-5-2014-evening-----Transdirect.php +0 -283
  8. app/code/local/Transdirect/Ship/Model/Carrier/bkp_30-5-2014---Transdirect.php +0 -304
  9. app/code/local/Transdirect/Ship/Model/Source/AddressType.php +26 -26
  10. app/code/local/Transdirect/Ship/Model/Source/Couriers.php +18 -18
  11. app/code/local/Transdirect/Ship/Model/Source/Quotes.php +14 -14
  12. app/code/local/Transdirect/Ship/controllers/IndexController.php +445 -5
  13. app/code/local/Transdirect/Ship/controllers/bkp_29-5-2014---IndexController.php +0 -412
  14. app/code/local/Transdirect/Ship/controllers/bkp_30-5-2014----IndexController.php +0 -427
  15. app/code/local/Transdirect/Ship/etc/adminhtml.xml +22 -22
  16. app/code/local/Transdirect/Ship/etc/bkp_30-5-2014---config.xml +0 -88
  17. app/code/local/Transdirect/Ship/etc/bkp_30-5-2014---system.xml +0 -207
  18. app/code/local/Transdirect/Ship/etc/config.xml +87 -87
  19. app/code/local/Transdirect/Ship/etc/system.xml +431 -431
  20. app/code/local/Transdirect/Ship/sql/ship_setup/mysql4-install-0.1.0.php +83 -83
  21. app/design/frontend/default/default/layout/ship.xml +45 -0
  22. app/design/frontend/default/default/template/ship/bkp_29-5-2014--working----product_shipping.phtml +0 -397
  23. app/design/frontend/default/default/template/ship/bkp_29-5-2014--working----shipping.phtml +0 -179
  24. app/design/frontend/default/default/template/ship/bkp_30-5-2014---product_shipping.phtml +0 -437
  25. app/design/frontend/default/default/template/ship/bkp_30-5-2014---shipping.phtml +0 -237
  26. app/design/frontend/default/default/template/ship/checkout/cart/totals.phtml +48 -48
  27. app/design/frontend/default/default/template/ship/footer/js.phtml +5 -7
  28. app/design/frontend/default/default/template/ship/product_shipping.phtml +309 -2
  29. app/design/frontend/default/default/template/ship/shipping.phtml +475 -111
  30. app/design/frontend/rwd/default/layout/ship.xml +45 -0
  31. app/design/frontend/rwd/default/template/ship/checkout/cart/totals.phtml +48 -0
  32. app/design/frontend/rwd/default/template/ship/footer/js.phtml +5 -0
  33. app/design/frontend/rwd/default/template/ship/product_shipping.phtml +307 -0
  34. app/design/frontend/rwd/default/template/ship/shipping.phtml +356 -0
  35. app/etc/modules/Transdirect_Ship.xml +9 -0
  36. package.xml +4 -4
  37. skin/frontend/default/default/ship/css/jquery.autoSuggest.css +256 -256
  38. skin/frontend/default/default/ship/js/jquery-1.11.0.js +10337 -10337
  39. skin/frontend/default/default/ship/js/jquery.autoSuggest.js +440 -440
  40. skin/frontend/{default/default/ship/css/bkp_4-7-2014----jquery.autoSuggest.css → rwd/default/ship/css/jquery.autoSuggest.css} +256 -252
  41. skin/frontend/rwd/default/ship/js/jquery-1.11.0.js +1987 -0
app/code/local/Transdirect/Ship/Block/Quotes.php CHANGED
@@ -1,5 +1,5 @@
1
- <?php
2
- class Transdirect_Ship_Block_Quotes extends Mage_Core_Block_Template
3
- {
4
-
5
  }
1
+ <?php
2
+ class Transdirect_Ship_Block_Quotes extends Mage_Core_Block_Template
3
+ {
4
+
5
  }
app/code/local/Transdirect/Ship/Block/Ship.php CHANGED
@@ -1,5 +1,5 @@
1
- <?php
2
- class Transdirect_Ship_Block_Ship extends Mage_Core_Block_Template
3
- {
4
-
5
  }
1
+ <?php
2
+ class Transdirect_Ship_Block_Ship extends Mage_Core_Block_Template
3
+ {
4
+
5
  }
app/code/local/Transdirect/Ship/Helper/Data.php CHANGED
@@ -1,6 +1,6 @@
1
- <?php
2
-
3
- class Transdirect_Ship_Helper_Data extends Mage_Core_Helper_Abstract
4
- {
5
-
6
  }
1
+ <?php
2
+
3
+ class Transdirect_Ship_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+
6
  }
app/code/local/Transdirect/Ship/Model/Carrier/Transdirect.php CHANGED
@@ -1,318 +1,635 @@
1
  <?php
 
2
  class Transdirect_Ship_Model_Carrier_Transdirect extends Mage_Shipping_Model_Carrier_Abstract
 
3
  implements Mage_Shipping_Model_Carrier_Interface {
 
4
  protected $_code = 'transdirect';
5
 
 
 
6
  public function collectRates(Mage_Shipping_Model_Rate_Request $request)
 
7
  {
 
8
  //echo '<pre>'; print_r($request); die('request');
 
9
  if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
 
10
  return false;
 
11
  }
 
12
 
 
13
  $price = $this->getConfigData('price'); // set a default shipping price maybe 0
 
14
  $price = 0;
 
15
 
 
16
  /* API Request Start */
 
17
 
 
18
  $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
 
19
  $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
 
20
  $warehouse_suburb = Mage::getStoreConfig('transdirect_section/warehouseaddress/suburb');
 
21
  $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
 
22
  $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
 
23
  $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
 
24
  $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
 
25
  $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
 
26
  $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
 
27
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
 
28
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
29
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
 
30
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
 
31
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
 
32
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
 
33
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
 
34
  $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
 
35
 
36
 
 
 
37
  // Cart Total Weight Code Start by Nayan
 
38
 
 
39
  $quote = Mage::getSingleton('checkout/session')->getQuote();
 
40
  $cartItems = $quote->getAllVisibleItems();
 
41
  $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
42
 
 
 
43
  $weight = 0;
 
44
  $height = 0;
 
45
  $width = 0;
 
46
  $length = 0;
 
47
  foreach ($cartItems as $item)
 
48
  {
 
49
  //echo '<pre>'; print_r($item->getQty()); die('qty');
 
50
  $productId = $item->getProductId();
 
51
  $productQty = $item->getQty();
52
 
 
 
53
  $product = Mage::getModel('catalog/product')->load($productId);
 
54
  //echo $product->getItemWeight();
 
55
  $weight += $product->getItemWeight() * $productQty;
 
56
  $height += $product->getItemHeight() * $productQty;
 
57
  $width += $product->getItemWidth() * $productQty;
 
58
  $length += $product->getItemDim() * $productQty;
 
59
  }
 
60
 
 
61
  $cart_total_weight = $weight;
 
62
  $cart_total_height = $height;
 
63
  $cart_total_width = $width;
 
64
  $cart_total_length = $length;
 
65
 
 
66
  // Cart Total Weight Code End by Nayan
67
 
 
 
68
 
 
69
  if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
 
70
  if(!$cart_total_height){ $cart_total_height = $dimension_height; }
 
71
  if(!$cart_total_width){ $cart_total_width = $dimension_width; }
 
72
  if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
73
 
 
 
74
  /* echo 'width--'.$cart_total_weight;
 
75
  echo 'height---'.$cart_total_height;
 
76
  echo 'width---'.$cart_total_width;
 
77
  echo 'length---'.$cart_total_length;
 
78
  die('here');
 
79
  */
80
 
 
 
81
  // Getting Cart page Quote Address Details Code Start by Nayan
 
82
 
 
83
  $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
 
84
  $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
 
85
  $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
 
86
  $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
 
87
 
 
88
  $region = Mage::getModel('directory/region')->load($receiver_regionId);
 
89
  $receiver_region_tmp = $region->getName();
 
90
 
 
91
  /*if($receiver_region == '') {
 
92
  Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
 
93
  session_write_close();
 
94
  //$this->_redirect('checkout/cart');
 
95
  return false;
 
96
  }*/
 
97
 
 
98
  /*if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
 
99
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
 
100
  session_write_close();
 
101
  return false;
 
102
  //$this->_redirect('checkout/cart');
 
103
  }*/
 
104
 
 
105
  if(!$receiver_regionId)
 
106
  {
 
107
  $receiver_suburb = $receiver_region;
 
108
  }
 
109
  else
 
110
  {
 
111
  $receiver_suburb = $receiver_region_tmp;
 
112
  }
 
113
 
 
114
  /*echo $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
 
115
  echo $tmp_cart_locality_val = $_COOKIE['cart_locality'];
 
116
  //die('val');*/
 
117
 
 
118
  $receiver_postcode = $_COOKIE['cart_postocde'];
 
119
  $receiver_suburb = $_COOKIE['cart_locality'];
 
120
 
 
121
 
 
122
  /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
 
123
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
 
124
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
 
125
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
 
126
  */
 
127
 
 
128
 
 
129
 
 
130
 
 
131
  //echo $receiver_suburb; die('suburb');
 
132
 
 
133
  // Getting Cart page Quote Address Details Code End by Nayan
134
 
 
 
135
  $quoteDetails = array(
 
136
  'declared_value'=>10000,
 
137
  'items' => array
 
138
  (
 
139
  array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
 
140
  ),
 
141
  'sender' => array('country' => 'AU', 'suburb'=> $warehouse_suburb, 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
 
142
  'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
 
143
  );
144
 
 
 
145
  $json_data = json_encode($quoteDetails);
 
146
  //echo '<pre>'; print_r($json_data); die('json');
 
147
 
 
148
  $ch = curl_init();
 
149
  curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
 
150
  //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
 
151
  curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
 
152
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
 
153
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
 
154
  curl_setopt($ch, CURLOPT_POST, TRUE);
 
155
  curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
 
156
  curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
 
157
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 
158
  $response = curl_exec($ch);
 
159
 
 
160
  $report = curl_getinfo($ch);
 
161
  //echo '<pre>'; print_r($report);
 
162
 
 
163
  if(curl_errno($ch)) {
 
164
  echo 'Response error: ' . curl_error($ch);
 
165
  }
 
166
 
 
167
  curl_close($ch);
 
168
 
 
169
  if ($response) {
 
170
  $json_decode_varible = json_decode($response, true);
 
171
  $quotes_val = $json_decode_varible['quotes'];
 
172
  //echo "<pre>"; print_r($quotes_val); die('quotes');
173
-
 
 
174
  Mage::getSingleton('core/session')->unsTransitVal();
 
175
  Mage::getSingleton('core/session')->unsSomeSessionVar();
 
176
  $session_val1 = Mage::getSingleton('core/session')->setSomeSessionVar1($quotes_val);
 
177
 
 
178
 
 
179
  } else {
 
180
  echo "Failed";
 
181
  }
 
182
 
 
183
  /* End */
 
184
 
 
185
 
 
186
  //$available_carriers = array($display_carriers);
 
187
  //print_r($available_carriers);
 
188
  $available_carriers = explode( ',', $display_carriers);
 
189
 
 
190
  /* function cmp1($a, $b) {
 
191
  return strcmp($a['transit_time'], $b['transit_time']);
 
192
  }
 
193
  */
 
194
 
195
- function build_sorter($key) {
196
- return function ($a, $b) use ($key) {
197
- return strnatcmp($a[$key], $b[$key]);
198
- };
199
- }
 
 
 
 
 
 
200
 
 
201
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
202
 
203
- if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
204
- if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
 
 
 
205
 
206
 
 
 
207
  $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
 
208
  $result = Mage::getModel('shipping/rate_result');
 
209
  $show = true;
 
210
  if($show){
 
211
 
 
212
  //die('before');
 
213
  //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
 
214
 
 
215
  //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
 
216
  //echo $session->getSomeSessionVar();
217
 
 
 
218
  //echo '<pre>'; print_r($session->getSomeSessionVar());
 
219
  //die('after');
 
220
 
 
221
  if($quotes_val == ''){
 
222
  Mage::getSingleton('core/session')->unsetAll();
223
- Mage::getSingleton('core/session')->addError("Please enter correct details, either suburb or postcode not entered properly.");
 
 
224
  //session_write_close();
 
225
  //return false;
 
226
 
 
227
  $method = Mage::getModel('shipping/rate_result_method');
 
228
  $method->setCarrier($this->_code);
 
229
  $method->setMethod($this->_code);
 
230
  $method->setCarrierTitle($this->getConfigData('title'));
 
231
  $method->setMethodTitle('Fixed Price');
 
232
 
 
233
  if($display_fixedprice == '1'){
 
234
  $method->setPrice($display_fixedprice1);
 
235
  $method->setCost($display_fixedprice1);
 
236
  }
 
237
 
 
238
  $result->append($method);
 
239
 
 
240
  }
 
241
  else {
 
242
 
 
243
 
 
244
 
 
245
 
 
246
  foreach($quotes_val as $key => $val) {
 
247
 
 
248
  if($key=='fastway'){ $method_title = "Fastway"; }
 
249
  if($key=='toll_priority_overnight'){$method_title = "Toll Priority Overnight"; }
 
250
  if($key=='couriers_please'){$method_title = "Couriers Please"; }
 
251
  if($key=='allied'){$method_title = "Allied Express"; }
 
252
  if($key=='toll'){ $method_title = "Toll"; }
 
253
  if($key=='mainfreight'){ $method_title = "Mainfreight"; }
 
254
  if($key=='northline'){$method_title = "Northline"; }
 
255
 
 
256
  $quote_form_region_val = Mage::getSingleton('core/session')->setTransitVal($quotes_val[$key]['transit_time']);
257
 
 
 
258
  //echo $method_title; die;
 
259
  // echo count($val); die;
 
260
  //echo $key.'<br>';
 
261
  //print_r($available_carriers);
 
262
 
 
263
  //usort($quotes_val, 'cmp1');
 
264
 
 
265
  $courier_title = $key;
 
266
  $courier_price = $quotes_val[$key]['total'];
 
267
 
 
268
  $method = Mage::getModel('shipping/rate_result_method');
 
269
  $method->setCarrier($this->_code);
 
270
  $method->setMethod($courier_title);
 
271
  $method->setCarrierTitle($this->getConfigData('title'));
 
272
 
 
273
  if($display_surcharge == '1'){
 
274
 
 
275
  $tmp_display_surcharge = $courier_price + $display_surcharge1;
 
276
  $tmp_method_title = $method_title.' + Handling Charge';
 
277
 
 
278
  if(in_array($key,$available_carriers)) {
 
279
  $method->setMethodTitle($tmp_method_title);
 
280
  $method->setPrice($tmp_display_surcharge);
 
281
  $method->setCost($tmp_display_surcharge);
 
282
  }
 
283
 
 
284
  } else {
 
285
 
 
286
  if(in_array($key,$available_carriers)) {
 
287
  //echo '<br>'.$key . ' - matched<br>';
 
288
  $method->setMethodTitle($method_title);
 
289
  $method->setSortOrder($quotes_val[$key]['transit_time']);
 
290
  $method->setPrice($courier_price);
 
291
  $method->setCost($courier_price);
 
292
  }
 
293
 
 
294
  }
 
295
 
 
296
  $result->append($method);
 
297
 
 
298
  }
 
299
  //die('arr');
 
300
  }
301
 
 
 
302
 
 
303
  //echo '<pre>'; print_r($result); die('model');
304
 
 
 
305
  }else{
 
306
  $error = Mage::getModel('shipping/rate_result_error');
 
307
  $error->setCarrier($this->_code);
 
308
  $error->setCarrierTitle($this->getConfigData('name'));
 
309
  $error->setErrorMessage($this->getConfigData('specificerrmsg'));
 
310
  $result->append($error);
 
311
  }
 
312
  return $result;
 
313
  }
 
314
  public function getAllowedMethods()
 
315
  {
 
316
  return array('transdirect'=>$this->getConfigData('name'));
 
317
  }
 
318
  }
1
  <?php
2
+
3
  class Transdirect_Ship_Model_Carrier_Transdirect extends Mage_Shipping_Model_Carrier_Abstract
4
+
5
  implements Mage_Shipping_Model_Carrier_Interface {
6
+
7
  protected $_code = 'transdirect';
8
 
9
+
10
+
11
  public function collectRates(Mage_Shipping_Model_Rate_Request $request)
12
+
13
  {
14
+
15
  //echo '<pre>'; print_r($request); die('request');
16
+
17
  if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
18
+
19
  return false;
20
+
21
  }
22
+
23
 
24
+
25
  $price = $this->getConfigData('price'); // set a default shipping price maybe 0
26
+
27
  $price = 0;
28
+
29
 
30
+
31
  /* API Request Start */
32
+
33
 
34
+
35
  $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
36
+
37
  $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
38
+
39
  $warehouse_suburb = Mage::getStoreConfig('transdirect_section/warehouseaddress/suburb');
40
+
41
  $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
42
+
43
  $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
44
+
45
  $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
46
+
47
  $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
48
+
49
  $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
50
+
51
  $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
52
+
53
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
54
+
55
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
56
+
57
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
58
+
59
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
60
+
61
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
62
+
63
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
64
+
65
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
66
+
67
  $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
68
+
69
 
70
 
71
+
72
+
73
  // Cart Total Weight Code Start by Nayan
74
+
75
 
76
+
77
  $quote = Mage::getSingleton('checkout/session')->getQuote();
78
+
79
  $cartItems = $quote->getAllVisibleItems();
80
+
81
  $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
82
 
83
+
84
+
85
  $weight = 0;
86
+
87
  $height = 0;
88
+
89
  $width = 0;
90
+
91
  $length = 0;
92
+
93
  foreach ($cartItems as $item)
94
+
95
  {
96
+
97
  //echo '<pre>'; print_r($item->getQty()); die('qty');
98
+
99
  $productId = $item->getProductId();
100
+
101
  $productQty = $item->getQty();
102
 
103
+
104
+
105
  $product = Mage::getModel('catalog/product')->load($productId);
106
+
107
  //echo $product->getItemWeight();
108
+
109
  $weight += $product->getItemWeight() * $productQty;
110
+
111
  $height += $product->getItemHeight() * $productQty;
112
+
113
  $width += $product->getItemWidth() * $productQty;
114
+
115
  $length += $product->getItemDim() * $productQty;
116
+
117
  }
118
+
119
 
120
+
121
  $cart_total_weight = $weight;
122
+
123
  $cart_total_height = $height;
124
+
125
  $cart_total_width = $width;
126
+
127
  $cart_total_length = $length;
128
+
129
 
130
+
131
  // Cart Total Weight Code End by Nayan
132
 
133
+
134
+
135
 
136
+
137
  if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
138
+
139
  if(!$cart_total_height){ $cart_total_height = $dimension_height; }
140
+
141
  if(!$cart_total_width){ $cart_total_width = $dimension_width; }
142
+
143
  if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
144
 
145
+
146
+
147
  /* echo 'width--'.$cart_total_weight;
148
+
149
  echo 'height---'.$cart_total_height;
150
+
151
  echo 'width---'.$cart_total_width;
152
+
153
  echo 'length---'.$cart_total_length;
154
+
155
  die('here');
156
+
157
  */
158
 
159
+
160
+
161
  // Getting Cart page Quote Address Details Code Start by Nayan
162
+
163
 
164
+
165
  $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
166
+
167
  $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
168
+
169
  $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
170
+
171
  $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
172
+
173
 
174
+
175
  $region = Mage::getModel('directory/region')->load($receiver_regionId);
176
+
177
  $receiver_region_tmp = $region->getName();
178
+
179
 
180
+
181
  /*if($receiver_region == '') {
182
+
183
  Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
184
+
185
  session_write_close();
186
+
187
  //$this->_redirect('checkout/cart');
188
+
189
  return false;
190
+
191
  }*/
192
+
193
 
194
+
195
  /*if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
196
+
197
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
198
+
199
  session_write_close();
200
+
201
  return false;
202
+
203
  //$this->_redirect('checkout/cart');
204
+
205
  }*/
206
+
207
 
208
+
209
  if(!$receiver_regionId)
210
+
211
  {
212
+
213
  $receiver_suburb = $receiver_region;
214
+
215
  }
216
+
217
  else
218
+
219
  {
220
+
221
  $receiver_suburb = $receiver_region_tmp;
222
+
223
  }
224
+
225
 
226
+
227
  /*echo $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
228
+
229
  echo $tmp_cart_locality_val = $_COOKIE['cart_locality'];
230
+
231
  //die('val');*/
232
+
233
 
234
+
235
  $receiver_postcode = $_COOKIE['cart_postocde'];
236
+
237
  $receiver_suburb = $_COOKIE['cart_locality'];
238
+
239
 
240
+
241
 
242
+
243
  /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
244
+
245
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
246
+
247
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
248
+
249
  echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
250
+
251
  */
252
+
253
 
254
+
255
 
256
+
257
 
258
+
259
 
260
+
261
  //echo $receiver_suburb; die('suburb');
262
+
263
 
264
+
265
  // Getting Cart page Quote Address Details Code End by Nayan
266
 
267
+
268
+
269
  $quoteDetails = array(
270
+
271
  'declared_value'=>10000,
272
+
273
  'items' => array
274
+
275
  (
276
+
277
  array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
278
+
279
  ),
280
+
281
  'sender' => array('country' => 'AU', 'suburb'=> $warehouse_suburb, 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
282
+
283
  'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
284
+
285
  );
286
 
287
+
288
+
289
  $json_data = json_encode($quoteDetails);
290
+
291
  //echo '<pre>'; print_r($json_data); die('json');
292
+
293
 
294
+
295
  $ch = curl_init();
296
+
297
  curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
298
+
299
  //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
300
+
301
  curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
302
+
303
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
304
+
305
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
306
+
307
  curl_setopt($ch, CURLOPT_POST, TRUE);
308
+
309
  curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
310
+
311
  curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
312
+
313
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
314
+
315
  $response = curl_exec($ch);
316
+
317
 
318
+
319
  $report = curl_getinfo($ch);
320
+
321
  //echo '<pre>'; print_r($report);
322
+
323
 
324
+
325
  if(curl_errno($ch)) {
326
+
327
  echo 'Response error: ' . curl_error($ch);
328
+
329
  }
330
+
331
 
332
+
333
  curl_close($ch);
334
+
335
 
336
+
337
  if ($response) {
338
+
339
  $json_decode_varible = json_decode($response, true);
340
+
341
  $quotes_val = $json_decode_varible['quotes'];
342
+
343
  //echo "<pre>"; print_r($quotes_val); die('quotes');
344
+
345
+ // var_dump($quotes_val);
346
+
347
  Mage::getSingleton('core/session')->unsTransitVal();
348
+
349
  Mage::getSingleton('core/session')->unsSomeSessionVar();
350
+
351
  $session_val1 = Mage::getSingleton('core/session')->setSomeSessionVar1($quotes_val);
352
+
353
 
354
+
355
 
356
+
357
  } else {
358
+
359
  echo "Failed";
360
+
361
  }
362
+
363
 
364
+
365
  /* End */
366
+
367
 
368
+
369
 
370
+
371
  //$available_carriers = array($display_carriers);
372
+
373
  //print_r($available_carriers);
374
+
375
  $available_carriers = explode( ',', $display_carriers);
376
+
377
 
378
+
379
  /* function cmp1($a, $b) {
380
+
381
  return strcmp($a['transit_time'], $b['transit_time']);
382
+
383
  }
384
+
385
  */
386
+
387
 
388
+
389
+ // function build_sorter($key) {
390
+
391
+ // return function ($a, $b) use ($key) {
392
+
393
+ // return strnatcmp($a[$key], $b[$key]);
394
+
395
+ // };
396
+
397
+ // }
398
+
399
 
400
+
401
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
402
+
403
 
404
+
405
+ //if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
406
+
407
+ //if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
408
+
409
 
410
 
411
+
412
+
413
  $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
414
+
415
  $result = Mage::getModel('shipping/rate_result');
416
+
417
  $show = true;
418
+
419
  if($show){
420
+
421
 
422
+
423
  //die('before');
424
+
425
  //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
426
+
427
 
428
+
429
  //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
430
+
431
  //echo $session->getSomeSessionVar();
432
 
433
+
434
+
435
  //echo '<pre>'; print_r($session->getSomeSessionVar());
436
+
437
  //die('after');
438
+
439
 
440
+
441
  if($quotes_val == ''){
442
+
443
  Mage::getSingleton('core/session')->unsetAll();
444
+
445
+ //Mage::getSingleton('core/session')->addError("Please enter correct details, either suburb or postcode not entered properly.");
446
+
447
  //session_write_close();
448
+
449
  //return false;
450
+
451
 
452
+
453
  $method = Mage::getModel('shipping/rate_result_method');
454
+
455
  $method->setCarrier($this->_code);
456
+
457
  $method->setMethod($this->_code);
458
+
459
  $method->setCarrierTitle($this->getConfigData('title'));
460
+
461
  $method->setMethodTitle('Fixed Price');
462
+
463
 
464
+
465
  if($display_fixedprice == '1'){
466
+
467
  $method->setPrice($display_fixedprice1);
468
+
469
  $method->setCost($display_fixedprice1);
470
+
471
  }
472
+
473
 
474
+
475
  $result->append($method);
476
+
477
 
478
+
479
  }
480
+
481
  else {
482
+
483
 
484
+
485
 
486
+
487
 
488
+
489
 
490
+
491
  foreach($quotes_val as $key => $val) {
492
+
493
 
494
+
495
  if($key=='fastway'){ $method_title = "Fastway"; }
496
+
497
  if($key=='toll_priority_overnight'){$method_title = "Toll Priority Overnight"; }
498
+
499
  if($key=='couriers_please'){$method_title = "Couriers Please"; }
500
+
501
  if($key=='allied'){$method_title = "Allied Express"; }
502
+
503
  if($key=='toll'){ $method_title = "Toll"; }
504
+
505
  if($key=='mainfreight'){ $method_title = "Mainfreight"; }
506
+
507
  if($key=='northline'){$method_title = "Northline"; }
508
+
509
 
510
+
511
  $quote_form_region_val = Mage::getSingleton('core/session')->setTransitVal($quotes_val[$key]['transit_time']);
512
 
513
+
514
+
515
  //echo $method_title; die;
516
+
517
  // echo count($val); die;
518
+
519
  //echo $key.'<br>';
520
+
521
  //print_r($available_carriers);
522
+
523
 
524
+
525
  //usort($quotes_val, 'cmp1');
526
+
527
 
528
+
529
  $courier_title = $key;
530
+
531
  $courier_price = $quotes_val[$key]['total'];
532
+
533
 
534
+
535
  $method = Mage::getModel('shipping/rate_result_method');
536
+
537
  $method->setCarrier($this->_code);
538
+
539
  $method->setMethod($courier_title);
540
+
541
  $method->setCarrierTitle($this->getConfigData('title'));
542
+
543
 
544
+
545
  if($display_surcharge == '1'){
546
+
547
 
548
+
549
  $tmp_display_surcharge = $courier_price + $display_surcharge1;
550
+
551
  $tmp_method_title = $method_title.' + Handling Charge';
552
+
553
 
554
+
555
  if(in_array($key,$available_carriers)) {
556
+
557
  $method->setMethodTitle($tmp_method_title);
558
+
559
  $method->setPrice($tmp_display_surcharge);
560
+
561
  $method->setCost($tmp_display_surcharge);
562
+
563
  }
564
+
565
 
566
+
567
  } else {
568
+
569
 
570
+
571
  if(in_array($key,$available_carriers)) {
572
+
573
  //echo '<br>'.$key . ' - matched<br>';
574
+
575
  $method->setMethodTitle($method_title);
576
+
577
  $method->setSortOrder($quotes_val[$key]['transit_time']);
578
+
579
  $method->setPrice($courier_price);
580
+
581
  $method->setCost($courier_price);
582
+
583
  }
584
+
585
 
586
+
587
  }
588
+
589
 
590
+
591
  $result->append($method);
592
+
593
 
594
+
595
  }
596
+
597
  //die('arr');
598
+
599
  }
600
 
601
+
602
+
603
 
604
+
605
  //echo '<pre>'; print_r($result); die('model');
606
 
607
+
608
+
609
  }else{
610
+
611
  $error = Mage::getModel('shipping/rate_result_error');
612
+
613
  $error->setCarrier($this->_code);
614
+
615
  $error->setCarrierTitle($this->getConfigData('name'));
616
+
617
  $error->setErrorMessage($this->getConfigData('specificerrmsg'));
618
+
619
  $result->append($error);
620
+
621
  }
622
+
623
  return $result;
624
+
625
  }
626
+
627
  public function getAllowedMethods()
628
+
629
  {
630
+
631
  return array('transdirect'=>$this->getConfigData('name'));
632
+
633
  }
634
+
635
  }
app/code/local/Transdirect/Ship/Model/Carrier/Transdirect_new_28-5-2014.php DELETED
@@ -1,302 +0,0 @@
1
- <?php
2
- class Transdirect_Ship_Model_Carrier_Transdirect extends Mage_Shipping_Model_Carrier_Abstract
3
- implements Mage_Shipping_Model_Carrier_Interface {
4
- protected $_code = 'transdirect';
5
-
6
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
7
- {
8
- //echo '<pre>'; print_r($request); die('request');
9
- if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
10
- return false;
11
- }
12
-
13
- $price = $this->getConfigData('price'); // set a default shipping price maybe 0
14
- $price = 0;
15
-
16
- /* API Request Start */
17
-
18
- $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
19
- $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
20
- $warehouse_suburb = Mage::getStoreConfig('transdirect_section/warehouseaddress/suburb');
21
- $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
22
- $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
23
- $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
24
- $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
25
- $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
26
- $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
27
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
28
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
29
- $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
30
- $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
31
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
32
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
33
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
34
- $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
35
-
36
-
37
- // Cart Total Weight Code Start by Nayan
38
-
39
- $quote = Mage::getSingleton('checkout/session')->getQuote();
40
- $cartItems = $quote->getAllVisibleItems();
41
- $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
42
-
43
- $weight = 0;
44
- $height = 0;
45
- $width = 0;
46
- $length = 0;
47
- foreach ($cartItems as $item)
48
- {
49
- //echo '<pre>'; print_r($item->getQty()); die('qty');
50
- $productId = $item->getProductId();
51
- $productQty = $item->getQty();
52
-
53
- $product = Mage::getModel('catalog/product')->load($productId);
54
- //echo $product->getItemWeight();
55
- $weight += $product->getItemWeight() * $productQty;
56
- $height += $product->getItemHeight() * $productQty;
57
- $width += $product->getItemWidth() * $productQty;
58
- $length += $product->getItemDim() * $productQty;
59
- }
60
-
61
- $cart_total_weight = $weight;
62
- $cart_total_height = $height;
63
- $cart_total_width = $width;
64
- $cart_total_length = $length;
65
-
66
- // Cart Total Weight Code End by Nayan
67
-
68
-
69
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
70
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
71
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
72
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
73
-
74
- /* echo 'width--'.$cart_total_weight;
75
- echo 'height---'.$cart_total_height;
76
- echo 'width---'.$cart_total_width;
77
- echo 'length---'.$cart_total_length;
78
- die('here');
79
- */
80
-
81
- // Getting Cart page Quote Address Details Code Start by Nayan
82
-
83
- $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
84
- $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
85
- $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
86
- $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
87
-
88
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
89
- $receiver_region_tmp = $region->getName();
90
-
91
- if($receiver_region == '') {
92
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
93
- session_write_close();
94
- //$this->_redirect('checkout/cart');
95
- return false;
96
- }
97
-
98
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
99
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
100
- session_write_close();
101
- return false;
102
- //$this->_redirect('checkout/cart');
103
- }
104
-
105
- if(!$receiver_regionId)
106
- {
107
- $receiver_suburb = $receiver_region;
108
- }
109
- else
110
- {
111
- $receiver_suburb = $receiver_region_tmp;
112
- }
113
-
114
-
115
- /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
116
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
117
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
118
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
119
- */
120
-
121
-
122
-
123
-
124
- //echo $receiver_suburb; die('suburb');
125
-
126
- // Getting Cart page Quote Address Details Code End by Nayan
127
-
128
- $quoteDetails = array(
129
- 'declared_value'=>10000,
130
- 'items' => array
131
- (
132
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
133
- ),
134
- 'sender' => array('country' => 'AU', 'suburb'=> $warehouse_suburb, 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
135
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
136
- );
137
-
138
- $json_data = json_encode($quoteDetails);
139
- //echo '<pre>'; print_r($json_data); //die('json');
140
-
141
- $ch = curl_init();
142
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
143
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
144
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
145
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
146
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
147
- curl_setopt($ch, CURLOPT_POST, TRUE);
148
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
149
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
150
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
151
- $response = curl_exec($ch);
152
-
153
- $report = curl_getinfo($ch);
154
- //echo '<pre>'; print_r($report);
155
-
156
- if(curl_errno($ch)) {
157
- echo 'Response error: ' . curl_error($ch);
158
- }
159
-
160
- curl_close($ch);
161
-
162
- if ($response) {
163
- $json_decode_varible = json_decode($response, true);
164
- $quotes_val = $json_decode_varible['quotes'];
165
- //echo "<pre>"; print_r($quotes_val);
166
-
167
- } else {
168
- echo "Failed";
169
- }
170
-
171
- /* End */
172
-
173
-
174
- //$available_carriers = array($display_carriers);
175
- //print_r($available_carriers);
176
- $available_carriers = explode( ',', $display_carriers);
177
-
178
- /* function cmp1($a, $b) {
179
- return strcmp($a['transit_time'], $b['transit_time']);
180
- }
181
- */
182
-
183
-
184
- function build_sorter($key) {
185
- return function ($a, $b) use ($key) {
186
- return strnatcmp($a[$key], $b[$key]);
187
- };
188
- }
189
-
190
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
191
-
192
- if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
193
- if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
194
-
195
-
196
- //echo "After sort</br>.<pre>"; print_r($quotes_val); die('quotes');
197
-
198
-
199
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
200
- $result = Mage::getModel('shipping/rate_result');
201
- $show = true;
202
- if($show){
203
-
204
- //die('before');
205
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
206
-
207
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
208
- //echo $session->getSomeSessionVar();
209
-
210
- //echo '<pre>'; print_r($session->getSomeSessionVar());
211
- //die('after');
212
-
213
- if($quotes_val == ''){
214
- Mage::getSingleton('core/session')->addError("Please fill the information properly, there is some fields are missing or not entered properly.");
215
- session_write_close();
216
- return false;
217
-
218
- $method = Mage::getModel('shipping/rate_result_method');
219
- $method->setCarrier($this->_code);
220
- $method->setMethod($this->_code);
221
- $method->setCarrierTitle($this->getConfigData('title'));
222
- $method->setMethodTitle('Fixed Price');
223
-
224
- if($display_fixedprice == '1'){
225
- $method->setPrice($display_fixedprice1);
226
- $method->setCost($display_fixedprice1);
227
- }
228
-
229
- $result->append($method);
230
-
231
- }
232
- else {
233
-
234
-
235
-
236
-
237
- foreach($quotes_val as $key => $val) {
238
- // echo count($val); die;
239
- //echo $key.'<br>';
240
- //print_r($available_carriers);
241
-
242
- //usort($quotes_val, 'cmp1');
243
-
244
- $courier_title = $key;
245
- $courier_price = $quotes_val[$key]['total'];
246
- $courier_transittime = $quotes_val[$key]['transit_time'];
247
-
248
- $method = Mage::getModel('shipping/rate_result_method');
249
- $method->setCarrier($this->_code);
250
- $method->setMethod($courier_title);
251
- $method->setCarrierTitle($this->getConfigData('title'));
252
-
253
- if($display_surcharge == '1'){
254
-
255
- $tmp_display_surcharge = $courier_price + $display_surcharge1;
256
- $tmp_method_title = $courier_title.' + Handling Charge';
257
-
258
- $method->setMethodTitle($tmp_method_title);
259
- $method->setTransitTime($courier_transittime);
260
- $method->setPrice($tmp_display_surcharge);
261
- $method->setCost($tmp_display_surcharge);
262
-
263
- } else {
264
-
265
- if(in_array($key,$available_carriers)) {
266
- //echo '<br>'.$key . ' - matched<br>';
267
- $method->setMethodTitle($courier_title);
268
- $method->setTransitTime($courier_transittime);
269
- $method->setPrice($courier_price);
270
- $method->setCost($courier_price);
271
- } else {
272
- //echo '<br>'.$key . ' - not found<br>';
273
- }
274
-
275
-
276
-
277
- }
278
-
279
- $result->append($method);
280
-
281
- }
282
- /*echo '<pre>'; print_r($result);
283
- die('arr');*/
284
- }
285
-
286
-
287
- //echo '<pre>'; print_r($result); //die('model');
288
-
289
- }else{
290
- $error = Mage::getModel('shipping/rate_result_error');
291
- $error->setCarrier($this->_code);
292
- $error->setCarrierTitle($this->getConfigData('name'));
293
- $error->setErrorMessage($this->getConfigData('specificerrmsg'));
294
- $result->append($error);
295
- }
296
- return $result;
297
- }
298
- public function getAllowedMethods()
299
- {
300
- return array('transdirect'=>$this->getConfigData('name'));
301
- }
302
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/Model/Carrier/bkp_26-5-2014-morning----Excellence.php DELETED
@@ -1,260 +0,0 @@
1
- <?php
2
- class Excellence_Ship_Model_Carrier_Excellence extends Mage_Shipping_Model_Carrier_Abstract
3
- implements Mage_Shipping_Model_Carrier_Interface {
4
- protected $_code = 'excellence';
5
-
6
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
7
- {
8
- //echo '<pre>'; print_r($request); die;
9
- if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
10
- return false;
11
- }
12
-
13
- $price = $this->getConfigData('price'); // set a default shipping price maybe 0
14
- $price = 0;
15
-
16
- /* API Request Start */
17
-
18
- $account_email = Mage::getStoreConfig('mycustom_section/authentication/email');
19
- $account_password = Mage::getStoreConfig('mycustom_section/authentication/password');
20
- $warehouse_postcode = Mage::getStoreConfig('mycustom_section/warehouseaddress/postcode');
21
- $warehouse_address = Mage::getStoreConfig('mycustom_section/warehouseaddress/address');
22
- $dimension_width = Mage::getStoreConfig('mycustom_section/defaultitemsize/dimensionswidth');
23
- $dimension_height = Mage::getStoreConfig('mycustom_section/defaultitemsize/dimensionsheight');
24
- $dimension_dim = Mage::getStoreConfig('mycustom_section/defaultitemsize/dimensionsdim');
25
- $dimension_weight = Mage::getStoreConfig('mycustom_section/defaultitemsize/weight');
26
- $display_carriers = Mage::getStoreConfig('mycustom_section/displayoptions/availablecoriers');
27
- $display_quote = Mage::getStoreConfig('mycustom_section/displayoptions/quotedisplay');
28
- $display_fixedprice = Mage::getStoreConfig('mycustom_section/displayoptions/fixedpriceonerror');
29
- $display_fixedprice1 = Mage::getStoreConfig('mycustom_section/displayoptions/fixedpriceonerror1');
30
- $display_showcouriername = Mage::getStoreConfig('mycustom_section/displayoptions/showcouriernames');
31
- $display_surcharge = Mage::getStoreConfig('mycustom_section/displayoptions/handlingsurcharge');
32
- $display_surcharge1 = Mage::getStoreConfig('mycustom_section/displayoptions/handlingsurcharge1');
33
- $display_includesurchage = Mage::getStoreConfig('mycustom_section/displayoptions/includesurcharge');
34
-
35
-
36
- // Cart Total Weight Code Start by Nayan
37
-
38
- $quote = Mage::getSingleton('checkout/session')->getQuote();
39
- $cartItems = $quote->getAllVisibleItems();
40
- $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
41
-
42
- $weight = 0;
43
- $height = 0;
44
- $width = 0;
45
- $length = 0;
46
- foreach ($cartItems as $item)
47
- {
48
- //echo '<pre>'; print_r($item->getQty()); die('qty');
49
- $productId = $item->getProductId();
50
- $productQty = $item->getQty();
51
-
52
- $product = Mage::getModel('catalog/product')->load($productId);
53
- //echo $product->getItemWeight();
54
- $weight += $product->getItemWeight() * $productQty;
55
- $height += $product->getItemHeight() * $productQty;
56
- $width += $product->getItemWidth() * $productQty;
57
- $length += $product->getItemDim() * $productQty;
58
- }
59
-
60
- $cart_total_weight = $weight;
61
- $cart_total_height = $height;
62
- $cart_total_width = $width;
63
- $cart_total_length = $length;
64
-
65
- // Cart Total Weight Code End by Nayan
66
-
67
-
68
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
69
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
70
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
71
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
72
-
73
- /* echo 'width--'.$cart_total_weight;
74
- echo 'height---'.$cart_total_height;
75
- echo 'width---'.$cart_total_width;
76
- echo 'length---'.$cart_total_length;
77
- die('here');
78
- */
79
-
80
- // Getting Cart page Quote Address Details Code Start by Nayan
81
-
82
- $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
83
- $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
84
- $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
85
- $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
86
-
87
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
88
- $receiver_region_tmp = $region->getName();
89
-
90
- if($receiver_region == '') {
91
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
92
- session_write_close();
93
- //$this->_redirect('checkout/cart');
94
- return false;
95
- }
96
-
97
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
98
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
99
- session_write_close();
100
- return false;
101
- //$this->_redirect('checkout/cart');
102
- }
103
-
104
- if(!$receiver_regionId)
105
- {
106
- $receiver_suburb = $receiver_region;
107
- }
108
- else
109
- {
110
- $receiver_suburb = $receiver_region_tmp;
111
- }
112
-
113
-
114
- /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
115
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
116
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
117
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
118
- */
119
-
120
-
121
-
122
-
123
- //echo $receiver_suburb; die('suburb');
124
-
125
- // Getting Cart page Quote Address Details Code End by Nayan
126
-
127
- $quoteDetails = array(
128
- /*'email' => $account_email,
129
- 'password' => $account_password, */
130
- 'declared_value'=>10000,
131
- 'items' => array
132
- (
133
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
134
- ),
135
- 'sender' => array('country' => 'AU', 'suburb'=>'SYDNEY', 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
136
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
137
- );
138
-
139
- $json_data = json_encode($quoteDetails);
140
- //echo '<pre>'; print_r($json_data); die('json');
141
-
142
- $ch = curl_init();
143
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
144
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
145
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
146
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
147
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
148
- curl_setopt($ch, CURLOPT_POST, TRUE);
149
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
150
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
151
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
152
- $response = curl_exec($ch);
153
-
154
- $report = curl_getinfo($ch);
155
- //echo '<pre>'; print_r($report);
156
-
157
- if(curl_errno($ch)) {
158
- echo 'Response error: ' . curl_error($ch);
159
- }
160
-
161
- curl_close($ch);
162
-
163
- if ($response) {
164
- //echo '<pre>'.$response;
165
-
166
- $json_decode_varible = json_decode($response, true);
167
-
168
- $quotes_val = $json_decode_varible['quotes'];
169
- //echo "<pre>"; print_r($quotes_val); die('quotes');
170
-
171
-
172
- // Passing Data from Controller to Template file code Start
173
-
174
-
175
-
176
-
177
- // End
178
-
179
-
180
-
181
- } else {
182
- echo "Failed";
183
- }
184
-
185
- /* End */
186
-
187
-
188
-
189
-
190
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
191
- $result = Mage::getModel('shipping/rate_result');
192
- $show = true;
193
- if($show){
194
-
195
- //die('before');
196
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
197
-
198
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
199
- //echo $session->getSomeSessionVar();
200
-
201
- //echo '<pre>'; print_r($session->getSomeSessionVar());
202
- //die('after');
203
-
204
- if($quotes_val == ''){
205
- /* Mage::getSingleton('checkout/session')->addError("Please Fill the information properly, There is some fields are missing or not proper.");
206
- session_write_close();
207
- return false;
208
- */
209
- $method = Mage::getModel('shipping/rate_result_method');
210
- $method->setCarrier($this->_code);
211
- $method->setMethod($this->_code);
212
- $method->setCarrierTitle($this->getConfigData('title'));
213
- $method->setMethodTitle('Fixed Price');
214
-
215
- if($display_fixedprice == '1'){
216
- $method->setPrice($display_fixedprice1);
217
- $method->setCost($display_fixedprice1);
218
- }
219
-
220
- $result->append($method);
221
-
222
- }
223
- else {
224
-
225
- foreach($quotes_val as $key => $val) {
226
- $courier_title = $key;
227
- $courier_price = $quotes_val[$key]['total'];
228
-
229
- $method = Mage::getModel('shipping/rate_result_method');
230
- $method->setCarrier($this->_code);
231
- $method->setMethod($courier_title);
232
- $method->setCarrierTitle($this->getConfigData('title'));
233
-
234
- $method->setMethodTitle($courier_title);
235
-
236
- $method->setPrice($courier_price);
237
- $method->setCost($courier_price);
238
-
239
- $result->append($method);
240
-
241
- }
242
-
243
- }
244
-
245
- //echo '<pre>'; print_r($result); //die('model');
246
-
247
- }else{
248
- $error = Mage::getModel('shipping/rate_result_error');
249
- $error->setCarrier($this->_code);
250
- $error->setCarrierTitle($this->getConfigData('name'));
251
- $error->setErrorMessage($this->getConfigData('specificerrmsg'));
252
- $result->append($error);
253
- }
254
- return $result;
255
- }
256
- public function getAllowedMethods()
257
- {
258
- return array('excellence'=>$this->getConfigData('name'));
259
- }
260
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/Model/Carrier/bkp_28-5-2014-evening-----Transdirect.php DELETED
@@ -1,283 +0,0 @@
1
- <?php
2
- class Transdirect_Ship_Model_Carrier_Transdirect extends Mage_Shipping_Model_Carrier_Abstract
3
- implements Mage_Shipping_Model_Carrier_Interface {
4
- protected $_code = 'transdirect';
5
-
6
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
7
- {
8
- //echo '<pre>'; print_r($request); die('request');
9
- if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
10
- return false;
11
- }
12
-
13
- $price = $this->getConfigData('price'); // set a default shipping price maybe 0
14
- $price = 0;
15
-
16
- /* API Request Start */
17
-
18
- $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
19
- $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
20
- $warehouse_suburb = Mage::getStoreConfig('transdirect_section/warehouseaddress/suburb');
21
- $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
22
- $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
23
- $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
24
- $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
25
- $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
26
- $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
27
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
28
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
29
- $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
30
- $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
31
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
32
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
33
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
34
- $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
35
-
36
-
37
- // Cart Total Weight Code Start by Nayan
38
-
39
- $quote = Mage::getSingleton('checkout/session')->getQuote();
40
- $cartItems = $quote->getAllVisibleItems();
41
- $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
42
-
43
- $weight = 0;
44
- $height = 0;
45
- $width = 0;
46
- $length = 0;
47
- foreach ($cartItems as $item)
48
- {
49
- //echo '<pre>'; print_r($item->getQty()); die('qty');
50
- $productId = $item->getProductId();
51
- $productQty = $item->getQty();
52
-
53
- $product = Mage::getModel('catalog/product')->load($productId);
54
- //echo $product->getItemWeight();
55
- $weight += $product->getItemWeight() * $productQty;
56
- $height += $product->getItemHeight() * $productQty;
57
- $width += $product->getItemWidth() * $productQty;
58
- $length += $product->getItemDim() * $productQty;
59
- }
60
-
61
- $cart_total_weight = $weight;
62
- $cart_total_height = $height;
63
- $cart_total_width = $width;
64
- $cart_total_length = $length;
65
-
66
- // Cart Total Weight Code End by Nayan
67
-
68
-
69
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
70
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
71
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
72
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
73
-
74
- /* echo 'width--'.$cart_total_weight;
75
- echo 'height---'.$cart_total_height;
76
- echo 'width---'.$cart_total_width;
77
- echo 'length---'.$cart_total_length;
78
- die('here');
79
- */
80
-
81
- // Getting Cart page Quote Address Details Code Start by Nayan
82
-
83
- $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
84
- $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
85
- $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
86
- $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
87
-
88
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
89
- $receiver_region_tmp = $region->getName();
90
-
91
- if($receiver_region == '') {
92
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
93
- session_write_close();
94
- //$this->_redirect('checkout/cart');
95
- return false;
96
- }
97
-
98
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
99
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
100
- session_write_close();
101
- return false;
102
- //$this->_redirect('checkout/cart');
103
- }
104
-
105
- if(!$receiver_regionId)
106
- {
107
- $receiver_suburb = $receiver_region;
108
- }
109
- else
110
- {
111
- $receiver_suburb = $receiver_region_tmp;
112
- }
113
-
114
-
115
- /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
116
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
117
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
118
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
119
- */
120
-
121
-
122
-
123
-
124
- //echo $receiver_suburb; die('suburb');
125
-
126
- // Getting Cart page Quote Address Details Code End by Nayan
127
-
128
- $quoteDetails = array(
129
- 'declared_value'=>10000,
130
- 'items' => array
131
- (
132
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
133
- ),
134
- 'sender' => array('country' => 'AU', 'suburb'=> $warehouse_suburb, 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
135
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
136
- );
137
-
138
- $json_data = json_encode($quoteDetails);
139
- //echo '<pre>'; print_r($json_data); //die('json');
140
-
141
- $ch = curl_init();
142
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
143
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
144
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
145
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
146
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
147
- curl_setopt($ch, CURLOPT_POST, TRUE);
148
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
149
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
150
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
151
- $response = curl_exec($ch);
152
-
153
- $report = curl_getinfo($ch);
154
- //echo '<pre>'; print_r($report);
155
-
156
- if(curl_errno($ch)) {
157
- echo 'Response error: ' . curl_error($ch);
158
- }
159
-
160
- curl_close($ch);
161
-
162
- if ($response) {
163
- $json_decode_varible = json_decode($response, true);
164
- $quotes_val = $json_decode_varible['quotes'];
165
- //echo "<pre>"; print_r($quotes_val); die('quotes');
166
-
167
- } else {
168
- echo "Failed";
169
- }
170
-
171
- /* End */
172
-
173
-
174
- //$available_carriers = array($display_carriers);
175
- //print_r($available_carriers);
176
- $available_carriers = explode( ',', $display_carriers);
177
-
178
- /* function cmp1($a, $b) {
179
- return strcmp($a['transit_time'], $b['transit_time']);
180
- }
181
- */
182
-
183
-
184
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
185
- $result = Mage::getModel('shipping/rate_result');
186
- $show = true;
187
- if($show){
188
-
189
- //die('before');
190
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
191
-
192
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
193
- //echo $session->getSomeSessionVar();
194
-
195
- //echo '<pre>'; print_r($session->getSomeSessionVar());
196
- //die('after');
197
-
198
- if($quotes_val == ''){
199
- Mage::getSingleton('core/session')->addError("Please fill the information properly, there is some fields are missing or not entered properly.");
200
- session_write_close();
201
- return false;
202
-
203
- $method = Mage::getModel('shipping/rate_result_method');
204
- $method->setCarrier($this->_code);
205
- $method->setMethod($this->_code);
206
- $method->setCarrierTitle($this->getConfigData('title'));
207
- $method->setMethodTitle('Fixed Price');
208
-
209
- if($display_fixedprice == '1'){
210
- $method->setPrice($display_fixedprice1);
211
- $method->setCost($display_fixedprice1);
212
- }
213
-
214
- $result->append($method);
215
-
216
- }
217
- else {
218
-
219
-
220
-
221
-
222
- foreach($quotes_val as $key => $val) {
223
- // echo count($val); die;
224
- //echo $key.'<br>';
225
- //print_r($available_carriers);
226
-
227
- //usort($quotes_val, 'cmp1');
228
-
229
- $courier_title = $key;
230
- $courier_price = $quotes_val[$key]['total'];
231
-
232
- $method = Mage::getModel('shipping/rate_result_method');
233
- $method->setCarrier($this->_code);
234
- $method->setMethod($courier_title);
235
- $method->setCarrierTitle($this->getConfigData('title'));
236
-
237
- if($display_surcharge == '1'){
238
-
239
- $tmp_display_surcharge = $courier_price + $display_surcharge1;
240
- $tmp_method_title = $courier_title.' + Handling Charge';
241
-
242
- $method->setMethodTitle($tmp_method_title);
243
- $method->setPrice($tmp_display_surcharge);
244
- $method->setCost($tmp_display_surcharge);
245
-
246
- } else {
247
-
248
- if(in_array($key,$available_carriers)) {
249
- //echo '<br>'.$key . ' - matched<br>';
250
- $method->setMethodTitle($courier_title);
251
- $method->setPrice($courier_price);
252
- $method->setCost($courier_price);
253
- } else {
254
- //echo '<br>'.$key . ' - not found<br>';
255
- }
256
-
257
-
258
-
259
- }
260
-
261
- $result->append($method);
262
-
263
- }
264
- //die('arr');
265
- }
266
-
267
-
268
- //echo '<pre>'; print_r($result); //die('model');
269
-
270
- }else{
271
- $error = Mage::getModel('shipping/rate_result_error');
272
- $error->setCarrier($this->_code);
273
- $error->setCarrierTitle($this->getConfigData('name'));
274
- $error->setErrorMessage($this->getConfigData('specificerrmsg'));
275
- $result->append($error);
276
- }
277
- return $result;
278
- }
279
- public function getAllowedMethods()
280
- {
281
- return array('transdirect'=>$this->getConfigData('name'));
282
- }
283
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/Model/Carrier/bkp_30-5-2014---Transdirect.php DELETED
@@ -1,304 +0,0 @@
1
- <?php
2
- class Transdirect_Ship_Model_Carrier_Transdirect extends Mage_Shipping_Model_Carrier_Abstract
3
- implements Mage_Shipping_Model_Carrier_Interface {
4
- protected $_code = 'transdirect';
5
-
6
- public function collectRates(Mage_Shipping_Model_Rate_Request $request)
7
- {
8
- //echo '<pre>'; print_r($request); die('request');
9
- if (!Mage::getStoreConfig('carriers/'.$this->_code.'/active')) {
10
- return false;
11
- }
12
-
13
- $price = $this->getConfigData('price'); // set a default shipping price maybe 0
14
- $price = 0;
15
-
16
- /* API Request Start */
17
-
18
- $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
19
- $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
20
- $warehouse_suburb = Mage::getStoreConfig('transdirect_section/warehouseaddress/suburb');
21
- $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
22
- $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
23
- $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
24
- $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
25
- $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
26
- $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
27
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
28
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
29
- $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
30
- $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
31
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
32
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
33
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
34
- $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
35
-
36
-
37
- // Cart Total Weight Code Start by Nayan
38
-
39
- $quote = Mage::getSingleton('checkout/session')->getQuote();
40
- $cartItems = $quote->getAllVisibleItems();
41
- $total_qty = Mage::helper('checkout/cart')->getSummaryCount();
42
-
43
- $weight = 0;
44
- $height = 0;
45
- $width = 0;
46
- $length = 0;
47
- foreach ($cartItems as $item)
48
- {
49
- //echo '<pre>'; print_r($item->getQty()); die('qty');
50
- $productId = $item->getProductId();
51
- $productQty = $item->getQty();
52
-
53
- $product = Mage::getModel('catalog/product')->load($productId);
54
- //echo $product->getItemWeight();
55
- $weight += $product->getItemWeight() * $productQty;
56
- $height += $product->getItemHeight() * $productQty;
57
- $width += $product->getItemWidth() * $productQty;
58
- $length += $product->getItemDim() * $productQty;
59
- }
60
-
61
- $cart_total_weight = $weight;
62
- $cart_total_height = $height;
63
- $cart_total_width = $width;
64
- $cart_total_length = $length;
65
-
66
- // Cart Total Weight Code End by Nayan
67
-
68
-
69
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
70
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
71
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
72
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
73
-
74
- /* echo 'width--'.$cart_total_weight;
75
- echo 'height---'.$cart_total_height;
76
- echo 'width---'.$cart_total_width;
77
- echo 'length---'.$cart_total_length;
78
- die('here');
79
- */
80
-
81
- // Getting Cart page Quote Address Details Code Start by Nayan
82
-
83
- $receiver_country = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
84
- $receiver_postcode = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
85
- $receiver_regionId = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
86
- $receiver_region = (string) Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
87
-
88
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
89
- $receiver_region_tmp = $region->getName();
90
-
91
- if($receiver_region == '') {
92
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
93
- session_write_close();
94
- //$this->_redirect('checkout/cart');
95
- return false;
96
- }
97
-
98
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
99
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
100
- session_write_close();
101
- return false;
102
- //$this->_redirect('checkout/cart');
103
- }
104
-
105
- if(!$receiver_regionId)
106
- {
107
- $receiver_suburb = $receiver_region;
108
- }
109
- else
110
- {
111
- $receiver_suburb = $receiver_region_tmp;
112
- }
113
-
114
-
115
- /* echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
116
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getCountryId();
117
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegion();
118
- echo Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getRegionId();
119
- */
120
-
121
-
122
-
123
-
124
- //echo $receiver_suburb; die('suburb');
125
-
126
- // Getting Cart page Quote Address Details Code End by Nayan
127
-
128
- $quoteDetails = array(
129
- 'declared_value'=>10000,
130
- 'items' => array
131
- (
132
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
133
- ),
134
- 'sender' => array('country' => 'AU', 'suburb'=> $warehouse_suburb, 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
135
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
136
- );
137
-
138
- $json_data = json_encode($quoteDetails);
139
- //echo '<pre>'; print_r($json_data); //die('json');
140
-
141
- $ch = curl_init();
142
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
143
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
144
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
145
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
146
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
147
- curl_setopt($ch, CURLOPT_POST, TRUE);
148
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
149
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
150
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
151
- $response = curl_exec($ch);
152
-
153
- $report = curl_getinfo($ch);
154
- //echo '<pre>'; print_r($report);
155
-
156
- if(curl_errno($ch)) {
157
- echo 'Response error: ' . curl_error($ch);
158
- }
159
-
160
- curl_close($ch);
161
-
162
- if ($response) {
163
- $json_decode_varible = json_decode($response, true);
164
- $quotes_val = $json_decode_varible['quotes'];
165
- //echo "<pre>"; print_r($quotes_val); die('quotes');
166
-
167
- } else {
168
- echo "Failed";
169
- }
170
-
171
- /* End */
172
-
173
-
174
- //$available_carriers = array($display_carriers);
175
- //print_r($available_carriers);
176
- $available_carriers = explode( ',', $display_carriers);
177
-
178
- /* function cmp1($a, $b) {
179
- return strcmp($a['transit_time'], $b['transit_time']);
180
- }
181
- */
182
-
183
- function build_sorter($key) {
184
- return function ($a, $b) use ($key) {
185
- return strnatcmp($a[$key], $b[$key]);
186
- };
187
- }
188
-
189
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
190
-
191
- if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
192
- if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
193
-
194
-
195
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
196
- $result = Mage::getModel('shipping/rate_result');
197
- $show = true;
198
- if($show){
199
-
200
- //die('before');
201
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
202
-
203
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
204
- //echo $session->getSomeSessionVar();
205
-
206
- //echo '<pre>'; print_r($session->getSomeSessionVar());
207
- //die('after');
208
-
209
- if($quotes_val == ''){
210
- Mage::getSingleton('core/session')->addError("Please fill the information properly, there is some fields are missing or not entered properly.");
211
- session_write_close();
212
- return false;
213
-
214
- $method = Mage::getModel('shipping/rate_result_method');
215
- $method->setCarrier($this->_code);
216
- $method->setMethod($this->_code);
217
- $method->setCarrierTitle($this->getConfigData('title'));
218
- $method->setMethodTitle('Fixed Price');
219
-
220
- if($display_fixedprice == '1'){
221
- $method->setPrice($display_fixedprice1);
222
- $method->setCost($display_fixedprice1);
223
- }
224
-
225
- $result->append($method);
226
-
227
- }
228
- else {
229
-
230
-
231
-
232
-
233
- foreach($quotes_val as $key => $val) {
234
-
235
- if($key=='fastway'){ $method_title = "Fastway"; }
236
- if($key=='toll_priority_overnight'){$method_title = "Toll Priority Overnight"; }
237
- if($key=='couriers_please'){$method_title = "Couriers Please"; }
238
- if($key=='allied'){$method_title = "Allied Express"; }
239
- if($key=='toll'){ $method_title = "Toll"; }
240
- if($key=='mainfreight'){ $method_title = "Mainfreight"; }
241
- if($key=='northline'){$method_title = "Northline"; }
242
-
243
- //echo $method_title; die;
244
- // echo count($val); die;
245
- //echo $key.'<br>';
246
- //print_r($available_carriers);
247
-
248
- //usort($quotes_val, 'cmp1');
249
-
250
- $courier_title = $key;
251
- $courier_price = $quotes_val[$key]['total'];
252
-
253
- $method = Mage::getModel('shipping/rate_result_method');
254
- $method->setCarrier($this->_code);
255
- $method->setMethod($courier_title);
256
- $method->setCarrierTitle($this->getConfigData('title'));
257
-
258
- if($display_surcharge == '1'){
259
-
260
- $tmp_display_surcharge = $courier_price + $display_surcharge1;
261
- $tmp_method_title = $method_title.' + Handling Charge';
262
-
263
- $method->setMethodTitle($tmp_method_title);
264
- $method->setPrice($tmp_display_surcharge);
265
- $method->setCost($tmp_display_surcharge);
266
-
267
- } else {
268
-
269
- if(in_array($key,$available_carriers)) {
270
- //echo '<br>'.$key . ' - matched<br>';
271
- $method->setMethodTitle($method_title);
272
- $method->setPrice($courier_price);
273
- $method->setCost($courier_price);
274
- } else {
275
- //echo '<br>'.$key . ' - not found<br>';
276
- }
277
-
278
-
279
-
280
- }
281
-
282
- $result->append($method);
283
-
284
- }
285
- //die('arr');
286
- }
287
-
288
-
289
- //echo '<pre>'; print_r($result); //die('model');
290
-
291
- }else{
292
- $error = Mage::getModel('shipping/rate_result_error');
293
- $error->setCarrier($this->_code);
294
- $error->setCarrierTitle($this->getConfigData('name'));
295
- $error->setErrorMessage($this->getConfigData('specificerrmsg'));
296
- $result->append($error);
297
- }
298
- return $result;
299
- }
300
- public function getAllowedMethods()
301
- {
302
- return array('transdirect'=>$this->getConfigData('name'));
303
- }
304
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/Model/Source/AddressType.php CHANGED
@@ -1,27 +1,27 @@
1
- <?php
2
-
3
-
4
-
5
- class Transdirect_Ship_Model_Source_AddressType extends Varien_Object
6
-
7
- {
8
-
9
- public function toOptionArray()
10
-
11
- {
12
-
13
- $hlp = Mage::helper('ship');
14
-
15
- return array(
16
-
17
- array('value' => 'residential', 'label' => $hlp->__('Residential')),
18
-
19
- array('value' => 'commercial', 'label' => $hlp->__('Commercial')),
20
-
21
- );
22
-
23
- }
24
-
25
-
26
-
27
  }
1
+ <?php
2
+
3
+
4
+
5
+ class Transdirect_Ship_Model_Source_AddressType extends Varien_Object
6
+
7
+ {
8
+
9
+ public function toOptionArray()
10
+
11
+ {
12
+
13
+ $hlp = Mage::helper('ship');
14
+
15
+ return array(
16
+
17
+ array('value' => 'residential', 'label' => $hlp->__('Residential')),
18
+
19
+ array('value' => 'commercial', 'label' => $hlp->__('Commercial')),
20
+
21
+ );
22
+
23
+ }
24
+
25
+
26
+
27
  }
app/code/local/Transdirect/Ship/Model/Source/Couriers.php CHANGED
@@ -1,19 +1,19 @@
1
- <?php
2
-
3
- class Transdirect_Ship_Model_Source_Couriers extends Varien_Object
4
- {
5
- public function toOptionArray()
6
- {
7
- $hlp = Mage::helper('ship');
8
- return array(
9
- array('value' => 'toll', 'label' => $hlp->__('Toll')),
10
- array('value' => 'toll_priority_overnight', 'label' => $hlp->__('Toll Priority')),
11
- array('value' => 'allied', 'label' => $hlp->__('Allied Express')),
12
- array('value' => 'couriers_please', 'label' => $hlp->__('Couriers Please')),
13
- array('value' => 'fastway', 'label' => $hlp->__('Fastway')),
14
- array('value' => 'mainfreight', 'label' => $hlp->__('Mainfreight')),
15
- array('value' => 'northline', 'label' => $hlp->__('Northline')),
16
- );
17
- }
18
-
19
  }
1
+ <?php
2
+
3
+ class Transdirect_Ship_Model_Source_Couriers extends Varien_Object
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ $hlp = Mage::helper('ship');
8
+ return array(
9
+ array('value' => 'toll', 'label' => $hlp->__('Toll')),
10
+ array('value' => 'toll_priority_overnight', 'label' => $hlp->__('Toll Priority')),
11
+ array('value' => 'allied', 'label' => $hlp->__('Allied Express')),
12
+ array('value' => 'couriers_please', 'label' => $hlp->__('Couriers Please')),
13
+ array('value' => 'fastway', 'label' => $hlp->__('Fastway')),
14
+ array('value' => 'mainfreight', 'label' => $hlp->__('Mainfreight')),
15
+ array('value' => 'northline', 'label' => $hlp->__('Northline')),
16
+ );
17
+ }
18
+
19
  }
app/code/local/Transdirect/Ship/Model/Source/Quotes.php CHANGED
@@ -1,15 +1,15 @@
1
- <?php
2
-
3
- class Transdirect_Ship_Model_Source_Quotes extends Varien_Object
4
- {
5
- public function toOptionArray()
6
- {
7
- $hlp = Mage::helper('ship');
8
- return array(
9
- array('value' => 'display_all_quotes', 'label' => $hlp->__('Display all Quotes')),
10
- array('value' => 'display_cheapest', 'label' => $hlp->__('Display Cheapest Quotes')),
11
- array('value' => 'display_cheapest_fastest', 'label' => $hlp->__('Display Fastest Quotes')),
12
- );
13
- }
14
-
15
  }
1
+ <?php
2
+
3
+ class Transdirect_Ship_Model_Source_Quotes extends Varien_Object
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ $hlp = Mage::helper('ship');
8
+ return array(
9
+ array('value' => 'display_all_quotes', 'label' => $hlp->__('Display all Quotes')),
10
+ array('value' => 'display_cheapest', 'label' => $hlp->__('Display Cheapest Quotes')),
11
+ array('value' => 'display_cheapest_fastest', 'label' => $hlp->__('Display Fastest Quotes')),
12
+ );
13
+ }
14
+
15
  }
app/code/local/Transdirect/Ship/controllers/IndexController.php CHANGED
@@ -1,441 +1,881 @@
1
  <?php
 
2
  class Transdirect_Ship_IndexController extends Mage_Core_Controller_Front_Action
 
3
  {
4
 
 
 
5
  protected function _getCart()
 
6
  {
 
7
  return Mage::getSingleton('checkout/cart');
 
8
  }
9
 
 
 
10
  /**
 
11
  * Get checkout session model instance
 
12
  *
 
13
  * @return Mage_Checkout_Model_Session
 
14
  */
 
15
  protected function _getSession()
 
16
  {
 
17
  return Mage::getSingleton('checkout/session');
 
18
  }
19
 
 
 
20
  /**
 
21
  * Get current active quote instance
 
22
  *
 
23
  * @return Mage_Sales_Model_Quote
 
24
  */
 
25
  protected function _getQuote()
 
26
  {
 
27
 
 
28
  return $this->_getCart()->getQuote();
 
29
  }
 
30
 
 
31
  protected function _goBack()
 
32
  {
 
33
  $returnUrl = $this->getRequest()->getParam('return_url');
 
34
  if ($returnUrl) {
 
35
  //die('if');
 
36
 
 
37
  if (!$this->_isUrlInternal($returnUrl)) {
 
38
  throw new Mage_Exception('External urls redirect to "' . $returnUrl . '" denied!');
 
39
  }
40
 
 
 
41
  $this->_getSession()->getMessages(true);
 
42
  $this->getResponse()->setRedirect($returnUrl);
 
43
  } elseif (!Mage::getStoreConfig('checkout/cart/redirect_to_cart')
 
44
 
 
45
  && !$this->getRequest()->getParam('in_cart')
 
46
  && $backUrl = $this->_getRefererUrl()
 
47
  ) {// die('else if');
 
48
  $this->getResponse()->setRedirect($backUrl);
 
49
  } else {
 
50
  //die('else');
 
51
 
 
52
  if (($this->getRequest()->getActionName() == 'add') && !$this->getRequest()->getParam('in_cart')) {
 
53
  $this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
 
54
  }
 
55
  $this->_redirect('checkout/cart');
 
56
  //die('go back');
 
57
  //$this->_redirectReferer();
 
58
  }
 
59
  return $this;
 
60
  }
61
 
 
 
62
  function indexAction()
 
63
  {
 
64
  //die('index');
 
65
 
 
66
  //$this->loadLayout();
 
67
 
 
68
  $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
 
69
  $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
 
70
  $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
 
71
  $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
 
72
  $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
 
73
  $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
 
74
  $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
 
75
  $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
 
76
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
 
77
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
78
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
 
79
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
 
80
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
 
81
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
 
82
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
 
83
  $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
 
84
 
85
 
 
 
86
  // Cart Total Weight Code Start by Nayan
 
87
 
 
88
  $quote = Mage::getSingleton('checkout/session')->getQuote();
 
89
  $cartItems = $quote->getAllVisibleItems();
 
90
  //$total_qty = Mage::helper('checkout/cart')->getSummaryCount();
 
91
  $total_qty = '1';
92
 
 
 
93
  /* if(Mage::registry('current_product')) {
 
94
  //this is a product page, do some stuff
 
95
  die('product');
 
96
  }
 
97
  else {
 
98
  die('not product');
 
99
  }
 
100
 
 
101
  echo Mage::app()->getFrontController()->getRequest()->getRouteName();
 
102
  die('name');*/
 
103
 
 
104
  $weight = 0;
 
105
  $height = 0;
 
106
  $width = 0;
 
107
  $length = 0;
 
108
  foreach ($cartItems as $item)
 
109
  {
 
110
  //echo '<pre>'; print_r($item->getQty()); die;
 
111
  $productId = $item->getProductId();
 
112
  $productQty = $item->getQty();
113
 
 
 
114
  $product = Mage::getModel('catalog/product')->load($productId);
 
115
  //echo $product->getItemWeight();
 
116
  $weight += $product->getItemWeight() * $productQty;
 
117
  $height += $product->getItemHeight() * $productQty;
 
118
  $width += $product->getItemWidth() * $productQty;
 
119
  $length += $product->getItemDim() * $productQty;
 
120
  }
 
121
 
 
122
  $product = Mage::getModel('catalog/product')->load($productId);
 
123
 
 
124
  $cart_total_weight = $product->getItemWeight();
 
125
  $cart_total_height = $product->getItemHeight();
 
126
  $cart_total_width = $product->getItemWidth();
 
127
  $cart_total_length = $product->getItemDim();
 
128
 
 
129
  // Cart Total Weight Code End by Nayan
130
 
 
 
131
 
 
132
  if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
 
133
  if(!$cart_total_height){ $cart_total_height = $dimension_height; }
 
134
  if(!$cart_total_width){ $cart_total_width = $dimension_width; }
 
135
  if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
136
 
 
 
137
  /* echo 'width--'.$cart_total_weight;
 
138
  echo 'height---'.$cart_total_height;
 
139
  echo 'width---'.$cart_total_width;
 
140
  echo 'length---'.$cart_total_length;
 
141
  die('here');
 
142
  */
143
 
 
 
144
  // Getting Cart page Quote Address Details Code Start by Nayan
145
 
 
 
146
  $receiver_country = (string) $this->getRequest()->getParam('country_id');
 
147
  $receiver_postcode = (string) $this->getRequest()->getParam('estimate_postcode');
 
148
  $receiver_regionId = (string) $this->getRequest()->getParam('region_id');
 
149
  $receiver_region = (string) $this->getRequest()->getParam('region');
150
 
 
 
151
  $region = Mage::getModel('directory/region')->load($receiver_regionId);
 
152
  $receiver_region_tmp = $region->getName();
 
153
 
 
154
  /*if($receiver_region == '') {
 
155
  Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
 
156
  session_write_close();
 
157
  $this->_redirectReferer();
 
158
  }*/
 
159
 
 
160
  /*if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
 
161
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
 
162
  session_write_close();
 
163
  $this->_redirectReferer();
 
164
  }*/
 
165
 
 
166
  if(!$receiver_regionId)
 
167
  {
 
168
  $receiver_suburb = $receiver_region;
 
169
  }
 
170
  else
 
171
  {
 
172
  $receiver_suburb = $receiver_region_tmp;
 
173
  }
 
174
 
 
175
 
 
176
  $receiver_postcode = $_COOKIE['cart_postocde'];
 
177
  $receiver_suburb = $_COOKIE['cart_locality'];
 
178
 
 
179
  //echo $receiver_suburb; die('suburb');
 
180
 
 
181
  // Getting Cart page Quote Address Details Code End by Nayan
182
 
 
 
183
  $quoteDetails = array(
 
184
  'declared_value'=>10000,
 
185
  'items' => array
 
186
  (
 
187
  array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
 
188
  ),
 
189
  'sender' => array('country' => 'AU', 'suburb'=>'SYDNEY', 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
 
190
  'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
 
191
  );
192
 
 
 
193
  $json_data = json_encode($quoteDetails);
 
194
  //echo '<pre>'; print_r($json_data); die('encode');
 
195
 
 
196
  $ch = curl_init();
 
197
  curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
 
198
  //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
 
199
  curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
 
200
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
 
201
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
 
202
  curl_setopt($ch, CURLOPT_POST, TRUE);
 
203
  curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
 
204
  curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
 
205
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 
206
  $response = curl_exec($ch);
 
207
 
 
208
  $report = curl_getinfo($ch);
 
209
  //echo '<pre>'; print_r($report);
 
210
 
 
211
  if(curl_errno($ch)) {
 
212
  echo 'Response error: ' . curl_error($ch);
 
213
  }
 
214
 
 
215
  curl_close($ch);
 
216
 
 
217
  if ($response) {
 
218
  //echo '<pre>'.$response;
 
219
 
 
220
 
 
221
 
 
222
  $json_decode_varible = json_decode($response, true);
 
223
 
 
224
  $quotes_val = $json_decode_varible['quotes'];
 
225
  //echo "<pre>"; print_r($quotes_val); die('decode');
 
226
 
 
227
 
 
228
  // Passing Data from Controller to Template file code Start
 
229
 
 
230
 
 
231
  //$quotes_val = Mage::register('quotes_val', $quotes_val);
 
232
 
 
233
  // End
 
234
 
 
235
  Mage::getSingleton('core/session')->unsSomeSessionVar();
 
236
  Mage::getSingleton('core/session')->unsCountryVal();
 
237
  Mage::getSingleton('core/session')->unsPostcodeVal();
 
238
  Mage::getSingleton('core/session')->unsRegionIdVal();
 
239
  Mage::getSingleton('core/session')->unsRegionVal();
 
240
 
 
241
  $country = (string) $this->getRequest()->getParam('country_id');
 
242
  $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
 
243
  $regionId = (string) $this->getRequest()->getParam('region_id');
 
244
  $region = (string) $this->getRequest()->getParam('region');
 
245
 
 
246
  //echo $country. $postcode . $city . $regionId . $region; die('data');
 
247
 
 
248
  //echo "<pre>"; print_r($quotes_val);
 
249
 
250
- function build_sorter($key) {
 
 
251
  return function ($a, $b) use ($key) {
 
252
  return strnatcmp($a[$key], $b[$key]);
 
253
  };
254
- }
 
 
255
 
 
256
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
257
 
258
- if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
259
- if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
 
 
 
260
 
 
261
  //echo "<pre>"; print_r($quotes_val); die('after');
 
262
 
 
263
  $session_val = Mage::getSingleton('core/session')->setSomeSessionVar($quotes_val); // In the Controller
264
 
 
 
265
  $quote_form_country_val = Mage::getSingleton('core/session')->setCountryVal($country); // In the Controller
 
266
  $quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
 
267
  $quote_form_regionId_val = Mage::getSingleton('core/session')->setRegionIdVal($regionId); // In the Controller
 
268
  $quote_form_region_val = Mage::getSingleton('core/session')->setRegionVal($region); // In the Controller
 
269
 
 
270
 
 
271
 
 
272
  //echo '<pre>'; print_r($session_val->getSomeSessionVar());
 
273
  //die('set');
 
274
 
 
275
  /*
 
276
  foreach($quotes_val as $key => $val) {
 
277
  $courier_title = $key;
 
278
  $courier_price = $quotes_val[$key]['total'];
 
279
 
 
280
  // Mage::register('couriertitledisplay', $courier_title);
 
281
  // Mage::register('courierpricedisplay', $courier_price);
 
282
 
 
283
 
 
284
 
 
285
  $block = $this->getLayout()->createBlock(
 
286
  'Mage_Core_Block_Template',
 
287
  'ship.quotes',
 
288
  array(
 
289
  'template' => 'ship/quotes.phtml'
 
290
  )
 
291
  ) // NOTE - Custom Variables Below
 
292
  ->setData('courier_title', $courier_title)
 
293
  ->setData('courier_price', $courier_price);
 
294
 
 
295
 
 
296
  $this->getLayout()->getBlock('content')->append($block);
 
297
  }
 
298
  */
 
299
 
 
300
  } else {
 
301
  echo "Failed";
 
302
  }
 
303
 
 
304
 
 
305
  $available_carriers = explode( ',', $display_carriers);
306
 
 
 
307
  $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
 
308
  $result = Mage::getModel('shipping/rate_result');
 
309
  $show = true;
 
310
  if($show){
 
311
 
 
312
  //die('before');
 
313
  //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
 
314
 
 
315
  //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
 
316
  //echo $session->getSomeSessionVar();
317
 
 
 
318
  //echo '<pre>'; print_r($session->getSomeSessionVar());
 
319
  //die('after');
 
320
 
 
321
  if($quotes_val == ''){ //die('if');
 
322
  //echo $quote_form_postcode_val; die;
 
323
  /* if(!is_numeric($quote_form_postcode_val) || $quote_form_postcode_val == "0" || $quote_form_postcode_val == "00" || $quote_form_postcode_val == "000" || $quote_form_postcode_val == "0000" || $quote_form_postcode_val == "00000" || $quote_form_postcode_val == "000000" || $quote_form_postcode_val == "0000000") {
 
324
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
 
325
  } else {*/
326
- Mage::getSingleton('core/session')->addError("Please enter correct details, either suburb or postcode not entered properly.");
 
 
327
  //}
 
328
 
 
329
 
 
330
  //Mage::getSingleton('core/session')->addError("Please fill the information properly, there are some fields are missing or not entered properly.");
 
331
 
 
332
  $method = Mage::getModel('shipping/rate_result_method');
 
333
  $method->setCarrier($this->_code);
 
334
  $method->setMethod($this->_code);
 
335
  $method->setCarrierTitle('Carrier');
 
336
  $method->setMethodTitle('Fixed Price');
 
337
 
 
338
  if($display_fixedprice == '1'){
 
339
  $method->setPrice($display_fixedprice1);
 
340
  $method->setCost($display_fixedprice1);
 
341
  }
 
342
 
 
343
  $result->append($method);
 
344
 
 
345
  }
 
346
  else {
 
347
  //die('else');
 
348
 
 
349
 
 
350
 
 
351
  foreach($quotes_val as $key => $val) {
 
352
  // echo count($val); die;
 
353
  //echo $key.'<br>';
 
354
  //print_r($available_carriers);
 
355
 
 
356
  //usort($quotes_val, 'cmp1');
 
357
 
 
358
  $courier_title = $key;
 
359
  $courier_price = $quotes_val[$key]['total'];
 
360
 
 
361
  $method = Mage::getModel('shipping/rate_result_method');
 
362
  $method->setCarrier($this->_code);
 
363
  $method->setMethod($courier_title);
 
364
  $method->setCarrierTitle('Carriers');
 
365
 
 
366
  if($display_surcharge == '1'){
 
367
 
 
368
  $tmp_display_surcharge = $courier_price + $display_surcharge1;
 
369
  $tmp_method_title = $courier_title.' + Handling Charge';
 
370
 
 
371
  $method->setMethodTitle($tmp_method_title);
 
372
  $method->setPrice($tmp_display_surcharge);
 
373
  $method->setCost($tmp_display_surcharge);
 
374
 
 
375
  } else {
 
376
 
 
377
  if(in_array($key,$available_carriers)) {
 
378
  //echo '<br>'.$key . ' - matched<br>';
 
379
  $method->setMethodTitle($courier_title);
 
380
  $method->setPrice($courier_price);
 
381
  $method->setCost($courier_price);
 
382
  } else {
 
383
  //echo '<br>'.$key . ' - not found<br>';
 
384
  }
 
385
 
 
386
 
 
387
 
 
388
  }
 
389
 
 
390
  $result->append($method);
 
391
 
 
392
  }
 
393
  //die('arr');
 
394
  }
395
 
 
 
396
 
 
397
  //echo '<pre>'; print_r($result); //die('model');
398
 
 
 
399
  }else{
 
400
  $error = Mage::getModel('shipping/rate_result_error');
 
401
  $error->setCarrier($this->_code);
 
402
  $error->setCarrierTitle('Carrier Title');
 
403
  $error->setErrorMessage('Error');
 
404
  $result->append($error);
 
405
  }
 
406
 
 
407
  //return $result;
 
408
 
 
409
 
 
410
  //$this->renderLayout();
 
411
  $this->_getQuote()->save();
 
412
  $this->_goBack();
 
413
 
 
414
  $this->_redirectReferer();
415
 
 
 
416
  return $this;
 
417
  }
 
418
 
 
419
  function productAction(){
 
420
  $country = (string) $this->getRequest()->getParam('country_id');
 
421
  $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
 
422
  $city = (string) $this->getRequest()->getParam('estimate_city');
 
423
  $regionId = (string) $this->getRequest()->getParam('region_id');
 
424
  $region = (string) $this->getRequest()->getParam('region');
425
 
 
 
426
  $this->_getQuote()->getShippingAddress()
 
427
  ->setCountryId($country)
 
428
  ->setCity($city)
 
429
  ->setPostcode($postcode)
 
430
  ->setRegionId($regionId)
 
431
  ->setRegion($region)
 
432
  ->setCollectShippingRates(true);
 
433
  $this->_getQuote()->save();
 
434
  $this->_goBack();
 
435
  //$this->_redirectReferer();
 
436
 
 
437
  }
 
438
 
 
439
 
 
440
 
 
441
  }
1
  <?php
2
+
3
  class Transdirect_Ship_IndexController extends Mage_Core_Controller_Front_Action
4
+
5
  {
6
 
7
+
8
+
9
  protected function _getCart()
10
+
11
  {
12
+
13
  return Mage::getSingleton('checkout/cart');
14
+
15
  }
16
 
17
+
18
+
19
  /**
20
+
21
  * Get checkout session model instance
22
+
23
  *
24
+
25
  * @return Mage_Checkout_Model_Session
26
+
27
  */
28
+
29
  protected function _getSession()
30
+
31
  {
32
+
33
  return Mage::getSingleton('checkout/session');
34
+
35
  }
36
 
37
+
38
+
39
  /**
40
+
41
  * Get current active quote instance
42
+
43
  *
44
+
45
  * @return Mage_Sales_Model_Quote
46
+
47
  */
48
+
49
  protected function _getQuote()
50
+
51
  {
52
+
53
 
54
+
55
  return $this->_getCart()->getQuote();
56
+
57
  }
58
+
59
 
60
+
61
  protected function _goBack()
62
+
63
  {
64
+
65
  $returnUrl = $this->getRequest()->getParam('return_url');
66
+
67
  if ($returnUrl) {
68
+
69
  //die('if');
70
+
71
 
72
+
73
  if (!$this->_isUrlInternal($returnUrl)) {
74
+
75
  throw new Mage_Exception('External urls redirect to "' . $returnUrl . '" denied!');
76
+
77
  }
78
 
79
+
80
+
81
  $this->_getSession()->getMessages(true);
82
+
83
  $this->getResponse()->setRedirect($returnUrl);
84
+
85
  } elseif (!Mage::getStoreConfig('checkout/cart/redirect_to_cart')
86
+
87
 
88
+
89
  && !$this->getRequest()->getParam('in_cart')
90
+
91
  && $backUrl = $this->_getRefererUrl()
92
+
93
  ) {// die('else if');
94
+
95
  $this->getResponse()->setRedirect($backUrl);
96
+
97
  } else {
98
+
99
  //die('else');
100
+
101
 
102
+
103
  if (($this->getRequest()->getActionName() == 'add') && !$this->getRequest()->getParam('in_cart')) {
104
+
105
  $this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
106
+
107
  }
108
+
109
  $this->_redirect('checkout/cart');
110
+
111
  //die('go back');
112
+
113
  //$this->_redirectReferer();
114
+
115
  }
116
+
117
  return $this;
118
+
119
  }
120
 
121
+
122
+
123
  function indexAction()
124
+
125
  {
126
+
127
  //die('index');
128
+
129
 
130
+
131
  //$this->loadLayout();
132
+
133
 
134
+
135
  $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
136
+
137
  $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
138
+
139
  $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
140
+
141
  $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
142
+
143
  $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
144
+
145
  $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
146
+
147
  $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
148
+
149
  $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
150
+
151
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
152
+
153
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
154
+
155
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
156
+
157
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
158
+
159
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
160
+
161
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
162
+
163
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
164
+
165
  $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
166
+
167
 
168
 
169
+
170
+
171
  // Cart Total Weight Code Start by Nayan
172
+
173
 
174
+
175
  $quote = Mage::getSingleton('checkout/session')->getQuote();
176
+
177
  $cartItems = $quote->getAllVisibleItems();
178
+
179
  //$total_qty = Mage::helper('checkout/cart')->getSummaryCount();
180
+
181
  $total_qty = '1';
182
 
183
+
184
+
185
  /* if(Mage::registry('current_product')) {
186
+
187
  //this is a product page, do some stuff
188
+
189
  die('product');
190
+
191
  }
192
+
193
  else {
194
+
195
  die('not product');
196
+
197
  }
198
+
199
 
200
+
201
  echo Mage::app()->getFrontController()->getRequest()->getRouteName();
202
+
203
  die('name');*/
204
+
205
 
206
+
207
  $weight = 0;
208
+
209
  $height = 0;
210
+
211
  $width = 0;
212
+
213
  $length = 0;
214
+
215
  foreach ($cartItems as $item)
216
+
217
  {
218
+
219
  //echo '<pre>'; print_r($item->getQty()); die;
220
+
221
  $productId = $item->getProductId();
222
+
223
  $productQty = $item->getQty();
224
 
225
+
226
+
227
  $product = Mage::getModel('catalog/product')->load($productId);
228
+
229
  //echo $product->getItemWeight();
230
+
231
  $weight += $product->getItemWeight() * $productQty;
232
+
233
  $height += $product->getItemHeight() * $productQty;
234
+
235
  $width += $product->getItemWidth() * $productQty;
236
+
237
  $length += $product->getItemDim() * $productQty;
238
+
239
  }
240
+
241
 
242
+
243
  $product = Mage::getModel('catalog/product')->load($productId);
244
+
245
 
246
+
247
  $cart_total_weight = $product->getItemWeight();
248
+
249
  $cart_total_height = $product->getItemHeight();
250
+
251
  $cart_total_width = $product->getItemWidth();
252
+
253
  $cart_total_length = $product->getItemDim();
254
+
255
 
256
+
257
  // Cart Total Weight Code End by Nayan
258
 
259
+
260
+
261
 
262
+
263
  if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
264
+
265
  if(!$cart_total_height){ $cart_total_height = $dimension_height; }
266
+
267
  if(!$cart_total_width){ $cart_total_width = $dimension_width; }
268
+
269
  if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
270
 
271
+
272
+
273
  /* echo 'width--'.$cart_total_weight;
274
+
275
  echo 'height---'.$cart_total_height;
276
+
277
  echo 'width---'.$cart_total_width;
278
+
279
  echo 'length---'.$cart_total_length;
280
+
281
  die('here');
282
+
283
  */
284
 
285
+
286
+
287
  // Getting Cart page Quote Address Details Code Start by Nayan
288
 
289
+
290
+
291
  $receiver_country = (string) $this->getRequest()->getParam('country_id');
292
+
293
  $receiver_postcode = (string) $this->getRequest()->getParam('estimate_postcode');
294
+
295
  $receiver_regionId = (string) $this->getRequest()->getParam('region_id');
296
+
297
  $receiver_region = (string) $this->getRequest()->getParam('region');
298
 
299
+
300
+
301
  $region = Mage::getModel('directory/region')->load($receiver_regionId);
302
+
303
  $receiver_region_tmp = $region->getName();
304
+
305
 
306
+
307
  /*if($receiver_region == '') {
308
+
309
  Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
310
+
311
  session_write_close();
312
+
313
  $this->_redirectReferer();
314
+
315
  }*/
316
+
317
 
318
+
319
  /*if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
320
+
321
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
322
+
323
  session_write_close();
324
+
325
  $this->_redirectReferer();
326
+
327
  }*/
328
+
329
 
330
+
331
  if(!$receiver_regionId)
332
+
333
  {
334
+
335
  $receiver_suburb = $receiver_region;
336
+
337
  }
338
+
339
  else
340
+
341
  {
342
+
343
  $receiver_suburb = $receiver_region_tmp;
344
+
345
  }
346
+
347
 
348
+
349
 
350
+
351
  $receiver_postcode = $_COOKIE['cart_postocde'];
352
+
353
  $receiver_suburb = $_COOKIE['cart_locality'];
354
+
355
 
356
+
357
  //echo $receiver_suburb; die('suburb');
358
+
359
 
360
+
361
  // Getting Cart page Quote Address Details Code End by Nayan
362
 
363
+
364
+
365
  $quoteDetails = array(
366
+
367
  'declared_value'=>10000,
368
+
369
  'items' => array
370
+
371
  (
372
+
373
  array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
374
+
375
  ),
376
+
377
  'sender' => array('country' => 'AU', 'suburb'=>'SYDNEY', 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
378
+
379
  'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
380
+
381
  );
382
 
383
+
384
+
385
  $json_data = json_encode($quoteDetails);
386
+
387
  //echo '<pre>'; print_r($json_data); die('encode');
388
+
389
 
390
+
391
  $ch = curl_init();
392
+
393
  curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
394
+
395
  //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
396
+
397
  curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
398
+
399
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
400
+
401
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
402
+
403
  curl_setopt($ch, CURLOPT_POST, TRUE);
404
+
405
  curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
406
+
407
  curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
408
+
409
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
410
+
411
  $response = curl_exec($ch);
412
+
413
 
414
+
415
  $report = curl_getinfo($ch);
416
+
417
  //echo '<pre>'; print_r($report);
418
+
419
 
420
+
421
  if(curl_errno($ch)) {
422
+
423
  echo 'Response error: ' . curl_error($ch);
424
+
425
  }
426
+
427
 
428
+
429
  curl_close($ch);
430
+
431
 
432
+
433
  if ($response) {
434
+
435
  //echo '<pre>'.$response;
436
+
437
 
438
+
439
 
440
+
441
 
442
+
443
  $json_decode_varible = json_decode($response, true);
444
+
445
 
446
+
447
  $quotes_val = $json_decode_varible['quotes'];
448
+
449
  //echo "<pre>"; print_r($quotes_val); die('decode');
450
+
451
 
452
+
453
 
454
+
455
  // Passing Data from Controller to Template file code Start
456
+
457
 
458
+
459
 
460
+
461
  //$quotes_val = Mage::register('quotes_val', $quotes_val);
462
+
463
 
464
+
465
  // End
466
+
467
 
468
+
469
  Mage::getSingleton('core/session')->unsSomeSessionVar();
470
+
471
  Mage::getSingleton('core/session')->unsCountryVal();
472
+
473
  Mage::getSingleton('core/session')->unsPostcodeVal();
474
+
475
  Mage::getSingleton('core/session')->unsRegionIdVal();
476
+
477
  Mage::getSingleton('core/session')->unsRegionVal();
478
+
479
 
480
+
481
  $country = (string) $this->getRequest()->getParam('country_id');
482
+
483
  $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
484
+
485
  $regionId = (string) $this->getRequest()->getParam('region_id');
486
+
487
  $region = (string) $this->getRequest()->getParam('region');
488
+
489
 
490
+
491
  //echo $country. $postcode . $city . $regionId . $region; die('data');
492
+
493
 
494
+
495
  //echo "<pre>"; print_r($quotes_val);
496
+
497
 
498
+
499
+ /*function build_sorter($key) {
500
+
501
  return function ($a, $b) use ($key) {
502
+
503
  return strnatcmp($a[$key], $b[$key]);
504
+
505
  };
506
+
507
+ }*/
508
+
509
 
510
+
511
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
512
+
513
 
514
+
515
+ //if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
516
+
517
+ //if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
518
+
519
 
520
+
521
  //echo "<pre>"; print_r($quotes_val); die('after');
522
+
523
 
524
+
525
  $session_val = Mage::getSingleton('core/session')->setSomeSessionVar($quotes_val); // In the Controller
526
 
527
+
528
+
529
  $quote_form_country_val = Mage::getSingleton('core/session')->setCountryVal($country); // In the Controller
530
+
531
  $quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
532
+
533
  $quote_form_regionId_val = Mage::getSingleton('core/session')->setRegionIdVal($regionId); // In the Controller
534
+
535
  $quote_form_region_val = Mage::getSingleton('core/session')->setRegionVal($region); // In the Controller
536
+
537
 
538
+
539
 
540
+
541
 
542
+
543
  //echo '<pre>'; print_r($session_val->getSomeSessionVar());
544
+
545
  //die('set');
546
+
547
 
548
+
549
  /*
550
+
551
  foreach($quotes_val as $key => $val) {
552
+
553
  $courier_title = $key;
554
+
555
  $courier_price = $quotes_val[$key]['total'];
556
+
557
 
558
+
559
  // Mage::register('couriertitledisplay', $courier_title);
560
+
561
  // Mage::register('courierpricedisplay', $courier_price);
562
+
563
 
564
+
565
 
566
+
567
 
568
+
569
  $block = $this->getLayout()->createBlock(
570
+
571
  'Mage_Core_Block_Template',
572
+
573
  'ship.quotes',
574
+
575
  array(
576
+
577
  'template' => 'ship/quotes.phtml'
578
+
579
  )
580
+
581
  ) // NOTE - Custom Variables Below
582
+
583
  ->setData('courier_title', $courier_title)
584
+
585
  ->setData('courier_price', $courier_price);
586
+
587
 
588
+
589
 
590
+
591
  $this->getLayout()->getBlock('content')->append($block);
592
+
593
  }
594
+
595
  */
596
+
597
 
598
+
599
  } else {
600
+
601
  echo "Failed";
602
+
603
  }
604
+
605
 
606
+
607
 
608
+
609
  $available_carriers = explode( ',', $display_carriers);
610
 
611
+
612
+
613
  $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
614
+
615
  $result = Mage::getModel('shipping/rate_result');
616
+
617
  $show = true;
618
+
619
  if($show){
620
+
621
 
622
+
623
  //die('before');
624
+
625
  //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
626
+
627
 
628
+
629
  //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
630
+
631
  //echo $session->getSomeSessionVar();
632
 
633
+
634
+
635
  //echo '<pre>'; print_r($session->getSomeSessionVar());
636
+
637
  //die('after');
638
+
639
 
640
+
641
  if($quotes_val == ''){ //die('if');
642
+
643
  //echo $quote_form_postcode_val; die;
644
+
645
  /* if(!is_numeric($quote_form_postcode_val) || $quote_form_postcode_val == "0" || $quote_form_postcode_val == "00" || $quote_form_postcode_val == "000" || $quote_form_postcode_val == "0000" || $quote_form_postcode_val == "00000" || $quote_form_postcode_val == "000000" || $quote_form_postcode_val == "0000000") {
646
+
647
  Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
648
+
649
  } else {*/
650
+
651
+ // Mage::getSingleton('core/session')->addError("Please enter correct details, either suburb or postcode not entered properly.");
652
+
653
  //}
654
+
655
 
656
+
657
 
658
+
659
  //Mage::getSingleton('core/session')->addError("Please fill the information properly, there are some fields are missing or not entered properly.");
660
+
661
 
662
+
663
  $method = Mage::getModel('shipping/rate_result_method');
664
+
665
  $method->setCarrier($this->_code);
666
+
667
  $method->setMethod($this->_code);
668
+
669
  $method->setCarrierTitle('Carrier');
670
+
671
  $method->setMethodTitle('Fixed Price');
672
+
673
 
674
+
675
  if($display_fixedprice == '1'){
676
+
677
  $method->setPrice($display_fixedprice1);
678
+
679
  $method->setCost($display_fixedprice1);
680
+
681
  }
682
+
683
 
684
+
685
  $result->append($method);
686
+
687
 
688
+
689
  }
690
+
691
  else {
692
+
693
  //die('else');
694
+
695
 
696
+
697
 
698
+
699
 
700
+
701
  foreach($quotes_val as $key => $val) {
702
+
703
  // echo count($val); die;
704
+
705
  //echo $key.'<br>';
706
+
707
  //print_r($available_carriers);
708
+
709
 
710
+
711
  //usort($quotes_val, 'cmp1');
712
+
713
 
714
+
715
  $courier_title = $key;
716
+
717
  $courier_price = $quotes_val[$key]['total'];
718
+
719
 
720
+
721
  $method = Mage::getModel('shipping/rate_result_method');
722
+
723
  $method->setCarrier($this->_code);
724
+
725
  $method->setMethod($courier_title);
726
+
727
  $method->setCarrierTitle('Carriers');
728
+
729
 
730
+
731
  if($display_surcharge == '1'){
732
+
733
 
734
+
735
  $tmp_display_surcharge = $courier_price + $display_surcharge1;
736
+
737
  $tmp_method_title = $courier_title.' + Handling Charge';
738
+
739
 
740
+
741
  $method->setMethodTitle($tmp_method_title);
742
+
743
  $method->setPrice($tmp_display_surcharge);
744
+
745
  $method->setCost($tmp_display_surcharge);
746
+
747
 
748
+
749
  } else {
750
+
751
 
752
+
753
  if(in_array($key,$available_carriers)) {
754
+
755
  //echo '<br>'.$key . ' - matched<br>';
756
+
757
  $method->setMethodTitle($courier_title);
758
+
759
  $method->setPrice($courier_price);
760
+
761
  $method->setCost($courier_price);
762
+
763
  } else {
764
+
765
  //echo '<br>'.$key . ' - not found<br>';
766
+
767
  }
768
+
769
 
770
+
771
 
772
+
773
 
774
+
775
  }
776
+
777
 
778
+
779
  $result->append($method);
780
+
781
 
782
+
783
  }
784
+
785
  //die('arr');
786
+
787
  }
788
 
789
+
790
+
791
 
792
+
793
  //echo '<pre>'; print_r($result); //die('model');
794
 
795
+
796
+
797
  }else{
798
+
799
  $error = Mage::getModel('shipping/rate_result_error');
800
+
801
  $error->setCarrier($this->_code);
802
+
803
  $error->setCarrierTitle('Carrier Title');
804
+
805
  $error->setErrorMessage('Error');
806
+
807
  $result->append($error);
808
+
809
  }
810
+
811
 
812
+
813
  //return $result;
814
+
815
 
816
+
817
 
818
+
819
  //$this->renderLayout();
820
+
821
  $this->_getQuote()->save();
822
+
823
  $this->_goBack();
824
+
825
 
826
+
827
  $this->_redirectReferer();
828
 
829
+
830
+
831
  return $this;
832
+
833
  }
834
+
835
 
836
+
837
  function productAction(){
838
+
839
  $country = (string) $this->getRequest()->getParam('country_id');
840
+
841
  $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
842
+
843
  $city = (string) $this->getRequest()->getParam('estimate_city');
844
+
845
  $regionId = (string) $this->getRequest()->getParam('region_id');
846
+
847
  $region = (string) $this->getRequest()->getParam('region');
848
 
849
+
850
+
851
  $this->_getQuote()->getShippingAddress()
852
+
853
  ->setCountryId($country)
854
+
855
  ->setCity($city)
856
+
857
  ->setPostcode($postcode)
858
+
859
  ->setRegionId($regionId)
860
+
861
  ->setRegion($region)
862
+
863
  ->setCollectShippingRates(true);
864
+
865
  $this->_getQuote()->save();
866
+
867
  $this->_goBack();
868
+
869
  //$this->_redirectReferer();
870
+
871
 
872
+
873
  }
874
+
875
 
876
+
877
 
878
+
879
 
880
+
881
  }
app/code/local/Transdirect/Ship/controllers/bkp_29-5-2014---IndexController.php DELETED
@@ -1,412 +0,0 @@
1
- <?php
2
- class Transdirect_Ship_IndexController extends Mage_Core_Controller_Front_Action
3
- {
4
-
5
- protected function _getCart()
6
- {
7
- return Mage::getSingleton('checkout/cart');
8
- }
9
-
10
- /**
11
- * Get checkout session model instance
12
- *
13
- * @return Mage_Checkout_Model_Session
14
- */
15
- protected function _getSession()
16
- {
17
- return Mage::getSingleton('checkout/session');
18
- }
19
-
20
- /**
21
- * Get current active quote instance
22
- *
23
- * @return Mage_Sales_Model_Quote
24
- */
25
- protected function _getQuote()
26
- {
27
-
28
- return $this->_getCart()->getQuote();
29
- }
30
-
31
- protected function _goBack()
32
- {
33
- $returnUrl = $this->getRequest()->getParam('return_url');
34
- if ($returnUrl) {
35
- //die('if');
36
-
37
- if (!$this->_isUrlInternal($returnUrl)) {
38
- throw new Mage_Exception('External urls redirect to "' . $returnUrl . '" denied!');
39
- }
40
-
41
- $this->_getSession()->getMessages(true);
42
- $this->getResponse()->setRedirect($returnUrl);
43
- } elseif (!Mage::getStoreConfig('checkout/cart/redirect_to_cart')
44
-
45
- && !$this->getRequest()->getParam('in_cart')
46
- && $backUrl = $this->_getRefererUrl()
47
- ) {// die('else if');
48
- $this->getResponse()->setRedirect($backUrl);
49
- } else {
50
- //die('else');
51
-
52
- if (($this->getRequest()->getActionName() == 'add') && !$this->getRequest()->getParam('in_cart')) {
53
- $this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
54
- }
55
- $this->_redirect('checkout/cart');
56
- //die('go back');
57
- //$this->_redirectReferer();
58
- }
59
- return $this;
60
- }
61
-
62
- function indexAction()
63
- {
64
- //die('index');
65
-
66
- //$this->loadLayout();
67
-
68
- $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
69
- $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
70
- $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
71
- $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
72
- $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
73
- $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
74
- $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
75
- $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
76
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
77
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
78
- $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
79
- $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
80
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
81
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
82
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
83
- $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
84
-
85
-
86
- // Cart Total Weight Code Start by Nayan
87
-
88
- $quote = Mage::getSingleton('checkout/session')->getQuote();
89
- $cartItems = $quote->getAllVisibleItems();
90
- //$total_qty = Mage::helper('checkout/cart')->getSummaryCount();
91
- $total_qty = '1';
92
-
93
- /* if(Mage::registry('current_product')) {
94
- //this is a product page, do some stuff
95
- die('product');
96
- }
97
- else {
98
- die('not product');
99
- }
100
-
101
- echo Mage::app()->getFrontController()->getRequest()->getRouteName();
102
- die('name');*/
103
-
104
- $weight = 0;
105
- $height = 0;
106
- $width = 0;
107
- $length = 0;
108
- foreach ($cartItems as $item)
109
- {
110
- //echo '<pre>'; print_r($item->getQty()); die;
111
- $productId = $item->getProductId();
112
- $productQty = $item->getQty();
113
-
114
- $product = Mage::getModel('catalog/product')->load($productId);
115
- //echo $product->getItemWeight();
116
- $weight += $product->getItemWeight() * $productQty;
117
- $height += $product->getItemHeight() * $productQty;
118
- $width += $product->getItemWidth() * $productQty;
119
- $length += $product->getItemDim() * $productQty;
120
- }
121
-
122
- $cart_total_weight = $weight;
123
- $cart_total_height = $height;
124
- $cart_total_width = $width;
125
- $cart_total_length = $length;
126
-
127
- // Cart Total Weight Code End by Nayan
128
-
129
-
130
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
131
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
132
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
133
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
134
-
135
- /* echo 'width--'.$cart_total_weight;
136
- echo 'height---'.$cart_total_height;
137
- echo 'width---'.$cart_total_width;
138
- echo 'length---'.$cart_total_length;
139
- die('here');
140
- */
141
-
142
- // Getting Cart page Quote Address Details Code Start by Nayan
143
-
144
- $receiver_country = (string) $this->getRequest()->getParam('country_id');
145
- $receiver_postcode = (string) $this->getRequest()->getParam('estimate_postcode');
146
- $receiver_regionId = (string) $this->getRequest()->getParam('region_id');
147
- $receiver_region = (string) $this->getRequest()->getParam('region');
148
-
149
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
150
- $receiver_region_tmp = $region->getName();
151
-
152
- if($receiver_region == '') {
153
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
154
- session_write_close();
155
- $this->_redirectReferer();
156
- }
157
-
158
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
159
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
160
- session_write_close();
161
- $this->_redirectReferer();
162
- }
163
-
164
- if(!$receiver_regionId)
165
- {
166
- $receiver_suburb = $receiver_region;
167
- }
168
- else
169
- {
170
- $receiver_suburb = $receiver_region_tmp;
171
- }
172
-
173
-
174
- //echo $receiver_suburb; die('suburb');
175
-
176
- // Getting Cart page Quote Address Details Code End by Nayan
177
-
178
- $quoteDetails = array(
179
- 'declared_value'=>10000,
180
- 'items' => array
181
- (
182
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
183
- ),
184
- 'sender' => array('country' => 'AU', 'suburb'=>'SYDNEY', 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
185
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
186
- );
187
-
188
- $json_data = json_encode($quoteDetails);
189
- //echo '<pre>'; print_r($json_data); die('encode');
190
-
191
- $ch = curl_init();
192
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
193
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
194
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
195
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
196
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
197
- curl_setopt($ch, CURLOPT_POST, TRUE);
198
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
199
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
200
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
201
- $response = curl_exec($ch);
202
-
203
- $report = curl_getinfo($ch);
204
- //echo '<pre>'; print_r($report);
205
-
206
- if(curl_errno($ch)) {
207
- echo 'Response error: ' . curl_error($ch);
208
- }
209
-
210
- curl_close($ch);
211
-
212
- if ($response) {
213
- //echo '<pre>'.$response;
214
-
215
-
216
-
217
- $json_decode_varible = json_decode($response, true);
218
-
219
- $quotes_val = $json_decode_varible['quotes'];
220
- //echo "<pre>"; print_r($quotes_val); die('decode');
221
-
222
-
223
- // Passing Data from Controller to Template file code Start
224
-
225
-
226
- //$quotes_val = Mage::register('quotes_val', $quotes_val);
227
-
228
- // End
229
-
230
- Mage::getSingleton('core/session')->unsSomeSessionVar();
231
- Mage::getSingleton('core/session')->unsCountryVal();
232
- Mage::getSingleton('core/session')->unsPostcodeVal();
233
- Mage::getSingleton('core/session')->unsRegionIdVal();
234
- Mage::getSingleton('core/session')->unsRegionVal();
235
-
236
- $country = (string) $this->getRequest()->getParam('country_id');
237
- $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
238
- $regionId = (string) $this->getRequest()->getParam('region_id');
239
- $region = (string) $this->getRequest()->getParam('region');
240
-
241
- //echo $country. $postcode . $city . $regionId . $region; die('data');
242
-
243
- $session_val = Mage::getSingleton('core/session')->setSomeSessionVar($quotes_val); // In the Controller
244
-
245
- $quote_form_country_val = Mage::getSingleton('core/session')->setCountryVal($country); // In the Controller
246
- $quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
247
- $quote_form_regionId_val = Mage::getSingleton('core/session')->setRegionIdVal($regionId); // In the Controller
248
- $quote_form_region_val = Mage::getSingleton('core/session')->setRegionVal($region); // In the Controller
249
-
250
-
251
-
252
- //echo '<pre>'; print_r($session_val->getSomeSessionVar());
253
- //die('set');
254
-
255
- /*
256
- foreach($quotes_val as $key => $val) {
257
- $courier_title = $key;
258
- $courier_price = $quotes_val[$key]['total'];
259
-
260
- // Mage::register('couriertitledisplay', $courier_title);
261
- // Mage::register('courierpricedisplay', $courier_price);
262
-
263
-
264
-
265
- $block = $this->getLayout()->createBlock(
266
- 'Mage_Core_Block_Template',
267
- 'ship.quotes',
268
- array(
269
- 'template' => 'ship/quotes.phtml'
270
- )
271
- ) // NOTE - Custom Variables Below
272
- ->setData('courier_title', $courier_title)
273
- ->setData('courier_price', $courier_price);
274
-
275
-
276
- $this->getLayout()->getBlock('content')->append($block);
277
- }
278
- */
279
-
280
- } else {
281
- echo "Failed";
282
- }
283
-
284
-
285
- $available_carriers = explode( ',', $display_carriers);
286
-
287
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
288
- $result = Mage::getModel('shipping/rate_result');
289
- $show = true;
290
- if($show){
291
-
292
- //die('before');
293
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
294
-
295
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
296
- //echo $session->getSomeSessionVar();
297
-
298
- //echo '<pre>'; print_r($session->getSomeSessionVar());
299
- //die('after');
300
-
301
- if($quotes_val == ''){ //die('if');
302
-
303
- $method = Mage::getModel('shipping/rate_result_method');
304
- $method->setCarrier($this->_code);
305
- $method->setMethod($this->_code);
306
- $method->setCarrierTitle('Carrier');
307
- $method->setMethodTitle('Fixed Price');
308
-
309
- if($display_fixedprice == '1'){
310
- $method->setPrice($display_fixedprice1);
311
- $method->setCost($display_fixedprice1);
312
- }
313
-
314
- $result->append($method);
315
-
316
- }
317
- else {
318
- //die('else');
319
-
320
-
321
-
322
- foreach($quotes_val as $key => $val) {
323
- // echo count($val); die;
324
- //echo $key.'<br>';
325
- //print_r($available_carriers);
326
-
327
- //usort($quotes_val, 'cmp1');
328
-
329
- $courier_title = $key;
330
- $courier_price = $quotes_val[$key]['total'];
331
-
332
- $method = Mage::getModel('shipping/rate_result_method');
333
- $method->setCarrier($this->_code);
334
- $method->setMethod($courier_title);
335
- $method->setCarrierTitle('Carriers');
336
-
337
- if($display_surcharge == '1'){
338
-
339
- $tmp_display_surcharge = $courier_price + $display_surcharge1;
340
- $tmp_method_title = $courier_title.' + Handling Charge';
341
-
342
- $method->setMethodTitle($tmp_method_title);
343
- $method->setPrice($tmp_display_surcharge);
344
- $method->setCost($tmp_display_surcharge);
345
-
346
- } else {
347
-
348
- if(in_array($key,$available_carriers)) {
349
- //echo '<br>'.$key . ' - matched<br>';
350
- $method->setMethodTitle($courier_title);
351
- $method->setPrice($courier_price);
352
- $method->setCost($courier_price);
353
- } else {
354
- //echo '<br>'.$key . ' - not found<br>';
355
- }
356
-
357
-
358
-
359
- }
360
-
361
- $result->append($method);
362
-
363
- }
364
- //die('arr');
365
- }
366
-
367
-
368
- //echo '<pre>'; print_r($result); //die('model');
369
-
370
- }else{
371
- $error = Mage::getModel('shipping/rate_result_error');
372
- $error->setCarrier($this->_code);
373
- $error->setCarrierTitle('Carrier Title');
374
- $error->setErrorMessage('Error');
375
- $result->append($error);
376
- }
377
-
378
- //return $result;
379
-
380
-
381
- //$this->renderLayout();
382
- $this->_getQuote()->save();
383
- $this->_goBack();
384
-
385
- $this->_redirectReferer();
386
-
387
- return $this;
388
- }
389
-
390
- function productAction(){
391
- $country = (string) $this->getRequest()->getParam('country_id');
392
- $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
393
- $city = (string) $this->getRequest()->getParam('estimate_city');
394
- $regionId = (string) $this->getRequest()->getParam('region_id');
395
- $region = (string) $this->getRequest()->getParam('region');
396
-
397
- $this->_getQuote()->getShippingAddress()
398
- ->setCountryId($country)
399
- ->setCity($city)
400
- ->setPostcode($postcode)
401
- ->setRegionId($regionId)
402
- ->setRegion($region)
403
- ->setCollectShippingRates(true);
404
- $this->_getQuote()->save();
405
- $this->_goBack();
406
- //$this->_redirectReferer();
407
-
408
- }
409
-
410
-
411
-
412
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/controllers/bkp_30-5-2014----IndexController.php DELETED
@@ -1,427 +0,0 @@
1
- <?php
2
- class Transdirect_Ship_IndexController extends Mage_Core_Controller_Front_Action
3
- {
4
-
5
- protected function _getCart()
6
- {
7
- return Mage::getSingleton('checkout/cart');
8
- }
9
-
10
- /**
11
- * Get checkout session model instance
12
- *
13
- * @return Mage_Checkout_Model_Session
14
- */
15
- protected function _getSession()
16
- {
17
- return Mage::getSingleton('checkout/session');
18
- }
19
-
20
- /**
21
- * Get current active quote instance
22
- *
23
- * @return Mage_Sales_Model_Quote
24
- */
25
- protected function _getQuote()
26
- {
27
-
28
- return $this->_getCart()->getQuote();
29
- }
30
-
31
- protected function _goBack()
32
- {
33
- $returnUrl = $this->getRequest()->getParam('return_url');
34
- if ($returnUrl) {
35
- //die('if');
36
-
37
- if (!$this->_isUrlInternal($returnUrl)) {
38
- throw new Mage_Exception('External urls redirect to "' . $returnUrl . '" denied!');
39
- }
40
-
41
- $this->_getSession()->getMessages(true);
42
- $this->getResponse()->setRedirect($returnUrl);
43
- } elseif (!Mage::getStoreConfig('checkout/cart/redirect_to_cart')
44
-
45
- && !$this->getRequest()->getParam('in_cart')
46
- && $backUrl = $this->_getRefererUrl()
47
- ) {// die('else if');
48
- $this->getResponse()->setRedirect($backUrl);
49
- } else {
50
- //die('else');
51
-
52
- if (($this->getRequest()->getActionName() == 'add') && !$this->getRequest()->getParam('in_cart')) {
53
- $this->_getSession()->setContinueShoppingUrl($this->_getRefererUrl());
54
- }
55
- $this->_redirect('checkout/cart');
56
- //die('go back');
57
- //$this->_redirectReferer();
58
- }
59
- return $this;
60
- }
61
-
62
- function indexAction()
63
- {
64
- //die('index');
65
-
66
- //$this->loadLayout();
67
-
68
- $account_email = Mage::getStoreConfig('transdirect_section/authentication/email');
69
- $account_password = Mage::getStoreConfig('transdirect_section/authentication/password');
70
- $warehouse_postcode = Mage::getStoreConfig('transdirect_section/warehouseaddress/postcode');
71
- $warehouse_address = Mage::getStoreConfig('transdirect_section/warehouseaddress/address');
72
- $dimension_width = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionswidth');
73
- $dimension_height = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsheight');
74
- $dimension_dim = Mage::getStoreConfig('transdirect_section/defaultitemsize/dimensionsdim');
75
- $dimension_weight = Mage::getStoreConfig('transdirect_section/defaultitemsize/weight');
76
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
77
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
78
- $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
79
- $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
80
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
81
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
82
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
83
- $display_includesurchage = Mage::getStoreConfig('transdirect_section/displayoptions/includesurcharge');
84
-
85
-
86
- // Cart Total Weight Code Start by Nayan
87
-
88
- $quote = Mage::getSingleton('checkout/session')->getQuote();
89
- $cartItems = $quote->getAllVisibleItems();
90
- //$total_qty = Mage::helper('checkout/cart')->getSummaryCount();
91
- $total_qty = '1';
92
-
93
- /* if(Mage::registry('current_product')) {
94
- //this is a product page, do some stuff
95
- die('product');
96
- }
97
- else {
98
- die('not product');
99
- }
100
-
101
- echo Mage::app()->getFrontController()->getRequest()->getRouteName();
102
- die('name');*/
103
-
104
- $weight = 0;
105
- $height = 0;
106
- $width = 0;
107
- $length = 0;
108
- foreach ($cartItems as $item)
109
- {
110
- //echo '<pre>'; print_r($item->getQty()); die;
111
- $productId = $item->getProductId();
112
- $productQty = $item->getQty();
113
-
114
- $product = Mage::getModel('catalog/product')->load($productId);
115
- //echo $product->getItemWeight();
116
- $weight += $product->getItemWeight() * $productQty;
117
- $height += $product->getItemHeight() * $productQty;
118
- $width += $product->getItemWidth() * $productQty;
119
- $length += $product->getItemDim() * $productQty;
120
- }
121
-
122
- $cart_total_weight = $weight;
123
- $cart_total_height = $height;
124
- $cart_total_width = $width;
125
- $cart_total_length = $length;
126
-
127
- // Cart Total Weight Code End by Nayan
128
-
129
-
130
- if(!$cart_total_weight){ $cart_total_weight = $dimension_weight; }
131
- if(!$cart_total_height){ $cart_total_height = $dimension_height; }
132
- if(!$cart_total_width){ $cart_total_width = $dimension_width; }
133
- if(!$cart_total_length){ $cart_total_length = $dimension_dim; }
134
-
135
- /* echo 'width--'.$cart_total_weight;
136
- echo 'height---'.$cart_total_height;
137
- echo 'width---'.$cart_total_width;
138
- echo 'length---'.$cart_total_length;
139
- die('here');
140
- */
141
-
142
- // Getting Cart page Quote Address Details Code Start by Nayan
143
-
144
- $receiver_country = (string) $this->getRequest()->getParam('country_id');
145
- $receiver_postcode = (string) $this->getRequest()->getParam('estimate_postcode');
146
- $receiver_regionId = (string) $this->getRequest()->getParam('region_id');
147
- $receiver_region = (string) $this->getRequest()->getParam('region');
148
-
149
- $region = Mage::getModel('directory/region')->load($receiver_regionId);
150
- $receiver_region_tmp = $region->getName();
151
-
152
- if($receiver_region == '') {
153
- Mage::getSingleton('checkout/session')->addError("Please enter state/province.");
154
- session_write_close();
155
- $this->_redirectReferer();
156
- }
157
-
158
- if(!is_numeric($receiver_postcode) || $receiver_postcode == "0" || $receiver_postcode == "00" || $receiver_postcode == "000" || $receiver_postcode == "0000" || $receiver_postcode == "00000" || $receiver_postcode == "000000" || $receiver_postcode == "0000000") {
159
- Mage::getSingleton('checkout/session')->addError("Please enter valid and correct postcode.");
160
- session_write_close();
161
- $this->_redirectReferer();
162
- }
163
-
164
- if(!$receiver_regionId)
165
- {
166
- $receiver_suburb = $receiver_region;
167
- }
168
- else
169
- {
170
- $receiver_suburb = $receiver_region_tmp;
171
- }
172
-
173
-
174
- //echo $receiver_suburb; die('suburb');
175
-
176
- // Getting Cart page Quote Address Details Code End by Nayan
177
-
178
- $quoteDetails = array(
179
- 'declared_value'=>10000,
180
- 'items' => array
181
- (
182
- array('width' => $cart_total_width, 'height' => $cart_total_height, 'weight'=> $cart_total_weight, 'length'=> $cart_total_length, 'quantity'=>$total_qty, 'description'=>'item description')
183
- ),
184
- 'sender' => array('country' => 'AU', 'suburb'=>'SYDNEY', 'postcode' => $warehouse_postcode, 'type'=> $warehouse_address),
185
- 'receiver' => array('country' => $receiver_country, 'suburb'=>$receiver_suburb, 'postcode' => $receiver_postcode, 'type'=> 'residential')
186
- );
187
-
188
- $json_data = json_encode($quoteDetails);
189
- //echo '<pre>'; print_r($json_data); die('encode');
190
-
191
- $ch = curl_init();
192
- curl_setopt($ch, CURLOPT_URL, "https://www.staging.transdirect.com.au/api/bookings");
193
- //curl_setopt($ch, CURLOPT_URL, "https://www.transdirect.com.au/api/bookings");
194
- curl_setopt($ch, CURLOPT_USERPWD, "$account_email:$account_password");
195
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
196
- curl_setopt($ch, CURLOPT_HEADER, FALSE);
197
- curl_setopt($ch, CURLOPT_POST, TRUE);
198
- curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
199
- curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
200
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
201
- $response = curl_exec($ch);
202
-
203
- $report = curl_getinfo($ch);
204
- //echo '<pre>'; print_r($report);
205
-
206
- if(curl_errno($ch)) {
207
- echo 'Response error: ' . curl_error($ch);
208
- }
209
-
210
- curl_close($ch);
211
-
212
- if ($response) {
213
- //echo '<pre>'.$response;
214
-
215
-
216
-
217
- $json_decode_varible = json_decode($response, true);
218
-
219
- $quotes_val = $json_decode_varible['quotes'];
220
- //echo "<pre>"; print_r($quotes_val); die('decode');
221
-
222
-
223
- // Passing Data from Controller to Template file code Start
224
-
225
-
226
- //$quotes_val = Mage::register('quotes_val', $quotes_val);
227
-
228
- // End
229
-
230
- Mage::getSingleton('core/session')->unsSomeSessionVar();
231
- Mage::getSingleton('core/session')->unsCountryVal();
232
- Mage::getSingleton('core/session')->unsPostcodeVal();
233
- Mage::getSingleton('core/session')->unsRegionIdVal();
234
- Mage::getSingleton('core/session')->unsRegionVal();
235
-
236
- $country = (string) $this->getRequest()->getParam('country_id');
237
- $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
238
- $regionId = (string) $this->getRequest()->getParam('region_id');
239
- $region = (string) $this->getRequest()->getParam('region');
240
-
241
- //echo $country. $postcode . $city . $regionId . $region; die('data');
242
-
243
- //echo "<pre>"; print_r($quotes_val);
244
-
245
- function build_sorter($key) {
246
- return function ($a, $b) use ($key) {
247
- return strnatcmp($a[$key], $b[$key]);
248
- };
249
- }
250
-
251
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
252
-
253
- if($display_quote == 'display_cheapest'){ uasort($quotes_val, build_sorter('total')); }
254
- if($display_quote == 'display_cheapest_fastest'){ uasort($quotes_val, build_sorter('transit_time')); }
255
-
256
- //echo "<pre>"; print_r($quotes_val); die('after');
257
-
258
- $session_val = Mage::getSingleton('core/session')->setSomeSessionVar($quotes_val); // In the Controller
259
-
260
- $quote_form_country_val = Mage::getSingleton('core/session')->setCountryVal($country); // In the Controller
261
- $quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
262
- $quote_form_regionId_val = Mage::getSingleton('core/session')->setRegionIdVal($regionId); // In the Controller
263
- $quote_form_region_val = Mage::getSingleton('core/session')->setRegionVal($region); // In the Controller
264
-
265
-
266
-
267
- //echo '<pre>'; print_r($session_val->getSomeSessionVar());
268
- //die('set');
269
-
270
- /*
271
- foreach($quotes_val as $key => $val) {
272
- $courier_title = $key;
273
- $courier_price = $quotes_val[$key]['total'];
274
-
275
- // Mage::register('couriertitledisplay', $courier_title);
276
- // Mage::register('courierpricedisplay', $courier_price);
277
-
278
-
279
-
280
- $block = $this->getLayout()->createBlock(
281
- 'Mage_Core_Block_Template',
282
- 'ship.quotes',
283
- array(
284
- 'template' => 'ship/quotes.phtml'
285
- )
286
- ) // NOTE - Custom Variables Below
287
- ->setData('courier_title', $courier_title)
288
- ->setData('courier_price', $courier_price);
289
-
290
-
291
- $this->getLayout()->getBlock('content')->append($block);
292
- }
293
- */
294
-
295
- } else {
296
- echo "Failed";
297
- }
298
-
299
-
300
- $available_carriers = explode( ',', $display_carriers);
301
-
302
- $handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
303
- $result = Mage::getModel('shipping/rate_result');
304
- $show = true;
305
- if($show){
306
-
307
- //die('before');
308
- //$quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
309
-
310
- //$session = Mage::getSingleton('core/session', array('name' => 'frontend'));
311
- //echo $session->getSomeSessionVar();
312
-
313
- //echo '<pre>'; print_r($session->getSomeSessionVar());
314
- //die('after');
315
-
316
- if($quotes_val == ''){ //die('if');
317
-
318
- $method = Mage::getModel('shipping/rate_result_method');
319
- $method->setCarrier($this->_code);
320
- $method->setMethod($this->_code);
321
- $method->setCarrierTitle('Carrier');
322
- $method->setMethodTitle('Fixed Price');
323
-
324
- if($display_fixedprice == '1'){
325
- $method->setPrice($display_fixedprice1);
326
- $method->setCost($display_fixedprice1);
327
- }
328
-
329
- $result->append($method);
330
-
331
- }
332
- else {
333
- //die('else');
334
-
335
-
336
-
337
- foreach($quotes_val as $key => $val) {
338
- // echo count($val); die;
339
- //echo $key.'<br>';
340
- //print_r($available_carriers);
341
-
342
- //usort($quotes_val, 'cmp1');
343
-
344
- $courier_title = $key;
345
- $courier_price = $quotes_val[$key]['total'];
346
-
347
- $method = Mage::getModel('shipping/rate_result_method');
348
- $method->setCarrier($this->_code);
349
- $method->setMethod($courier_title);
350
- $method->setCarrierTitle('Carriers');
351
-
352
- if($display_surcharge == '1'){
353
-
354
- $tmp_display_surcharge = $courier_price + $display_surcharge1;
355
- $tmp_method_title = $courier_title.' + Handling Charge';
356
-
357
- $method->setMethodTitle($tmp_method_title);
358
- $method->setPrice($tmp_display_surcharge);
359
- $method->setCost($tmp_display_surcharge);
360
-
361
- } else {
362
-
363
- if(in_array($key,$available_carriers)) {
364
- //echo '<br>'.$key . ' - matched<br>';
365
- $method->setMethodTitle($courier_title);
366
- $method->setPrice($courier_price);
367
- $method->setCost($courier_price);
368
- } else {
369
- //echo '<br>'.$key . ' - not found<br>';
370
- }
371
-
372
-
373
-
374
- }
375
-
376
- $result->append($method);
377
-
378
- }
379
- //die('arr');
380
- }
381
-
382
-
383
- //echo '<pre>'; print_r($result); //die('model');
384
-
385
- }else{
386
- $error = Mage::getModel('shipping/rate_result_error');
387
- $error->setCarrier($this->_code);
388
- $error->setCarrierTitle('Carrier Title');
389
- $error->setErrorMessage('Error');
390
- $result->append($error);
391
- }
392
-
393
- //return $result;
394
-
395
-
396
- //$this->renderLayout();
397
- $this->_getQuote()->save();
398
- $this->_goBack();
399
-
400
- $this->_redirectReferer();
401
-
402
- return $this;
403
- }
404
-
405
- function productAction(){
406
- $country = (string) $this->getRequest()->getParam('country_id');
407
- $postcode = (string) $this->getRequest()->getParam('estimate_postcode');
408
- $city = (string) $this->getRequest()->getParam('estimate_city');
409
- $regionId = (string) $this->getRequest()->getParam('region_id');
410
- $region = (string) $this->getRequest()->getParam('region');
411
-
412
- $this->_getQuote()->getShippingAddress()
413
- ->setCountryId($country)
414
- ->setCity($city)
415
- ->setPostcode($postcode)
416
- ->setRegionId($regionId)
417
- ->setRegion($region)
418
- ->setCollectShippingRates(true);
419
- $this->_getQuote()->save();
420
- $this->_goBack();
421
- //$this->_redirectReferer();
422
-
423
- }
424
-
425
-
426
-
427
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/etc/adminhtml.xml CHANGED
@@ -1,23 +1,23 @@
1
- <?xml version="1.0" ?>
2
- <config>
3
- <acl>
4
- <resources>
5
- <admin>
6
- <children>
7
- <system>
8
- <children>
9
- <config>
10
- <children>
11
- <transdirect_section translate="title" module="ship">
12
- <title>Transdirect Section</title>
13
- <sort_order>100</sort_order>
14
- </transdirect_section>
15
- </children>
16
- </config>
17
- </children>
18
- </system>
19
- </children>
20
- </admin>
21
- </resources>
22
- </acl>
23
  </config>
1
+ <?xml version="1.0" ?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <transdirect_section translate="title" module="ship">
12
+ <title>Transdirect Section</title>
13
+ <sort_order>100</sort_order>
14
+ </transdirect_section>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
  </config>
app/code/local/Transdirect/Ship/etc/bkp_30-5-2014---config.xml DELETED
@@ -1,88 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Transdirect_Ship>
5
- <version>0.1.0</version>
6
- </Transdirect_Ship>
7
- </modules>
8
- <frontend>
9
- <routers>
10
- <ship>
11
- <use>standard</use>
12
- <args>
13
- <module>Transdirect_Ship</module>
14
- <frontName>ship</frontName>
15
- </args>
16
- </ship>
17
- </routers>
18
- <layout>
19
- <updates>
20
- <ship>
21
- <file>ship.xml</file>
22
- </ship>
23
- </updates>
24
- </layout>
25
- </frontend>
26
- <global>
27
- <models>
28
- <ship>
29
- <class>Transdirect_Ship_Model</class>
30
- <resourceModel>ship_mysql4</resourceModel>
31
- </ship>
32
- <ship_mysql4>
33
- <class>Transdirect_Ship_Model_Mysql4</class>
34
- <entities>
35
- <ship>
36
- <table>ship</table>
37
- </ship>
38
- </entities>
39
- </ship_mysql4>
40
- </models>
41
- <resources>
42
- <ship_setup>
43
- <setup>
44
- <module>Transdirect_Ship</module>
45
- </setup>
46
- <connection>
47
- <use>core_setup</use>
48
- </connection>
49
- </ship_setup>
50
- <ship_write>
51
- <connection>
52
- <use>core_write</use>
53
- </connection>
54
- </ship_write>
55
- <ship_read>
56
- <connection>
57
- <use>core_read</use>
58
- </connection>
59
- </ship_read>
60
- </resources>
61
- <blocks>
62
- <ship>
63
- <class>Transdirect_Ship_Block</class>
64
- </ship>
65
- </blocks>
66
- <helpers>
67
- <ship>
68
- <class>Transdirect_Ship_Helper</class>
69
- </ship>
70
- </helpers>
71
- </global>
72
- <default>
73
- <carriers>
74
- <transdirect_section>
75
- <warehouseaddress><address>1</address></warehouseaddress>
76
- <displayoptions><showcouriernames>1</showcouriernames></displayoptions>
77
- </transdirect_section>
78
- <transdirect>
79
- <active>1</active>
80
- <model>ship/carrier_transdirect</model>
81
- <title>Carrier</title>
82
- <name>Method Name</name>
83
- <price>5.00</price>
84
- <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
85
- </transdirect>
86
- </carriers>
87
- </default>
88
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/etc/bkp_30-5-2014---system.xml DELETED
@@ -1,207 +0,0 @@
1
- <?xml version="1.0" ?>
2
- <config>
3
- <tabs>
4
- <transdirect_ship module="ship" translate="label">
5
- <label>Transdirect Shipping Module</label>
6
- <sort_order>100</sort_order>
7
- </transdirect_ship>
8
- </tabs>
9
- <sections>
10
- <transdirect_section module="ship" translate="label">
11
- <label>General</label>
12
- <sort_order>200</sort_order>
13
- <show_in_default>1</show_in_default>
14
- <show_in_website>1</show_in_website>
15
- <show_in_store>1</show_in_store>
16
- <tab>transdirect_ship</tab>
17
- <groups>
18
- <authentication translate="label">
19
- <label>Authentication (Member Details)</label>
20
- <sort_order>1</sort_order>
21
- <show_in_default>1</show_in_default>
22
- <show_in_website>1</show_in_website>
23
- <show_in_store>1</show_in_store>
24
- <fields>
25
- <email translate="label tooltip comment">
26
- <label>Email</label>
27
- <sort_order>1</sort_order>
28
- <show_in_default>1</show_in_default>
29
- <show_in_website>1</show_in_website>
30
- <show_in_store>1</show_in_store>
31
- <frontend_type>text</frontend_type>
32
- </email>
33
- <password translate="label tooltip comment">
34
- <label>Password</label>
35
- <sort_order>2</sort_order>
36
- <show_in_default>1</show_in_default>
37
- <show_in_website>1</show_in_website>
38
- <show_in_store>1</show_in_store>
39
- <frontend_type>text</frontend_type>
40
- </password>
41
- </fields>
42
- </authentication>
43
- <warehouseaddress translate="label">
44
- <label>Warehouse Address</label>
45
- <sort_order>2</sort_order>
46
- <show_in_default>1</show_in_default>
47
- <show_in_website>1</show_in_website>
48
- <show_in_store>1</show_in_store>
49
- <fields>
50
- <suburb translate="label tooltip comment">
51
- <label>Suburb</label>
52
- <sort_order>1</sort_order>
53
- <show_in_default>1</show_in_default>
54
- <show_in_website>1</show_in_website>
55
- <show_in_store>1</show_in_store>
56
- <frontend_type>text</frontend_type>
57
- </suburb>
58
- <postcode translate="label tooltip comment">
59
- <label>Postcode</label>
60
- <sort_order>2</sort_order>
61
- <show_in_default>1</show_in_default>
62
- <show_in_website>1</show_in_website>
63
- <show_in_store>1</show_in_store>
64
- <frontend_type>text</frontend_type>
65
- </postcode>
66
- <address translate="label tooltip comment">
67
- <label>Address</label>
68
- <sort_order>3</sort_order>
69
- <show_in_default>1</show_in_default>
70
- <show_in_website>1</show_in_website>
71
- <show_in_store>1</show_in_store>
72
- <frontend_type>select</frontend_type>
73
- <source_model>ship/source_addressType</source_model>
74
- </address>
75
- </fields>
76
- </warehouseaddress>
77
- <defaultitemsize translate="label">
78
- <label>Default Item Size</label>
79
- <sort_order>3</sort_order>
80
- <show_in_default>1</show_in_default>
81
- <show_in_website>1</show_in_website>
82
- <show_in_store>1</show_in_store>
83
- <fields>
84
- <dimensionswidth translate="label tooltip comment">
85
- <label>Dimensions</label>
86
- <sort_order>1</sort_order>
87
- <comment>Width</comment>
88
- <show_in_default>1</show_in_default>
89
- <show_in_website>1</show_in_website>
90
- <show_in_store>1</show_in_store>
91
- <frontend_type>text</frontend_type>
92
- </dimensionswidth>
93
- <dimensionsheight translate="label tooltip comment">
94
- <sort_order>2</sort_order>
95
- <comment>Height</comment>
96
- <show_in_default>1</show_in_default>
97
- <show_in_website>1</show_in_website>
98
- <show_in_store>1</show_in_store>
99
- <frontend_type>text</frontend_type>
100
- </dimensionsheight>
101
- <dimensionsdim translate="label tooltip comment">
102
- <sort_order>3</sort_order>
103
- <comment>Length</comment>
104
- <show_in_default>1</show_in_default>
105
- <show_in_website>1</show_in_website>
106
- <show_in_store>1</show_in_store>
107
- <frontend_type>text</frontend_type>
108
- </dimensionsdim>
109
- <weight translate="label tooltip comment">
110
- <label>Weight</label>
111
- <sort_order>4</sort_order>
112
- <comment>KG</comment>
113
- <show_in_default>1</show_in_default>
114
- <show_in_website>1</show_in_website>
115
- <show_in_store>1</show_in_store>
116
- <frontend_type>text</frontend_type>
117
- </weight>
118
- </fields>
119
- </defaultitemsize>
120
- <displayoptions translate="label">
121
- <label>Display Options</label>
122
- <sort_order>4</sort_order>
123
- <show_in_default>1</show_in_default>
124
- <show_in_website>1</show_in_website>
125
- <show_in_store>1</show_in_store>
126
- <fields>
127
- <availablecoriers translate="label tooltip comment">
128
- <label>Available Couriers: (Shift Select)</label>
129
- <sort_order>1</sort_order>
130
- <show_in_default>1</show_in_default>
131
- <show_in_website>1</show_in_website>
132
- <show_in_store>1</show_in_store>
133
- <frontend_type>Multiselect</frontend_type>
134
- <source_model>ship/source_couriers</source_model>
135
- </availablecoriers>
136
- <quotedisplay translate="label tooltip comment">
137
- <label>Quote Display</label>
138
- <sort_order>2</sort_order>
139
- <show_in_default>1</show_in_default>
140
- <show_in_website>1</show_in_website>
141
- <show_in_store>1</show_in_store>
142
- <frontend_type>select</frontend_type>
143
- <source_model>ship/source_quotes</source_model>
144
- </quotedisplay>
145
- <fixedpriceonerror translate="label tooltip comment">
146
- <label>Fixed Price On Error</label>
147
- <sort_order>3</sort_order>
148
- <show_in_default>1</show_in_default>
149
- <show_in_website>1</show_in_website>
150
- <show_in_store>1</show_in_store>
151
- <!--<frontend_type>checkbox</frontend_type>-->
152
- <frontend_type>select</frontend_type>
153
- <source_model>adminhtml/system_config_source_yesno</source_model>
154
- <comment>If there is some error getting a quote, just return the set fixed price.</comment>
155
- </fixedpriceonerror>
156
- <fixedpriceonerror1 translate="label tooltip comment">
157
- <label>Fixed Price On Error (Value)</label>
158
- <sort_order>4</sort_order>
159
- <show_in_default>1</show_in_default>
160
- <show_in_website>1</show_in_website>
161
- <show_in_store>1</show_in_store>
162
- <frontend_type>text</frontend_type>
163
- </fixedpriceonerror1>
164
- <showcouriernames translate="label tooltip comment">
165
- <label>Show Courier Names</label>
166
- <sort_order>5</sort_order>
167
- <show_in_default>1</show_in_default>
168
- <show_in_website>1</show_in_website>
169
- <show_in_store>1</show_in_store>
170
- <frontend_type>select</frontend_type>
171
- <source_model>adminhtml/system_config_source_yesno</source_model>
172
- <comment>eg. show (Price - Courier Name - Shipping Time) instead of just (Price - Shipping Time).</comment>
173
- </showcouriernames>
174
- <handlingsurcharge translate="label tooltip comment">
175
- <label>Handling Surcharge</label>
176
- <sort_order>6</sort_order>
177
- <show_in_default>1</show_in_default>
178
- <show_in_website>1</show_in_website>
179
- <show_in_store>1</show_in_store>
180
- <frontend_type>select</frontend_type>
181
- <source_model>adminhtml/system_config_source_yesno</source_model>
182
- <comment>Add a surcharge to the quoted amounts.</comment>
183
- </handlingsurcharge>
184
- <handlingsurcharge1 translate="label tooltip comment">
185
- <label>Handling Surcharge (Value)</label>
186
- <sort_order>7</sort_order>
187
- <show_in_default>1</show_in_default>
188
- <show_in_website>1</show_in_website>
189
- <show_in_store>1</show_in_store>
190
- <frontend_type>text</frontend_type>
191
- </handlingsurcharge1>
192
- <includesurcharge translate="label tooltip comment">
193
- <label>Include Insurance Surcharge, If you remove this item, please see FAQ's.</label>
194
- <sort_order>8</sort_order>
195
- <show_in_default>1</show_in_default>
196
- <show_in_website>1</show_in_website>
197
- <show_in_store>1</show_in_store>
198
- <frontend_type>select</frontend_type>
199
- <source_model>adminhtml/system_config_source_yesno</source_model>
200
- <comment>This is an option from the api when requesting a quote.</comment>
201
- </includesurcharge>
202
- </fields>
203
- </displayoptions>
204
- </groups>
205
- </transdirect_section>
206
- </sections>
207
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Transdirect/Ship/etc/config.xml CHANGED
@@ -1,88 +1,88 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Transdirect_Ship>
5
- <version>0.1.0</version>
6
- </Transdirect_Ship>
7
- </modules>
8
- <frontend>
9
- <routers>
10
- <ship>
11
- <use>standard</use>
12
- <args>
13
- <module>Transdirect_Ship</module>
14
- <frontName>ship</frontName>
15
- </args>
16
- </ship>
17
- </routers>
18
- <layout>
19
- <updates>
20
- <ship>
21
- <file>ship.xml</file>
22
- </ship>
23
- </updates>
24
- </layout>
25
- </frontend>
26
- <global>
27
- <models>
28
- <ship>
29
- <class>Transdirect_Ship_Model</class>
30
- <resourceModel>ship_mysql4</resourceModel>
31
- </ship>
32
- <ship_mysql4>
33
- <class>Transdirect_Ship_Model_Mysql4</class>
34
- <entities>
35
- <ship>
36
- <table>ship</table>
37
- </ship>
38
- </entities>
39
- </ship_mysql4>
40
- </models>
41
- <resources>
42
- <ship_setup>
43
- <setup>
44
- <module>Transdirect_Ship</module>
45
- </setup>
46
- <connection>
47
- <use>core_setup</use>
48
- </connection>
49
- </ship_setup>
50
- <ship_write>
51
- <connection>
52
- <use>core_write</use>
53
- </connection>
54
- </ship_write>
55
- <ship_read>
56
- <connection>
57
- <use>core_read</use>
58
- </connection>
59
- </ship_read>
60
- </resources>
61
- <blocks>
62
- <ship>
63
- <class>Transdirect_Ship_Block</class>
64
- </ship>
65
- </blocks>
66
- <helpers>
67
- <ship>
68
- <class>Transdirect_Ship_Helper</class>
69
- </ship>
70
- </helpers>
71
- </global>
72
- <default>
73
- <carriers>
74
- <transdirect_section>
75
- <warehouseaddress><address>1</address></warehouseaddress>
76
- <displayoptions><showcouriernames>1</showcouriernames></displayoptions>
77
- </transdirect_section>
78
- <transdirect>
79
- <active>1</active>
80
- <model>ship/carrier_transdirect</model>
81
- <title>Carrier</title>
82
- <name>Method Name</name>
83
- <price>5.00</price>
84
- <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
85
- </transdirect>
86
- </carriers>
87
- </default>
88
  </config>
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Transdirect_Ship>
5
+ <version>0.1.0</version>
6
+ </Transdirect_Ship>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <ship>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Transdirect_Ship</module>
14
+ <frontName>ship</frontName>
15
+ </args>
16
+ </ship>
17
+ </routers>
18
+ <layout>
19
+ <updates>
20
+ <ship>
21
+ <file>ship.xml</file>
22
+ </ship>
23
+ </updates>
24
+ </layout>
25
+ </frontend>
26
+ <global>
27
+ <models>
28
+ <ship>
29
+ <class>Transdirect_Ship_Model</class>
30
+ <resourceModel>ship_mysql4</resourceModel>
31
+ </ship>
32
+ <ship_mysql4>
33
+ <class>Transdirect_Ship_Model_Mysql4</class>
34
+ <entities>
35
+ <ship>
36
+ <table>ship</table>
37
+ </ship>
38
+ </entities>
39
+ </ship_mysql4>
40
+ </models>
41
+ <resources>
42
+ <ship_setup>
43
+ <setup>
44
+ <module>Transdirect_Ship</module>
45
+ </setup>
46
+ <connection>
47
+ <use>core_setup</use>
48
+ </connection>
49
+ </ship_setup>
50
+ <ship_write>
51
+ <connection>
52
+ <use>core_write</use>
53
+ </connection>
54
+ </ship_write>
55
+ <ship_read>
56
+ <connection>
57
+ <use>core_read</use>
58
+ </connection>
59
+ </ship_read>
60
+ </resources>
61
+ <blocks>
62
+ <ship>
63
+ <class>Transdirect_Ship_Block</class>
64
+ </ship>
65
+ </blocks>
66
+ <helpers>
67
+ <ship>
68
+ <class>Transdirect_Ship_Helper</class>
69
+ </ship>
70
+ </helpers>
71
+ </global>
72
+ <default>
73
+ <carriers>
74
+ <transdirect_section>
75
+ <warehouseaddress><address>1</address></warehouseaddress>
76
+ <displayoptions><showcouriernames>1</showcouriernames></displayoptions>
77
+ </transdirect_section>
78
+ <transdirect>
79
+ <active>1</active>
80
+ <model>ship/carrier_transdirect</model>
81
+ <title>Carrier</title>
82
+ <name>Method Name</name>
83
+ <price>5.00</price>
84
+ <specificerrmsg>This shipping method is currently unavailable. If you would like to ship using this shipping method, please contact us.</specificerrmsg>
85
+ </transdirect>
86
+ </carriers>
87
+ </default>
88
  </config>
app/code/local/Transdirect/Ship/etc/system.xml CHANGED
@@ -1,432 +1,432 @@
1
- <?xml version="1.0" ?>
2
-
3
- <config>
4
-
5
- <tabs>
6
-
7
- <transdirect_ship module="ship" translate="label">
8
-
9
- <label>Transdirect Shipping Module</label>
10
-
11
- <sort_order>100</sort_order>
12
-
13
- </transdirect_ship>
14
-
15
- </tabs>
16
-
17
- <sections>
18
-
19
- <transdirect_section module="ship" translate="label">
20
-
21
- <label>General Settings</label>
22
-
23
- <sort_order>200</sort_order>
24
-
25
- <show_in_default>1</show_in_default>
26
-
27
- <show_in_website>1</show_in_website>
28
-
29
- <show_in_store>1</show_in_store>
30
-
31
- <tab>transdirect_ship</tab>
32
-
33
- <groups>
34
-
35
- <enabletab translate="label">
36
- <label>Enable Extension</label>
37
- <sort_order>1</sort_order>
38
- <show_in_default>1</show_in_default>
39
- <show_in_website>1</show_in_website>
40
- <show_in_store>1</show_in_store>
41
- <fields>
42
- <enable translate="label tooltip comment">
43
- <label>Enable</label>
44
- <sort_order>1</sort_order>
45
- <show_in_default>1</show_in_default>
46
- <show_in_website>1</show_in_website>
47
- <show_in_store>1</show_in_store>
48
- <frontend_type>select</frontend_type>
49
- <source_model>adminhtml/system_config_source_yesno</source_model>
50
- </enable>
51
- </fields>
52
- </enabletab>
53
-
54
- <authentication translate="label">
55
-
56
- <label>Authentication (Member Details)</label>
57
-
58
- <sort_order>2</sort_order>
59
-
60
- <show_in_default>1</show_in_default>
61
-
62
- <show_in_website>1</show_in_website>
63
-
64
- <show_in_store>1</show_in_store>
65
-
66
- <fields>
67
-
68
- <email translate="label tooltip comment">
69
-
70
- <label>Email</label>
71
-
72
- <sort_order>1</sort_order>
73
-
74
- <show_in_default>1</show_in_default>
75
-
76
- <show_in_website>1</show_in_website>
77
-
78
- <show_in_store>1</show_in_store>
79
-
80
- <frontend_type>text</frontend_type>
81
-
82
- </email>
83
-
84
- <password translate="label tooltip comment">
85
-
86
- <label>Password</label>
87
-
88
- <sort_order>2</sort_order>
89
-
90
- <show_in_default>1</show_in_default>
91
-
92
- <show_in_website>1</show_in_website>
93
-
94
- <show_in_store>1</show_in_store>
95
-
96
- <frontend_type>text</frontend_type>
97
-
98
- </password>
99
-
100
- </fields>
101
-
102
- </authentication>
103
-
104
- <warehouseaddress translate="label">
105
-
106
- <label>Warehouse Address</label>
107
-
108
- <sort_order>3</sort_order>
109
-
110
- <show_in_default>1</show_in_default>
111
-
112
- <show_in_website>1</show_in_website>
113
-
114
- <show_in_store>1</show_in_store>
115
-
116
- <fields>
117
-
118
- <suburb translate="label tooltip comment">
119
-
120
- <label>Suburb</label>
121
-
122
- <sort_order>1</sort_order>
123
-
124
- <show_in_default>1</show_in_default>
125
-
126
- <show_in_website>1</show_in_website>
127
-
128
- <show_in_store>1</show_in_store>
129
-
130
- <frontend_type>text</frontend_type>
131
-
132
- </suburb>
133
-
134
- <postcode translate="label tooltip comment">
135
-
136
- <label>Postcode</label>
137
-
138
- <sort_order>2</sort_order>
139
-
140
- <show_in_default>1</show_in_default>
141
-
142
- <show_in_website>1</show_in_website>
143
-
144
- <show_in_store>1</show_in_store>
145
-
146
- <frontend_type>text</frontend_type>
147
-
148
- </postcode>
149
-
150
- <address translate="label tooltip comment">
151
-
152
- <label>Address</label>
153
-
154
- <sort_order>3</sort_order>
155
-
156
- <show_in_default>1</show_in_default>
157
-
158
- <show_in_website>1</show_in_website>
159
-
160
- <show_in_store>1</show_in_store>
161
-
162
- <frontend_type>select</frontend_type>
163
-
164
- <source_model>ship/source_addressType</source_model>
165
-
166
- </address>
167
-
168
- </fields>
169
-
170
- </warehouseaddress>
171
-
172
- <defaultitemsize translate="label">
173
-
174
- <label>Default Item Size</label>
175
-
176
- <sort_order>4</sort_order>
177
-
178
- <show_in_default>1</show_in_default>
179
-
180
- <show_in_website>1</show_in_website>
181
-
182
- <show_in_store>1</show_in_store>
183
-
184
- <fields>
185
-
186
- <dimensionswidth translate="label tooltip comment">
187
-
188
- <label>Dimensions</label>
189
-
190
- <sort_order>1</sort_order>
191
-
192
- <comment>Width (cm)</comment>
193
-
194
- <show_in_default>1</show_in_default>
195
-
196
- <show_in_website>1</show_in_website>
197
-
198
- <show_in_store>1</show_in_store>
199
-
200
- <frontend_type>text</frontend_type>
201
-
202
- </dimensionswidth>
203
-
204
- <dimensionsheight translate="label tooltip comment">
205
-
206
- <sort_order>2</sort_order>
207
-
208
- <comment>Height (cm)</comment>
209
-
210
- <show_in_default>1</show_in_default>
211
-
212
- <show_in_website>1</show_in_website>
213
-
214
- <show_in_store>1</show_in_store>
215
-
216
- <frontend_type>text</frontend_type>
217
-
218
- </dimensionsheight>
219
-
220
- <dimensionsdim translate="label tooltip comment">
221
-
222
- <sort_order>3</sort_order>
223
-
224
- <comment>Length (cm)</comment>
225
-
226
- <show_in_default>1</show_in_default>
227
-
228
- <show_in_website>1</show_in_website>
229
-
230
- <show_in_store>1</show_in_store>
231
-
232
- <frontend_type>text</frontend_type>
233
-
234
- </dimensionsdim>
235
-
236
- <weight translate="label tooltip comment">
237
-
238
- <label>Weight</label>
239
-
240
- <sort_order>4</sort_order>
241
-
242
- <comment>KG</comment>
243
-
244
- <show_in_default>1</show_in_default>
245
-
246
- <show_in_website>1</show_in_website>
247
-
248
- <show_in_store>1</show_in_store>
249
-
250
- <frontend_type>text</frontend_type>
251
-
252
- </weight>
253
-
254
- </fields>
255
-
256
- </defaultitemsize>
257
-
258
- <displayoptions translate="label">
259
-
260
- <label>Display Options</label>
261
-
262
- <sort_order>5</sort_order>
263
-
264
- <show_in_default>1</show_in_default>
265
-
266
- <show_in_website>1</show_in_website>
267
-
268
- <show_in_store>1</show_in_store>
269
-
270
- <fields>
271
-
272
- <availablecoriers translate="label tooltip comment">
273
-
274
- <label>Available Couriers: (Shift Select)</label>
275
-
276
- <sort_order>1</sort_order>
277
-
278
- <show_in_default>1</show_in_default>
279
-
280
- <show_in_website>1</show_in_website>
281
-
282
- <show_in_store>1</show_in_store>
283
-
284
- <frontend_type>Multiselect</frontend_type>
285
-
286
- <source_model>ship/source_couriers</source_model>
287
-
288
- </availablecoriers>
289
-
290
- <quotedisplay translate="label tooltip comment">
291
-
292
- <label>Quote Display</label>
293
-
294
- <sort_order>2</sort_order>
295
-
296
- <show_in_default>1</show_in_default>
297
-
298
- <show_in_website>1</show_in_website>
299
-
300
- <show_in_store>1</show_in_store>
301
-
302
- <frontend_type>select</frontend_type>
303
-
304
- <source_model>ship/source_quotes</source_model>
305
-
306
- </quotedisplay>
307
-
308
- <fixedpriceonerror translate="label tooltip comment">
309
-
310
- <label>Fixed Price On Error</label>
311
-
312
- <sort_order>3</sort_order>
313
-
314
- <show_in_default>1</show_in_default>
315
-
316
- <show_in_website>1</show_in_website>
317
-
318
- <show_in_store>1</show_in_store>
319
-
320
- <!--<frontend_type>checkbox</frontend_type>-->
321
-
322
- <frontend_type>select</frontend_type>
323
-
324
- <source_model>adminhtml/system_config_source_yesno</source_model>
325
-
326
- <comment>If there is some error getting a quote, just return the set fixed price.</comment>
327
-
328
- </fixedpriceonerror>
329
-
330
- <fixedpriceonerror1 translate="label tooltip comment">
331
-
332
- <label>Fixed Price On Error (Value)</label>
333
-
334
- <sort_order>4</sort_order>
335
-
336
- <show_in_default>1</show_in_default>
337
-
338
- <show_in_website>1</show_in_website>
339
-
340
- <show_in_store>1</show_in_store>
341
-
342
- <frontend_type>text</frontend_type>
343
-
344
- </fixedpriceonerror1>
345
-
346
- <showcouriernames translate="label tooltip comment">
347
-
348
- <label>Show Courier Names</label>
349
-
350
- <sort_order>5</sort_order>
351
-
352
- <show_in_default>1</show_in_default>
353
-
354
- <show_in_website>1</show_in_website>
355
-
356
- <show_in_store>1</show_in_store>
357
-
358
- <frontend_type>select</frontend_type>
359
-
360
- <source_model>adminhtml/system_config_source_yesno</source_model>
361
-
362
- <comment>eg. show (Courier Name - Price - Shipping Time) instead of just (Price - Shipping Time).</comment>
363
-
364
- </showcouriernames>
365
-
366
- <handlingsurcharge translate="label tooltip comment">
367
-
368
- <label>Handling Surcharge</label>
369
-
370
- <sort_order>6</sort_order>
371
-
372
- <show_in_default>1</show_in_default>
373
-
374
- <show_in_website>1</show_in_website>
375
-
376
- <show_in_store>1</show_in_store>
377
-
378
- <frontend_type>select</frontend_type>
379
-
380
- <source_model>adminhtml/system_config_source_yesno</source_model>
381
-
382
- <comment>Add a surcharge to the quoted amounts.</comment>
383
-
384
- </handlingsurcharge>
385
-
386
- <handlingsurcharge1 translate="label tooltip comment">
387
-
388
- <label>Handling Surcharge (Value)</label>
389
-
390
- <sort_order>7</sort_order>
391
-
392
- <show_in_default>1</show_in_default>
393
-
394
- <show_in_website>1</show_in_website>
395
-
396
- <show_in_store>1</show_in_store>
397
-
398
- <frontend_type>text</frontend_type>
399
-
400
- </handlingsurcharge1>
401
-
402
- <includesurcharge translate="label tooltip comment">
403
-
404
- <label>Include Insurance Surcharge</label>
405
-
406
- <sort_order>8</sort_order>
407
-
408
- <show_in_default>1</show_in_default>
409
-
410
- <show_in_website>1</show_in_website>
411
-
412
- <show_in_store>1</show_in_store>
413
-
414
- <frontend_type>select</frontend_type>
415
-
416
- <source_model>adminhtml/system_config_source_yesno</source_model>
417
-
418
- <comment>This is an option from the api when requesting a quote.</comment>
419
-
420
- </includesurcharge>
421
-
422
- </fields>
423
-
424
- </displayoptions>
425
-
426
- </groups>
427
-
428
- </transdirect_section>
429
-
430
- </sections>
431
-
432
  </config>
1
+ <?xml version="1.0" ?>
2
+
3
+ <config>
4
+
5
+ <tabs>
6
+
7
+ <transdirect_ship module="ship" translate="label">
8
+
9
+ <label>Transdirect Shipping Module</label>
10
+
11
+ <sort_order>100</sort_order>
12
+
13
+ </transdirect_ship>
14
+
15
+ </tabs>
16
+
17
+ <sections>
18
+
19
+ <transdirect_section module="ship" translate="label">
20
+
21
+ <label>General Settings</label>
22
+
23
+ <sort_order>200</sort_order>
24
+
25
+ <show_in_default>1</show_in_default>
26
+
27
+ <show_in_website>1</show_in_website>
28
+
29
+ <show_in_store>1</show_in_store>
30
+
31
+ <tab>transdirect_ship</tab>
32
+
33
+ <groups>
34
+
35
+ <enabletab translate="label">
36
+ <label>Enable Extension</label>
37
+ <sort_order>1</sort_order>
38
+ <show_in_default>1</show_in_default>
39
+ <show_in_website>1</show_in_website>
40
+ <show_in_store>1</show_in_store>
41
+ <fields>
42
+ <enable translate="label tooltip comment">
43
+ <label>Enable</label>
44
+ <sort_order>1</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ <frontend_type>select</frontend_type>
49
+ <source_model>adminhtml/system_config_source_yesno</source_model>
50
+ </enable>
51
+ </fields>
52
+ </enabletab>
53
+
54
+ <authentication translate="label">
55
+
56
+ <label>Authentication (Member Details)</label>
57
+
58
+ <sort_order>2</sort_order>
59
+
60
+ <show_in_default>1</show_in_default>
61
+
62
+ <show_in_website>1</show_in_website>
63
+
64
+ <show_in_store>1</show_in_store>
65
+
66
+ <fields>
67
+
68
+ <email translate="label tooltip comment">
69
+
70
+ <label>Email</label>
71
+
72
+ <sort_order>1</sort_order>
73
+
74
+ <show_in_default>1</show_in_default>
75
+
76
+ <show_in_website>1</show_in_website>
77
+
78
+ <show_in_store>1</show_in_store>
79
+
80
+ <frontend_type>text</frontend_type>
81
+
82
+ </email>
83
+
84
+ <password translate="label tooltip comment">
85
+
86
+ <label>Password</label>
87
+
88
+ <sort_order>2</sort_order>
89
+
90
+ <show_in_default>1</show_in_default>
91
+
92
+ <show_in_website>1</show_in_website>
93
+
94
+ <show_in_store>1</show_in_store>
95
+
96
+ <frontend_type>text</frontend_type>
97
+
98
+ </password>
99
+
100
+ </fields>
101
+
102
+ </authentication>
103
+
104
+ <warehouseaddress translate="label">
105
+
106
+ <label>Warehouse Address</label>
107
+
108
+ <sort_order>3</sort_order>
109
+
110
+ <show_in_default>1</show_in_default>
111
+
112
+ <show_in_website>1</show_in_website>
113
+
114
+ <show_in_store>1</show_in_store>
115
+
116
+ <fields>
117
+
118
+ <suburb translate="label tooltip comment">
119
+
120
+ <label>Suburb</label>
121
+
122
+ <sort_order>1</sort_order>
123
+
124
+ <show_in_default>1</show_in_default>
125
+
126
+ <show_in_website>1</show_in_website>
127
+
128
+ <show_in_store>1</show_in_store>
129
+
130
+ <frontend_type>text</frontend_type>
131
+
132
+ </suburb>
133
+
134
+ <postcode translate="label tooltip comment">
135
+
136
+ <label>Postcode</label>
137
+
138
+ <sort_order>2</sort_order>
139
+
140
+ <show_in_default>1</show_in_default>
141
+
142
+ <show_in_website>1</show_in_website>
143
+
144
+ <show_in_store>1</show_in_store>
145
+
146
+ <frontend_type>text</frontend_type>
147
+
148
+ </postcode>
149
+
150
+ <address translate="label tooltip comment">
151
+
152
+ <label>Address</label>
153
+
154
+ <sort_order>3</sort_order>
155
+
156
+ <show_in_default>1</show_in_default>
157
+
158
+ <show_in_website>1</show_in_website>
159
+
160
+ <show_in_store>1</show_in_store>
161
+
162
+ <frontend_type>select</frontend_type>
163
+
164
+ <source_model>ship/source_addressType</source_model>
165
+
166
+ </address>
167
+
168
+ </fields>
169
+
170
+ </warehouseaddress>
171
+
172
+ <defaultitemsize translate="label">
173
+
174
+ <label>Default Item Size</label>
175
+
176
+ <sort_order>4</sort_order>
177
+
178
+ <show_in_default>1</show_in_default>
179
+
180
+ <show_in_website>1</show_in_website>
181
+
182
+ <show_in_store>1</show_in_store>
183
+
184
+ <fields>
185
+
186
+ <dimensionswidth translate="label tooltip comment">
187
+
188
+ <label>Dimensions</label>
189
+
190
+ <sort_order>1</sort_order>
191
+
192
+ <comment>Width (cm)</comment>
193
+
194
+ <show_in_default>1</show_in_default>
195
+
196
+ <show_in_website>1</show_in_website>
197
+
198
+ <show_in_store>1</show_in_store>
199
+
200
+ <frontend_type>text</frontend_type>
201
+
202
+ </dimensionswidth>
203
+
204
+ <dimensionsheight translate="label tooltip comment">
205
+
206
+ <sort_order>2</sort_order>
207
+
208
+ <comment>Height (cm)</comment>
209
+
210
+ <show_in_default>1</show_in_default>
211
+
212
+ <show_in_website>1</show_in_website>
213
+
214
+ <show_in_store>1</show_in_store>
215
+
216
+ <frontend_type>text</frontend_type>
217
+
218
+ </dimensionsheight>
219
+
220
+ <dimensionsdim translate="label tooltip comment">
221
+
222
+ <sort_order>3</sort_order>
223
+
224
+ <comment>Length (cm)</comment>
225
+
226
+ <show_in_default>1</show_in_default>
227
+
228
+ <show_in_website>1</show_in_website>
229
+
230
+ <show_in_store>1</show_in_store>
231
+
232
+ <frontend_type>text</frontend_type>
233
+
234
+ </dimensionsdim>
235
+
236
+ <weight translate="label tooltip comment">
237
+
238
+ <label>Weight</label>
239
+
240
+ <sort_order>4</sort_order>
241
+
242
+ <comment>KG</comment>
243
+
244
+ <show_in_default>1</show_in_default>
245
+
246
+ <show_in_website>1</show_in_website>
247
+
248
+ <show_in_store>1</show_in_store>
249
+
250
+ <frontend_type>text</frontend_type>
251
+
252
+ </weight>
253
+
254
+ </fields>
255
+
256
+ </defaultitemsize>
257
+
258
+ <displayoptions translate="label">
259
+
260
+ <label>Display Options</label>
261
+
262
+ <sort_order>5</sort_order>
263
+
264
+ <show_in_default>1</show_in_default>
265
+
266
+ <show_in_website>1</show_in_website>
267
+
268
+ <show_in_store>1</show_in_store>
269
+
270
+ <fields>
271
+
272
+ <availablecoriers translate="label tooltip comment">
273
+
274
+ <label>Available Couriers: (Shift Select)</label>
275
+
276
+ <sort_order>1</sort_order>
277
+
278
+ <show_in_default>1</show_in_default>
279
+
280
+ <show_in_website>1</show_in_website>
281
+
282
+ <show_in_store>1</show_in_store>
283
+
284
+ <frontend_type>Multiselect</frontend_type>
285
+
286
+ <source_model>ship/source_couriers</source_model>
287
+
288
+ </availablecoriers>
289
+
290
+ <quotedisplay translate="label tooltip comment">
291
+
292
+ <label>Quote Display</label>
293
+
294
+ <sort_order>2</sort_order>
295
+
296
+ <show_in_default>1</show_in_default>
297
+
298
+ <show_in_website>1</show_in_website>
299
+
300
+ <show_in_store>1</show_in_store>
301
+
302
+ <frontend_type>select</frontend_type>
303
+
304
+ <source_model>ship/source_quotes</source_model>
305
+
306
+ </quotedisplay>
307
+
308
+ <fixedpriceonerror translate="label tooltip comment">
309
+
310
+ <label>Fixed Price On Error</label>
311
+
312
+ <sort_order>3</sort_order>
313
+
314
+ <show_in_default>1</show_in_default>
315
+
316
+ <show_in_website>1</show_in_website>
317
+
318
+ <show_in_store>1</show_in_store>
319
+
320
+ <!--<frontend_type>checkbox</frontend_type>-->
321
+
322
+ <frontend_type>select</frontend_type>
323
+
324
+ <source_model>adminhtml/system_config_source_yesno</source_model>
325
+
326
+ <comment>If there is some error getting a quote, just return the set fixed price.</comment>
327
+
328
+ </fixedpriceonerror>
329
+
330
+ <fixedpriceonerror1 translate="label tooltip comment">
331
+
332
+ <label>Fixed Price On Error (Value)</label>
333
+
334
+ <sort_order>4</sort_order>
335
+
336
+ <show_in_default>1</show_in_default>
337
+
338
+ <show_in_website>1</show_in_website>
339
+
340
+ <show_in_store>1</show_in_store>
341
+
342
+ <frontend_type>text</frontend_type>
343
+
344
+ </fixedpriceonerror1>
345
+
346
+ <showcouriernames translate="label tooltip comment">
347
+
348
+ <label>Show Courier Names</label>
349
+
350
+ <sort_order>5</sort_order>
351
+
352
+ <show_in_default>1</show_in_default>
353
+
354
+ <show_in_website>1</show_in_website>
355
+
356
+ <show_in_store>1</show_in_store>
357
+
358
+ <frontend_type>select</frontend_type>
359
+
360
+ <source_model>adminhtml/system_config_source_yesno</source_model>
361
+
362
+ <comment>eg. show (Courier Name - Price - Shipping Time) instead of just (Price - Shipping Time).</comment>
363
+
364
+ </showcouriernames>
365
+
366
+ <handlingsurcharge translate="label tooltip comment">
367
+
368
+ <label>Handling Surcharge</label>
369
+
370
+ <sort_order>6</sort_order>
371
+
372
+ <show_in_default>1</show_in_default>
373
+
374
+ <show_in_website>1</show_in_website>
375
+
376
+ <show_in_store>1</show_in_store>
377
+
378
+ <frontend_type>select</frontend_type>
379
+
380
+ <source_model>adminhtml/system_config_source_yesno</source_model>
381
+
382
+ <comment>Add a surcharge to the quoted amounts.</comment>
383
+
384
+ </handlingsurcharge>
385
+
386
+ <handlingsurcharge1 translate="label tooltip comment">
387
+
388
+ <label>Handling Surcharge (Value)</label>
389
+
390
+ <sort_order>7</sort_order>
391
+
392
+ <show_in_default>1</show_in_default>
393
+
394
+ <show_in_website>1</show_in_website>
395
+
396
+ <show_in_store>1</show_in_store>
397
+
398
+ <frontend_type>text</frontend_type>
399
+
400
+ </handlingsurcharge1>
401
+
402
+ <includesurcharge translate="label tooltip comment">
403
+
404
+ <label>Include Insurance Surcharge</label>
405
+
406
+ <sort_order>8</sort_order>
407
+
408
+ <show_in_default>1</show_in_default>
409
+
410
+ <show_in_website>1</show_in_website>
411
+
412
+ <show_in_store>1</show_in_store>
413
+
414
+ <frontend_type>select</frontend_type>
415
+
416
+ <source_model>adminhtml/system_config_source_yesno</source_model>
417
+
418
+ <comment>This is an option from the api when requesting a quote.</comment>
419
+
420
+ </includesurcharge>
421
+
422
+ </fields>
423
+
424
+ </displayoptions>
425
+
426
+ </groups>
427
+
428
+ </transdirect_section>
429
+
430
+ </sections>
431
+
432
  </config>
app/code/local/Transdirect/Ship/sql/ship_setup/mysql4-install-0.1.0.php CHANGED
@@ -1,84 +1,84 @@
1
- <?php
2
-
3
-
4
- $installer = $this;
5
-
6
- /* $installer Mage_Core_Model_Resource_Setup */
7
-
8
- $installer->startSetup();
9
- $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
10
-
11
-
12
- $setup->addAttribute('catalog_product', 'item_height', array(
13
- 'backend' => '',
14
- 'source' => '',
15
- 'entity_model' => 'catalog/product',
16
- 'label' => 'Item Height',
17
- //'group' => 'ItemSize',
18
- 'group' => 'For Shipping Item Information',
19
- 'input' => 'text',
20
- 'type' => 'text',
21
- 'is_html_allowed_on_front' => true,
22
- 'global' => true,
23
- 'visible' => true,
24
- 'required' => false,
25
- 'user_defined' => false,
26
- 'default' => '',
27
- 'visible_on_front' => true
28
- ));
29
-
30
- $setup->addAttribute('catalog_product', 'item_width', array(
31
- 'backend' => '',
32
- 'source' => '',
33
- 'entity_model' => 'catalog/product',
34
- 'label' => 'Item Width',
35
- //'group' => 'ItemSize',
36
- 'group' => 'For Shipping Item Information',
37
- 'input' => 'text',
38
- 'type' => 'text',
39
- 'is_html_allowed_on_front' => true,
40
- 'global' => true,
41
- 'visible' => true,
42
- 'required' => false,
43
- 'user_defined' => false,
44
- 'default' => '',
45
- 'visible_on_front' => true
46
- ));
47
-
48
- $setup->addAttribute('catalog_product', 'item_dim', array(
49
- 'backend' => '',
50
- 'source' => '',
51
- 'entity_model' => 'catalog/product',
52
- 'label' => 'Item Length',
53
- //'group' => 'ItemSize',
54
- 'group' => 'For Shipping Item Information',
55
- 'input' => 'text',
56
- 'type' => 'text',
57
- 'is_html_allowed_on_front' => true,
58
- 'global' => true,
59
- 'visible' => true,
60
- 'required' => false,
61
- 'user_defined' => false,
62
- 'default' => '',
63
- 'visible_on_front' => true
64
- ));
65
-
66
- $setup->addAttribute('catalog_product', 'item_weight', array(
67
- 'backend' => '',
68
- 'source' => '',
69
- 'entity_model' => 'catalog/product',
70
- 'label' => 'Item Weight',
71
- //'group' => 'ItemSize',
72
- 'group' => 'For Shipping Item Information',
73
- 'input' => 'text',
74
- 'type' => 'text',
75
- 'is_html_allowed_on_front' => true,
76
- 'global' => true,
77
- 'visible' => true,
78
- 'required' => false,
79
- 'user_defined' => false,
80
- 'default' => '',
81
- 'visible_on_front' => true
82
- ));
83
-
84
  $installer->endSetup();
1
+ <?php
2
+
3
+
4
+ $installer = $this;
5
+
6
+ /* $installer Mage_Core_Model_Resource_Setup */
7
+
8
+ $installer->startSetup();
9
+ $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
10
+
11
+
12
+ $setup->addAttribute('catalog_product', 'item_height', array(
13
+ 'backend' => '',
14
+ 'source' => '',
15
+ 'entity_model' => 'catalog/product',
16
+ 'label' => 'Item Height',
17
+ //'group' => 'ItemSize',
18
+ 'group' => 'For Shipping Item Information',
19
+ 'input' => 'text',
20
+ 'type' => 'text',
21
+ 'is_html_allowed_on_front' => true,
22
+ 'global' => true,
23
+ 'visible' => true,
24
+ 'required' => false,
25
+ 'user_defined' => false,
26
+ 'default' => '',
27
+ 'visible_on_front' => true
28
+ ));
29
+
30
+ $setup->addAttribute('catalog_product', 'item_width', array(
31
+ 'backend' => '',
32
+ 'source' => '',
33
+ 'entity_model' => 'catalog/product',
34
+ 'label' => 'Item Width',
35
+ //'group' => 'ItemSize',
36
+ 'group' => 'For Shipping Item Information',
37
+ 'input' => 'text',
38
+ 'type' => 'text',
39
+ 'is_html_allowed_on_front' => true,
40
+ 'global' => true,
41
+ 'visible' => true,
42
+ 'required' => false,
43
+ 'user_defined' => false,
44
+ 'default' => '',
45
+ 'visible_on_front' => true
46
+ ));
47
+
48
+ $setup->addAttribute('catalog_product', 'item_dim', array(
49
+ 'backend' => '',
50
+ 'source' => '',
51
+ 'entity_model' => 'catalog/product',
52
+ 'label' => 'Item Length',
53
+ //'group' => 'ItemSize',
54
+ 'group' => 'For Shipping Item Information',
55
+ 'input' => 'text',
56
+ 'type' => 'text',
57
+ 'is_html_allowed_on_front' => true,
58
+ 'global' => true,
59
+ 'visible' => true,
60
+ 'required' => false,
61
+ 'user_defined' => false,
62
+ 'default' => '',
63
+ 'visible_on_front' => true
64
+ ));
65
+
66
+ $setup->addAttribute('catalog_product', 'item_weight', array(
67
+ 'backend' => '',
68
+ 'source' => '',
69
+ 'entity_model' => 'catalog/product',
70
+ 'label' => 'Item Weight',
71
+ //'group' => 'ItemSize',
72
+ 'group' => 'For Shipping Item Information',
73
+ 'input' => 'text',
74
+ 'type' => 'text',
75
+ 'is_html_allowed_on_front' => true,
76
+ 'global' => true,
77
+ 'visible' => true,
78
+ 'required' => false,
79
+ 'user_defined' => false,
80
+ 'default' => '',
81
+ 'visible_on_front' => true
82
+ ));
83
+
84
  $installer->endSetup();
app/design/frontend/default/default/layout/ship.xml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <block type="core/template" name="unique_name_here" template="ship/footer/js.phtml" />
6
+ </reference>
7
+
8
+ <reference name="head">
9
+ <!--<block type="core/text" name="external.cdn.jquery" before="-">
10
+ <action method="setText">
11
+ <text>
12
+ <![CDATA[
13
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
14
+ <script type="text/javascript">jQuery.noConflict();</script>
15
+ ]]>
16
+ </text>
17
+ </action>
18
+ </block>-->
19
+ <!--<action method="addCss"><stylesheet>ship/css/jquery.autoSuggest.css</stylesheet></action>
20
+ <action method="addItem"><type>skin_js</type><name>ship/js/location_script.js</name><params/></action>
21
+ <action method="addItem"><type>skin_js</type><name>ship/js/jquery.autoSuggest.js</name><params/></action>-->
22
+ </reference>
23
+
24
+ <!--<reference name="head">
25
+ <action method="addItem"><type>skin_js</type><name>ship/js/jquery-1.11.0.js</name><params/></action>
26
+ </reference>-->
27
+ </default>
28
+
29
+ <checkout_cart_index>
30
+ <reference name="checkout.cart.shipping">
31
+ <action method="setTemplate"><template>ship/shipping.phtml</template></action>
32
+ </reference>
33
+
34
+ <reference name="checkout.cart.totals">
35
+ <action method="setTemplate"><template>ship/checkout/cart/totals.phtml</template></action>
36
+ </reference>
37
+
38
+ </checkout_cart_index>
39
+
40
+ <catalog_product_view translate="label">
41
+ <reference name="right">
42
+ <block type="checkout/cart_shipping" name="checkout.cart.shipping" as="shipping" template="ship/product_shipping.phtml"/>
43
+ </reference>
44
+ </catalog_product_view>
45
+ </layout>
app/design/frontend/default/default/template/ship/bkp_29-5-2014--working----product_shipping.phtml DELETED
@@ -1,397 +0,0 @@
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) 2013 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
- <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
28
- <?php
29
-
30
- $country_val = Mage::getSingleton('core/session')->getCountryVal();
31
- $postocde_val = Mage::getSingleton('core/session')->getPostcodeVal();
32
- $regionid_val = Mage::getSingleton('core/session')->getRegionIdVal();
33
- $region_val = Mage::getSingleton('core/session')->getRegionVal();
34
-
35
- ?>
36
- <div class="shipping_product">
37
- <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
38
- <div class="shipping-form">
39
- <form action="<?php echo $this->getUrl('ship/index/index/') ?>" method="post" id="shipping-zip-form">
40
- <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
41
- <ul class="form-list">
42
- <li>
43
- <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
44
- <div class="input-box">
45
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
46
- </div>
47
- </li>
48
- <?php //if($this->getStateActive()):
49
- //echo $this->isStateProvinceRequired(); //die('st');
50
- ?>
51
- <li>
52
- <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('State/Province') ?></label>
53
- <div class="input-box">
54
- <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
55
- <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
56
- </select>
57
- <script type="text/javascript">
58
- //<![CDATA[
59
- $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
60
- //]]>
61
- </script>
62
- <input type="text" id="region" name="region" value="<?php if($region_val){ echo $region_val;} else { echo $this->escapeHtml($this->getEstimateRegion()); } ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text validate-alpha required-entry" style="display:none;" />
63
- </div>
64
- </li>
65
- <?php //endif; ?>
66
- <?php if($this->getCityActive()): ?>
67
- <li>
68
- <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
69
- <div class="input-box">
70
- <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
71
- </div>
72
- </li>
73
- <?php endif; ?>
74
- <li>
75
- <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
76
- <div class="input-box">
77
- <input class="input-text validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php if($postocde_val){ echo $postocde_val;} else { echo $this->escapeHtml($this->getEstimatePostcode()); } ?>" />
78
- </div>
79
- </li>
80
- </ul>
81
- <div class="buttons-set">
82
- <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
83
- </div>
84
- </form>
85
- <script type="text/javascript">
86
- //<![CDATA[
87
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
88
- //]]>
89
- </script>
90
-
91
- <?php //if (($_shippingRateGroups = $this->getEstimateRates())): ?>
92
- <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
93
- <dl class="sp-methods">
94
-
95
- <?php
96
-
97
- //$quotes_val = Mage::register('store_id', Mage::app()->getStore()->getId());
98
- //$quotes_val = Mage::registry('quotes_val');
99
- //echo '<pre>'; print_r($quotes_val); //die('val');
100
-
101
- //$val = Mage::getSingleton('checkout/session')->getQuote();
102
-
103
- $quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
104
-
105
-
106
-
107
- //echo $country_val. $postocde_val . $regionid_val . $region_val; //die('data');
108
-
109
- //echo '<pre>'; print_r($quotes_val);
110
- //die('sess set');
111
-
112
- if($quotes_val){
113
-
114
- ?>
115
- <dt><?php echo $this->__('Carrier');?></dt>
116
- <dd>
117
- <ul>
118
-
119
- <?php
120
-
121
- function cmp($a, $b) {
122
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
123
-
124
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['name'], $b['name']); }
125
- }
126
-
127
- uasort($quotes_val, 'cmp');
128
-
129
- foreach($quotes_val as $key => $val) {
130
- //echo count($val); die;
131
- //echo $key.'<br>';
132
- //echo $quotes_val[$key]['total']; ?>
133
-
134
- <li>
135
- <label for="s_method">
136
- <?php
137
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
138
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
139
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
140
-
141
- if($display_showcouriername == '1'){
142
- echo $key;
143
- }
144
- if($display_showcouriername == '1' && $display_surcharge == '1') {
145
- echo ' + '.$this->__("Handling Charge");
146
- }
147
- ?>
148
- <?php //echo $key.'&nbsp;&nbsp;&nbsp;'; ?>
149
- <?php $curr_symbol = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();?>
150
- <span class="price">
151
- <?php
152
- $tmp_display_surcharge = $quotes_val[$key]['total'] + $display_surcharge1;
153
- if($display_surcharge == '1'){
154
- echo $curr_symbol. number_format($tmp_display_surcharge,2);
155
- } else {
156
- echo $curr_symbol. number_format($quotes_val[$key]['total'],2);
157
- }
158
-
159
- ?>
160
- </span>
161
- </label>
162
- </li>
163
-
164
- <?php } ?>
165
-
166
- </ul>
167
- </dd>
168
- <?php } ?>
169
-
170
- <?php /*
171
- function cmp($a, $b) {
172
- $display_quote = Mage::getStoreConfig('mycustom_section/displayoptions/quotedisplay');
173
-
174
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['name'], $b['name']); }
175
- }
176
-
177
- foreach ($_shippingRateGroups as $code => $_rates): ?>
178
- <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
179
- <dd>
180
- <ul>
181
- <?php
182
-
183
-
184
- usort($_rates, 'cmp');
185
-
186
- foreach ($_rates as $_rate):
187
-
188
- // echo '<pre>'; print_r($_rate->getData());
189
- if($_rate->getMethodTitle()){
190
- ?>
191
- <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
192
- <?php if ($_rate->getErrorMessage()): ?>
193
- <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
194
- <?php else: ?>
195
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
196
- <label for="s_method_<?php echo $_rate->getCode() ?>">
197
-
198
- <?php
199
- $display_showcouriername = Mage::getStoreConfig('mycustom_section/displayoptions/showcouriernames');
200
- if($display_showcouriername == '1'){
201
- echo $this->escapeHtml($_rate->getMethodTitle());
202
- }
203
- ?>
204
-
205
- <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
206
- <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
207
- <?php echo $_excl; ?>
208
- <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
209
- (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
210
- <?php endif; ?>
211
- </label>
212
- <?php endif ?>
213
- </li>
214
- <?php }
215
- endforeach;
216
- // die('rate'); ?>
217
-
218
- </ul>
219
- </dd>
220
- <?php endforeach; ?>
221
- */?>
222
-
223
-
224
- </dl>
225
- <?php /*?><div class="buttons-set">
226
- <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
227
- </div><?php */?>
228
-
229
- </form>
230
- <?php //endif; ?>
231
- <script type="text/javascript">
232
- //<![CDATA[
233
- var coShippingMethodForm = new VarienForm('shipping-zip-form');
234
- var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
235
-
236
- coShippingMethodForm.submit = function () {
237
- var country = $F('country');
238
- var optionalZip = false;
239
- var optionregion = false;
240
-
241
- for (i=0; i < countriesWithOptionalZip.length; i++) {
242
- if (countriesWithOptionalZip[i] == country) {
243
- optionalZip = true;
244
- }
245
- }
246
- if (optionalZip) {
247
- $('postcode').removeClassName('required-entry');
248
- }
249
- else {
250
- $('postcode').addClassName('required-entry');
251
- }
252
-
253
- if (optionregion) {
254
- $('region').removeClassName('required-entry');
255
- }
256
- else {
257
- $('region').addClassName('required-entry');
258
- }
259
-
260
- return VarienForm.prototype.submit.bind(coShippingMethodForm)();
261
- }
262
- //]]>
263
- </script>
264
- </div>
265
- </div>
266
-
267
- <style type="text/css">
268
- .shipping_product {border: 1px solid #D0CBC1; margin: 0 0 18px; padding: 10px;}
269
- .shipping-form,.form-list .input-box, .form-list select {width:100%;}
270
- .form-list input.input-text{width:97%;}
271
- </style>
272
-
273
-
274
- <?php /*
275
- <div class="block block-shipping-estimate">
276
- <div class="block-title">
277
- <strong><span>Calculate Shipping</span></strong>
278
- </div>
279
- <div class="block-content">
280
- <p class="block-subtitle">Enter your destination to get a shipping estimate.</p>
281
- <ul id="shipping-estimation-form" class="shipping-estimation-form">
282
- <li class="item odd">
283
- <label class="required" for="estimate_country"><em>*</em>Country</label>
284
- <div class="input-box">
285
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
286
- </div>
287
- </li>
288
- <li class="item even">
289
- <label for="estimate_region_id">State/Province</label>
290
- <div class="input-box">
291
- <select style="display: none;" title="State/Province" name="estimate[region_id]" id="estimate_region_id" defaultvalue="" class="">
292
- <option value="">Please select an option</option>
293
- </select><div style="display: none;" id="advice-required-entry-estimate_region_id" class="validation-advice">This is a required field.</div>
294
- <script type="text/javascript">
295
- //&lt;![CDATA[
296
- $('estimate_region_id').setAttribute('defaultValue', '');
297
- //]]&gt;
298
- </script>
299
- <input type="text" style="" class="input-text validation-passed" title="State/Province" value="" name="estimate[region]" id="estimate_region">
300
- </div>
301
- </li>
302
- <script type="text/javascript">
303
- //&lt;![CDATA[
304
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
305
- //]]&gt;
306
- </script>
307
- <li class="item odd">
308
- <label for="city">City</label>
309
- <div class="input-box">
310
- <input type="text" value="" name="estimate[city]" id="estimate_city" class="input-text validation-passed">
311
- </div>
312
- </li>
313
- <li class="item even">
314
- <label for="estimate_postcode">Zip/Postal Code</label>
315
- <div class="input-box">
316
- <input type="text" value="" name="estimate[postcode]" id="estimate_postcode" class="input-text validate-postcode validation-passed">
317
- </div>
318
- </li>
319
- <li class="item odd">
320
- <label for="estimate_coupon_code">Coupon Code</label>
321
- <div class="input-box">
322
- <input type="text" value="" name="estimate[coupon_code]" id="estimate_coupon_code" class="input-text validation-passed">
323
- </div>
324
- </li>
325
- <li class="item radio last even">
326
- <label for="estimate_cart_yes">Include Cart Items</label>
327
- <div class="input-box">
328
- <input type="radio" checked="checked" value="1" name="estimate[cart]" id="estimate_cart_yes">Yes <input type="radio" value="0" name="estimate[cart]" id="estimate_cart_no"> No </div>
329
- </li>
330
- </ul>
331
- <script type="text/javascript">decorateList('shipping-estimation-form');</script>
332
- <div class="actions">
333
- <span style="display: none;" id="shipping-estimate-loading-message" class="please-wait f-left">
334
- Loading rates... </span>
335
- <div class="f-right">
336
- <button class="button" onclick="estimateProductShipping()" title="Get a Quote" type="button"><span><span>Get a Quote</span></span></button>
337
- </div>
338
- </div>
339
- </div>
340
- <div style="" id="shipping-estimate-results"><div class="block-shipping-results">
341
- <div class="block-title">
342
- <strong><span>Shipping Rates</span></strong>
343
- </div>
344
- <div class="block-content">
345
- <dl>
346
- <dt>Free Shipping</dt>
347
- <dd>
348
- <ul>
349
- <li>
350
- Free <span class="price">$0.00</span> </li>
351
- </ul>
352
- </dd>
353
- <dt>Flat Rate</dt>
354
- <dd>
355
- <ul>
356
- <li>
357
- Fixed <span class="price">$5.00</span> </li>
358
- </ul>
359
- </dd>
360
- </dl>
361
- </div>
362
- </div></div>
363
- </div>
364
-
365
-
366
- <script type="text/javascript">
367
- //&lt;![CDATA[
368
- function estimateProductShipping()
369
- {
370
- var estimationUrl = 'http://localhost/test-magento/index.php/ship/index/product/';
371
- var items = $$(['.shipping-estimation-form input',
372
- '.shipping-estimation-form select',
373
- '#product_addtocart_form input',
374
- '#product_addtocart_form select']);
375
-
376
- var validationResult = true;
377
-
378
- // Check the valid input
379
- if (!items.map(Validation.validate).all()) {
380
- return;
381
- }
382
-
383
- var parameters = Form.serializeElements(items, true);
384
- $('shipping-estimate-loading-message').show();
385
- $('shipping-estimate-results').hide();
386
- new Ajax.Updater('shipping-estimate-results', estimationUrl, {
387
- parameters: parameters,
388
- onComplete: function() {
389
- $('shipping-estimate-loading-message').hide();
390
- $('shipping-estimate-results').show();
391
- }
392
- });
393
-
394
- }
395
- //]]&gt;
396
- </script>
397
- */?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/default/default/template/ship/bkp_29-5-2014--working----shipping.phtml DELETED
@@ -1,179 +0,0 @@
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) 2013 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
- <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
28
- <div class="shipping">
29
- <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
30
- <div class="shipping-form">
31
- <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
32
- <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
33
- <ul class="form-list">
34
- <li>
35
- <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
36
- <div class="input-box">
37
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
38
- </div>
39
- </li>
40
- <?php //if($this->getStateActive()): ?>
41
- <li>
42
- <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('State/Province') ?></label>
43
- <div class="input-box">
44
- <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
45
- <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
46
- </select>
47
- <script type="text/javascript">
48
- //<![CDATA[
49
- $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
50
- //]]>
51
- </script>
52
- <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getEstimateRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text validate-alpha required-entry" style="display:none;" />
53
- </div>
54
- </li>
55
- <?php //endif; ?>
56
- <?php if($this->getCityActive()): ?>
57
- <li>
58
- <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
59
- <div class="input-box">
60
- <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
61
- </div>
62
- </li>
63
- <?php endif; ?>
64
- <li>
65
- <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
66
- <div class="input-box">
67
- <input class="input-text validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" />
68
- </div>
69
- </li>
70
- </ul>
71
- <div class="buttons-set">
72
- <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
73
- </div>
74
- </form>
75
- <script type="text/javascript">
76
- //<![CDATA[
77
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
78
- //]]>
79
- </script>
80
-
81
- <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
82
- <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
83
- <dl class="sp-methods">
84
-
85
- <?php
86
- function cmp($a, $b) {
87
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
88
-
89
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['name'], $b['name']); }
90
- }
91
-
92
- // get data
93
- foreach ($_shippingRateGroups as $code => $_rates): ?>
94
- <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
95
- <dd>
96
- <ul>
97
- <?php
98
-
99
-
100
- usort($_rates, 'cmp');
101
-
102
- foreach ($_rates as $_rate):
103
-
104
- if($_rate->getMethodTitle()){
105
- ?>
106
- <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
107
- <?php if ($_rate->getErrorMessage()): ?>
108
- <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
109
- <?php else: ?>
110
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
111
- <label for="s_method_<?php echo $_rate->getCode() ?>">
112
-
113
- <?php
114
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
115
- if($display_showcouriername == '1'){
116
- echo $this->escapeHtml($_rate->getMethodTitle());
117
- }
118
- ?>
119
-
120
- <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
121
- <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
122
- <?php echo $_excl; ?>
123
- <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
124
- (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
125
- <?php endif; ?>
126
- </label>
127
- <?php endif ?>
128
- </li>
129
- <?php }
130
- endforeach;
131
- // die('rate'); ?>
132
- <?php /*?> <li>
133
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
134
- <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitleOne()) ?>
135
- <?php $_incl = $this->getShippingPrice($_rate->getPriceOne(), true); ?>
136
- </li><?php */?>
137
- </ul>
138
- </dd>
139
- <?php endforeach; ?>
140
- </dl>
141
- <div class="buttons-set">
142
- <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
143
- </div>
144
- </form>
145
- <?php endif; ?>
146
- <script type="text/javascript">
147
- //<![CDATA[
148
- var coShippingMethodForm = new VarienForm('shipping-zip-form');
149
- var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
150
-
151
- coShippingMethodForm.submit = function () {
152
- var country = $F('country');
153
- var optionalZip = false;
154
- var optionregion = false;
155
-
156
- for (i=0; i < countriesWithOptionalZip.length; i++) {
157
- if (countriesWithOptionalZip[i] == country) {
158
- optionalZip = true;
159
- }
160
- }
161
- if (optionalZip) {
162
- $('postcode').removeClassName('required-entry');
163
- }
164
- else {
165
- $('postcode').addClassName('required-entry');
166
- }
167
- if (optionregion) {
168
- $('region').removeClassName('required-entry');
169
- }
170
- else {
171
- $('region').addClassName('required-entry');
172
- }
173
-
174
- return VarienForm.prototype.submit.bind(coShippingMethodForm)();
175
- }
176
- //]]>
177
- </script>
178
- </div>
179
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/default/default/template/ship/bkp_30-5-2014---product_shipping.phtml DELETED
@@ -1,437 +0,0 @@
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) 2013 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
- <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
28
- <?php
29
-
30
- $country_val = Mage::getSingleton('core/session')->getCountryVal();
31
- $postocde_val = Mage::getSingleton('core/session')->getPostcodeVal();
32
- $regionid_val = Mage::getSingleton('core/session')->getRegionIdVal();
33
- $region_val = Mage::getSingleton('core/session')->getRegionVal();
34
-
35
- ?>
36
- <div class="shipping_product">
37
- <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
38
- <div class="shipping-form">
39
- <form action="<?php echo $this->getUrl('ship/index/index/') ?>" method="post" id="shipping-zip-form">
40
- <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
41
- <ul class="form-list">
42
- <li>
43
- <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
44
- <div class="input-box">
45
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
46
- </div>
47
- </li>
48
- <?php //if($this->getStateActive()):
49
- //echo $this->isStateProvinceRequired(); //die('st');
50
- ?>
51
- <li>
52
- <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('State/Province') ?></label>
53
- <div class="input-box">
54
- <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
55
- <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
56
- </select>
57
- <script type="text/javascript">
58
- //<![CDATA[
59
- $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
60
- //]]>
61
- </script>
62
- <input type="text" id="region" name="region" value="<?php if($region_val){ echo $region_val;} else { echo $this->escapeHtml($this->getEstimateRegion()); } ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text validate-alpha required-entry" style="display:none;" />
63
- </div>
64
- </li>
65
- <?php //endif; ?>
66
- <?php if($this->getCityActive()): ?>
67
- <li>
68
- <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
69
- <div class="input-box">
70
- <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
71
- </div>
72
- </li>
73
- <?php endif; ?>
74
- <li>
75
- <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
76
- <div class="input-box">
77
- <input class="input-text validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php if($postocde_val){ echo $postocde_val;} else { echo $this->escapeHtml($this->getEstimatePostcode()); } ?>" />
78
- </div>
79
- </li>
80
- </ul>
81
- <div class="buttons-set">
82
- <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
83
- </div>
84
- </form>
85
- <script type="text/javascript">
86
- //<![CDATA[
87
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
88
- //]]>
89
- </script>
90
-
91
- <?php //if (($_shippingRateGroups = $this->getEstimateRates())): ?>
92
- <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
93
- <dl class="sp-methods">
94
-
95
- <?php
96
-
97
- //$quotes_val = Mage::register('store_id', Mage::app()->getStore()->getId());
98
- //$quotes_val = Mage::registry('quotes_val');
99
- //echo '<pre>'; print_r($quotes_val); //die('val');
100
-
101
- //$val = Mage::getSingleton('checkout/session')->getQuote();
102
-
103
- $quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
104
-
105
-
106
-
107
- //echo $country_val. $postocde_val . $regionid_val . $region_val; //die('data');
108
-
109
- //echo '<pre>'; print_r($quotes_val);
110
- //die('sess set');
111
-
112
- if($quotes_val){
113
-
114
- ?>
115
- <dt><?php echo $this->__('Carrier');?></dt>
116
- <dd>
117
- <ul>
118
-
119
- <?php
120
- /*
121
- function cmp($a, $b) {
122
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
123
-
124
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['name'], $b['name']); }
125
- }
126
-
127
- uasort($quotes_val, 'cmp'); */
128
-
129
- //foreach($quotes_val as $key => $val) {
130
-
131
- $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
132
- $available_carriers = explode( ',', $display_carriers);
133
-
134
- foreach ($quotes_val as $key => $val):
135
-
136
- //echo '<pre>'; print_r($quotes_val);
137
-
138
- if(in_array($key,$available_carriers)) {
139
- //echo '<br>'.$key . ' - matched<br>';
140
- $xyz[$key] = $quotes_val[$key];
141
- }
142
-
143
-
144
-
145
-
146
-
147
- /*echo $key.'<br>';
148
- echo '<pre>'; print_r($xyz);
149
- die('xyz');*/
150
-
151
- endforeach; //die;
152
- //echo '<pre>'; print_r($xyz); die;
153
-
154
- foreach($xyz as $key => $abc):
155
- //echo $key;
156
- //echo '<pre>'; print_r($abc);
157
-
158
- //echo count($val); die;
159
- //echo $key.'<br>';
160
- //echo $quotes_val[$key]['total'];
161
-
162
- if($key){
163
- ?>
164
-
165
- <li>
166
- <label for="s_method">
167
- <?php
168
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
169
- $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
170
- $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
171
-
172
- if($display_showcouriername == '1'){
173
- //echo $key;
174
- if($key=='fastway'){echo $this->__("Fastway"); }
175
- if($key=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
176
- if($key=='couriers_please'){echo $this->__("Couriers Please"); }
177
- if($key=='allied'){echo $this->__("Allied Express"); }
178
- if($key=='toll'){echo $this->__("Toll"); }
179
- if($key=='mainfreight'){echo $this->__("Mainfreight"); }
180
- if($key=='northline'){echo $this->__("Northline"); }
181
-
182
- }
183
- if($display_showcouriername == '1' && $display_surcharge == '1') {
184
- echo ' + '.$this->__("Handling Charge");
185
- }
186
- ?>
187
- <?php //echo $key.'&nbsp;&nbsp;&nbsp;'; ?>
188
- <?php $curr_symbol = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();?>
189
- <span class="price">
190
- <?php
191
- $tmp_display_surcharge = $abc['total'] + $display_surcharge1;
192
- if($display_surcharge == '1'){
193
- echo $curr_symbol. number_format($tmp_display_surcharge,2);
194
- } else {
195
- echo $curr_symbol. number_format($abc['total'],2);
196
- }
197
-
198
- ?>
199
- </span>
200
- </label>
201
- </li>
202
-
203
- <?php }
204
- endforeach; //} ?>
205
-
206
- </ul>
207
- </dd>
208
- <?php } ?>
209
-
210
- <?php /*
211
- function cmp($a, $b) {
212
- $display_quote = Mage::getStoreConfig('mycustom_section/displayoptions/quotedisplay');
213
-
214
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['name'], $b['name']); }
215
- }
216
-
217
- foreach ($_shippingRateGroups as $code => $_rates): ?>
218
- <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
219
- <dd>
220
- <ul>
221
- <?php
222
-
223
-
224
- usort($_rates, 'cmp');
225
-
226
- foreach ($_rates as $_rate):
227
-
228
- // echo '<pre>'; print_r($_rate->getData());
229
- if($_rate->getMethodTitle()){
230
- ?>
231
- <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
232
- <?php if ($_rate->getErrorMessage()): ?>
233
- <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
234
- <?php else: ?>
235
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
236
- <label for="s_method_<?php echo $_rate->getCode() ?>">
237
-
238
- <?php
239
- $display_showcouriername = Mage::getStoreConfig('mycustom_section/displayoptions/showcouriernames');
240
- if($display_showcouriername == '1'){
241
- echo $this->escapeHtml($_rate->getMethodTitle());
242
- }
243
- ?>
244
-
245
- <?php $_excl = $this->getShippingPrice($_rate->getPrice(), $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
246
- <?php $_incl = $this->getShippingPrice($_rate->getPrice(), true); ?>
247
- <?php echo $_excl; ?>
248
- <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
249
- (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
250
- <?php endif; ?>
251
- </label>
252
- <?php endif ?>
253
- </li>
254
- <?php }
255
- endforeach;
256
- // die('rate'); ?>
257
-
258
- </ul>
259
- </dd>
260
- <?php endforeach; ?>
261
- */?>
262
-
263
-
264
- </dl>
265
- <?php /*?><div class="buttons-set">
266
- <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
267
- </div><?php */?>
268
-
269
- </form>
270
- <?php //endif; ?>
271
- <script type="text/javascript">
272
- //<![CDATA[
273
- var coShippingMethodForm = new VarienForm('shipping-zip-form');
274
- var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
275
-
276
- coShippingMethodForm.submit = function () {
277
- var country = $F('country');
278
- var optionalZip = false;
279
- var optionregion = false;
280
-
281
- for (i=0; i < countriesWithOptionalZip.length; i++) {
282
- if (countriesWithOptionalZip[i] == country) {
283
- optionalZip = true;
284
- }
285
- }
286
- if (optionalZip) {
287
- $('postcode').removeClassName('required-entry');
288
- }
289
- else {
290
- $('postcode').addClassName('required-entry');
291
- }
292
-
293
- if (optionregion) {
294
- $('region').removeClassName('required-entry');
295
- }
296
- else {
297
- $('region').addClassName('required-entry');
298
- }
299
-
300
- return VarienForm.prototype.submit.bind(coShippingMethodForm)();
301
- }
302
- //]]>
303
- </script>
304
- </div>
305
- </div>
306
-
307
- <style type="text/css">
308
- .shipping_product {border: 1px solid #D0CBC1; margin: 0 0 18px; padding: 10px;}
309
- .shipping-form,.form-list .input-box, .form-list select {width:100%;}
310
- .form-list input.input-text{width:97%;}
311
- </style>
312
-
313
-
314
- <?php /*
315
- <div class="block block-shipping-estimate">
316
- <div class="block-title">
317
- <strong><span>Calculate Shipping</span></strong>
318
- </div>
319
- <div class="block-content">
320
- <p class="block-subtitle">Enter your destination to get a shipping estimate.</p>
321
- <ul id="shipping-estimation-form" class="shipping-estimation-form">
322
- <li class="item odd">
323
- <label class="required" for="estimate_country"><em>*</em>Country</label>
324
- <div class="input-box">
325
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
326
- </div>
327
- </li>
328
- <li class="item even">
329
- <label for="estimate_region_id">State/Province</label>
330
- <div class="input-box">
331
- <select style="display: none;" title="State/Province" name="estimate[region_id]" id="estimate_region_id" defaultvalue="" class="">
332
- <option value="">Please select an option</option>
333
- </select><div style="display: none;" id="advice-required-entry-estimate_region_id" class="validation-advice">This is a required field.</div>
334
- <script type="text/javascript">
335
- //&lt;![CDATA[
336
- $('estimate_region_id').setAttribute('defaultValue', '');
337
- //]]&gt;
338
- </script>
339
- <input type="text" style="" class="input-text validation-passed" title="State/Province" value="" name="estimate[region]" id="estimate_region">
340
- </div>
341
- </li>
342
- <script type="text/javascript">
343
- //&lt;![CDATA[
344
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
345
- //]]&gt;
346
- </script>
347
- <li class="item odd">
348
- <label for="city">City</label>
349
- <div class="input-box">
350
- <input type="text" value="" name="estimate[city]" id="estimate_city" class="input-text validation-passed">
351
- </div>
352
- </li>
353
- <li class="item even">
354
- <label for="estimate_postcode">Zip/Postal Code</label>
355
- <div class="input-box">
356
- <input type="text" value="" name="estimate[postcode]" id="estimate_postcode" class="input-text validate-postcode validation-passed">
357
- </div>
358
- </li>
359
- <li class="item odd">
360
- <label for="estimate_coupon_code">Coupon Code</label>
361
- <div class="input-box">
362
- <input type="text" value="" name="estimate[coupon_code]" id="estimate_coupon_code" class="input-text validation-passed">
363
- </div>
364
- </li>
365
- <li class="item radio last even">
366
- <label for="estimate_cart_yes">Include Cart Items</label>
367
- <div class="input-box">
368
- <input type="radio" checked="checked" value="1" name="estimate[cart]" id="estimate_cart_yes">Yes <input type="radio" value="0" name="estimate[cart]" id="estimate_cart_no"> No </div>
369
- </li>
370
- </ul>
371
- <script type="text/javascript">decorateList('shipping-estimation-form');</script>
372
- <div class="actions">
373
- <span style="display: none;" id="shipping-estimate-loading-message" class="please-wait f-left">
374
- Loading rates... </span>
375
- <div class="f-right">
376
- <button class="button" onclick="estimateProductShipping()" title="Get a Quote" type="button"><span><span>Get a Quote</span></span></button>
377
- </div>
378
- </div>
379
- </div>
380
- <div style="" id="shipping-estimate-results"><div class="block-shipping-results">
381
- <div class="block-title">
382
- <strong><span>Shipping Rates</span></strong>
383
- </div>
384
- <div class="block-content">
385
- <dl>
386
- <dt>Free Shipping</dt>
387
- <dd>
388
- <ul>
389
- <li>
390
- Free <span class="price">$0.00</span> </li>
391
- </ul>
392
- </dd>
393
- <dt>Flat Rate</dt>
394
- <dd>
395
- <ul>
396
- <li>
397
- Fixed <span class="price">$5.00</span> </li>
398
- </ul>
399
- </dd>
400
- </dl>
401
- </div>
402
- </div></div>
403
- </div>
404
-
405
-
406
- <script type="text/javascript">
407
- //&lt;![CDATA[
408
- function estimateProductShipping()
409
- {
410
- var estimationUrl = 'http://localhost/test-magento/index.php/ship/index/product/';
411
- var items = $$(['.shipping-estimation-form input',
412
- '.shipping-estimation-form select',
413
- '#product_addtocart_form input',
414
- '#product_addtocart_form select']);
415
-
416
- var validationResult = true;
417
-
418
- // Check the valid input
419
- if (!items.map(Validation.validate).all()) {
420
- return;
421
- }
422
-
423
- var parameters = Form.serializeElements(items, true);
424
- $('shipping-estimate-loading-message').show();
425
- $('shipping-estimate-results').hide();
426
- new Ajax.Updater('shipping-estimate-results', estimationUrl, {
427
- parameters: parameters,
428
- onComplete: function() {
429
- $('shipping-estimate-loading-message').hide();
430
- $('shipping-estimate-results').show();
431
- }
432
- });
433
-
434
- }
435
- //]]&gt;
436
- </script>
437
- */?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/default/default/template/ship/bkp_30-5-2014---shipping.phtml DELETED
@@ -1,237 +0,0 @@
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) 2013 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
- <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
28
- <div class="shipping">
29
- <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
30
- <div class="shipping-form">
31
- <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
32
- <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
33
- <ul class="form-list">
34
- <li>
35
- <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
36
- <div class="input-box">
37
- <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
38
- </div>
39
- </li>
40
- <?php //if($this->getStateActive()): ?>
41
- <li>
42
- <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('State/Province') ?></label>
43
- <div class="input-box">
44
- <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
45
- <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
46
- </select>
47
- <script type="text/javascript">
48
- //<![CDATA[
49
- $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
50
- //]]>
51
- </script>
52
- <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getEstimateRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text validate-alpha required-entry" style="display:none;" />
53
- </div>
54
- </li>
55
- <?php //endif; ?>
56
- <?php if($this->getCityActive()): ?>
57
- <li>
58
- <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
59
- <div class="input-box">
60
- <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
61
- </div>
62
- </li>
63
- <?php endif; ?>
64
- <li>
65
- <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
66
- <div class="input-box">
67
- <input class="input-text validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" />
68
- </div>
69
- </li>
70
- </ul>
71
- <div class="buttons-set">
72
- <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
73
- </div>
74
- </form>
75
- <script type="text/javascript">
76
- //<![CDATA[
77
- new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
78
- //]]>
79
- </script>
80
-
81
- <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
82
- <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
83
- <dl class="sp-methods">
84
-
85
- <?php
86
- /*function cmp($a, $b) {
87
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
88
-
89
- if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['method_title'], $b['method_title']); }
90
- } */
91
- function cmp($key) {
92
- return function ($a, $b) use ($key) {
93
- return strnatcmp($a[$key], $b[$key]);
94
- };
95
- }
96
-
97
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
98
-
99
- /* function build_sorter($key) {
100
- return function ($a, $b) use ($key) {
101
- return strnatcmp($a[$key], $b[$key]);
102
- };
103
- }*/
104
-
105
-
106
- // get data
107
- foreach ($_shippingRateGroups as $code => $_rates): ?>
108
- <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt>
109
- <dd>
110
- <ul>
111
- <?php
112
-
113
-
114
- //usort($_rates, 'cmp');
115
-
116
- foreach ($_rates as $_rate):
117
-
118
- $xyz[] = $_rate->getData();
119
- //echo '<pre>'; print_r($_rate->getData());
120
-
121
- endforeach;
122
-
123
- endforeach;
124
-
125
- // echo '<pre>'; print_r($xyz); die;
126
-
127
- // sorting
128
-
129
- if($display_quote == 'display_cheapest'){ usort($xyz, cmp('price')); }
130
- if($display_quote == 'display_all_quotes'){ usort($xyz, cmp('method_title')); }
131
- //usort($xyz, cmp('price'));
132
-
133
- /*
134
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
135
-
136
- if($display_quote == 'display_cheapest'){ usort($xyz, build_sorter('price')); }
137
- if($display_quote == 'display_all_quotes'){ usort($xyz, build_sorter('price')); }
138
- if($display_quote == 'display_cheapest_fastest'){ usort($xyz, build_sorter('price')); }
139
- */
140
-
141
-
142
- //echo '<pre>'; print_r($xyz);
143
-
144
- // display
145
- foreach($xyz as $key => $abc):
146
- //echo '<pre>'; print_r($abc); die('ship');
147
- //endforeach;
148
- //echo $abc['code'];die;
149
-
150
-
151
- if($abc['method_title']){
152
- ?>
153
- <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
154
- <?php if ($_rate->getErrorMessage()): ?>
155
- <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
156
- <?php else: ?>
157
- <input name="estimate_method" type="radio" value="<?php echo $abc['code']; //$this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $abc['code'] ?>"<?php if($abc['code']===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
158
- <label for="s_method_<?php echo $abc['code']; ?>">
159
-
160
- <?php
161
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
162
- if($display_showcouriername == '1'){
163
- echo $abc['method_title'];
164
- /*
165
- if($abc['method_title']=='fastway'){echo $this->__("Fastway"); }
166
- if($abc['method_title']=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
167
- if($abc['method_title']=='couriers_please'){echo $this->__("Couriers Please"); }
168
- if($abc['method_title']=='allied'){echo $this->__("Allied Express"); }
169
- if($abc['method_title']=='toll'){echo $this->__("Toll"); }
170
- if($abc['method_title']=='mainfreight'){echo $this->__("Mainfreight"); }
171
- if($abc['method_title']=='northline'){echo $this->__("Northline"); }
172
- */
173
-
174
- //$this->escapeHtml($_rate->getMethodTitle());
175
- }
176
- ?>
177
-
178
- <?php $_excl = $this->getShippingPrice($abc['price'], $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
179
- <?php $_incl = $this->getShippingPrice($abc['price'], true); ?>
180
- <?php echo $_excl; ?>
181
- <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
182
- (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
183
- <?php endif; ?>
184
- </label>
185
- <?php endif ?>
186
- </li>
187
- <?php }
188
- endforeach;
189
- // die('rate'); ?>
190
- <?php /*?> <li>
191
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
192
- <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitleOne()) ?>
193
- <?php $_incl = $this->getShippingPrice($_rate->getPriceOne(), true); ?>
194
- </li><?php */?>
195
- </ul>
196
- </dd>
197
- <?php //endforeach; ?>
198
- </dl>
199
- <div class="buttons-set">
200
- <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
201
- </div>
202
- </form>
203
- <?php endif; ?>
204
- <script type="text/javascript">
205
- //<![CDATA[
206
- var coShippingMethodForm = new VarienForm('shipping-zip-form');
207
- var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
208
-
209
- coShippingMethodForm.submit = function () {
210
- var country = $F('country');
211
- var optionalZip = false;
212
- var optionregion = false;
213
-
214
- for (i=0; i < countriesWithOptionalZip.length; i++) {
215
- if (countriesWithOptionalZip[i] == country) {
216
- optionalZip = true;
217
- }
218
- }
219
- if (optionalZip) {
220
- $('postcode').removeClassName('required-entry');
221
- }
222
- else {
223
- $('postcode').addClassName('required-entry');
224
- }
225
- if (optionregion) {
226
- $('region').removeClassName('required-entry');
227
- }
228
- else {
229
- $('region').addClassName('required-entry');
230
- }
231
-
232
- return VarienForm.prototype.submit.bind(coShippingMethodForm)();
233
- }
234
- //]]>
235
- </script>
236
- </div>
237
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/default/default/template/ship/checkout/cart/totals.phtml CHANGED
@@ -1,48 +1,48 @@
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) 2013 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
- <?php
28
- /**
29
- * Shopping cart totals template
30
- *
31
- * @see Mage_Checkout_Block_Cart_Totals
32
- * @var $this Mage_Checkout_Block_Cart_Totals
33
- */
34
- ?>
35
- <?php if ($this->canApplyMsrp()): ?>
36
- <div class="cart-msrp-totals"><?php echo $this->__('ORDER TOTAL WILL BE DISPLAYED BEFORE YOU SUBMIT THE ORDER'); ?></div>
37
- <?php else: ?>
38
- <table id="shopping-cart-totals-table">
39
- <col />
40
- <col width="1" />
41
- <tfoot>
42
- <?php echo $this->renderTotals('footer'); ?>
43
- </tfoot>
44
- <tbody>
45
- <?php echo $this->renderTotals(); ?>
46
- </tbody>
47
- </table>
48
- <?php endif; ?>
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) 2013 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
+ <?php
28
+ /**
29
+ * Shopping cart totals template
30
+ *
31
+ * @see Mage_Checkout_Block_Cart_Totals
32
+ * @var $this Mage_Checkout_Block_Cart_Totals
33
+ */
34
+ ?>
35
+ <?php if ($this->canApplyMsrp()): ?>
36
+ <div class="cart-msrp-totals"><?php echo $this->__('ORDER TOTAL WILL BE DISPLAYED BEFORE YOU SUBMIT THE ORDER'); ?></div>
37
+ <?php else: ?>
38
+ <table id="shopping-cart-totals-table">
39
+ <col />
40
+ <col width="1" />
41
+ <tfoot>
42
+ <?php echo $this->renderTotals('footer'); ?>
43
+ </tfoot>
44
+ <tbody>
45
+ <?php echo $this->renderTotals(); ?>
46
+ </tbody>
47
+ </table>
48
+ <?php endif; ?>
app/design/frontend/default/default/template/ship/footer/js.phtml CHANGED
@@ -1,7 +1,5 @@
1
- <link href="<?php echo $this->getSkinUrl();?>ship/css/jquery.autoSuggest.css" rel="stylesheet" />
2
- <script type="text/javascript" src="<?php echo $this->getSkinUrl();?>ship/js/jquery-1.11.0.js"></script>
3
- <script type="text/javascript">jQuery.noConflict();</script>
4
- <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
5
- <!--<script src="<?php echo $this->getSkinUrl();?>ship/js/location_script.js"></script>-->
6
- <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>
7
-
1
+ <link href="<?php echo $this->getSkinUrl();?>ship/css/jquery.autoSuggest.css" rel="stylesheet" />
2
+ <script type="text/javascript" src="<?php echo $this->getSkinUrl();?>ship/js/jquery-1.11.0.js"></script>
3
+ <script type="text/javascript">jQuery.noConflict();</script>
4
+ <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
5
+ <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>
 
 
app/design/frontend/default/default/template/ship/product_shipping.phtml CHANGED
@@ -1,307 +1,614 @@
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) 2013 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
  <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
 
28
  <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
29
 
 
 
30
  <script type="text/javascript">
 
31
  jQuery(document).ready(function(e) {
 
32
  var result;
 
33
  var data = {items: []};
 
34
  jQuery.each( TDLocationsList, function( i, item ) {
 
35
  data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
 
36
  });
 
37
  jQuery("#autosuggest").autoSuggest(data.items,
 
38
  {
 
39
  selectedItemProp: "name",
 
40
  searchObjProps: "name",
 
41
  selectionLimit: 1,
 
42
  minChars: 3,
 
43
  selectionAdded: function(elem)
 
44
  {
 
45
  result = elem.text();
 
46
  getresultval(result);
 
47
  }
 
48
  }
 
49
  );
 
50
  function getresultval(res){
 
51
  var postcode = res.substr(1,4);
 
52
  var locality = res.substr(6);
 
53
  jQuery('#suburb').attr("value", locality);
 
54
  jQuery('#postcode').attr("value", postcode);
 
55
 
56
- document.cookie="cart_postocde="+postcode;
57
- document.cookie="cart_locality="+locality;
 
 
 
 
58
  }
 
59
  });
 
60
 
 
61
  </script>
62
 
 
 
63
  <?php $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
 
64
  $tmp_cart_locality_val = $_COOKIE['cart_locality'];
 
65
  ?>
66
 
 
 
67
  <?php
 
68
  $country_val = Mage::getSingleton('core/session')->getCountryVal();
 
69
  $postocde_val = Mage::getSingleton('core/session')->getPostcodeVal();
 
70
  $regionid_val = Mage::getSingleton('core/session')->getRegionIdVal();
 
71
  $region_val = Mage::getSingleton('core/session')->getRegionVal();
 
72
  ?>
 
73
  <div class="shipping_product">
 
74
  <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
 
75
  <div class="shipping-form">
 
76
  <form action="<?php echo $this->getUrl('ship/index/index/') ?>" method="post" id="shipping-zip-form">
 
77
  <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
 
78
  <ul class="form-list">
 
79
  <li>
 
80
  <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
 
81
  <div class="input-box">
 
82
  <select name="country_id" id="country" class="validate-select" title="Country" >
 
83
  <option value="AU" selected="selected" ><?php echo $this->__('Australia') ?></option>
 
84
  </select>
 
85
  </div>
 
86
  <?php /*?><div class="input-box">
 
87
  <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
 
88
  </div><?php */?>
 
89
  </li>
 
90
  <?php /*
 
91
  //if($this->getStateActive()):
 
92
 
 
93
  ?>
 
94
  <li>
 
95
  <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('Suburb') ?></label>
 
96
  <div class="input-box">
 
97
  <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
 
98
  <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
 
99
  </select>
 
100
  <script type="text/javascript">
 
101
  //<![CDATA[
 
102
  $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
 
103
  //]]>
 
104
  </script>
 
105
  <input type="text" id="region" name="region" value="<?php if($region_val){ echo $region_val;} else { echo $this->escapeHtml($this->getEstimateRegion()); } ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" style="display:none;" />
 
106
  </div>
 
107
  </li>
 
108
  <?php //endif; */ ?>
 
109
  <?php if($this->getCityActive()): ?>
 
110
  <li>
 
111
  <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
 
112
  <div class="input-box">
 
113
  <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
 
114
  </div>
 
115
  </li>
 
116
  <?php endif; ?>
 
117
  <li>
 
118
  <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
 
119
  <div class="input-box postcode_suburb">
 
120
  <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php if($postocde_val){ echo $postocde_val;} else { echo $this->escapeHtml($this->getEstimatePostcode()); } ?>" maxlength="4" /><?php */?>
 
121
 
 
122
  <input id="autosuggest" type="text" />
 
123
  <input type="hidden" name="suburb" id="suburb" value="" />
 
124
  <input type="hidden" name="postcode" id="postcode" value="" />
125
 
 
 
126
  <?php
 
127
  //echo $tmp_cart_postcode_val; die('val');
 
128
  if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
 
129
  <script type="text/javascript">
 
130
  var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
 
131
 
 
132
  jQuery(document).ready(function(e) {
 
133
  if(jQuery(".as-selections").find(".as-selection-item").html()){
 
134
  } else {
 
135
  jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
 
136
  }
 
137
  });
 
138
  </script>
 
139
  <?php } ?>
 
140
 
 
141
  </div>
 
142
  </li>
 
143
  </ul>
 
144
  <div class="buttons-set">
 
145
  <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
 
146
  </div>
 
147
  </form>
 
148
  <script type="text/javascript">
 
149
  //<![CDATA[
 
150
  new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
 
151
  //]]>
 
152
  </script>
 
153
  <?php //if (($_shippingRateGroups = $this->getEstimateRates())): ?>
 
154
  <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
 
155
  <dl class="sp-methods">
 
156
 
 
157
  <?php
 
158
 
 
159
  //$quotes_val = Mage::register('store_id', Mage::app()->getStore()->getId());
 
160
  //$quotes_val = Mage::registry('quotes_val');
 
161
  //echo '<pre>'; print_r($quotes_val); //die('val');
 
162
 
 
163
  //$val = Mage::getSingleton('checkout/session')->getQuote();
 
164
 
 
165
  $quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
 
166
 
 
167
 
 
168
 
 
169
  //echo $country_val. $postocde_val . $regionid_val . $region_val; //die('data');
 
170
 
 
171
  //echo '<pre>'; print_r($quotes_val);
 
172
  //die('sess set');
 
173
 
 
174
  if($quotes_val){ //die('response');
 
175
 
 
176
  ?>
 
177
  <dt><?php echo $this->__('Carrier');?></dt>
 
178
  <dd>
 
179
  <ul>
 
180
 
 
181
  <?php
 
182
 
 
183
  //foreach($quotes_val as $key => $val) {
 
184
 
 
185
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
 
186
  $available_carriers = explode( ',', $display_carriers);
 
187
 
 
188
  foreach ($quotes_val as $key => $val):
 
189
 
 
190
  if(in_array($key,$available_carriers)) {
 
191
  //echo '<br>'.$key . ' - matched<br>';
 
192
  $xyz[$key] = $quotes_val[$key];
 
193
  }
 
194
 
 
195
  endforeach; //die;
 
196
 
 
197
  foreach($xyz as $key => $abc):
 
198
  if($key){
 
199
  ?>
 
200
 
 
201
  <li>
 
202
  <label for="s_method">
 
203
  <?php
 
204
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
 
205
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
 
206
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
 
207
 
 
208
  if($display_showcouriername == '1'){
 
209
  //echo $key;
 
210
  if($key=='fastway'){echo $this->__("Fastway"); }
 
211
  if($key=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
 
212
  if($key=='couriers_please'){echo $this->__("Couriers Please"); }
 
213
  if($key=='allied'){echo $this->__("Allied Express"); }
 
214
  if($key=='toll'){echo $this->__("Toll"); }
 
215
  if($key=='mainfreight'){echo $this->__("Mainfreight"); }
 
216
  if($key=='northline'){echo $this->__("Northline"); }
 
217
 
 
218
  }
 
219
  if($display_showcouriername == '1' && $display_surcharge == '1') {
 
220
  echo ' + '.$this->__("Handling Charge");
 
221
  }
 
222
  ?>
 
223
  <?php //echo $key.'&nbsp;&nbsp;&nbsp;'; ?>
 
224
  <?php $curr_symbol = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();?>
 
225
  <span class="price">
 
226
  <?php
 
227
  $tmp_display_surcharge = $abc['total'] + $display_surcharge1;
 
228
  if($display_surcharge == '1'){
 
229
  echo $curr_symbol. number_format($tmp_display_surcharge,2);
 
230
  } else {
 
231
  echo $curr_symbol. number_format($abc['total'],2);
 
232
  }
 
233
 
 
234
  ?></span>
 
235
  <span>
 
236
  <?php echo '(Shipping Time - '. $abc['transit_time'].')'; ?>
 
237
  </span>
 
238
  </label>
 
239
  </li>
 
240
 
 
241
  <?php }
 
242
  endforeach; //} ?>
 
243
 
 
244
  </ul>
 
245
  </dd>
 
246
  <?php }
 
247
  if($quotes_val == '' && $postocde_val != ''){
 
248
 
 
249
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
 
250
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
 
251
  ?>
 
252
 
 
253
  <dt><?php echo $this->__('Carrier');?></dt>
 
254
  <dd>
 
255
  <ul>
 
256
  <li>
 
257
  <label for="s_method"> <?php echo $this->__('Fixed Price'); ?>
 
258
  <span class="price"> <?php echo $display_fixedprice1; ?> </span>
 
259
  </label>
 
260
  </li>
 
261
  </ul>
 
262
  </dd>
 
263
 
 
264
  <?php } ?>
 
265
 
 
266
  </dl>
267
 
 
 
268
  <script type="text/javascript">
 
269
  //<![CDATA[
 
270
  var coShippingMethodForm = new VarienForm('shipping-zip-form');
 
271
  var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
 
272
  coShippingMethodForm.submit = function () {
 
273
  var country = $F('country');
 
274
  var optionalZip = false;
 
275
  var optionregion = false;
 
276
  for (i=0; i < countriesWithOptionalZip.length; i++) {
 
277
  if (countriesWithOptionalZip[i] == country) {
 
278
  optionalZip = true;
 
279
  }
 
280
  }
 
281
  if (optionalZip) {
 
282
  $('postcode').removeClassName('required-entry');
 
283
  }
 
284
  else {
 
285
  $('postcode').addClassName('required-entry');
 
286
  }
 
287
 
 
288
  /*if (optionregion) {
 
289
  $('region').removeClassName('required-entry');
 
290
  }
 
291
  else {
 
292
  $('region').addClassName('required-entry');
 
293
  }*/
 
294
 
 
295
  return VarienForm.prototype.submit.bind(coShippingMethodForm)();
 
296
  }
 
297
  //]]>
 
298
  </script>
 
299
  </div>
 
300
  </div>
 
301
  <style type="text/css">
 
302
  .shipping_product {border: 1px solid #D0CBC1; margin: 0 0 18px; padding: 10px;}
 
303
  .shipping-form,.form-list .input-box, .form-list select {width:100%;}
 
304
  .form-list input.input-text{width:97%;}
 
305
  </style>
306
 
 
 
307
  <?php } ?>
1
  <?php
2
+
3
  /**
4
+
5
  * Magento
6
+
7
  *
8
+
9
  * NOTICE OF LICENSE
10
+
11
  *
12
+
13
  * This source file is subject to the Academic Free License (AFL 3.0)
14
+
15
  * that is bundled with this package in the file LICENSE_AFL.txt.
16
+
17
  * It is also available through the world-wide-web at this URL:
18
+
19
  * http://opensource.org/licenses/afl-3.0.php
20
+
21
  * If you did not receive a copy of the license and are unable to
22
+
23
  * obtain it through the world-wide-web, please send an email
24
+
25
  * to license@magentocommerce.com so we can send you a copy immediately.
26
+
27
  *
28
+
29
  * DISCLAIMER
30
+
31
  *
32
+
33
  * Do not edit or add to this file if you wish to upgrade Magento to newer
34
+
35
  * versions in the future. If you wish to customize Magento for your
36
+
37
  * needs please refer to http://www.magentocommerce.com for more information.
38
+
39
  *
40
+
41
  * @category design
42
+
43
  * @package base_default
44
+
45
  * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
46
+
47
  * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
48
+
49
  */
50
+
51
  ?>
52
+
53
  <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
54
+
55
  <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
56
 
57
+
58
+
59
  <script type="text/javascript">
60
+
61
  jQuery(document).ready(function(e) {
62
+
63
  var result;
64
+
65
  var data = {items: []};
66
+
67
  jQuery.each( TDLocationsList, function( i, item ) {
68
+
69
  data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
70
+
71
  });
72
+
73
  jQuery("#autosuggest").autoSuggest(data.items,
74
+
75
  {
76
+
77
  selectedItemProp: "name",
78
+
79
  searchObjProps: "name",
80
+
81
  selectionLimit: 1,
82
+
83
  minChars: 3,
84
+
85
  selectionAdded: function(elem)
86
+
87
  {
88
+
89
  result = elem.text();
90
+
91
  getresultval(result);
92
+
93
  }
94
+
95
  }
96
+
97
  );
98
+
99
  function getresultval(res){
100
+
101
  var postcode = res.substr(1,4);
102
+
103
  var locality = res.substr(6);
104
+
105
  jQuery('#suburb').attr("value", locality);
106
+
107
  jQuery('#postcode').attr("value", postcode);
108
+
109
 
110
+ var d = new Date();
111
+ d.setTime(d.getTime() + (5*24*60*60*1000));
112
+
113
+ document.cookie="cart_postocde="+postcode+"; expires="+d.toUTCString()+"; path=/";
114
+ document.cookie="cart_locality="+locality+"; expires="+d.toUTCString()+"; path=/";
115
+
116
  }
117
+
118
  });
119
+
120
 
121
+
122
  </script>
123
 
124
+
125
+
126
  <?php $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
127
+
128
  $tmp_cart_locality_val = $_COOKIE['cart_locality'];
129
+
130
  ?>
131
 
132
+
133
+
134
  <?php
135
+
136
  $country_val = Mage::getSingleton('core/session')->getCountryVal();
137
+
138
  $postocde_val = Mage::getSingleton('core/session')->getPostcodeVal();
139
+
140
  $regionid_val = Mage::getSingleton('core/session')->getRegionIdVal();
141
+
142
  $region_val = Mage::getSingleton('core/session')->getRegionVal();
143
+
144
  ?>
145
+
146
  <div class="shipping_product">
147
+
148
  <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
149
+
150
  <div class="shipping-form">
151
+
152
  <form action="<?php echo $this->getUrl('ship/index/index/') ?>" method="post" id="shipping-zip-form">
153
+
154
  <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
155
+
156
  <ul class="form-list">
157
+
158
  <li>
159
+
160
  <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
161
+
162
  <div class="input-box">
163
+
164
  <select name="country_id" id="country" class="validate-select" title="Country" >
165
+
166
  <option value="AU" selected="selected" ><?php echo $this->__('Australia') ?></option>
167
+
168
  </select>
169
+
170
  </div>
171
+
172
  <?php /*?><div class="input-box">
173
+
174
  <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
175
+
176
  </div><?php */?>
177
+
178
  </li>
179
+
180
  <?php /*
181
+
182
  //if($this->getStateActive()):
183
+
184
 
185
+
186
  ?>
187
+
188
  <li>
189
+
190
  <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('Suburb') ?></label>
191
+
192
  <div class="input-box">
193
+
194
  <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
195
+
196
  <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
197
+
198
  </select>
199
+
200
  <script type="text/javascript">
201
+
202
  //<![CDATA[
203
+
204
  $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
205
+
206
  //]]>
207
+
208
  </script>
209
+
210
  <input type="text" id="region" name="region" value="<?php if($region_val){ echo $region_val;} else { echo $this->escapeHtml($this->getEstimateRegion()); } ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" style="display:none;" />
211
+
212
  </div>
213
+
214
  </li>
215
+
216
  <?php //endif; */ ?>
217
+
218
  <?php if($this->getCityActive()): ?>
219
+
220
  <li>
221
+
222
  <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
223
+
224
  <div class="input-box">
225
+
226
  <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
227
+
228
  </div>
229
+
230
  </li>
231
+
232
  <?php endif; ?>
233
+
234
  <li>
235
+
236
  <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
237
+
238
  <div class="input-box postcode_suburb">
239
+
240
  <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php if($postocde_val){ echo $postocde_val;} else { echo $this->escapeHtml($this->getEstimatePostcode()); } ?>" maxlength="4" /><?php */?>
241
+
242
 
243
+
244
  <input id="autosuggest" type="text" />
245
+
246
  <input type="hidden" name="suburb" id="suburb" value="" />
247
+
248
  <input type="hidden" name="postcode" id="postcode" value="" />
249
 
250
+
251
+
252
  <?php
253
+
254
  //echo $tmp_cart_postcode_val; die('val');
255
+
256
  if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
257
+
258
  <script type="text/javascript">
259
+
260
  var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
261
+
262
 
263
+
264
  jQuery(document).ready(function(e) {
265
+
266
  if(jQuery(".as-selections").find(".as-selection-item").html()){
267
+
268
  } else {
269
+
270
  jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
271
+
272
  }
273
+
274
  });
275
+
276
  </script>
277
+
278
  <?php } ?>
279
+
280
 
281
+
282
  </div>
283
+
284
  </li>
285
+
286
  </ul>
287
+
288
  <div class="buttons-set">
289
+
290
  <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
291
+
292
  </div>
293
+
294
  </form>
295
+
296
  <script type="text/javascript">
297
+
298
  //<![CDATA[
299
+
300
  new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
301
+
302
  //]]>
303
+
304
  </script>
305
+
306
  <?php //if (($_shippingRateGroups = $this->getEstimateRates())): ?>
307
+
308
  <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
309
+
310
  <dl class="sp-methods">
311
+
312
 
313
+
314
  <?php
315
+
316
 
317
+
318
  //$quotes_val = Mage::register('store_id', Mage::app()->getStore()->getId());
319
+
320
  //$quotes_val = Mage::registry('quotes_val');
321
+
322
  //echo '<pre>'; print_r($quotes_val); //die('val');
323
+
324
 
325
+
326
  //$val = Mage::getSingleton('checkout/session')->getQuote();
327
+
328
 
329
+
330
  $quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
331
+
332
 
333
+
334
 
335
+
336
 
337
+
338
  //echo $country_val. $postocde_val . $regionid_val . $region_val; //die('data');
339
+
340
 
341
+
342
  //echo '<pre>'; print_r($quotes_val);
343
+
344
  //die('sess set');
345
+
346
 
347
+
348
  if($quotes_val){ //die('response');
349
+
350
 
351
+
352
  ?>
353
+
354
  <dt><?php echo $this->__('Carrier');?></dt>
355
+
356
  <dd>
357
+
358
  <ul>
359
+
360
 
361
+
362
  <?php
363
+
364
 
365
+
366
  //foreach($quotes_val as $key => $val) {
367
+
368
 
369
+
370
  $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
371
+
372
  $available_carriers = explode( ',', $display_carriers);
373
+
374
 
375
+
376
  foreach ($quotes_val as $key => $val):
377
+
378
 
379
+
380
  if(in_array($key,$available_carriers)) {
381
+
382
  //echo '<br>'.$key . ' - matched<br>';
383
+
384
  $xyz[$key] = $quotes_val[$key];
385
+
386
  }
387
+
388
 
389
+
390
  endforeach; //die;
391
+
392
 
393
+
394
  foreach($xyz as $key => $abc):
395
+
396
  if($key){
397
+
398
  ?>
399
+
400
 
401
+
402
  <li>
403
+
404
  <label for="s_method">
405
+
406
  <?php
407
+
408
  $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
409
+
410
  $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
411
+
412
  $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
413
+
414
 
415
+
416
  if($display_showcouriername == '1'){
417
+
418
  //echo $key;
419
+
420
  if($key=='fastway'){echo $this->__("Fastway"); }
421
+
422
  if($key=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
423
+
424
  if($key=='couriers_please'){echo $this->__("Couriers Please"); }
425
+
426
  if($key=='allied'){echo $this->__("Allied Express"); }
427
+
428
  if($key=='toll'){echo $this->__("Toll"); }
429
+
430
  if($key=='mainfreight'){echo $this->__("Mainfreight"); }
431
+
432
  if($key=='northline'){echo $this->__("Northline"); }
433
+
434
 
435
+
436
  }
437
+
438
  if($display_showcouriername == '1' && $display_surcharge == '1') {
439
+
440
  echo ' + '.$this->__("Handling Charge");
441
+
442
  }
443
+
444
  ?>
445
+
446
  <?php //echo $key.'&nbsp;&nbsp;&nbsp;'; ?>
447
+
448
  <?php $curr_symbol = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();?>
449
+
450
  <span class="price">
451
+
452
  <?php
453
+
454
  $tmp_display_surcharge = $abc['total'] + $display_surcharge1;
455
+
456
  if($display_surcharge == '1'){
457
+
458
  echo $curr_symbol. number_format($tmp_display_surcharge,2);
459
+
460
  } else {
461
+
462
  echo $curr_symbol. number_format($abc['total'],2);
463
+
464
  }
465
+
466
 
467
+
468
  ?></span>
469
+
470
  <span>
471
+
472
  <?php echo '(Shipping Time - '. $abc['transit_time'].')'; ?>
473
+
474
  </span>
475
+
476
  </label>
477
+
478
  </li>
479
+
480
 
481
+
482
  <?php }
483
+
484
  endforeach; //} ?>
485
+
486
 
487
+
488
  </ul>
489
+
490
  </dd>
491
+
492
  <?php }
493
+
494
  if($quotes_val == '' && $postocde_val != ''){
495
+
496
 
497
+
498
  $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
499
+
500
  $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
501
+
502
  ?>
503
+
504
 
505
+
506
  <dt><?php echo $this->__('Carrier');?></dt>
507
+
508
  <dd>
509
+
510
  <ul>
511
+
512
  <li>
513
+
514
  <label for="s_method"> <?php echo $this->__('Fixed Price'); ?>
515
+
516
  <span class="price"> <?php echo $display_fixedprice1; ?> </span>
517
+
518
  </label>
519
+
520
  </li>
521
+
522
  </ul>
523
+
524
  </dd>
525
+
526
 
527
+
528
  <?php } ?>
529
+
530
 
531
+
532
  </dl>
533
 
534
+
535
+
536
  <script type="text/javascript">
537
+
538
  //<![CDATA[
539
+
540
  var coShippingMethodForm = new VarienForm('shipping-zip-form');
541
+
542
  var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
543
+
544
  coShippingMethodForm.submit = function () {
545
+
546
  var country = $F('country');
547
+
548
  var optionalZip = false;
549
+
550
  var optionregion = false;
551
+
552
  for (i=0; i < countriesWithOptionalZip.length; i++) {
553
+
554
  if (countriesWithOptionalZip[i] == country) {
555
+
556
  optionalZip = true;
557
+
558
  }
559
+
560
  }
561
+
562
  if (optionalZip) {
563
+
564
  $('postcode').removeClassName('required-entry');
565
+
566
  }
567
+
568
  else {
569
+
570
  $('postcode').addClassName('required-entry');
571
+
572
  }
573
+
574
 
575
+
576
  /*if (optionregion) {
577
+
578
  $('region').removeClassName('required-entry');
579
+
580
  }
581
+
582
  else {
583
+
584
  $('region').addClassName('required-entry');
585
+
586
  }*/
587
+
588
 
589
+
590
  return VarienForm.prototype.submit.bind(coShippingMethodForm)();
591
+
592
  }
593
+
594
  //]]>
595
+
596
  </script>
597
+
598
  </div>
599
+
600
  </div>
601
+
602
  <style type="text/css">
603
+
604
  .shipping_product {border: 1px solid #D0CBC1; margin: 0 0 18px; padding: 10px;}
605
+
606
  .shipping-form,.form-list .input-box, .form-list select {width:100%;}
607
+
608
  .form-list input.input-text{width:97%;}
609
+
610
  </style>
611
 
612
+
613
+
614
  <?php } ?>
app/design/frontend/default/default/template/ship/shipping.phtml CHANGED
@@ -1,354 +1,718 @@
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) 2013 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
  <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */
28
 
 
 
29
  ?>
30
 
 
 
31
  <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
32
 
 
 
33
  <!--<link href="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.css" rel="stylesheet" />
 
34
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
 
35
  <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
36
- <script src="<?php echo $this->getSkinUrl();?>ship/js/location_script.js"></script>
 
 
37
  <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>-->
38
 
 
 
39
  <script type="text/javascript">
 
40
  jQuery(document).ready(function(e) {
 
41
  var result;
 
42
  var data = {items: []};
 
43
  jQuery.each( TDLocationsList, function( i, item ) {
 
44
  data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
 
45
  });
 
46
  jQuery("#autosuggest").autoSuggest(data.items,
 
47
  {
 
48
  selectedItemProp: "name",
 
49
  searchObjProps: "name",
 
50
  selectionLimit: 1,
 
51
  minChars: 3,
 
52
  selectionAdded: function(elem)
 
53
  {
 
54
  result = elem.text();
 
55
  getresultval(result);
 
56
  }
 
57
  }
 
58
  );
 
59
  function getresultval(res){
 
60
  var postcode = res.substr(1,4);
 
61
  var locality = res.substr(6);
 
62
  jQuery('#suburb').attr("value", locality);
 
63
  jQuery('#postcode').attr("value", postcode);
 
64
 
65
- document.cookie="cart_postocde="+postcode;
66
- document.cookie="cart_locality="+locality;
 
 
 
 
 
 
 
 
67
  }
 
68
  if(jQuery( ".as-results .as-message:contains('No Results Found')" )){
 
69
  jQuery(".postcode_suburb .as-results").css("display","none");
 
70
  }
 
71
  });
 
72
 
 
73
  </script>
74
 
 
 
75
  <?php
 
76
  $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
 
77
  $tmp_cart_locality_val = $_COOKIE['cart_locality'];
 
78
  ?>
 
79
 
 
80
  <?php Mage::getSingleton('core/session')->unsCartpostcodeVal();
 
81
  Mage::getSingleton('core/session')->unsCartlocalityVal();
82
 
 
 
83
  // $cart_postcode_val = Mage::getSingleton('core/session')->setCartpostcodeVal($tmp_cart_postcode_val);
 
84
  // $cart_locality_val = Mage::getSingleton('core/session')->setCartlocalityVal($tmp_cart_locality_val);
 
85
 
 
86
  ?>
87
 
 
 
88
  <?php $transit_val = Mage::getSingleton('core/session')->getTransitVal(); //die('tra');
 
89
  $quotes_val1 = Mage::getSingleton('core/session')->getSomeSessionVar1();
 
 
 
 
 
 
 
90
  //echo '<pre>'; print_r($quotes_val1); die;
91
 
 
 
92
  //$quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
93
 
 
 
94
  ?>
 
95
  <div class="shipping">
 
96
  <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
 
97
  <?php echo $this->getChildHtml('global_messages') ?>
 
98
  <div class="shipping-form">
 
99
  <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
 
100
  <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
 
101
  <ul class="form-list">
 
102
  <li>
 
103
  <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
 
104
  <div class="input-box">
 
105
  <select name="country_id" id="country" class="validate-select" title="Country" >
 
106
  <option value="AU" selected="selected" >Australia</option>
 
107
  </select>
 
108
  </div>
 
109
  <?php /*?><div class="input-box">
 
110
  <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
 
111
  </div><?php */?>
 
112
  </li>
 
113
  <?php //if($this->getStateActive()): ?>
 
114
  <?php /*?>
 
115
  <li>
 
116
  <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>>
 
117
  <?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?>
 
118
  <?php echo $this->__('Suburb') ?></label>
 
119
  <div class="input-box">
 
120
  <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
 
121
  <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
 
122
  </select>
 
123
  <script type="text/javascript">
 
124
  //<![CDATA[
 
125
  $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
 
126
  //]]>
 
127
  </script>
 
128
  <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getEstimateRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" />
 
129
  </div>
 
130
  </li><?php */?>
 
131
  <?php //endif; ?>
 
132
  <?php if($this->getCityActive()): ?>
 
133
  <li>
 
134
  <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>>
 
135
  <?php if ($this->isCityRequired()) echo '<em>*</em>' ?>
 
136
  <?php echo $this->__('City') ?></label>
 
137
  <div class="input-box">
 
138
  <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
 
139
  </div>
 
140
  </li>
 
141
  <?php endif; ?>
 
142
  <li>
 
143
  <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>>
 
144
  <?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?>
 
145
  <?php echo $this->__('Suburb / Postal Code') ?></label>
 
146
  <div class="input-box postcode_suburb">
 
147
  <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" maxlength="4"/><?php */?>
 
148
 
 
149
  <input id="autosuggest" type="text" />
 
150
  <input type="hidden" name="suburb" id="suburb" value="" />
 
151
  <input type="hidden" name="postcode" id="postcode" value="" />
152
 
 
 
153
  <?php
 
154
  //echo $tmp_cart_postcode_val; die('val');
 
155
  if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
 
156
  <script type="text/javascript">
 
157
  var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
 
158
 
 
159
  jQuery(document).ready(function(e) {
 
160
  if(jQuery(".as-selections").find(".as-selection-item").html()){
 
161
  jQuery(".previous-selection").css('display','none');
 
162
  } else {
 
163
  jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
 
164
  }
 
165
  });
 
166
  </script>
 
167
  <?php } ?>
 
168
 
 
169
  </div>
 
170
  </li>
 
171
  </ul>
 
172
  <div class="buttons-set">
 
173
  <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
 
174
  </div>
 
175
  </form>
 
176
  <script type="text/javascript">
 
177
  //<![CDATA[
 
178
  new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
 
179
  //]]>
180
- </script>
 
 
 
 
181
  <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
 
 
 
182
  <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
183
- <dl class="sp-methods">
184
- <dt><?php echo $this->__("Carrier"); ?></dt>
185
- <?php
 
 
 
 
186
  /*function cmp($a, $b) {
 
187
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
188
 
 
189
  if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['method_title'], $b['method_title']); }
 
190
  } */
 
191
  function cmp($key) {
 
192
  return function ($a, $b) use ($key) {
 
193
  return strnatcmp($a[$key], $b[$key]);
 
194
  };
 
195
  }
 
196
 
 
197
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
 
198
 
199
- /* function build_sorter($key) {
 
 
200
  return function ($a, $b) use ($key) {
 
201
  return strnatcmp($a[$key], $b[$key]);
 
202
  };
203
- }*/
204
-
205
- // get data
206
- foreach ($_shippingRateGroups as $code => $_rates):
207
-
208
  //echo '<pre>'; print_r($_shippingRateGroups); die;
209
- ?>
210
- <?php /*?> <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt><?php */?>
211
- <dd>
212
- <ul>
213
- <?php
214
-
215
-
216
- //usort($_rates, 'cmp');
217
-
218
- foreach ($_rates as $ratekey => $_rate):
219
-
220
- $xyz[$ratekey] = $_rates[$ratekey]->getData();
221
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  foreach ($quotes_val1 as $key => $val):
223
-
224
  //echo $key .' = '. $xyz[$ratekey]['method'].'<br>';
 
225
  //echo $quotes_val1[$key]['transit_time'];
 
226
  if($key == $xyz[$ratekey]['method']) {
 
 
 
227
  $xyz[$ratekey]['transit_time'] = $quotes_val1[$key]['transit_time'];
 
228
  break;
 
229
  }
 
230
  endforeach;
231
- //die;
232
-
233
- //$xyz[] = $transit_val;
234
-
235
- //echo '<pre>'; print_r($_rate->getData());
236
-
237
- endforeach;
238
-
239
- endforeach;
240
-
241
- //echo '<pre>'; print_r($xyz); die;
242
-
243
- // sorting
244
-
245
- if($display_quote == 'display_cheapest'){ usort($xyz, cmp('price')); }
246
- if($display_quote == 'display_all_quotes'){ usort($xyz, cmp('method_title')); }
247
- if($display_quote == 'display_cheapest_fastest'){ usort($xyz, cmp('transit_time')); }
248
- //usort($xyz, cmp('price'));
249
-
250
- /*
251
- $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
252
-
253
- if($display_quote == 'display_cheapest'){ usort($xyz, build_sorter('price')); }
254
- if($display_quote == 'display_all_quotes'){ usort($xyz, build_sorter('price')); }
255
- if($display_quote == 'display_cheapest_fastest'){ usort($xyz, build_sorter('price')); }
256
- */
257
-
258
- //echo '<pre>'; print_r($xyz);
259
-
260
- // display
261
- foreach($xyz as $key => $abc):
262
- //echo '<pre>'; print_r($abc); die('ship');
263
- //endforeach;
264
- //echo $abc['code'];die;
265
-
266
-
267
- if($abc['method_title']){
268
- ?>
269
- <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
270
- <?php if ($_rate->getErrorMessage()): ?>
271
- <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
272
- <?php else: ?>
273
- <input name="estimate_method" type="radio" value="<?php echo $abc['code']; //$this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $abc['code'] ?>"<?php if($abc['code']===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
274
- <label for="s_method_<?php echo $abc['code']; ?>">
275
- <?php
276
- $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
277
- if($display_showcouriername == '1'){
278
- echo $abc['method_title'];
279
- /*
280
- if($abc['method_title']=='fastway'){echo $this->__("Fastway"); }
281
- if($abc['method_title']=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
282
- if($abc['method_title']=='couriers_please'){echo $this->__("Couriers Please"); }
283
- if($abc['method_title']=='allied'){echo $this->__("Allied Express"); }
284
- if($abc['method_title']=='toll'){echo $this->__("Toll"); }
285
- if($abc['method_title']=='mainfreight'){echo $this->__("Mainfreight"); }
286
- if($abc['method_title']=='northline'){echo $this->__("Northline"); }
287
- */
288
-
289
- //$this->escapeHtml($_rate->getMethodTitle());
290
- }
291
- ?>
292
- <?php $_excl = $this->getShippingPrice($abc['price'], $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
293
- <?php $_incl = $this->getShippingPrice($abc['price'], true); ?>
294
- <?php echo $_excl; ?>
295
- <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
296
- (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
297
- <?php endif; ?>
298
- <?php if($abc['method_title'] != 'Fixed Price' && $abc['transit_time'] != '') {?>
299
- <span> <?php echo '&nbsp;&nbsp;(Shipping Time - '. $abc['transit_time'].')'; ?> </span>
300
- <?php } ?>
301
- </label>
302
- <?php endif ?>
303
- </li>
304
- <?php }
305
  endforeach;
306
- // die('rate'); ?>
307
- <?php /*?> <li>
308
- <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
309
- <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitleOne()) ?>
310
- <?php $_incl = $this->getShippingPrice($_rate->getPriceOne(), true); ?>
311
- </li><?php */?>
312
- </ul>
313
- </dd>
314
- <?php //endforeach; ?>
315
- </dl>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  <div class="buttons-set">
 
317
  <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
 
318
  </div>
 
 
 
319
  </form>
 
320
  <?php endif; ?>
 
 
 
321
  <script type="text/javascript">
 
322
  //<![CDATA[
 
323
  var coShippingMethodForm = new VarienForm('shipping-zip-form');
 
324
  var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
 
325
  coShippingMethodForm.submit = function () {
 
326
  var country = $F('country');
 
327
  var optionalZip = false;
 
328
  var optionregion = false;
 
329
  for (i=0; i < countriesWithOptionalZip.length; i++) {
 
330
  if (countriesWithOptionalZip[i] == country) {
 
331
  optionalZip = true;
 
332
  }
 
333
  }
 
334
  if (optionalZip) {
 
335
  $('postcode').removeClassName('required-entry');
 
336
  }
 
337
  else {
 
338
  $('postcode').addClassName('required-entry');
 
339
  }
 
340
  /* if (optionregion) {
 
341
  $('region').removeClassName('required-entry');
 
342
  }
 
343
  else {
 
344
  $('region').addClassName('required-entry');
 
345
  }
 
346
  */
 
347
  return VarienForm.prototype.submit.bind(coShippingMethodForm)();
 
348
  }
 
349
  //]]>
 
350
  </script>
 
351
  </div>
 
352
  </div>
353
 
 
 
354
  <?php } ?>
1
  <?php
2
+
3
  /**
4
+
5
  * Magento
6
+
7
  *
8
+
9
  * NOTICE OF LICENSE
10
+
11
  *
12
+
13
  * This source file is subject to the Academic Free License (AFL 3.0)
14
+
15
  * that is bundled with this package in the file LICENSE_AFL.txt.
16
+
17
  * It is also available through the world-wide-web at this URL:
18
+
19
  * http://opensource.org/licenses/afl-3.0.php
20
+
21
  * If you did not receive a copy of the license and are unable to
22
+
23
  * obtain it through the world-wide-web, please send an email
24
+
25
  * to license@magentocommerce.com so we can send you a copy immediately.
26
+
27
  *
28
+
29
  * DISCLAIMER
30
+
31
  *
32
+
33
  * Do not edit or add to this file if you wish to upgrade Magento to newer
34
+
35
  * versions in the future. If you wish to customize Magento for your
36
+
37
  * needs please refer to http://www.magentocommerce.com for more information.
38
+
39
  *
40
+
41
  * @category design
42
+
43
  * @package base_default
44
+
45
  * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
46
+
47
  * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
48
+
49
  */
50
+
51
  ?>
52
+
53
  <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */
54
 
55
+
56
+
57
  ?>
58
 
59
+
60
+
61
  <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
62
 
63
+
64
+
65
  <!--<link href="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.css" rel="stylesheet" />
66
+
67
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
68
+
69
  <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
70
+
71
+ <script src="<?php //echo $this->getSkinUrl();?>ship/js/location_script.js"></script>
72
+
73
  <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>-->
74
 
75
+
76
+
77
  <script type="text/javascript">
78
+
79
  jQuery(document).ready(function(e) {
80
+
81
  var result;
82
+
83
  var data = {items: []};
84
+
85
  jQuery.each( TDLocationsList, function( i, item ) {
86
+
87
  data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
88
+
89
  });
90
+
91
  jQuery("#autosuggest").autoSuggest(data.items,
92
+
93
  {
94
+
95
  selectedItemProp: "name",
96
+
97
  searchObjProps: "name",
98
+
99
  selectionLimit: 1,
100
+
101
  minChars: 3,
102
+
103
  selectionAdded: function(elem)
104
+
105
  {
106
+
107
  result = elem.text();
108
+
109
  getresultval(result);
110
+
111
  }
112
+
113
  }
114
+
115
  );
116
+
117
  function getresultval(res){
118
+
119
  var postcode = res.substr(1,4);
120
+
121
  var locality = res.substr(6);
122
+
123
  jQuery('#suburb').attr("value", locality);
124
+
125
  jQuery('#postcode').attr("value", postcode);
126
+
127
 
128
+ var d = new Date();
129
+ d.setTime(d.getTime() + (5*24*60*60*1000));
130
+
131
+ document.cookie="cart_postocde="+postcode+"; expires="+d.toUTCString()+"; path=/";
132
+ document.cookie="cart_locality="+locality+"; expires="+d.toUTCString()+"; path=/";
133
+
134
+ /*document.cookie="cart_postocde="+postcode;
135
+
136
+ document.cookie="cart_locality="+locality;*/
137
+
138
  }
139
+
140
  if(jQuery( ".as-results .as-message:contains('No Results Found')" )){
141
+
142
  jQuery(".postcode_suburb .as-results").css("display","none");
143
+
144
  }
145
+
146
  });
147
+
148
 
149
+
150
  </script>
151
 
152
+
153
+
154
  <?php
155
+
156
  $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
157
+
158
  $tmp_cart_locality_val = $_COOKIE['cart_locality'];
159
+
160
  ?>
161
+
162
 
163
+
164
  <?php Mage::getSingleton('core/session')->unsCartpostcodeVal();
165
+
166
  Mage::getSingleton('core/session')->unsCartlocalityVal();
167
 
168
+
169
+
170
  // $cart_postcode_val = Mage::getSingleton('core/session')->setCartpostcodeVal($tmp_cart_postcode_val);
171
+
172
  // $cart_locality_val = Mage::getSingleton('core/session')->setCartlocalityVal($tmp_cart_locality_val);
173
+
174
 
175
+
176
  ?>
177
 
178
+
179
+
180
  <?php $transit_val = Mage::getSingleton('core/session')->getTransitVal(); //die('tra');
181
+
182
  $quotes_val1 = Mage::getSingleton('core/session')->getSomeSessionVar1();
183
+
184
+
185
+
186
+ // var_dump($transit_val);
187
+
188
+ // var_dump($quotes_val1);
189
+
190
  //echo '<pre>'; print_r($quotes_val1); die;
191
 
192
+
193
+
194
  //$quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
195
 
196
+
197
+
198
  ?>
199
+
200
  <div class="shipping">
201
+
202
  <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
203
+
204
  <?php echo $this->getChildHtml('global_messages') ?>
205
+
206
  <div class="shipping-form">
207
+
208
  <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
209
+
210
  <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
211
+
212
  <ul class="form-list">
213
+
214
  <li>
215
+
216
  <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
217
+
218
  <div class="input-box">
219
+
220
  <select name="country_id" id="country" class="validate-select" title="Country" >
221
+
222
  <option value="AU" selected="selected" >Australia</option>
223
+
224
  </select>
225
+
226
  </div>
227
+
228
  <?php /*?><div class="input-box">
229
+
230
  <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
231
+
232
  </div><?php */?>
233
+
234
  </li>
235
+
236
  <?php //if($this->getStateActive()): ?>
237
+
238
  <?php /*?>
239
+
240
  <li>
241
+
242
  <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>>
243
+
244
  <?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?>
245
+
246
  <?php echo $this->__('Suburb') ?></label>
247
+
248
  <div class="input-box">
249
+
250
  <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
251
+
252
  <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
253
+
254
  </select>
255
+
256
  <script type="text/javascript">
257
+
258
  //<![CDATA[
259
+
260
  $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
261
+
262
  //]]>
263
+
264
  </script>
265
+
266
  <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getEstimateRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" />
267
+
268
  </div>
269
+
270
  </li><?php */?>
271
+
272
  <?php //endif; ?>
273
+
274
  <?php if($this->getCityActive()): ?>
275
+
276
  <li>
277
+
278
  <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>>
279
+
280
  <?php if ($this->isCityRequired()) echo '<em>*</em>' ?>
281
+
282
  <?php echo $this->__('City') ?></label>
283
+
284
  <div class="input-box">
285
+
286
  <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
287
+
288
  </div>
289
+
290
  </li>
291
+
292
  <?php endif; ?>
293
+
294
  <li>
295
+
296
  <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>>
297
+
298
  <?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?>
299
+
300
  <?php echo $this->__('Suburb / Postal Code') ?></label>
301
+
302
  <div class="input-box postcode_suburb">
303
+
304
  <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" maxlength="4"/><?php */?>
305
+
306
 
307
+
308
  <input id="autosuggest" type="text" />
309
+
310
  <input type="hidden" name="suburb" id="suburb" value="" />
311
+
312
  <input type="hidden" name="postcode" id="postcode" value="" />
313
 
314
+
315
+
316
  <?php
317
+
318
  //echo $tmp_cart_postcode_val; die('val');
319
+
320
  if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
321
+
322
  <script type="text/javascript">
323
+
324
  var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
325
+
326
 
327
+
328
  jQuery(document).ready(function(e) {
329
+
330
  if(jQuery(".as-selections").find(".as-selection-item").html()){
331
+
332
  jQuery(".previous-selection").css('display','none');
333
+
334
  } else {
335
+
336
  jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
337
+
338
  }
339
+
340
  });
341
+
342
  </script>
343
+
344
  <?php } ?>
345
+
346
 
347
+
348
  </div>
349
+
350
  </li>
351
+
352
  </ul>
353
+
354
  <div class="buttons-set">
355
+
356
  <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
357
+
358
  </div>
359
+
360
  </form>
361
+
362
  <script type="text/javascript">
363
+
364
  //<![CDATA[
365
+
366
  new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
367
+
368
  //]]>
369
+
370
+ </script>
371
+
372
+
373
+
374
  <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
375
+
376
+
377
+
378
  <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
379
+
380
+ <dl class="sp-methods">
381
+
382
+ <dt><?php echo $this->__("Carrier"); ?></dt>
383
+
384
+ <?php
385
+
386
  /*function cmp($a, $b) {
387
+
388
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
389
+
390
 
391
+
392
  if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['method_title'], $b['method_title']); }
393
+
394
  } */
395
+
396
  function cmp($key) {
397
+
398
  return function ($a, $b) use ($key) {
399
+
400
  return strnatcmp($a[$key], $b[$key]);
401
+
402
  };
403
+
404
  }
405
+
406
 
407
+
408
  $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
409
+
410
 
411
+
412
+ /* function build_sorter($key) {
413
+
414
  return function ($a, $b) use ($key) {
415
+
416
  return strnatcmp($a[$key], $b[$key]);
417
+
418
  };
419
+
420
+ }*/
421
+
 
 
422
  //echo '<pre>'; print_r($_shippingRateGroups); die;
423
+
424
+ ?>
425
+
426
+ <!-- get data -->
427
+
428
+ <?php /*?> <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt><?php */
429
+
430
+ ?>
431
+
432
+ <dd>
433
+
434
+ <ul>
435
+
436
+ <?php //usort($_rates, 'cmp');
437
+
438
+ foreach ($_shippingRateGroups as $code => $_rates):
439
+
440
+ foreach ($_rates as $ratekey => $_rate):
441
+
442
+
443
+
444
+ $xyz[] = $_rates[$ratekey]->getData();
445
+
446
+ $ratekey = sizeof($xyz) - 1;
447
+
448
+
449
+
450
  foreach ($quotes_val1 as $key => $val):
451
+
452
  //echo $key .' = '. $xyz[$ratekey]['method'].'<br>';
453
+
454
  //echo $quotes_val1[$key]['transit_time'];
455
+
456
  if($key == $xyz[$ratekey]['method']) {
457
+
458
+ // var_dump($xyz[$ratekey]);
459
+
460
  $xyz[$ratekey]['transit_time'] = $quotes_val1[$key]['transit_time'];
461
+
462
  break;
463
+
464
  }
465
+
466
  endforeach;
467
+
468
+ //die;
469
+
470
+ //$xyz[] = $transit_val;
471
+
472
+ //echo '<pre>'; print_r($_rate->getData());
473
+
474
+ endforeach;
475
+
476
+
477
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  endforeach;
479
+
480
+ //echo '<pre>'; print_r($xyz); die;
481
+
482
+
483
+
484
+ // sorting
485
+
486
+ if($display_quote == 'display_cheapest'){ usort($xyz, cmp('price')); }
487
+
488
+ if($display_quote == 'display_all_quotes'){ usort($xyz, cmp('method_title')); }
489
+
490
+ if($display_quote == 'display_cheapest_fastest'){ usort($xyz, cmp('transit_time')); }
491
+
492
+ //usort($xyz, cmp('price'));
493
+
494
+
495
+
496
+ /*
497
+
498
+ $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
499
+
500
+
501
+
502
+ if($display_quote == 'display_cheapest'){ usort($xyz, build_sorter('price')); }
503
+
504
+ if($display_quote == 'display_all_quotes'){ usort($xyz, build_sorter('price')); }
505
+
506
+ if($display_quote == 'display_cheapest_fastest'){ usort($xyz, build_sorter('price')); }
507
+
508
+ */
509
+
510
+
511
+
512
+ //echo '<pre>'; print_r($xyz);
513
+
514
+
515
+
516
+ // display
517
+
518
+ foreach($xyz as $key => $abc):
519
+
520
+ //echo '<pre>'; print_r($abc); die('ship');
521
+
522
+ //endforeach;
523
+
524
+ //echo $abc['code'];die;
525
+
526
+
527
+
528
+ if($abc['method_title']){?>
529
+
530
+ <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
531
+
532
+ <?php if ($_rate->getErrorMessage()): ?>
533
+
534
+ <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
535
+
536
+ <?php else: ?>
537
+
538
+ <input name="estimate_method" type="radio" value="<?php echo $abc['code'];
539
+
540
+ //$this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $abc['code'] ?>"
541
+
542
+ <?php if($abc['code']===$this->getAddressShippingMethod()) echo ' checked="checked"' ?>
543
+
544
+ class="radio" />
545
+
546
+ <label for="s_method_<?php echo $abc['code']; ?>">
547
+
548
+ <?php
549
+
550
+ $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
551
+
552
+ if($display_showcouriername == '1'){
553
+
554
+ echo $abc['method_title'];
555
+
556
+ /*
557
+
558
+ if($abc['method_title']=='fastway'){echo $this->__("Fastway"); }
559
+
560
+ if($abc['method_title']=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
561
+
562
+ if($abc['method_title']=='couriers_please'){echo $this->__("Couriers Please"); }
563
+
564
+ if($abc['method_title']=='allied'){echo $this->__("Allied Express"); }
565
+
566
+ if($abc['method_title']=='toll'){echo $this->__("Toll"); }
567
+
568
+ if($abc['method_title']=='mainfreight'){echo $this->__("Mainfreight"); }
569
+
570
+ if($abc['method_title']=='northline'){echo $this->__("Northline"); }
571
+
572
+ */
573
+
574
+ //$this->escapeHtml($_rate->getMethodTitle());
575
+
576
+ }
577
+
578
+ ?>
579
+
580
+ <?php $_excl = $this->getShippingPrice($abc['price'],
581
+
582
+ $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
583
+
584
+ <?php $_incl = $this->getShippingPrice($abc['price'], true); ?>
585
+
586
+ <?php echo $_excl; ?>
587
+
588
+
589
+
590
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
591
+
592
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
593
+
594
+ <?php endif; ?>
595
+
596
+
597
+
598
+ <?php if($abc['method_title'] != 'Fixed Price' && $abc['transit_time'] != '') {?>
599
+
600
+ <span> <?php echo '&nbsp;&nbsp;(Shipping Time - '. $abc['transit_time'].')';?> </span>
601
+
602
+ <?php } ?>
603
+
604
+ </label>
605
+
606
+ <?php endif; ?>
607
+
608
+ </li>
609
+
610
+ <?php }
611
+
612
+ endforeach;
613
+
614
+ // die('rate'); ?>
615
+
616
+ <?php /*?> <li>
617
+
618
+ <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
619
+
620
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitleOne()) ?>
621
+
622
+ <?php $_incl = $this->getShippingPrice($_rate->getPriceOne(), true); ?>
623
+
624
+ </li><?php */?>
625
+
626
+ </ul>
627
+
628
+ </dd>
629
+
630
+ <?php //endforeach; ?>
631
+
632
+ </dl>
633
+
634
+
635
+
636
+
637
+
638
  <div class="buttons-set">
639
+
640
  <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
641
+
642
  </div>
643
+
644
+
645
+
646
  </form>
647
+
648
  <?php endif; ?>
649
+
650
+
651
+
652
  <script type="text/javascript">
653
+
654
  //<![CDATA[
655
+
656
  var coShippingMethodForm = new VarienForm('shipping-zip-form');
657
+
658
  var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
659
+
660
  coShippingMethodForm.submit = function () {
661
+
662
  var country = $F('country');
663
+
664
  var optionalZip = false;
665
+
666
  var optionregion = false;
667
+
668
  for (i=0; i < countriesWithOptionalZip.length; i++) {
669
+
670
  if (countriesWithOptionalZip[i] == country) {
671
+
672
  optionalZip = true;
673
+
674
  }
675
+
676
  }
677
+
678
  if (optionalZip) {
679
+
680
  $('postcode').removeClassName('required-entry');
681
+
682
  }
683
+
684
  else {
685
+
686
  $('postcode').addClassName('required-entry');
687
+
688
  }
689
+
690
  /* if (optionregion) {
691
+
692
  $('region').removeClassName('required-entry');
693
+
694
  }
695
+
696
  else {
697
+
698
  $('region').addClassName('required-entry');
699
+
700
  }
701
+
702
  */
703
+
704
  return VarienForm.prototype.submit.bind(coShippingMethodForm)();
705
+
706
  }
707
+
708
  //]]>
709
+
710
  </script>
711
+
712
  </div>
713
+
714
  </div>
715
 
716
+
717
+
718
  <?php } ?>
app/design/frontend/rwd/default/layout/ship.xml ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default>
4
+ <reference name="head">
5
+ <block type="core/template" name="unique_name_here" template="ship/footer/js.phtml" />
6
+ </reference>
7
+
8
+ <reference name="head">
9
+ <!--<block type="core/text" name="external.cdn.jquery" before="-">
10
+ <action method="setText">
11
+ <text>
12
+ <![CDATA[
13
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
14
+ <script type="text/javascript">jQuery.noConflict();</script>
15
+ ]]>
16
+ </text>
17
+ </action>
18
+ </block>-->
19
+ <!--<action method="addCss"><stylesheet>ship/css/jquery.autoSuggest.css</stylesheet></action>
20
+ <action method="addItem"><type>skin_js</type><name>ship/js/location_script.js</name><params/></action>
21
+ <action method="addItem"><type>skin_js</type><name>ship/js/jquery.autoSuggest.js</name><params/></action>-->
22
+ </reference>
23
+
24
+ <!--<reference name="head">
25
+ <action method="addItem"><type>skin_js</type><name>ship/js/jquery-1.11.0.js</name><params/></action>
26
+ </reference>-->
27
+ </default>
28
+
29
+ <checkout_cart_index>
30
+ <reference name="checkout.cart.shipping">
31
+ <action method="setTemplate"><template>ship/shipping.phtml</template></action>
32
+ </reference>
33
+
34
+ <reference name="checkout.cart.totals">
35
+ <action method="setTemplate"><template>ship/checkout/cart/totals.phtml</template></action>
36
+ </reference>
37
+
38
+ </checkout_cart_index>
39
+
40
+ <catalog_product_view translate="label">
41
+ <reference name="right">
42
+ <block type="checkout/cart_shipping" name="checkout.cart.shipping" as="shipping" template="ship/product_shipping.phtml"/>
43
+ </reference>
44
+ </catalog_product_view>
45
+ </layout>
app/design/frontend/rwd/default/template/ship/checkout/cart/totals.phtml ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2013 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
+ <?php
28
+ /**
29
+ * Shopping cart totals template
30
+ *
31
+ * @see Mage_Checkout_Block_Cart_Totals
32
+ * @var $this Mage_Checkout_Block_Cart_Totals
33
+ */
34
+ ?>
35
+ <?php if ($this->canApplyMsrp()): ?>
36
+ <div class="cart-msrp-totals"><?php echo $this->__('ORDER TOTAL WILL BE DISPLAYED BEFORE YOU SUBMIT THE ORDER'); ?></div>
37
+ <?php else: ?>
38
+ <table id="shopping-cart-totals-table">
39
+ <col />
40
+ <col width="1" />
41
+ <tfoot>
42
+ <?php echo $this->renderTotals('footer'); ?>
43
+ </tfoot>
44
+ <tbody>
45
+ <?php echo $this->renderTotals(); ?>
46
+ </tbody>
47
+ </table>
48
+ <?php endif; ?>
app/design/frontend/rwd/default/template/ship/footer/js.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <link href="<?php echo $this->getSkinUrl();?>ship/css/jquery.autoSuggest.css" rel="stylesheet" />
2
+ <script type="text/javascript" src="<?php echo $this->getSkinUrl();?>ship/js/jquery-1.11.0.js"></script>
3
+ <script type="text/javascript">jQuery.noConflict();</script>
4
+ <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
5
+ <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>
app/design/frontend/rwd/default/template/ship/product_shipping.phtml ADDED
@@ -0,0 +1,307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2013 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
+ <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */ ?>
28
+ <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
29
+
30
+ <script type="text/javascript">
31
+ jQuery(document).ready(function(e) {
32
+ var result;
33
+ var data = {items: []};
34
+ jQuery.each( TDLocationsList, function( i, item ) {
35
+ data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
36
+ });
37
+ jQuery("#autosuggest").autoSuggest(data.items,
38
+ {
39
+ selectedItemProp: "name",
40
+ searchObjProps: "name",
41
+ selectionLimit: 1,
42
+ minChars: 3,
43
+ selectionAdded: function(elem)
44
+ {
45
+ result = elem.text();
46
+ getresultval(result);
47
+ }
48
+ }
49
+ );
50
+ function getresultval(res){
51
+ var postcode = res.substr(1,4);
52
+ var locality = res.substr(6);
53
+ jQuery('#suburb').attr("value", locality);
54
+ jQuery('#postcode').attr("value", postcode);
55
+
56
+ document.cookie="cart_postocde="+postcode;
57
+ document.cookie="cart_locality="+locality;
58
+ }
59
+ });
60
+
61
+ </script>
62
+
63
+ <?php $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
64
+ $tmp_cart_locality_val = $_COOKIE['cart_locality'];
65
+ ?>
66
+
67
+ <?php
68
+ $country_val = Mage::getSingleton('core/session')->getCountryVal();
69
+ $postocde_val = Mage::getSingleton('core/session')->getPostcodeVal();
70
+ $regionid_val = Mage::getSingleton('core/session')->getRegionIdVal();
71
+ $region_val = Mage::getSingleton('core/session')->getRegionVal();
72
+ ?>
73
+ <div class="shipping_product">
74
+ <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
75
+ <div class="shipping-form">
76
+ <form action="<?php echo $this->getUrl('ship/index/index/') ?>" method="post" id="shipping-zip-form">
77
+ <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
78
+ <ul class="form-list">
79
+ <li>
80
+ <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
81
+ <div class="input-box">
82
+ <select name="country_id" id="country" class="validate-select" title="Country" >
83
+ <option value="AU" selected="selected" ><?php echo $this->__('Australia') ?></option>
84
+ </select>
85
+ </div>
86
+ <?php /*?><div class="input-box">
87
+ <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
88
+ </div><?php */?>
89
+ </li>
90
+ <?php /*
91
+ //if($this->getStateActive()):
92
+
93
+ ?>
94
+ <li>
95
+ <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>><?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?><?php echo $this->__('Suburb') ?></label>
96
+ <div class="input-box">
97
+ <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
98
+ <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
99
+ </select>
100
+ <script type="text/javascript">
101
+ //<![CDATA[
102
+ $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
103
+ //]]>
104
+ </script>
105
+ <input type="text" id="region" name="region" value="<?php if($region_val){ echo $region_val;} else { echo $this->escapeHtml($this->getEstimateRegion()); } ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" style="display:none;" />
106
+ </div>
107
+ </li>
108
+ <?php //endif; */ ?>
109
+ <?php if($this->getCityActive()): ?>
110
+ <li>
111
+ <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>><?php if ($this->isCityRequired()) echo '<em>*</em>' ?><?php echo $this->__('City') ?></label>
112
+ <div class="input-box">
113
+ <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
114
+ </div>
115
+ </li>
116
+ <?php endif; ?>
117
+ <li>
118
+ <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>><?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?><?php echo $this->__('Zip/Postal Code') ?></label>
119
+ <div class="input-box postcode_suburb">
120
+ <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php if($postocde_val){ echo $postocde_val;} else { echo $this->escapeHtml($this->getEstimatePostcode()); } ?>" maxlength="4" /><?php */?>
121
+
122
+ <input id="autosuggest" type="text" />
123
+ <input type="hidden" name="suburb" id="suburb" value="" />
124
+ <input type="hidden" name="postcode" id="postcode" value="" />
125
+
126
+ <?php
127
+ //echo $tmp_cart_postcode_val; die('val');
128
+ if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
129
+ <script type="text/javascript">
130
+ var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
131
+
132
+ jQuery(document).ready(function(e) {
133
+ if(jQuery(".as-selections").find(".as-selection-item").html()){
134
+ } else {
135
+ jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
136
+ }
137
+ });
138
+ </script>
139
+ <?php } ?>
140
+
141
+ </div>
142
+ </li>
143
+ </ul>
144
+ <div class="buttons-set">
145
+ <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
146
+ </div>
147
+ </form>
148
+ <script type="text/javascript">
149
+ //<![CDATA[
150
+ new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
151
+ //]]>
152
+ </script>
153
+ <?php //if (($_shippingRateGroups = $this->getEstimateRates())): ?>
154
+ <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
155
+ <dl class="sp-methods">
156
+
157
+ <?php
158
+
159
+ //$quotes_val = Mage::register('store_id', Mage::app()->getStore()->getId());
160
+ //$quotes_val = Mage::registry('quotes_val');
161
+ //echo '<pre>'; print_r($quotes_val); //die('val');
162
+
163
+ //$val = Mage::getSingleton('checkout/session')->getQuote();
164
+
165
+ $quotes_val = Mage::getSingleton('core/session')->getSomeSessionVar();
166
+
167
+
168
+
169
+ //echo $country_val. $postocde_val . $regionid_val . $region_val; //die('data');
170
+
171
+ //echo '<pre>'; print_r($quotes_val);
172
+ //die('sess set');
173
+
174
+ if($quotes_val){ //die('response');
175
+
176
+ ?>
177
+ <dt><?php echo $this->__('Carrier');?></dt>
178
+ <dd>
179
+ <ul>
180
+
181
+ <?php
182
+
183
+ //foreach($quotes_val as $key => $val) {
184
+
185
+ $display_carriers = Mage::getStoreConfig('transdirect_section/displayoptions/availablecoriers');
186
+ $available_carriers = explode( ',', $display_carriers);
187
+
188
+ foreach ($quotes_val as $key => $val):
189
+
190
+ if(in_array($key,$available_carriers)) {
191
+ //echo '<br>'.$key . ' - matched<br>';
192
+ $xyz[$key] = $quotes_val[$key];
193
+ }
194
+
195
+ endforeach; //die;
196
+
197
+ foreach($xyz as $key => $abc):
198
+ if($key){
199
+ ?>
200
+
201
+ <li>
202
+ <label for="s_method">
203
+ <?php
204
+ $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
205
+ $display_surcharge = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge');
206
+ $display_surcharge1 = Mage::getStoreConfig('transdirect_section/displayoptions/handlingsurcharge1');
207
+
208
+ if($display_showcouriername == '1'){
209
+ //echo $key;
210
+ if($key=='fastway'){echo $this->__("Fastway"); }
211
+ if($key=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
212
+ if($key=='couriers_please'){echo $this->__("Couriers Please"); }
213
+ if($key=='allied'){echo $this->__("Allied Express"); }
214
+ if($key=='toll'){echo $this->__("Toll"); }
215
+ if($key=='mainfreight'){echo $this->__("Mainfreight"); }
216
+ if($key=='northline'){echo $this->__("Northline"); }
217
+
218
+ }
219
+ if($display_showcouriername == '1' && $display_surcharge == '1') {
220
+ echo ' + '.$this->__("Handling Charge");
221
+ }
222
+ ?>
223
+ <?php //echo $key.'&nbsp;&nbsp;&nbsp;'; ?>
224
+ <?php $curr_symbol = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();?>
225
+ <span class="price">
226
+ <?php
227
+ $tmp_display_surcharge = $abc['total'] + $display_surcharge1;
228
+ if($display_surcharge == '1'){
229
+ echo $curr_symbol. number_format($tmp_display_surcharge,2);
230
+ } else {
231
+ echo $curr_symbol. number_format($abc['total'],2);
232
+ }
233
+
234
+ ?></span>
235
+ <span>
236
+ <?php echo '(Shipping Time - '. $abc['transit_time'].')'; ?>
237
+ </span>
238
+ </label>
239
+ </li>
240
+
241
+ <?php }
242
+ endforeach; //} ?>
243
+
244
+ </ul>
245
+ </dd>
246
+ <?php }
247
+ if($quotes_val == '' && $postocde_val != ''){
248
+
249
+ $display_fixedprice = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror');
250
+ $display_fixedprice1 = Mage::getStoreConfig('transdirect_section/displayoptions/fixedpriceonerror1');
251
+ ?>
252
+
253
+ <dt><?php echo $this->__('Carrier');?></dt>
254
+ <dd>
255
+ <ul>
256
+ <li>
257
+ <label for="s_method"> <?php echo $this->__('Fixed Price'); ?>
258
+ <span class="price"> <?php echo $display_fixedprice1; ?> </span>
259
+ </label>
260
+ </li>
261
+ </ul>
262
+ </dd>
263
+
264
+ <?php } ?>
265
+
266
+ </dl>
267
+
268
+ <script type="text/javascript">
269
+ //<![CDATA[
270
+ var coShippingMethodForm = new VarienForm('shipping-zip-form');
271
+ var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
272
+ coShippingMethodForm.submit = function () {
273
+ var country = $F('country');
274
+ var optionalZip = false;
275
+ var optionregion = false;
276
+ for (i=0; i < countriesWithOptionalZip.length; i++) {
277
+ if (countriesWithOptionalZip[i] == country) {
278
+ optionalZip = true;
279
+ }
280
+ }
281
+ if (optionalZip) {
282
+ $('postcode').removeClassName('required-entry');
283
+ }
284
+ else {
285
+ $('postcode').addClassName('required-entry');
286
+ }
287
+
288
+ /*if (optionregion) {
289
+ $('region').removeClassName('required-entry');
290
+ }
291
+ else {
292
+ $('region').addClassName('required-entry');
293
+ }*/
294
+
295
+ return VarienForm.prototype.submit.bind(coShippingMethodForm)();
296
+ }
297
+ //]]>
298
+ </script>
299
+ </div>
300
+ </div>
301
+ <style type="text/css">
302
+ .shipping_product {border: 1px solid #D0CBC1; margin: 0 0 18px; padding: 10px;}
303
+ .shipping-form,.form-list .input-box, .form-list select {width:100%;}
304
+ .form-list input.input-text{width:97%;}
305
+ </style>
306
+
307
+ <?php } ?>
app/design/frontend/rwd/default/template/ship/shipping.phtml ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) 2013 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
+ <?php /** @var $this Mage_Checkout_Block_Cart_Shipping */
28
+
29
+ ?>
30
+
31
+ <?php if(Mage::getStoreConfig('transdirect_section/enabletab/enable')){ ?>
32
+
33
+ <!--<link href="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.css" rel="stylesheet" />
34
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
35
+ <script type="text/javascript" src="https://www.transdirect.com.au/api/locations/script"></script>
36
+ <script src="<?php echo $this->getSkinUrl();?>ship/js/location_script.js"></script>
37
+ <script src="<?php echo $this->getSkinUrl();?>ship/js/jquery.autoSuggest.js"></script>-->
38
+
39
+ <script type="text/javascript">
40
+ jQuery(document).ready(function(e) {
41
+ var result;
42
+ var data = {items: []};
43
+ jQuery.each( TDLocationsList, function( i, item ) {
44
+ data.items.push({ value: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality , name: TDLocationsList[i].postcode +' '+ TDLocationsList[i].locality});
45
+ });
46
+ jQuery("#autosuggest").autoSuggest(data.items,
47
+ {
48
+ selectedItemProp: "name",
49
+ searchObjProps: "name",
50
+ selectionLimit: 1,
51
+ minChars: 3,
52
+ selectionAdded: function(elem)
53
+ {
54
+ result = elem.text();
55
+ getresultval(result);
56
+ }
57
+ }
58
+ );
59
+ function getresultval(res){
60
+ var postcode = res.substr(1,4);
61
+ var locality = res.substr(6);
62
+ jQuery('#suburb').attr("value", locality);
63
+ jQuery('#postcode').attr("value", postcode);
64
+
65
+ document.cookie="cart_postocde="+postcode;
66
+ document.cookie="cart_locality="+locality;
67
+ }
68
+ if(jQuery( ".as-results .as-message:contains('No Results Found')" )){
69
+ jQuery(".postcode_suburb .as-results").css("display","none");
70
+ }
71
+ });
72
+
73
+ </script>
74
+
75
+ <?php
76
+ $tmp_cart_postcode_val = $_COOKIE['cart_postocde'];
77
+ $tmp_cart_locality_val = $_COOKIE['cart_locality'];
78
+ ?>
79
+
80
+ <?php Mage::getSingleton('core/session')->unsCartpostcodeVal();
81
+ Mage::getSingleton('core/session')->unsCartlocalityVal();
82
+
83
+ // $cart_postcode_val = Mage::getSingleton('core/session')->setCartpostcodeVal($tmp_cart_postcode_val);
84
+ // $cart_locality_val = Mage::getSingleton('core/session')->setCartlocalityVal($tmp_cart_locality_val);
85
+
86
+ ?>
87
+
88
+ <?php $transit_val = Mage::getSingleton('core/session')->getTransitVal(); //die('tra');
89
+ $quotes_val1 = Mage::getSingleton('core/session')->getSomeSessionVar1();
90
+ //echo '<pre>'; print_r($quotes_val1); die;
91
+
92
+ //$quote_form_postcode_val = Mage::getSingleton('core/session')->setPostcodeVal($postcode); // In the Controller
93
+
94
+ ?>
95
+ <div class="shipping">
96
+ <h2><?php echo $this->__('Get A Shipping Quote') ?></h2>
97
+ <?php echo $this->getChildHtml('global_messages') ?>
98
+ <div class="shipping-form">
99
+ <form action="<?php echo $this->getUrl('checkout/cart/estimatePost') ?>" method="post" id="shipping-zip-form">
100
+ <p><?php echo $this->__('Enter your destination to get a shipping estimate.') ?></p>
101
+ <ul class="form-list">
102
+ <li>
103
+ <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>
104
+ <div class="input-box">
105
+ <select name="country_id" id="country" class="validate-select" title="Country" >
106
+ <option value="AU" selected="selected" >Australia</option>
107
+ </select>
108
+ </div>
109
+ <?php /*?><div class="input-box">
110
+ <?php echo Mage::getBlockSingleton('directory/data')->getCountryHtmlSelect($this->getEstimateCountryId()) ?>
111
+ </div><?php */?>
112
+ </li>
113
+ <?php //if($this->getStateActive()): ?>
114
+ <?php /*?>
115
+ <li>
116
+ <label for="region_id"<?php if ($this->isStateProvinceRequired()) echo ' class="required"' ?>>
117
+ <?php if ($this->isStateProvinceRequired()) echo '<em>*</em>' ?>
118
+ <?php echo $this->__('Suburb') ?></label>
119
+ <div class="input-box">
120
+ <select id="region_id" name="region_id" title="<?php echo $this->__('Suburb') ?>" style="display:none;"<?php echo ($this->isStateProvinceRequired() ? ' class="validate-select"' : '') ?>>
121
+ <option value=""><?php echo $this->__('Please select region, state or province') ?></option>
122
+ </select>
123
+ <script type="text/javascript">
124
+ //<![CDATA[
125
+ $('region_id').setAttribute('defaultValue', "<?php echo $this->getEstimateRegionId() ?>");
126
+ //]]>
127
+ </script>
128
+ <input type="text" id="region" name="region" value="<?php echo $this->escapeHtml($this->getEstimateRegion()) ?>" title="<?php echo $this->__('State/Province') ?>" class="input-text required-entry" />
129
+ </div>
130
+ </li><?php */?>
131
+ <?php //endif; ?>
132
+ <?php if($this->getCityActive()): ?>
133
+ <li>
134
+ <label for="city"<?php if ($this->isCityRequired()) echo ' class="required"' ?>>
135
+ <?php if ($this->isCityRequired()) echo '<em>*</em>' ?>
136
+ <?php echo $this->__('City') ?></label>
137
+ <div class="input-box">
138
+ <input class="input-text<?php if ($this->isCityRequired()):?> required-entry<?php endif;?>" id="city" type="text" name="estimate_city" value="<?php echo $this->escapeHtml($this->getEstimateCity()) ?>" />
139
+ </div>
140
+ </li>
141
+ <?php endif; ?>
142
+ <li>
143
+ <label for="postcode"<?php if ($this->isZipCodeRequired()) echo ' class="required"' ?>>
144
+ <?php if ($this->isZipCodeRequired()) echo '<em>*</em>' ?>
145
+ <?php echo $this->__('Suburb / Postal Code') ?></label>
146
+ <div class="input-box postcode_suburb">
147
+ <?php /*?><input class="input-text validate-number validate-postcode<?php if ($this->isZipCodeRequired()):?> required-entry<?php endif;?>" type="text" id="postcode" name="estimate_postcode" value="<?php echo $this->escapeHtml($this->getEstimatePostcode()) ?>" maxlength="4"/><?php */?>
148
+
149
+ <input id="autosuggest" type="text" />
150
+ <input type="hidden" name="suburb" id="suburb" value="" />
151
+ <input type="hidden" name="postcode" id="postcode" value="" />
152
+
153
+ <?php
154
+ //echo $tmp_cart_postcode_val; die('val');
155
+ if(!$tmp_cart_postcode_val=='' || !$tmp_cart_locality_val==''){ ?>
156
+ <script type="text/javascript">
157
+ var prev_suggest_value = '<div class="previous-selection"><span class="text"><?php echo 'Your Last Selection:'.'&nbsp;&nbsp;&nbsp;'?></span><span class="post"><?php echo 'Postcode:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_postcode_val.'&nbsp;&nbsp;'; ?></span><span class="locality"><?php echo 'Suburb:'.'&nbsp;&nbsp;&nbsp;'.$tmp_cart_locality_val?></span></div>';
158
+
159
+ jQuery(document).ready(function(e) {
160
+ if(jQuery(".as-selections").find(".as-selection-item").html()){
161
+ jQuery(".previous-selection").css('display','none');
162
+ } else {
163
+ jQuery("#shipping-zip-form .postcode_suburb").after(prev_suggest_value);
164
+ }
165
+ });
166
+ </script>
167
+ <?php } ?>
168
+
169
+ </div>
170
+ </li>
171
+ </ul>
172
+ <div class="buttons-set">
173
+ <button type="button" title="<?php echo $this->__('Get a Quote') ?>" onclick="coShippingMethodForm.submit()" class="button"><span><span><?php echo $this->__('Get a Quote') ?></span></span></button>
174
+ </div>
175
+ </form>
176
+ <script type="text/javascript">
177
+ //<![CDATA[
178
+ new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>);
179
+ //]]>
180
+ </script>
181
+ <?php if (($_shippingRateGroups = $this->getEstimateRates())): ?>
182
+ <form id="co-shipping-method-form" action="<?php echo $this->getUrl('checkout/cart/estimateUpdatePost') ?>">
183
+ <dl class="sp-methods">
184
+ <dt><?php echo $this->__("Carrier"); ?></dt>
185
+ <?php
186
+ /*function cmp($a, $b) {
187
+ $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
188
+
189
+ if($display_quote == 'display_cheapest'){ return strcmp($a['price'], $b['price']); } else { return strcmp($a['method_title'], $b['method_title']); }
190
+ } */
191
+ function cmp($key) {
192
+ return function ($a, $b) use ($key) {
193
+ return strnatcmp($a[$key], $b[$key]);
194
+ };
195
+ }
196
+
197
+ $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
198
+
199
+ /* function build_sorter($key) {
200
+ return function ($a, $b) use ($key) {
201
+ return strnatcmp($a[$key], $b[$key]);
202
+ };
203
+ }*/
204
+
205
+ // get data
206
+ foreach ($_shippingRateGroups as $code => $_rates):
207
+
208
+ //echo '<pre>'; print_r($_shippingRateGroups); die;
209
+ ?>
210
+ <?php /*?> <dt><?php echo $this->escapeHtml($this->getCarrierName($code)) ?></dt><?php */?>
211
+ <dd>
212
+ <ul>
213
+ <?php
214
+
215
+
216
+ //usort($_rates, 'cmp');
217
+
218
+ foreach ($_rates as $ratekey => $_rate):
219
+
220
+ $xyz[] = $_rates[$ratekey]->getData();
221
+ $ratekey = sizeof($xyz) - 1;
222
+
223
+ foreach ($quotes_val1 as $key => $val):
224
+
225
+ //echo $key .' = '. $xyz[$ratekey]['method'].'<br>';
226
+ //echo $quotes_val1[$key]['transit_time'];
227
+ if($key == $xyz[$ratekey]['method']) {
228
+ // var_dump($xyz[$ratekey]);
229
+ $xyz[$ratekey]['transit_time'] = $quotes_val1[$key]['transit_time'];
230
+ break;
231
+ }
232
+ endforeach;
233
+ //die;
234
+
235
+ //$xyz[] = $transit_val;
236
+
237
+ //echo '<pre>'; print_r($_rate->getData());
238
+
239
+ endforeach;
240
+
241
+ endforeach;
242
+
243
+ //echo '<pre>'; print_r($xyz); die;
244
+
245
+ // sorting
246
+
247
+ if($display_quote == 'display_cheapest'){ usort($xyz, cmp('price')); }
248
+ if($display_quote == 'display_all_quotes'){ usort($xyz, cmp('method_title')); }
249
+ if($display_quote == 'display_cheapest_fastest'){ usort($xyz, cmp('transit_time')); }
250
+ //usort($xyz, cmp('price'));
251
+
252
+ /*
253
+ $display_quote = Mage::getStoreConfig('transdirect_section/displayoptions/quotedisplay');
254
+
255
+ if($display_quote == 'display_cheapest'){ usort($xyz, build_sorter('price')); }
256
+ if($display_quote == 'display_all_quotes'){ usort($xyz, build_sorter('price')); }
257
+ if($display_quote == 'display_cheapest_fastest'){ usort($xyz, build_sorter('price')); }
258
+ */
259
+
260
+ //echo '<pre>'; print_r($xyz);
261
+
262
+ // display
263
+ foreach($xyz as $key => $abc):
264
+ //echo '<pre>'; print_r($abc); die('ship');
265
+ //endforeach;
266
+ //echo $abc['code'];die;
267
+
268
+
269
+ if($abc['method_title']){
270
+ ?>
271
+ <li<?php if ($_rate->getErrorMessage()) echo ' class="error-msg"';?>>
272
+ <?php if ($_rate->getErrorMessage()): ?>
273
+ <?php echo $this->escapeHtml($_rate->getErrorMessage()) ?>
274
+ <?php else: ?>
275
+ <input name="estimate_method" type="radio" value="<?php echo $abc['code']; //$this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $abc['code'] ?>"<?php if($abc['code']===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
276
+ <label for="s_method_<?php echo $abc['code']; ?>">
277
+ <?php
278
+ $display_showcouriername = Mage::getStoreConfig('transdirect_section/displayoptions/showcouriernames');
279
+ if($display_showcouriername == '1'){
280
+ echo $abc['method_title'];
281
+ /*
282
+ if($abc['method_title']=='fastway'){echo $this->__("Fastway"); }
283
+ if($abc['method_title']=='toll_priority_overnight'){echo $this->__("Toll Priority Overnight"); }
284
+ if($abc['method_title']=='couriers_please'){echo $this->__("Couriers Please"); }
285
+ if($abc['method_title']=='allied'){echo $this->__("Allied Express"); }
286
+ if($abc['method_title']=='toll'){echo $this->__("Toll"); }
287
+ if($abc['method_title']=='mainfreight'){echo $this->__("Mainfreight"); }
288
+ if($abc['method_title']=='northline'){echo $this->__("Northline"); }
289
+ */
290
+
291
+ //$this->escapeHtml($_rate->getMethodTitle());
292
+ }
293
+ ?>
294
+ <?php $_excl = $this->getShippingPrice($abc['price'], $this->helper('tax')->displayShippingPriceIncludingTax()); ?>
295
+ <?php $_incl = $this->getShippingPrice($abc['price'], true); ?>
296
+ <?php echo $_excl; ?>
297
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
298
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
299
+ <?php endif; ?>
300
+ <?php if($abc['method_title'] != 'Fixed Price' && $abc['transit_time'] != '') {?>
301
+ <span> <?php echo '&nbsp;&nbsp;(Shipping Time - '. $abc['transit_time'].')'; ?> </span>
302
+ <?php } ?>
303
+ </label>
304
+ <?php endif ?>
305
+ </li>
306
+ <?php }
307
+ endforeach;
308
+ // die('rate'); ?>
309
+ <?php /*?> <li>
310
+ <input name="estimate_method" type="radio" value="<?php echo $this->escapeHtml($_rate->getCode()) ?>" id="s_method_<?php echo $_rate->getCode() ?>"<?php if($_rate->getCode()===$this->getAddressShippingMethod()) echo ' checked="checked"' ?> class="radio" />
311
+ <label for="s_method_<?php echo $_rate->getCode() ?>"><?php echo $this->escapeHtml($_rate->getMethodTitleOne()) ?>
312
+ <?php $_incl = $this->getShippingPrice($_rate->getPriceOne(), true); ?>
313
+ </li><?php */?>
314
+ </ul>
315
+ </dd>
316
+ <?php //endforeach; ?>
317
+ </dl>
318
+ <div class="buttons-set">
319
+ <button type="submit" title="<?php echo $this->__('Update Total') ?>" class="button" name="do" value="<?php echo $this->__('Update Total') ?>"><span><span><?php echo $this->__('Update Total') ?></span></span></button>
320
+ </div>
321
+ </form>
322
+ <?php endif; ?>
323
+ <script type="text/javascript">
324
+ //<![CDATA[
325
+ var coShippingMethodForm = new VarienForm('shipping-zip-form');
326
+ var countriesWithOptionalZip = <?php echo $this->helper('directory')->getCountriesWithOptionalZip(true) ?>;
327
+ coShippingMethodForm.submit = function () {
328
+ var country = $F('country');
329
+ var optionalZip = false;
330
+ var optionregion = false;
331
+ for (i=0; i < countriesWithOptionalZip.length; i++) {
332
+ if (countriesWithOptionalZip[i] == country) {
333
+ optionalZip = true;
334
+ }
335
+ }
336
+ if (optionalZip) {
337
+ $('postcode').removeClassName('required-entry');
338
+ }
339
+ else {
340
+ $('postcode').addClassName('required-entry');
341
+ }
342
+ /* if (optionregion) {
343
+ $('region').removeClassName('required-entry');
344
+ }
345
+ else {
346
+ $('region').addClassName('required-entry');
347
+ }
348
+ */
349
+ return VarienForm.prototype.submit.bind(coShippingMethodForm)();
350
+ }
351
+ //]]>
352
+ </script>
353
+ </div>
354
+ </div>
355
+
356
+ <?php } ?>
app/etc/modules/Transdirect_Ship.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Transdirect_Ship>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Transdirect_Ship>
8
+ </modules>
9
+ </config>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Transdirect_Shipping</name>
4
- <version>1.0.0</version>
5
  <stability>stable</stability>
6
  <license>Open Software License (OSL)</license>
7
  <channel>community</channel>
@@ -32,9 +32,9 @@ To find out more about Transdirect's service, please contact sales@transdirect.c
32
  Transdirect - Delivering Solutions.</description>
33
  <notes>First version of Magento Module</notes>
34
  <authors><author><name>Joshua Oliver</name><user>transdirect</user><email>josh+transdirect@bywave.com.au</email></author></authors>
35
- <date>2014-08-31</date>
36
- <time>23:08:29</time>
37
- <contents><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="ship"><dir name="css"><file name="bkp_4-7-2014----jquery.autoSuggest.css" hash="8c6c14cc2da45fcd253604d7f75d09d4"/><file name="jquery.autoSuggest.css" hash="3c4accec3e181b557eefb86323f4f857"/></dir><dir name="js"><file name="bkp_4-7-2014---jquery.autoSuggest.js" hash="71d6c104b20fe51af0999846714ed3f3"/><file name="jquery-1.11.0.js" hash="3b80424646a7ecdb19273d86800c1ac0"/><file name="jquery.autoSuggest.js" hash="2737d8e2ddcaa3b0e399f8f2fd3fd62d"/><file name="location_script.js" hash="9238343017e0cb8552bc7b02c6ad2c04"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Transdirect"><dir><dir name="Ship"><dir name="Block"><file name="Quotes.php" hash="b0c361689dfe4b717a7fb5da0fd7791b"/><file name="Ship.php" hash="a5f51609d984777741720bf6e37f32bb"/></dir><dir name="Helper"><file name="Data.php" hash="6d320e97bdaca96d9e56414475d12f76"/></dir><dir name="Model"><dir name="Carrier"><file name="Transdirect.php" hash="42ca7855bbb6a8f98bb22ebc177477e0"/><file name="Transdirect_new_28-5-2014.php" hash="4584dfabc240496eb783a7c41c4e06ac"/><file name="bkp_26-5-2014-morning----Excellence.php" hash="8344e4ee91a526d9c57d22c34f1d7947"/><file name="bkp_28-5-2014-evening-----Transdirect.php" hash="30c8d0699a0ae44bfe0a73b8aea0f5e1"/><file name="bkp_30-5-2014---Transdirect.php" hash="b60f6d452c479d4475081c8591b66f43"/></dir><dir name="Source"><file name="AddressType.php" hash="503ce2451e315a59ff4c9a047699c5a0"/><file name="Couriers.php" hash="558e058b371287319dc1293ded6e1c77"/><file name="Quotes.php" hash="d2dac88da54640a7e49b770368ca7297"/></dir></dir><dir name="controllers"><file name="IndexController.php" hash="aed3817bd5ba51588962293b2474eef8"/><file name="bkp_29-5-2014---IndexController.php" hash="9527f179d5ba3ab8edb2a985d18974cf"/><file name="bkp_30-5-2014----IndexController.php" hash="818a062ef783df5dc998c03939271053"/></dir><dir name="etc"><file name="adminhtml.xml" hash="29d649800f1cabfa2ad3e96bf06cff22"/><file name="bkp_30-5-2014---config.xml" hash="d2d455d310db7cd7ff075f945e84c4e6"/><file name="bkp_30-5-2014---system.xml" hash="730cc695f5cdebdbfeb5e1db97878e35"/><file name="config.xml" hash="29332e55c017c8fb95904a1cd30fbeb5"/><file name="system.xml" hash="604f3a4354842736041e7707ca899ea3"/></dir><dir name="sql"><dir name="ship_setup"><file name="mysql4-install-0.1.0.php" hash="aed964c7ba72cd866e9c3982bad77027"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><file name="layout" hash="d41d8cd98f00b204e9800998ecf8427e"/><dir name="template"><dir name="ship"><file name="bkp_29-5-2014--working----product_shipping.phtml" hash="a60d44bf1302c801824a20eb8f05ad20"/><file name="bkp_29-5-2014--working----shipping.phtml" hash="2412c53fe7bcf5861a6e6fcd6d5244ae"/><file name="bkp_30-5-2014---product_shipping.phtml" hash="62f02055aa131337fb3facbabe1d85a7"/><file name="bkp_30-5-2014---shipping.phtml" hash="0203cb036dc9ad38d075e7a31c9c88a8"/><dir name="checkout"><dir name="cart"><file name="totals.phtml" hash="5b69442fec9380e0e6d2afc6f95fd04a"/></dir></dir><dir name="footer"><file name="js.phtml" hash="9bf30816c1685347a44d106de14ea2f9"/></dir><file name="product_shipping.phtml" hash="83fef427e326b8a8041249220330d0bb"/><file name="shipping.phtml" hash="24647ca7529d6bc60076114893c9e561"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="."><file name="modules" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></target></contents>
38
  <compatible/>
39
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
40
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Transdirect_Shipping</name>
4
+ <version>1.1.0</version>
5
  <stability>stable</stability>
6
  <license>Open Software License (OSL)</license>
7
  <channel>community</channel>
32
  Transdirect - Delivering Solutions.</description>
33
  <notes>First version of Magento Module</notes>
34
  <authors><author><name>Joshua Oliver</name><user>transdirect</user><email>josh+transdirect@bywave.com.au</email></author></authors>
35
+ <date>2014-10-21</date>
36
+ <time>08:49:07</time>
37
+ <contents><target name="magelocal"><dir name="Transdirect"><dir name="Ship"><dir name="Block"><file name="Quotes.php" hash="0e539cc0a2831069789a3d9b3f647772"/><file name="Ship.php" hash="27112cddd22559ebd1f3d6b7abf64a3d"/></dir><dir name="Helper"><file name="Data.php" hash="0252ec0e51cfda0a3f23ddf359f75202"/></dir><dir name="Model"><dir name="Carrier"><file name="Transdirect.php" hash="ca0a520a9f1a4c1b407ecad4ec6c71ca"/></dir><dir name="Source"><file name="AddressType.php" hash="3385ec33de0d820a9098f3aa25d3d3d1"/><file name="Couriers.php" hash="f75b6dd256d6b07fb3542a2568eb62df"/><file name="Quotes.php" hash="d382cf07326522786c4f929bbb5e228f"/></dir></dir><dir name="controllers"><file name="IndexController.php" hash="0a7b2535288aedd6323990e56049b452"/></dir><dir name="etc"><file name="adminhtml.xml" hash="79534cef195241413dc4503010a9ad18"/><file name="config.xml" hash="d2d455d310db7cd7ff075f945e84c4e6"/><file name="system.xml" hash="830ef06a64d7c78de1e4fda416619b1a"/></dir><dir name="sql"><dir name="ship_setup"><file name="mysql4-install-0.1.0.php" hash="281f495aac68bbaf08b43039e57973a4"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Transdirect_Ship.xml" hash="fbc66a2834c10ad65dd55a7dd4bea798"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="default"><dir name="default"><dir name="ship"><dir name="css"><file name="jquery.autoSuggest.css" hash="e976e6a48799083cf955aa5373d2838c"/></dir><dir name="js"><file name="jquery-1.11.0.js" hash="573025dfa115bc306dac7dfa18153675"/><file name="jquery.autoSuggest.js" hash="b1833197f28b1321b565b3c56b8a1403"/><file name="location_script.js" hash="9238343017e0cb8552bc7b02c6ad2c04"/></dir></dir></dir></dir><dir name="rwd"><dir name="default"><dir name="ship"><dir name="css"><file name="jquery.autoSuggest.css" hash="e976e6a48799083cf955aa5373d2838c"/></dir><dir name="js"><file name="jquery-1.11.0.js" hash="573025dfa115bc306dac7dfa18153675"/><file name="jquery.autoSuggest.js" hash="b1833197f28b1321b565b3c56b8a1403"/><file name="location_script.js" hash="9238343017e0cb8552bc7b02c6ad2c04"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="ship.xml" hash="7b6b6dcee52e6af102111b227da4b16d"/></dir><dir name="template"><dir name="ship"><dir name="checkout"><dir name="cart"><file name="totals.phtml" hash="96e28634c4a68102067349ef0149cd32"/></dir></dir><dir name="footer"><file name="js.phtml" hash="729153a7b05e9e397ad96abbda8e3a84"/></dir><file name="product_shipping.phtml" hash="a56e35a53ddf0484bc633d5d54fc9ea3"/><file name="shipping.phtml" hash="61f839c1dd36da82f32ae34e62070a46"/></dir></dir></dir></dir><dir name="rwd"><dir name="default"><dir name="layout"><file name="ship.xml" hash="7b6b6dcee52e6af102111b227da4b16d"/></dir><dir name="template"><dir name="ship"><dir name="checkout"><dir name="cart"><file name="totals.phtml" hash="96e28634c4a68102067349ef0149cd32"/></dir></dir><dir name="footer"><file name="js.phtml" hash="729153a7b05e9e397ad96abbda8e3a84"/></dir><file name="product_shipping.phtml" hash="f86fc4817054df798c0549970bc9dc16"/><file name="shipping.phtml" hash="a8e00a911251ba4af976d77b838feb01"/></dir></dir></dir></dir></dir></target></contents>
38
  <compatible/>
39
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
40
  </package>
skin/frontend/default/default/ship/css/jquery.autoSuggest.css CHANGED
@@ -1,257 +1,257 @@
1
- /* AutoSuggest CSS - Version 1.2 */
2
-
3
- ul.as-selections {
4
- list-style-type: none;
5
- border-top: 1px solid #888;
6
- border-bottom: 1px solid #b6b6b6;
7
- border-left: 1px solid #aaa;
8
- border-right: 1px solid #aaa;
9
- padding: 0 0 0 4px;
10
- margin: 0;
11
- overflow: auto;
12
- background-color: #fff;
13
- /*box-shadow:inset 0 1px 2px #888;
14
- -webkit-box-shadow:inset 0 1px 2px #888;
15
- -moz-box-shadow:inset 0 1px 2px #888;*/
16
- }
17
-
18
- ul.as-selections.loading {
19
- background-color: #eee;
20
- }
21
-
22
- ul.as-selections li {
23
- float: left;
24
- margin: 0px 4px 0px 0;
25
- /*width:90%;*/
26
- width:91%;
27
- }
28
-
29
- ul.as-selections li.as-selection-item {
30
- color: #2b3840;
31
- font-size: 12px;
32
- font-family: "Lucida Grande", arial, sans-serif;
33
- text-shadow: 0 1px 1px #fff;
34
- padding: 2px 5px 0;
35
- /*border: 1px solid #747474;
36
- border-top-color: #747474;
37
- background-color: #ddeefe;
38
- background-image: -moz-linear-gradient(top, #ddeefe, #bfe0f1);
39
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddeefe), to(#bfe0f1));
40
- border-radius: 12px;
41
- -webkit-border-radius: 12px;
42
- -moz-border-radius: 12px;
43
- box-shadow: 0 1px 1px #e4edf2;
44
- -webkit-box-shadow: 0 1px 1px #e4edf2;
45
- -moz-box-shadow: 0 1px 1px #e4edf2;*/
46
- }
47
-
48
- ul.as-selections li.as-selection-item:last-child {
49
- margin-left: 30px;
50
- }
51
-
52
- ul.as-selections li.as-selection-item a.as-close {
53
- float: right;
54
- margin: -4px 0 -2px 7px;
55
- padding: 0 2px;
56
- cursor: pointer;
57
- color: #747474;
58
- font-family: "Helvetica", helvetica, arial, sans-serif;
59
- font-size: 17px;
60
- text-decoration:none;
61
- font-weight: bold;
62
- text-shadow: 0 1px 1px #fff;
63
- -webkit-transition: color .1s ease-in;
64
- }
65
-
66
- ul.as-selections li.as-selection-item.blur {
67
- color: #666666;
68
- background-color: #f4f4f4;
69
- background-image: -moz-linear-gradient(top, #f4f4f4, #d5d5d5);
70
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f4f4f4), to(#d5d5d5));
71
- border-color: #bbb;
72
- border-top-color: #ccc;
73
- box-shadow: 0 1px 1px #e9e9e9;
74
- -webkit-box-shadow: 0 1px 1px #e9e9e9;
75
- -moz-box-shadow: 0 1px 1px #e9e9e9;
76
- }
77
-
78
- ul.as-selections li.as-selection-item.blur a.as-close {
79
- color: #999;
80
- }
81
-
82
- ul.as-selections li:hover.as-selection-item {
83
- /*color: #2b3840;
84
- background-color: #bbd4f1;
85
- background-image: -moz-linear-gradient(top, #bbd4f1, #a3c2e5);
86
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbd4f1), to(#a3c2e5));
87
- border-color: #6da0e0;
88
- border-top-color: #8bb7ed;*/
89
- }
90
-
91
- ul.as-selections li:hover.as-selection-item a.as-close {
92
- color: #4d70b0;
93
- }
94
-
95
- ul.as-selections li.as-selection-item.selected {
96
- /*border-color: #1f30e4;*/
97
- }
98
-
99
- ul.as-selections li.as-selection-item a:hover.as-close {
100
- color: #1b3c65;
101
- }
102
-
103
- ul.as-selections li.as-selection-item a:active.as-close {
104
- color: #4d70b0;
105
- }
106
-
107
- ul.as-selections li.as-original {
108
- margin-left: 0;
109
- }
110
-
111
- ul.as-selections li.as-original input {
112
- border: none;
113
- outline: none;
114
- font-size: 12px;
115
- width: 120px;
116
- height: 18px;
117
- /*padding-top: 3px;*/
118
- width:100%;
119
- }
120
- .catalog-product-view ul.as-selections li.as-original input {font-size:11px;}
121
- ul.as-selections li.as-original input[type=text]:disabled { background: none; }
122
-
123
- ul.as-list {
124
- position: absolute;
125
- list-style-type: none;
126
- margin: 2px 0 0 0;
127
- padding: 0;
128
- font-size: 12px;
129
- color: #000;
130
- font-family: "Lucida Grande", arial, sans-serif;
131
- background-color: #fff;
132
- background-color: rgba(255,255,255,0.95);
133
- z-index: 2;
134
- box-shadow: 0 2px 12px #222;
135
- -webkit-box-shadow: 0 2px 12px #222;
136
- -moz-box-shadow: 0 2px 12px #222;
137
- border-radius: 5px;
138
- -webkit-border-radius: 5px;
139
- -moz-border-radius: 5px;
140
- max-height:290px;
141
- min-height:33px;
142
- overflow-y: auto;
143
- }
144
-
145
- li.as-result-item, li.as-message {
146
- margin: 0 0 0 0;
147
- padding: 5px 12px;
148
- background-color: transparent;
149
- border: 1px solid #fff;
150
- border-bottom: 1px solid #ddd;
151
- cursor: pointer;
152
- border-radius: 5px;
153
- -webkit-border-radius: 5px;
154
- -moz-border-radius: 5px;
155
- }
156
-
157
- li:first-child.as-result-item {
158
- margin: 0;
159
- }
160
-
161
- li.as-message {
162
- margin: 0;
163
- cursor: default;
164
- }
165
-
166
- li.as-result-item.active {
167
- background-color: #ddeefe;
168
- background-image: -moz-linear-gradient(top, #ddeefe, #ddeefe);
169
- background-image: -webkit-gradient(linear, 0% 0%, 0% 64%, from(rgb(110, 129, 245)), to(rgb(62, 82, 242)));
170
- border-color: #ddeefe;
171
- color: #000;
172
- text-shadow:none;
173
- }
174
-
175
- li.as-result-item em {
176
- font-style: normal;
177
- /*background: #444;
178
- color: #fff;*/
179
- background: none;
180
- color: #000;
181
- padding: 0px;
182
- }
183
-
184
- li.as-result-item.active em {
185
- /*background: #253f7a;
186
- color: #fff;*/
187
- background: none;
188
- color: #000;
189
- }
190
-
191
- /* Webkit Hacks */
192
- @media screen and (-webkit-min-device-pixel-ratio:0) {
193
- ul.as-selections {
194
- border-top-width: 2px;
195
- }
196
- ul.as-selections li.as-selection-item {
197
- padding-top: 3px;
198
- padding-bottom: 3px;
199
- }
200
- ul.as-selections li.as-selection-item a.as-close {
201
- margin-top: -1px;
202
- }
203
- ul.as-selections li.as-original input {
204
- height: 19px;
205
- }
206
- }
207
-
208
- /* Opera Hacks */
209
- @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
210
- ul.as-list {
211
- border: 1px solid #888;
212
- }
213
- ul.as-selections li.as-selection-item a.as-close {
214
- margin-left: 4px;
215
- margin-top: 0;
216
- }
217
- }
218
-
219
- /* IE Hacks */
220
- ul.as-list {
221
- border: 1px solid #888\9;
222
- }
223
- ul.as-selections li.as-selection-item a.as-close {
224
- margin-left: 4px\9;
225
- margin-top: 0\9;
226
- }
227
-
228
- /* Firefox 3.0 Hacks */
229
- ul.as-list, x:-moz-any-link, x:default {
230
- border: 1px solid #888;
231
- }
232
- BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */
233
- border: none;
234
- }
235
-
236
- .as-results .as-message {/* display:none;*/}
237
-
238
- .previous-selection {
239
- float: left;
240
- margin-top: 10px;
241
- width: 100%;
242
- }
243
- .previous-selection .text {
244
- float: left;
245
- font-size: 13px;
246
- font-weight: bold;
247
- }
248
- .previous-selection .post {
249
- float: left;
250
- width: 100%;
251
- font-weight: bold;
252
- }
253
- .previous-selection .locality {
254
- float: left;
255
- width: 100%;
256
- font-weight: bold;
257
  }
1
+ /* AutoSuggest CSS - Version 1.2 */
2
+
3
+ ul.as-selections {
4
+ list-style-type: none;
5
+ border-top: 1px solid #888;
6
+ border-bottom: 1px solid #b6b6b6;
7
+ border-left: 1px solid #aaa;
8
+ border-right: 1px solid #aaa;
9
+ padding: 0 0 0 4px;
10
+ margin: 0;
11
+ overflow: auto;
12
+ background-color: #fff;
13
+ /*box-shadow:inset 0 1px 2px #888;
14
+ -webkit-box-shadow:inset 0 1px 2px #888;
15
+ -moz-box-shadow:inset 0 1px 2px #888;*/
16
+ }
17
+
18
+ ul.as-selections.loading {
19
+ background-color: #eee;
20
+ }
21
+
22
+ ul.as-selections li {
23
+ float: left;
24
+ margin: 0px 4px 0px 0;
25
+ /*width:90%;*/
26
+ width:91%;
27
+ }
28
+
29
+ ul.as-selections li.as-selection-item {
30
+ color: #2b3840;
31
+ font-size: 12px;
32
+ font-family: "Lucida Grande", arial, sans-serif;
33
+ text-shadow: 0 1px 1px #fff;
34
+ padding: 2px 5px 0;
35
+ /*border: 1px solid #747474;
36
+ border-top-color: #747474;
37
+ background-color: #ddeefe;
38
+ background-image: -moz-linear-gradient(top, #ddeefe, #bfe0f1);
39
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddeefe), to(#bfe0f1));
40
+ border-radius: 12px;
41
+ -webkit-border-radius: 12px;
42
+ -moz-border-radius: 12px;
43
+ box-shadow: 0 1px 1px #e4edf2;
44
+ -webkit-box-shadow: 0 1px 1px #e4edf2;
45
+ -moz-box-shadow: 0 1px 1px #e4edf2;*/
46
+ }
47
+
48
+ ul.as-selections li.as-selection-item:last-child {
49
+ margin-left: 30px;
50
+ }
51
+
52
+ ul.as-selections li.as-selection-item a.as-close {
53
+ float: right;
54
+ margin: -4px 0 -2px 7px;
55
+ padding: 0 2px;
56
+ cursor: pointer;
57
+ color: #747474;
58
+ font-family: "Helvetica", helvetica, arial, sans-serif;
59
+ font-size: 17px;
60
+ text-decoration:none;
61
+ font-weight: bold;
62
+ text-shadow: 0 1px 1px #fff;
63
+ -webkit-transition: color .1s ease-in;
64
+ }
65
+
66
+ ul.as-selections li.as-selection-item.blur {
67
+ color: #666666;
68
+ background-color: #f4f4f4;
69
+ background-image: -moz-linear-gradient(top, #f4f4f4, #d5d5d5);
70
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f4f4f4), to(#d5d5d5));
71
+ border-color: #bbb;
72
+ border-top-color: #ccc;
73
+ box-shadow: 0 1px 1px #e9e9e9;
74
+ -webkit-box-shadow: 0 1px 1px #e9e9e9;
75
+ -moz-box-shadow: 0 1px 1px #e9e9e9;
76
+ }
77
+
78
+ ul.as-selections li.as-selection-item.blur a.as-close {
79
+ color: #999;
80
+ }
81
+
82
+ ul.as-selections li:hover.as-selection-item {
83
+ /*color: #2b3840;
84
+ background-color: #bbd4f1;
85
+ background-image: -moz-linear-gradient(top, #bbd4f1, #a3c2e5);
86
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbd4f1), to(#a3c2e5));
87
+ border-color: #6da0e0;
88
+ border-top-color: #8bb7ed;*/
89
+ }
90
+
91
+ ul.as-selections li:hover.as-selection-item a.as-close {
92
+ color: #4d70b0;
93
+ }
94
+
95
+ ul.as-selections li.as-selection-item.selected {
96
+ /*border-color: #1f30e4;*/
97
+ }
98
+
99
+ ul.as-selections li.as-selection-item a:hover.as-close {
100
+ color: #1b3c65;
101
+ }
102
+
103
+ ul.as-selections li.as-selection-item a:active.as-close {
104
+ color: #4d70b0;
105
+ }
106
+
107
+ ul.as-selections li.as-original {
108
+ margin-left: 0;
109
+ }
110
+
111
+ ul.as-selections li.as-original input {
112
+ border: none;
113
+ outline: none;
114
+ font-size: 12px;
115
+ width: 120px;
116
+ height: 18px;
117
+ /*padding-top: 3px;*/
118
+ width:100%;
119
+ }
120
+ .catalog-product-view ul.as-selections li.as-original input {font-size:11px;}
121
+ ul.as-selections li.as-original input[type=text]:disabled { background: none; }
122
+
123
+ ul.as-list {
124
+ position: absolute;
125
+ list-style-type: none;
126
+ margin: 2px 0 0 0;
127
+ padding: 0;
128
+ font-size: 12px;
129
+ color: #000;
130
+ font-family: "Lucida Grande", arial, sans-serif;
131
+ background-color: #fff;
132
+ background-color: rgba(255,255,255,0.95);
133
+ z-index: 2;
134
+ box-shadow: 0 2px 12px #222;
135
+ -webkit-box-shadow: 0 2px 12px #222;
136
+ -moz-box-shadow: 0 2px 12px #222;
137
+ border-radius: 5px;
138
+ -webkit-border-radius: 5px;
139
+ -moz-border-radius: 5px;
140
+ max-height:290px;
141
+ min-height:33px;
142
+ overflow-y: auto;
143
+ }
144
+
145
+ li.as-result-item, li.as-message {
146
+ margin: 0 0 0 0;
147
+ padding: 5px 12px;
148
+ background-color: transparent;
149
+ border: 1px solid #fff;
150
+ border-bottom: 1px solid #ddd;
151
+ cursor: pointer;
152
+ border-radius: 5px;
153
+ -webkit-border-radius: 5px;
154
+ -moz-border-radius: 5px;
155
+ }
156
+
157
+ li:first-child.as-result-item {
158
+ margin: 0;
159
+ }
160
+
161
+ li.as-message {
162
+ margin: 0;
163
+ cursor: default;
164
+ }
165
+
166
+ li.as-result-item.active {
167
+ background-color: #ddeefe;
168
+ background-image: -moz-linear-gradient(top, #ddeefe, #ddeefe);
169
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 64%, from(rgb(110, 129, 245)), to(rgb(62, 82, 242)));
170
+ border-color: #ddeefe;
171
+ color: #000;
172
+ text-shadow:none;
173
+ }
174
+
175
+ li.as-result-item em {
176
+ font-style: normal;
177
+ /*background: #444;
178
+ color: #fff;*/
179
+ background: none;
180
+ color: #000;
181
+ padding: 0px;
182
+ }
183
+
184
+ li.as-result-item.active em {
185
+ /*background: #253f7a;
186
+ color: #fff;*/
187
+ background: none;
188
+ color: #000;
189
+ }
190
+
191
+ /* Webkit Hacks */
192
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
193
+ ul.as-selections {
194
+ border-top-width: 2px;
195
+ }
196
+ ul.as-selections li.as-selection-item {
197
+ padding-top: 3px;
198
+ padding-bottom: 3px;
199
+ }
200
+ ul.as-selections li.as-selection-item a.as-close {
201
+ margin-top: -1px;
202
+ }
203
+ ul.as-selections li.as-original input {
204
+ height: 19px;
205
+ }
206
+ }
207
+
208
+ /* Opera Hacks */
209
+ @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
210
+ ul.as-list {
211
+ border: 1px solid #888;
212
+ }
213
+ ul.as-selections li.as-selection-item a.as-close {
214
+ margin-left: 4px;
215
+ margin-top: 0;
216
+ }
217
+ }
218
+
219
+ /* IE Hacks */
220
+ ul.as-list {
221
+ border: 1px solid #888\9;
222
+ }
223
+ ul.as-selections li.as-selection-item a.as-close {
224
+ margin-left: 4px\9;
225
+ margin-top: 0\9;
226
+ }
227
+
228
+ /* Firefox 3.0 Hacks */
229
+ ul.as-list, x:-moz-any-link, x:default {
230
+ border: 1px solid #888;
231
+ }
232
+ BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */
233
+ border: none;
234
+ }
235
+
236
+ .as-results .as-message {/* display:none;*/}
237
+
238
+ .previous-selection {
239
+ float: left;
240
+ margin-top: 10px;
241
+ width: 100%;
242
+ }
243
+ .previous-selection .text {
244
+ float: left;
245
+ font-size: 13px;
246
+ font-weight: bold;
247
+ }
248
+ .previous-selection .post {
249
+ float: left;
250
+ width: 100%;
251
+ font-weight: bold;
252
+ }
253
+ .previous-selection .locality {
254
+ float: left;
255
+ width: 100%;
256
+ font-weight: bold;
257
  }
skin/frontend/default/default/ship/js/jquery-1.11.0.js CHANGED
@@ -1,10337 +1,10337 @@
1
- /*!
2
- * jQuery JavaScript Library v1.11.0
3
- * http://jquery.com/
4
- *
5
- * Includes Sizzle.js
6
- * http://sizzlejs.com/
7
- *
8
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9
- * Released under the MIT license
10
- * http://jquery.org/license
11
- *
12
- * Date: 2014-01-23T21:02Z
13
- */
14
-
15
- (function( global, factory ) {
16
-
17
- if ( typeof module === "object" && typeof module.exports === "object" ) {
18
- // For CommonJS and CommonJS-like environments where a proper window is present,
19
- // execute the factory and get jQuery
20
- // For environments that do not inherently posses a window with a document
21
- // (such as Node.js), expose a jQuery-making factory as module.exports
22
- // This accentuates the need for the creation of a real window
23
- // e.g. var jQuery = require("jquery")(window);
24
- // See ticket #14549 for more info
25
- module.exports = global.document ?
26
- factory( global, true ) :
27
- function( w ) {
28
- if ( !w.document ) {
29
- throw new Error( "jQuery requires a window with a document" );
30
- }
31
- return factory( w );
32
- };
33
- } else {
34
- factory( global );
35
- }
36
-
37
- // Pass this if window is not defined yet
38
- }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
-
40
- // Can't do this because several apps including ASP.NET trace
41
- // the stack via arguments.caller.callee and Firefox dies if
42
- // you try to trace through "use strict" call chains. (#13335)
43
- // Support: Firefox 18+
44
- //
45
-
46
- var deletedIds = [];
47
-
48
- var slice = deletedIds.slice;
49
-
50
- var concat = deletedIds.concat;
51
-
52
- var push = deletedIds.push;
53
-
54
- var indexOf = deletedIds.indexOf;
55
-
56
- var class2type = {};
57
-
58
- var toString = class2type.toString;
59
-
60
- var hasOwn = class2type.hasOwnProperty;
61
-
62
- var trim = "".trim;
63
-
64
- var support = {};
65
-
66
-
67
-
68
- var
69
- version = "1.11.0",
70
-
71
- // Define a local copy of jQuery
72
- jQuery = function( selector, context ) {
73
- // The jQuery object is actually just the init constructor 'enhanced'
74
- // Need init if jQuery is called (just allow error to be thrown if not included)
75
- return new jQuery.fn.init( selector, context );
76
- },
77
-
78
- // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
79
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
80
-
81
- // Matches dashed string for camelizing
82
- rmsPrefix = /^-ms-/,
83
- rdashAlpha = /-([\da-z])/gi,
84
-
85
- // Used by jQuery.camelCase as callback to replace()
86
- fcamelCase = function( all, letter ) {
87
- return letter.toUpperCase();
88
- };
89
-
90
- jQuery.fn = jQuery.prototype = {
91
- // The current version of jQuery being used
92
- jquery: version,
93
-
94
- constructor: jQuery,
95
-
96
- // Start with an empty selector
97
- selector: "",
98
-
99
- // The default length of a jQuery object is 0
100
- length: 0,
101
-
102
- toArray: function() {
103
- return slice.call( this );
104
- },
105
-
106
- // Get the Nth element in the matched element set OR
107
- // Get the whole matched element set as a clean array
108
- get: function( num ) {
109
- return num != null ?
110
-
111
- // Return a 'clean' array
112
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
113
-
114
- // Return just the object
115
- slice.call( this );
116
- },
117
-
118
- // Take an array of elements and push it onto the stack
119
- // (returning the new matched element set)
120
- pushStack: function( elems ) {
121
-
122
- // Build a new jQuery matched element set
123
- var ret = jQuery.merge( this.constructor(), elems );
124
-
125
- // Add the old object onto the stack (as a reference)
126
- ret.prevObject = this;
127
- ret.context = this.context;
128
-
129
- // Return the newly-formed element set
130
- return ret;
131
- },
132
-
133
- // Execute a callback for every element in the matched set.
134
- // (You can seed the arguments with an array of args, but this is
135
- // only used internally.)
136
- each: function( callback, args ) {
137
- return jQuery.each( this, callback, args );
138
- },
139
-
140
- map: function( callback ) {
141
- return this.pushStack( jQuery.map(this, function( elem, i ) {
142
- return callback.call( elem, i, elem );
143
- }));
144
- },
145
-
146
- slice: function() {
147
- return this.pushStack( slice.apply( this, arguments ) );
148
- },
149
-
150
- first: function() {
151
- return this.eq( 0 );
152
- },
153
-
154
- last: function() {
155
- return this.eq( -1 );
156
- },
157
-
158
- eq: function( i ) {
159
- var len = this.length,
160
- j = +i + ( i < 0 ? len : 0 );
161
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
162
- },
163
-
164
- end: function() {
165
- return this.prevObject || this.constructor(null);
166
- },
167
-
168
- // For internal use only.
169
- // Behaves like an Array's method, not like a jQuery method.
170
- push: push,
171
- sort: deletedIds.sort,
172
- splice: deletedIds.splice
173
- };
174
-
175
- jQuery.extend = jQuery.fn.extend = function() {
176
- var src, copyIsArray, copy, name, options, clone,
177
- target = arguments[0] || {},
178
- i = 1,
179
- length = arguments.length,
180
- deep = false;
181
-
182
- // Handle a deep copy situation
183
- if ( typeof target === "boolean" ) {
184
- deep = target;
185
-
186
- // skip the boolean and the target
187
- target = arguments[ i ] || {};
188
- i++;
189
- }
190
-
191
- // Handle case when target is a string or something (possible in deep copy)
192
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
193
- target = {};
194
- }
195
-
196
- // extend jQuery itself if only one argument is passed
197
- if ( i === length ) {
198
- target = this;
199
- i--;
200
- }
201
-
202
- for ( ; i < length; i++ ) {
203
- // Only deal with non-null/undefined values
204
- if ( (options = arguments[ i ]) != null ) {
205
- // Extend the base object
206
- for ( name in options ) {
207
- src = target[ name ];
208
- copy = options[ name ];
209
-
210
- // Prevent never-ending loop
211
- if ( target === copy ) {
212
- continue;
213
- }
214
-
215
- // Recurse if we're merging plain objects or arrays
216
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
217
- if ( copyIsArray ) {
218
- copyIsArray = false;
219
- clone = src && jQuery.isArray(src) ? src : [];
220
-
221
- } else {
222
- clone = src && jQuery.isPlainObject(src) ? src : {};
223
- }
224
-
225
- // Never move original objects, clone them
226
- target[ name ] = jQuery.extend( deep, clone, copy );
227
-
228
- // Don't bring in undefined values
229
- } else if ( copy !== undefined ) {
230
- target[ name ] = copy;
231
- }
232
- }
233
- }
234
- }
235
-
236
- // Return the modified object
237
- return target;
238
- };
239
-
240
- jQuery.extend({
241
- // Unique for each copy of jQuery on the page
242
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
243
-
244
- // Assume jQuery is ready without the ready module
245
- isReady: true,
246
-
247
- error: function( msg ) {
248
- throw new Error( msg );
249
- },
250
-
251
- noop: function() {},
252
-
253
- // See test/unit/core.js for details concerning isFunction.
254
- // Since version 1.3, DOM methods and functions like alert
255
- // aren't supported. They return false on IE (#2968).
256
- isFunction: function( obj ) {
257
- return jQuery.type(obj) === "function";
258
- },
259
-
260
- isArray: Array.isArray || function( obj ) {
261
- return jQuery.type(obj) === "array";
262
- },
263
-
264
- isWindow: function( obj ) {
265
- /* jshint eqeqeq: false */
266
- return obj != null && obj == obj.window;
267
- },
268
-
269
- isNumeric: function( obj ) {
270
- // parseFloat NaNs numeric-cast false positives (null|true|false|"")
271
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
272
- // subtraction forces infinities to NaN
273
- return obj - parseFloat( obj ) >= 0;
274
- },
275
-
276
- isEmptyObject: function( obj ) {
277
- var name;
278
- for ( name in obj ) {
279
- return false;
280
- }
281
- return true;
282
- },
283
-
284
- isPlainObject: function( obj ) {
285
- var key;
286
-
287
- // Must be an Object.
288
- // Because of IE, we also have to check the presence of the constructor property.
289
- // Make sure that DOM nodes and window objects don't pass through, as well
290
- if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
291
- return false;
292
- }
293
-
294
- try {
295
- // Not own constructor property must be Object
296
- if ( obj.constructor &&
297
- !hasOwn.call(obj, "constructor") &&
298
- !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
299
- return false;
300
- }
301
- } catch ( e ) {
302
- // IE8,9 Will throw exceptions on certain host objects #9897
303
- return false;
304
- }
305
-
306
- // Support: IE<9
307
- // Handle iteration over inherited properties before own properties.
308
- if ( support.ownLast ) {
309
- for ( key in obj ) {
310
- return hasOwn.call( obj, key );
311
- }
312
- }
313
-
314
- // Own properties are enumerated firstly, so to speed up,
315
- // if last one is own, then all properties are own.
316
- for ( key in obj ) {}
317
-
318
- return key === undefined || hasOwn.call( obj, key );
319
- },
320
-
321
- type: function( obj ) {
322
- if ( obj == null ) {
323
- return obj + "";
324
- }
325
- return typeof obj === "object" || typeof obj === "function" ?
326
- class2type[ toString.call(obj) ] || "object" :
327
- typeof obj;
328
- },
329
-
330
- // Evaluates a script in a global context
331
- // Workarounds based on findings by Jim Driscoll
332
- // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
333
- globalEval: function( data ) {
334
- if ( data && jQuery.trim( data ) ) {
335
- // We use execScript on Internet Explorer
336
- // We use an anonymous function so that context is window
337
- // rather than jQuery in Firefox
338
- ( window.execScript || function( data ) {
339
- window[ "eval" ].call( window, data );
340
- } )( data );
341
- }
342
- },
343
-
344
- // Convert dashed to camelCase; used by the css and data modules
345
- // Microsoft forgot to hump their vendor prefix (#9572)
346
- camelCase: function( string ) {
347
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
348
- },
349
-
350
- nodeName: function( elem, name ) {
351
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
352
- },
353
-
354
- // args is for internal usage only
355
- each: function( obj, callback, args ) {
356
- var value,
357
- i = 0,
358
- length = obj.length,
359
- isArray = isArraylike( obj );
360
-
361
- if ( args ) {
362
- if ( isArray ) {
363
- for ( ; i < length; i++ ) {
364
- value = callback.apply( obj[ i ], args );
365
-
366
- if ( value === false ) {
367
- break;
368
- }
369
- }
370
- } else {
371
- for ( i in obj ) {
372
- value = callback.apply( obj[ i ], args );
373
-
374
- if ( value === false ) {
375
- break;
376
- }
377
- }
378
- }
379
-
380
- // A special, fast, case for the most common use of each
381
- } else {
382
- if ( isArray ) {
383
- for ( ; i < length; i++ ) {
384
- value = callback.call( obj[ i ], i, obj[ i ] );
385
-
386
- if ( value === false ) {
387
- break;
388
- }
389
- }
390
- } else {
391
- for ( i in obj ) {
392
- value = callback.call( obj[ i ], i, obj[ i ] );
393
-
394
- if ( value === false ) {
395
- break;
396
- }
397
- }
398
- }
399
- }
400
-
401
- return obj;
402
- },
403
-
404
- // Use native String.trim function wherever possible
405
- trim: trim && !trim.call("\uFEFF\xA0") ?
406
- function( text ) {
407
- return text == null ?
408
- "" :
409
- trim.call( text );
410
- } :
411
-
412
- // Otherwise use our own trimming functionality
413
- function( text ) {
414
- return text == null ?
415
- "" :
416
- ( text + "" ).replace( rtrim, "" );
417
- },
418
-
419
- // results is for internal usage only
420
- makeArray: function( arr, results ) {
421
- var ret = results || [];
422
-
423
- if ( arr != null ) {
424
- if ( isArraylike( Object(arr) ) ) {
425
- jQuery.merge( ret,
426
- typeof arr === "string" ?
427
- [ arr ] : arr
428
- );
429
- } else {
430
- push.call( ret, arr );
431
- }
432
- }
433
-
434
- return ret;
435
- },
436
-
437
- inArray: function( elem, arr, i ) {
438
- var len;
439
-
440
- if ( arr ) {
441
- if ( indexOf ) {
442
- return indexOf.call( arr, elem, i );
443
- }
444
-
445
- len = arr.length;
446
- i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
447
-
448
- for ( ; i < len; i++ ) {
449
- // Skip accessing in sparse arrays
450
- if ( i in arr && arr[ i ] === elem ) {
451
- return i;
452
- }
453
- }
454
- }
455
-
456
- return -1;
457
- },
458
-
459
- merge: function( first, second ) {
460
- var len = +second.length,
461
- j = 0,
462
- i = first.length;
463
-
464
- while ( j < len ) {
465
- first[ i++ ] = second[ j++ ];
466
- }
467
-
468
- // Support: IE<9
469
- // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
470
- if ( len !== len ) {
471
- while ( second[j] !== undefined ) {
472
- first[ i++ ] = second[ j++ ];
473
- }
474
- }
475
-
476
- first.length = i;
477
-
478
- return first;
479
- },
480
-
481
- grep: function( elems, callback, invert ) {
482
- var callbackInverse,
483
- matches = [],
484
- i = 0,
485
- length = elems.length,
486
- callbackExpect = !invert;
487
-
488
- // Go through the array, only saving the items
489
- // that pass the validator function
490
- for ( ; i < length; i++ ) {
491
- callbackInverse = !callback( elems[ i ], i );
492
- if ( callbackInverse !== callbackExpect ) {
493
- matches.push( elems[ i ] );
494
- }
495
- }
496
-
497
- return matches;
498
- },
499
-
500
- // arg is for internal usage only
501
- map: function( elems, callback, arg ) {
502
- var value,
503
- i = 0,
504
- length = elems.length,
505
- isArray = isArraylike( elems ),
506
- ret = [];
507
-
508
- // Go through the array, translating each of the items to their new values
509
- if ( isArray ) {
510
- for ( ; i < length; i++ ) {
511
- value = callback( elems[ i ], i, arg );
512
-
513
- if ( value != null ) {
514
- ret.push( value );
515
- }
516
- }
517
-
518
- // Go through every key on the object,
519
- } else {
520
- for ( i in elems ) {
521
- value = callback( elems[ i ], i, arg );
522
-
523
- if ( value != null ) {
524
- ret.push( value );
525
- }
526
- }
527
- }
528
-
529
- // Flatten any nested arrays
530
- return concat.apply( [], ret );
531
- },
532
-
533
- // A global GUID counter for objects
534
- guid: 1,
535
-
536
- // Bind a function to a context, optionally partially applying any
537
- // arguments.
538
- proxy: function( fn, context ) {
539
- var args, proxy, tmp;
540
-
541
- if ( typeof context === "string" ) {
542
- tmp = fn[ context ];
543
- context = fn;
544
- fn = tmp;
545
- }
546
-
547
- // Quick check to determine if target is callable, in the spec
548
- // this throws a TypeError, but we will just return undefined.
549
- if ( !jQuery.isFunction( fn ) ) {
550
- return undefined;
551
- }
552
-
553
- // Simulated bind
554
- args = slice.call( arguments, 2 );
555
- proxy = function() {
556
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
557
- };
558
-
559
- // Set the guid of unique handler to the same of original handler, so it can be removed
560
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
561
-
562
- return proxy;
563
- },
564
-
565
- now: function() {
566
- return +( new Date() );
567
- },
568
-
569
- // jQuery.support is not used in Core but other projects attach their
570
- // properties to it so it needs to exist.
571
- support: support
572
- });
573
-
574
- // Populate the class2type map
575
- jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
576
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
577
- });
578
-
579
- function isArraylike( obj ) {
580
- var length = obj.length,
581
- type = jQuery.type( obj );
582
-
583
- if ( type === "function" || jQuery.isWindow( obj ) ) {
584
- return false;
585
- }
586
-
587
- if ( obj.nodeType === 1 && length ) {
588
- return true;
589
- }
590
-
591
- return type === "array" || length === 0 ||
592
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
593
- }
594
- var Sizzle =
595
- /*!
596
- * Sizzle CSS Selector Engine v1.10.16
597
- * http://sizzlejs.com/
598
- *
599
- * Copyright 2013 jQuery Foundation, Inc. and other contributors
600
- * Released under the MIT license
601
- * http://jquery.org/license
602
- *
603
- * Date: 2014-01-13
604
- */
605
- (function( window ) {
606
-
607
- var i,
608
- support,
609
- Expr,
610
- getText,
611
- isXML,
612
- compile,
613
- outermostContext,
614
- sortInput,
615
- hasDuplicate,
616
-
617
- // Local document vars
618
- setDocument,
619
- document,
620
- docElem,
621
- documentIsHTML,
622
- rbuggyQSA,
623
- rbuggyMatches,
624
- matches,
625
- contains,
626
-
627
- // Instance-specific data
628
- expando = "sizzle" + -(new Date()),
629
- preferredDoc = window.document,
630
- dirruns = 0,
631
- done = 0,
632
- classCache = createCache(),
633
- tokenCache = createCache(),
634
- compilerCache = createCache(),
635
- sortOrder = function( a, b ) {
636
- if ( a === b ) {
637
- hasDuplicate = true;
638
- }
639
- return 0;
640
- },
641
-
642
- // General-purpose constants
643
- strundefined = typeof undefined,
644
- MAX_NEGATIVE = 1 << 31,
645
-
646
- // Instance methods
647
- hasOwn = ({}).hasOwnProperty,
648
- arr = [],
649
- pop = arr.pop,
650
- push_native = arr.push,
651
- push = arr.push,
652
- slice = arr.slice,
653
- // Use a stripped-down indexOf if we can't use a native one
654
- indexOf = arr.indexOf || function( elem ) {
655
- var i = 0,
656
- len = this.length;
657
- for ( ; i < len; i++ ) {
658
- if ( this[i] === elem ) {
659
- return i;
660
- }
661
- }
662
- return -1;
663
- },
664
-
665
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
666
-
667
- // Regular expressions
668
-
669
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
670
- whitespace = "[\\x20\\t\\r\\n\\f]",
671
- // http://www.w3.org/TR/css3-syntax/#characters
672
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
673
-
674
- // Loosely modeled on CSS identifier characters
675
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
676
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
677
- identifier = characterEncoding.replace( "w", "w#" ),
678
-
679
- // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
680
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
681
- "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
682
-
683
- // Prefer arguments quoted,
684
- // then not containing pseudos/brackets,
685
- // then attribute selectors/non-parenthetical expressions,
686
- // then anything else
687
- // These preferences are here to reduce the number of selectors
688
- // needing tokenize in the PSEUDO preFilter
689
- pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
690
-
691
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
692
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
693
-
694
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
695
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
696
-
697
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
698
-
699
- rpseudo = new RegExp( pseudos ),
700
- ridentifier = new RegExp( "^" + identifier + "$" ),
701
-
702
- matchExpr = {
703
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
704
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
705
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
706
- "ATTR": new RegExp( "^" + attributes ),
707
- "PSEUDO": new RegExp( "^" + pseudos ),
708
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
709
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
710
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
711
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
712
- // For use in libraries implementing .is()
713
- // We use this for POS matching in `select`
714
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
715
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
716
- },
717
-
718
- rinputs = /^(?:input|select|textarea|button)$/i,
719
- rheader = /^h\d$/i,
720
-
721
- rnative = /^[^{]+\{\s*\[native \w/,
722
-
723
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
724
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
725
-
726
- rsibling = /[+~]/,
727
- rescape = /'|\\/g,
728
-
729
- // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
730
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
731
- funescape = function( _, escaped, escapedWhitespace ) {
732
- var high = "0x" + escaped - 0x10000;
733
- // NaN means non-codepoint
734
- // Support: Firefox
735
- // Workaround erroneous numeric interpretation of +"0x"
736
- return high !== high || escapedWhitespace ?
737
- escaped :
738
- high < 0 ?
739
- // BMP codepoint
740
- String.fromCharCode( high + 0x10000 ) :
741
- // Supplemental Plane codepoint (surrogate pair)
742
- String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
743
- };
744
-
745
- // Optimize for push.apply( _, NodeList )
746
- try {
747
- push.apply(
748
- (arr = slice.call( preferredDoc.childNodes )),
749
- preferredDoc.childNodes
750
- );
751
- // Support: Android<4.0
752
- // Detect silently failing push.apply
753
- arr[ preferredDoc.childNodes.length ].nodeType;
754
- } catch ( e ) {
755
- push = { apply: arr.length ?
756
-
757
- // Leverage slice if possible
758
- function( target, els ) {
759
- push_native.apply( target, slice.call(els) );
760
- } :
761
-
762
- // Support: IE<9
763
- // Otherwise append directly
764
- function( target, els ) {
765
- var j = target.length,
766
- i = 0;
767
- // Can't trust NodeList.length
768
- while ( (target[j++] = els[i++]) ) {}
769
- target.length = j - 1;
770
- }
771
- };
772
- }
773
-
774
- function Sizzle( selector, context, results, seed ) {
775
- var match, elem, m, nodeType,
776
- // QSA vars
777
- i, groups, old, nid, newContext, newSelector;
778
-
779
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
780
- setDocument( context );
781
- }
782
-
783
- context = context || document;
784
- results = results || [];
785
-
786
- if ( !selector || typeof selector !== "string" ) {
787
- return results;
788
- }
789
-
790
- if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
791
- return [];
792
- }
793
-
794
- if ( documentIsHTML && !seed ) {
795
-
796
- // Shortcuts
797
- if ( (match = rquickExpr.exec( selector )) ) {
798
- // Speed-up: Sizzle("#ID")
799
- if ( (m = match[1]) ) {
800
- if ( nodeType === 9 ) {
801
- elem = context.getElementById( m );
802
- // Check parentNode to catch when Blackberry 4.6 returns
803
- // nodes that are no longer in the document (jQuery #6963)
804
- if ( elem && elem.parentNode ) {
805
- // Handle the case where IE, Opera, and Webkit return items
806
- // by name instead of ID
807
- if ( elem.id === m ) {
808
- results.push( elem );
809
- return results;
810
- }
811
- } else {
812
- return results;
813
- }
814
- } else {
815
- // Context is not a document
816
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
817
- contains( context, elem ) && elem.id === m ) {
818
- results.push( elem );
819
- return results;
820
- }
821
- }
822
-
823
- // Speed-up: Sizzle("TAG")
824
- } else if ( match[2] ) {
825
- push.apply( results, context.getElementsByTagName( selector ) );
826
- return results;
827
-
828
- // Speed-up: Sizzle(".CLASS")
829
- } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
830
- push.apply( results, context.getElementsByClassName( m ) );
831
- return results;
832
- }
833
- }
834
-
835
- // QSA path
836
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
837
- nid = old = expando;
838
- newContext = context;
839
- newSelector = nodeType === 9 && selector;
840
-
841
- // qSA works strangely on Element-rooted queries
842
- // We can work around this by specifying an extra ID on the root
843
- // and working up from there (Thanks to Andrew Dupont for the technique)
844
- // IE 8 doesn't work on object elements
845
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
846
- groups = tokenize( selector );
847
-
848
- if ( (old = context.getAttribute("id")) ) {
849
- nid = old.replace( rescape, "\\$&" );
850
- } else {
851
- context.setAttribute( "id", nid );
852
- }
853
- nid = "[id='" + nid + "'] ";
854
-
855
- i = groups.length;
856
- while ( i-- ) {
857
- groups[i] = nid + toSelector( groups[i] );
858
- }
859
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
860
- newSelector = groups.join(",");
861
- }
862
-
863
- if ( newSelector ) {
864
- try {
865
- push.apply( results,
866
- newContext.querySelectorAll( newSelector )
867
- );
868
- return results;
869
- } catch(qsaError) {
870
- } finally {
871
- if ( !old ) {
872
- context.removeAttribute("id");
873
- }
874
- }
875
- }
876
- }
877
- }
878
-
879
- // All others
880
- return select( selector.replace( rtrim, "$1" ), context, results, seed );
881
- }
882
-
883
- /**
884
- * Create key-value caches of limited size
885
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
886
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
887
- * deleting the oldest entry
888
- */
889
- function createCache() {
890
- var keys = [];
891
-
892
- function cache( key, value ) {
893
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
894
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
895
- // Only keep the most recent entries
896
- delete cache[ keys.shift() ];
897
- }
898
- return (cache[ key + " " ] = value);
899
- }
900
- return cache;
901
- }
902
-
903
- /**
904
- * Mark a function for special use by Sizzle
905
- * @param {Function} fn The function to mark
906
- */
907
- function markFunction( fn ) {
908
- fn[ expando ] = true;
909
- return fn;
910
- }
911
-
912
- /**
913
- * Support testing using an element
914
- * @param {Function} fn Passed the created div and expects a boolean result
915
- */
916
- function assert( fn ) {
917
- var div = document.createElement("div");
918
-
919
- try {
920
- return !!fn( div );
921
- } catch (e) {
922
- return false;
923
- } finally {
924
- // Remove from its parent by default
925
- if ( div.parentNode ) {
926
- div.parentNode.removeChild( div );
927
- }
928
- // release memory in IE
929
- div = null;
930
- }
931
- }
932
-
933
- /**
934
- * Adds the same handler for all of the specified attrs
935
- * @param {String} attrs Pipe-separated list of attributes
936
- * @param {Function} handler The method that will be applied
937
- */
938
- function addHandle( attrs, handler ) {
939
- var arr = attrs.split("|"),
940
- i = attrs.length;
941
-
942
- while ( i-- ) {
943
- Expr.attrHandle[ arr[i] ] = handler;
944
- }
945
- }
946
-
947
- /**
948
- * Checks document order of two siblings
949
- * @param {Element} a
950
- * @param {Element} b
951
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
952
- */
953
- function siblingCheck( a, b ) {
954
- var cur = b && a,
955
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
956
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
957
- ( ~a.sourceIndex || MAX_NEGATIVE );
958
-
959
- // Use IE sourceIndex if available on both nodes
960
- if ( diff ) {
961
- return diff;
962
- }
963
-
964
- // Check if b follows a
965
- if ( cur ) {
966
- while ( (cur = cur.nextSibling) ) {
967
- if ( cur === b ) {
968
- return -1;
969
- }
970
- }
971
- }
972
-
973
- return a ? 1 : -1;
974
- }
975
-
976
- /**
977
- * Returns a function to use in pseudos for input types
978
- * @param {String} type
979
- */
980
- function createInputPseudo( type ) {
981
- return function( elem ) {
982
- var name = elem.nodeName.toLowerCase();
983
- return name === "input" && elem.type === type;
984
- };
985
- }
986
-
987
- /**
988
- * Returns a function to use in pseudos for buttons
989
- * @param {String} type
990
- */
991
- function createButtonPseudo( type ) {
992
- return function( elem ) {
993
- var name = elem.nodeName.toLowerCase();
994
- return (name === "input" || name === "button") && elem.type === type;
995
- };
996
- }
997
-
998
- /**
999
- * Returns a function to use in pseudos for positionals
1000
- * @param {Function} fn
1001
- */
1002
- function createPositionalPseudo( fn ) {
1003
- return markFunction(function( argument ) {
1004
- argument = +argument;
1005
- return markFunction(function( seed, matches ) {
1006
- var j,
1007
- matchIndexes = fn( [], seed.length, argument ),
1008
- i = matchIndexes.length;
1009
-
1010
- // Match elements found at the specified indexes
1011
- while ( i-- ) {
1012
- if ( seed[ (j = matchIndexes[i]) ] ) {
1013
- seed[j] = !(matches[j] = seed[j]);
1014
- }
1015
- }
1016
- });
1017
- });
1018
- }
1019
-
1020
- /**
1021
- * Checks a node for validity as a Sizzle context
1022
- * @param {Element|Object=} context
1023
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1024
- */
1025
- function testContext( context ) {
1026
- return context && typeof context.getElementsByTagName !== strundefined && context;
1027
- }
1028
-
1029
- // Expose support vars for convenience
1030
- support = Sizzle.support = {};
1031
-
1032
- /**
1033
- * Detects XML nodes
1034
- * @param {Element|Object} elem An element or a document
1035
- * @returns {Boolean} True iff elem is a non-HTML XML node
1036
- */
1037
- isXML = Sizzle.isXML = function( elem ) {
1038
- // documentElement is verified for cases where it doesn't yet exist
1039
- // (such as loading iframes in IE - #4833)
1040
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1041
- return documentElement ? documentElement.nodeName !== "HTML" : false;
1042
- };
1043
-
1044
- /**
1045
- * Sets document-related variables once based on the current document
1046
- * @param {Element|Object} [doc] An element or document object to use to set the document
1047
- * @returns {Object} Returns the current document
1048
- */
1049
- setDocument = Sizzle.setDocument = function( node ) {
1050
- var hasCompare,
1051
- doc = node ? node.ownerDocument || node : preferredDoc,
1052
- parent = doc.defaultView;
1053
-
1054
- // If no document and documentElement is available, return
1055
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1056
- return document;
1057
- }
1058
-
1059
- // Set our document
1060
- document = doc;
1061
- docElem = doc.documentElement;
1062
-
1063
- // Support tests
1064
- documentIsHTML = !isXML( doc );
1065
-
1066
- // Support: IE>8
1067
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1068
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1069
- // IE6-8 do not support the defaultView property so parent will be undefined
1070
- if ( parent && parent !== parent.top ) {
1071
- // IE11 does not have attachEvent, so all must suffer
1072
- if ( parent.addEventListener ) {
1073
- parent.addEventListener( "unload", function() {
1074
- setDocument();
1075
- }, false );
1076
- } else if ( parent.attachEvent ) {
1077
- parent.attachEvent( "onunload", function() {
1078
- setDocument();
1079
- });
1080
- }
1081
- }
1082
-
1083
- /* Attributes
1084
- ---------------------------------------------------------------------- */
1085
-
1086
- // Support: IE<8
1087
- // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1088
- support.attributes = assert(function( div ) {
1089
- div.className = "i";
1090
- return !div.getAttribute("className");
1091
- });
1092
-
1093
- /* getElement(s)By*
1094
- ---------------------------------------------------------------------- */
1095
-
1096
- // Check if getElementsByTagName("*") returns only elements
1097
- support.getElementsByTagName = assert(function( div ) {
1098
- div.appendChild( doc.createComment("") );
1099
- return !div.getElementsByTagName("*").length;
1100
- });
1101
-
1102
- // Check if getElementsByClassName can be trusted
1103
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1104
- div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1105
-
1106
- // Support: Safari<4
1107
- // Catch class over-caching
1108
- div.firstChild.className = "i";
1109
- // Support: Opera<10
1110
- // Catch gEBCN failure to find non-leading classes
1111
- return div.getElementsByClassName("i").length === 2;
1112
- });
1113
-
1114
- // Support: IE<10
1115
- // Check if getElementById returns elements by name
1116
- // The broken getElementById methods don't pick up programatically-set names,
1117
- // so use a roundabout getElementsByName test
1118
- support.getById = assert(function( div ) {
1119
- docElem.appendChild( div ).id = expando;
1120
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1121
- });
1122
-
1123
- // ID find and filter
1124
- if ( support.getById ) {
1125
- Expr.find["ID"] = function( id, context ) {
1126
- if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1127
- var m = context.getElementById( id );
1128
- // Check parentNode to catch when Blackberry 4.6 returns
1129
- // nodes that are no longer in the document #6963
1130
- return m && m.parentNode ? [m] : [];
1131
- }
1132
- };
1133
- Expr.filter["ID"] = function( id ) {
1134
- var attrId = id.replace( runescape, funescape );
1135
- return function( elem ) {
1136
- return elem.getAttribute("id") === attrId;
1137
- };
1138
- };
1139
- } else {
1140
- // Support: IE6/7
1141
- // getElementById is not reliable as a find shortcut
1142
- delete Expr.find["ID"];
1143
-
1144
- Expr.filter["ID"] = function( id ) {
1145
- var attrId = id.replace( runescape, funescape );
1146
- return function( elem ) {
1147
- var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1148
- return node && node.value === attrId;
1149
- };
1150
- };
1151
- }
1152
-
1153
- // Tag
1154
- Expr.find["TAG"] = support.getElementsByTagName ?
1155
- function( tag, context ) {
1156
- if ( typeof context.getElementsByTagName !== strundefined ) {
1157
- return context.getElementsByTagName( tag );
1158
- }
1159
- } :
1160
- function( tag, context ) {
1161
- var elem,
1162
- tmp = [],
1163
- i = 0,
1164
- results = context.getElementsByTagName( tag );
1165
-
1166
- // Filter out possible comments
1167
- if ( tag === "*" ) {
1168
- while ( (elem = results[i++]) ) {
1169
- if ( elem.nodeType === 1 ) {
1170
- tmp.push( elem );
1171
- }
1172
- }
1173
-
1174
- return tmp;
1175
- }
1176
- return results;
1177
- };
1178
-
1179
- // Class
1180
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1181
- if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1182
- return context.getElementsByClassName( className );
1183
- }
1184
- };
1185
-
1186
- /* QSA/matchesSelector
1187
- ---------------------------------------------------------------------- */
1188
-
1189
- // QSA and matchesSelector support
1190
-
1191
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1192
- rbuggyMatches = [];
1193
-
1194
- // qSa(:focus) reports false when true (Chrome 21)
1195
- // We allow this because of a bug in IE8/9 that throws an error
1196
- // whenever `document.activeElement` is accessed on an iframe
1197
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
1198
- // See http://bugs.jquery.com/ticket/13378
1199
- rbuggyQSA = [];
1200
-
1201
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1202
- // Build QSA regex
1203
- // Regex strategy adopted from Diego Perini
1204
- assert(function( div ) {
1205
- // Select is set to empty string on purpose
1206
- // This is to test IE's treatment of not explicitly
1207
- // setting a boolean content attribute,
1208
- // since its presence should be enough
1209
- // http://bugs.jquery.com/ticket/12359
1210
- div.innerHTML = "<select t=''><option selected=''></option></select>";
1211
-
1212
- // Support: IE8, Opera 10-12
1213
- // Nothing should be selected when empty strings follow ^= or $= or *=
1214
- if ( div.querySelectorAll("[t^='']").length ) {
1215
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1216
- }
1217
-
1218
- // Support: IE8
1219
- // Boolean attributes and "value" are not treated correctly
1220
- if ( !div.querySelectorAll("[selected]").length ) {
1221
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1222
- }
1223
-
1224
- // Webkit/Opera - :checked should return selected option elements
1225
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1226
- // IE8 throws error here and will not see later tests
1227
- if ( !div.querySelectorAll(":checked").length ) {
1228
- rbuggyQSA.push(":checked");
1229
- }
1230
- });
1231
-
1232
- assert(function( div ) {
1233
- // Support: Windows 8 Native Apps
1234
- // The type and name attributes are restricted during .innerHTML assignment
1235
- var input = doc.createElement("input");
1236
- input.setAttribute( "type", "hidden" );
1237
- div.appendChild( input ).setAttribute( "name", "D" );
1238
-
1239
- // Support: IE8
1240
- // Enforce case-sensitivity of name attribute
1241
- if ( div.querySelectorAll("[name=d]").length ) {
1242
- rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1243
- }
1244
-
1245
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1246
- // IE8 throws error here and will not see later tests
1247
- if ( !div.querySelectorAll(":enabled").length ) {
1248
- rbuggyQSA.push( ":enabled", ":disabled" );
1249
- }
1250
-
1251
- // Opera 10-11 does not throw on post-comma invalid pseudos
1252
- div.querySelectorAll("*,:x");
1253
- rbuggyQSA.push(",.*:");
1254
- });
1255
- }
1256
-
1257
- if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1258
- docElem.mozMatchesSelector ||
1259
- docElem.oMatchesSelector ||
1260
- docElem.msMatchesSelector) )) ) {
1261
-
1262
- assert(function( div ) {
1263
- // Check to see if it's possible to do matchesSelector
1264
- // on a disconnected node (IE 9)
1265
- support.disconnectedMatch = matches.call( div, "div" );
1266
-
1267
- // This should fail with an exception
1268
- // Gecko does not error, returns false instead
1269
- matches.call( div, "[s!='']:x" );
1270
- rbuggyMatches.push( "!=", pseudos );
1271
- });
1272
- }
1273
-
1274
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1275
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1276
-
1277
- /* Contains
1278
- ---------------------------------------------------------------------- */
1279
- hasCompare = rnative.test( docElem.compareDocumentPosition );
1280
-
1281
- // Element contains another
1282
- // Purposefully does not implement inclusive descendent
1283
- // As in, an element does not contain itself
1284
- contains = hasCompare || rnative.test( docElem.contains ) ?
1285
- function( a, b ) {
1286
- var adown = a.nodeType === 9 ? a.documentElement : a,
1287
- bup = b && b.parentNode;
1288
- return a === bup || !!( bup && bup.nodeType === 1 && (
1289
- adown.contains ?
1290
- adown.contains( bup ) :
1291
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1292
- ));
1293
- } :
1294
- function( a, b ) {
1295
- if ( b ) {
1296
- while ( (b = b.parentNode) ) {
1297
- if ( b === a ) {
1298
- return true;
1299
- }
1300
- }
1301
- }
1302
- return false;
1303
- };
1304
-
1305
- /* Sorting
1306
- ---------------------------------------------------------------------- */
1307
-
1308
- // Document order sorting
1309
- sortOrder = hasCompare ?
1310
- function( a, b ) {
1311
-
1312
- // Flag for duplicate removal
1313
- if ( a === b ) {
1314
- hasDuplicate = true;
1315
- return 0;
1316
- }
1317
-
1318
- // Sort on method existence if only one input has compareDocumentPosition
1319
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1320
- if ( compare ) {
1321
- return compare;
1322
- }
1323
-
1324
- // Calculate position if both inputs belong to the same document
1325
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1326
- a.compareDocumentPosition( b ) :
1327
-
1328
- // Otherwise we know they are disconnected
1329
- 1;
1330
-
1331
- // Disconnected nodes
1332
- if ( compare & 1 ||
1333
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1334
-
1335
- // Choose the first element that is related to our preferred document
1336
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1337
- return -1;
1338
- }
1339
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1340
- return 1;
1341
- }
1342
-
1343
- // Maintain original order
1344
- return sortInput ?
1345
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1346
- 0;
1347
- }
1348
-
1349
- return compare & 4 ? -1 : 1;
1350
- } :
1351
- function( a, b ) {
1352
- // Exit early if the nodes are identical
1353
- if ( a === b ) {
1354
- hasDuplicate = true;
1355
- return 0;
1356
- }
1357
-
1358
- var cur,
1359
- i = 0,
1360
- aup = a.parentNode,
1361
- bup = b.parentNode,
1362
- ap = [ a ],
1363
- bp = [ b ];
1364
-
1365
- // Parentless nodes are either documents or disconnected
1366
- if ( !aup || !bup ) {
1367
- return a === doc ? -1 :
1368
- b === doc ? 1 :
1369
- aup ? -1 :
1370
- bup ? 1 :
1371
- sortInput ?
1372
- ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1373
- 0;
1374
-
1375
- // If the nodes are siblings, we can do a quick check
1376
- } else if ( aup === bup ) {
1377
- return siblingCheck( a, b );
1378
- }
1379
-
1380
- // Otherwise we need full lists of their ancestors for comparison
1381
- cur = a;
1382
- while ( (cur = cur.parentNode) ) {
1383
- ap.unshift( cur );
1384
- }
1385
- cur = b;
1386
- while ( (cur = cur.parentNode) ) {
1387
- bp.unshift( cur );
1388
- }
1389
-
1390
- // Walk down the tree looking for a discrepancy
1391
- while ( ap[i] === bp[i] ) {
1392
- i++;
1393
- }
1394
-
1395
- return i ?
1396
- // Do a sibling check if the nodes have a common ancestor
1397
- siblingCheck( ap[i], bp[i] ) :
1398
-
1399
- // Otherwise nodes in our document sort first
1400
- ap[i] === preferredDoc ? -1 :
1401
- bp[i] === preferredDoc ? 1 :
1402
- 0;
1403
- };
1404
-
1405
- return doc;
1406
- };
1407
-
1408
- Sizzle.matches = function( expr, elements ) {
1409
- return Sizzle( expr, null, null, elements );
1410
- };
1411
-
1412
- Sizzle.matchesSelector = function( elem, expr ) {
1413
- // Set document vars if needed
1414
- if ( ( elem.ownerDocument || elem ) !== document ) {
1415
- setDocument( elem );
1416
- }
1417
-
1418
- // Make sure that attribute selectors are quoted
1419
- expr = expr.replace( rattributeQuotes, "='$1']" );
1420
-
1421
- if ( support.matchesSelector && documentIsHTML &&
1422
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1423
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1424
-
1425
- try {
1426
- var ret = matches.call( elem, expr );
1427
-
1428
- // IE 9's matchesSelector returns false on disconnected nodes
1429
- if ( ret || support.disconnectedMatch ||
1430
- // As well, disconnected nodes are said to be in a document
1431
- // fragment in IE 9
1432
- elem.document && elem.document.nodeType !== 11 ) {
1433
- return ret;
1434
- }
1435
- } catch(e) {}
1436
- }
1437
-
1438
- return Sizzle( expr, document, null, [elem] ).length > 0;
1439
- };
1440
-
1441
- Sizzle.contains = function( context, elem ) {
1442
- // Set document vars if needed
1443
- if ( ( context.ownerDocument || context ) !== document ) {
1444
- setDocument( context );
1445
- }
1446
- return contains( context, elem );
1447
- };
1448
-
1449
- Sizzle.attr = function( elem, name ) {
1450
- // Set document vars if needed
1451
- if ( ( elem.ownerDocument || elem ) !== document ) {
1452
- setDocument( elem );
1453
- }
1454
-
1455
- var fn = Expr.attrHandle[ name.toLowerCase() ],
1456
- // Don't get fooled by Object.prototype properties (jQuery #13807)
1457
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1458
- fn( elem, name, !documentIsHTML ) :
1459
- undefined;
1460
-
1461
- return val !== undefined ?
1462
- val :
1463
- support.attributes || !documentIsHTML ?
1464
- elem.getAttribute( name ) :
1465
- (val = elem.getAttributeNode(name)) && val.specified ?
1466
- val.value :
1467
- null;
1468
- };
1469
-
1470
- Sizzle.error = function( msg ) {
1471
- throw new Error( "Syntax error, unrecognized expression: " + msg );
1472
- };
1473
-
1474
- /**
1475
- * Document sorting and removing duplicates
1476
- * @param {ArrayLike} results
1477
- */
1478
- Sizzle.uniqueSort = function( results ) {
1479
- var elem,
1480
- duplicates = [],
1481
- j = 0,
1482
- i = 0;
1483
-
1484
- // Unless we *know* we can detect duplicates, assume their presence
1485
- hasDuplicate = !support.detectDuplicates;
1486
- sortInput = !support.sortStable && results.slice( 0 );
1487
- results.sort( sortOrder );
1488
-
1489
- if ( hasDuplicate ) {
1490
- while ( (elem = results[i++]) ) {
1491
- if ( elem === results[ i ] ) {
1492
- j = duplicates.push( i );
1493
- }
1494
- }
1495
- while ( j-- ) {
1496
- results.splice( duplicates[ j ], 1 );
1497
- }
1498
- }
1499
-
1500
- // Clear input after sorting to release objects
1501
- // See https://github.com/jquery/sizzle/pull/225
1502
- sortInput = null;
1503
-
1504
- return results;
1505
- };
1506
-
1507
- /**
1508
- * Utility function for retrieving the text value of an array of DOM nodes
1509
- * @param {Array|Element} elem
1510
- */
1511
- getText = Sizzle.getText = function( elem ) {
1512
- var node,
1513
- ret = "",
1514
- i = 0,
1515
- nodeType = elem.nodeType;
1516
-
1517
- if ( !nodeType ) {
1518
- // If no nodeType, this is expected to be an array
1519
- while ( (node = elem[i++]) ) {
1520
- // Do not traverse comment nodes
1521
- ret += getText( node );
1522
- }
1523
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1524
- // Use textContent for elements
1525
- // innerText usage removed for consistency of new lines (jQuery #11153)
1526
- if ( typeof elem.textContent === "string" ) {
1527
- return elem.textContent;
1528
- } else {
1529
- // Traverse its children
1530
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1531
- ret += getText( elem );
1532
- }
1533
- }
1534
- } else if ( nodeType === 3 || nodeType === 4 ) {
1535
- return elem.nodeValue;
1536
- }
1537
- // Do not include comment or processing instruction nodes
1538
-
1539
- return ret;
1540
- };
1541
-
1542
- Expr = Sizzle.selectors = {
1543
-
1544
- // Can be adjusted by the user
1545
- cacheLength: 50,
1546
-
1547
- createPseudo: markFunction,
1548
-
1549
- match: matchExpr,
1550
-
1551
- attrHandle: {},
1552
-
1553
- find: {},
1554
-
1555
- relative: {
1556
- ">": { dir: "parentNode", first: true },
1557
- " ": { dir: "parentNode" },
1558
- "+": { dir: "previousSibling", first: true },
1559
- "~": { dir: "previousSibling" }
1560
- },
1561
-
1562
- preFilter: {
1563
- "ATTR": function( match ) {
1564
- match[1] = match[1].replace( runescape, funescape );
1565
-
1566
- // Move the given value to match[3] whether quoted or unquoted
1567
- match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1568
-
1569
- if ( match[2] === "~=" ) {
1570
- match[3] = " " + match[3] + " ";
1571
- }
1572
-
1573
- return match.slice( 0, 4 );
1574
- },
1575
-
1576
- "CHILD": function( match ) {
1577
- /* matches from matchExpr["CHILD"]
1578
- 1 type (only|nth|...)
1579
- 2 what (child|of-type)
1580
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1581
- 4 xn-component of xn+y argument ([+-]?\d*n|)
1582
- 5 sign of xn-component
1583
- 6 x of xn-component
1584
- 7 sign of y-component
1585
- 8 y of y-component
1586
- */
1587
- match[1] = match[1].toLowerCase();
1588
-
1589
- if ( match[1].slice( 0, 3 ) === "nth" ) {
1590
- // nth-* requires argument
1591
- if ( !match[3] ) {
1592
- Sizzle.error( match[0] );
1593
- }
1594
-
1595
- // numeric x and y parameters for Expr.filter.CHILD
1596
- // remember that false/true cast respectively to 0/1
1597
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1598
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1599
-
1600
- // other types prohibit arguments
1601
- } else if ( match[3] ) {
1602
- Sizzle.error( match[0] );
1603
- }
1604
-
1605
- return match;
1606
- },
1607
-
1608
- "PSEUDO": function( match ) {
1609
- var excess,
1610
- unquoted = !match[5] && match[2];
1611
-
1612
- if ( matchExpr["CHILD"].test( match[0] ) ) {
1613
- return null;
1614
- }
1615
-
1616
- // Accept quoted arguments as-is
1617
- if ( match[3] && match[4] !== undefined ) {
1618
- match[2] = match[4];
1619
-
1620
- // Strip excess characters from unquoted arguments
1621
- } else if ( unquoted && rpseudo.test( unquoted ) &&
1622
- // Get excess from tokenize (recursively)
1623
- (excess = tokenize( unquoted, true )) &&
1624
- // advance to the next closing parenthesis
1625
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1626
-
1627
- // excess is a negative index
1628
- match[0] = match[0].slice( 0, excess );
1629
- match[2] = unquoted.slice( 0, excess );
1630
- }
1631
-
1632
- // Return only captures needed by the pseudo filter method (type and argument)
1633
- return match.slice( 0, 3 );
1634
- }
1635
- },
1636
-
1637
- filter: {
1638
-
1639
- "TAG": function( nodeNameSelector ) {
1640
- var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1641
- return nodeNameSelector === "*" ?
1642
- function() { return true; } :
1643
- function( elem ) {
1644
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1645
- };
1646
- },
1647
-
1648
- "CLASS": function( className ) {
1649
- var pattern = classCache[ className + " " ];
1650
-
1651
- return pattern ||
1652
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1653
- classCache( className, function( elem ) {
1654
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1655
- });
1656
- },
1657
-
1658
- "ATTR": function( name, operator, check ) {
1659
- return function( elem ) {
1660
- var result = Sizzle.attr( elem, name );
1661
-
1662
- if ( result == null ) {
1663
- return operator === "!=";
1664
- }
1665
- if ( !operator ) {
1666
- return true;
1667
- }
1668
-
1669
- result += "";
1670
-
1671
- return operator === "=" ? result === check :
1672
- operator === "!=" ? result !== check :
1673
- operator === "^=" ? check && result.indexOf( check ) === 0 :
1674
- operator === "*=" ? check && result.indexOf( check ) > -1 :
1675
- operator === "$=" ? check && result.slice( -check.length ) === check :
1676
- operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1677
- operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1678
- false;
1679
- };
1680
- },
1681
-
1682
- "CHILD": function( type, what, argument, first, last ) {
1683
- var simple = type.slice( 0, 3 ) !== "nth",
1684
- forward = type.slice( -4 ) !== "last",
1685
- ofType = what === "of-type";
1686
-
1687
- return first === 1 && last === 0 ?
1688
-
1689
- // Shortcut for :nth-*(n)
1690
- function( elem ) {
1691
- return !!elem.parentNode;
1692
- } :
1693
-
1694
- function( elem, context, xml ) {
1695
- var cache, outerCache, node, diff, nodeIndex, start,
1696
- dir = simple !== forward ? "nextSibling" : "previousSibling",
1697
- parent = elem.parentNode,
1698
- name = ofType && elem.nodeName.toLowerCase(),
1699
- useCache = !xml && !ofType;
1700
-
1701
- if ( parent ) {
1702
-
1703
- // :(first|last|only)-(child|of-type)
1704
- if ( simple ) {
1705
- while ( dir ) {
1706
- node = elem;
1707
- while ( (node = node[ dir ]) ) {
1708
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1709
- return false;
1710
- }
1711
- }
1712
- // Reverse direction for :only-* (if we haven't yet done so)
1713
- start = dir = type === "only" && !start && "nextSibling";
1714
- }
1715
- return true;
1716
- }
1717
-
1718
- start = [ forward ? parent.firstChild : parent.lastChild ];
1719
-
1720
- // non-xml :nth-child(...) stores cache data on `parent`
1721
- if ( forward && useCache ) {
1722
- // Seek `elem` from a previously-cached index
1723
- outerCache = parent[ expando ] || (parent[ expando ] = {});
1724
- cache = outerCache[ type ] || [];
1725
- nodeIndex = cache[0] === dirruns && cache[1];
1726
- diff = cache[0] === dirruns && cache[2];
1727
- node = nodeIndex && parent.childNodes[ nodeIndex ];
1728
-
1729
- while ( (node = ++nodeIndex && node && node[ dir ] ||
1730
-
1731
- // Fallback to seeking `elem` from the start
1732
- (diff = nodeIndex = 0) || start.pop()) ) {
1733
-
1734
- // When found, cache indexes on `parent` and break
1735
- if ( node.nodeType === 1 && ++diff && node === elem ) {
1736
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1737
- break;
1738
- }
1739
- }
1740
-
1741
- // Use previously-cached element index if available
1742
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1743
- diff = cache[1];
1744
-
1745
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1746
- } else {
1747
- // Use the same loop as above to seek `elem` from the start
1748
- while ( (node = ++nodeIndex && node && node[ dir ] ||
1749
- (diff = nodeIndex = 0) || start.pop()) ) {
1750
-
1751
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1752
- // Cache the index of each encountered element
1753
- if ( useCache ) {
1754
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1755
- }
1756
-
1757
- if ( node === elem ) {
1758
- break;
1759
- }
1760
- }
1761
- }
1762
- }
1763
-
1764
- // Incorporate the offset, then check against cycle size
1765
- diff -= last;
1766
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
1767
- }
1768
- };
1769
- },
1770
-
1771
- "PSEUDO": function( pseudo, argument ) {
1772
- // pseudo-class names are case-insensitive
1773
- // http://www.w3.org/TR/selectors/#pseudo-classes
1774
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1775
- // Remember that setFilters inherits from pseudos
1776
- var args,
1777
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1778
- Sizzle.error( "unsupported pseudo: " + pseudo );
1779
-
1780
- // The user may use createPseudo to indicate that
1781
- // arguments are needed to create the filter function
1782
- // just as Sizzle does
1783
- if ( fn[ expando ] ) {
1784
- return fn( argument );
1785
- }
1786
-
1787
- // But maintain support for old signatures
1788
- if ( fn.length > 1 ) {
1789
- args = [ pseudo, pseudo, "", argument ];
1790
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1791
- markFunction(function( seed, matches ) {
1792
- var idx,
1793
- matched = fn( seed, argument ),
1794
- i = matched.length;
1795
- while ( i-- ) {
1796
- idx = indexOf.call( seed, matched[i] );
1797
- seed[ idx ] = !( matches[ idx ] = matched[i] );
1798
- }
1799
- }) :
1800
- function( elem ) {
1801
- return fn( elem, 0, args );
1802
- };
1803
- }
1804
-
1805
- return fn;
1806
- }
1807
- },
1808
-
1809
- pseudos: {
1810
- // Potentially complex pseudos
1811
- "not": markFunction(function( selector ) {
1812
- // Trim the selector passed to compile
1813
- // to avoid treating leading and trailing
1814
- // spaces as combinators
1815
- var input = [],
1816
- results = [],
1817
- matcher = compile( selector.replace( rtrim, "$1" ) );
1818
-
1819
- return matcher[ expando ] ?
1820
- markFunction(function( seed, matches, context, xml ) {
1821
- var elem,
1822
- unmatched = matcher( seed, null, xml, [] ),
1823
- i = seed.length;
1824
-
1825
- // Match elements unmatched by `matcher`
1826
- while ( i-- ) {
1827
- if ( (elem = unmatched[i]) ) {
1828
- seed[i] = !(matches[i] = elem);
1829
- }
1830
- }
1831
- }) :
1832
- function( elem, context, xml ) {
1833
- input[0] = elem;
1834
- matcher( input, null, xml, results );
1835
- return !results.pop();
1836
- };
1837
- }),
1838
-
1839
- "has": markFunction(function( selector ) {
1840
- return function( elem ) {
1841
- return Sizzle( selector, elem ).length > 0;
1842
- };
1843
- }),
1844
-
1845
- "contains": markFunction(function( text ) {
1846
- return function( elem ) {
1847
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1848
- };
1849
- }),
1850
-
1851
- // "Whether an element is represented by a :lang() selector
1852
- // is based solely on the element's language value
1853
- // being equal to the identifier C,
1854
- // or beginning with the identifier C immediately followed by "-".
1855
- // The matching of C against the element's language value is performed case-insensitively.
1856
- // The identifier C does not have to be a valid language name."
1857
- // http://www.w3.org/TR/selectors/#lang-pseudo
1858
- "lang": markFunction( function( lang ) {
1859
- // lang value must be a valid identifier
1860
- if ( !ridentifier.test(lang || "") ) {
1861
- Sizzle.error( "unsupported lang: " + lang );
1862
- }
1863
- lang = lang.replace( runescape, funescape ).toLowerCase();
1864
- return function( elem ) {
1865
- var elemLang;
1866
- do {
1867
- if ( (elemLang = documentIsHTML ?
1868
- elem.lang :
1869
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1870
-
1871
- elemLang = elemLang.toLowerCase();
1872
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1873
- }
1874
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1875
- return false;
1876
- };
1877
- }),
1878
-
1879
- // Miscellaneous
1880
- "target": function( elem ) {
1881
- var hash = window.location && window.location.hash;
1882
- return hash && hash.slice( 1 ) === elem.id;
1883
- },
1884
-
1885
- "root": function( elem ) {
1886
- return elem === docElem;
1887
- },
1888
-
1889
- "focus": function( elem ) {
1890
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1891
- },
1892
-
1893
- // Boolean properties
1894
- "enabled": function( elem ) {
1895
- return elem.disabled === false;
1896
- },
1897
-
1898
- "disabled": function( elem ) {
1899
- return elem.disabled === true;
1900
- },
1901
-
1902
- "checked": function( elem ) {
1903
- // In CSS3, :checked should return both checked and selected elements
1904
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1905
- var nodeName = elem.nodeName.toLowerCase();
1906
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1907
- },
1908
-
1909
- "selected": function( elem ) {
1910
- // Accessing this property makes selected-by-default
1911
- // options in Safari work properly
1912
- if ( elem.parentNode ) {
1913
- elem.parentNode.selectedIndex;
1914
- }
1915
-
1916
- return elem.selected === true;
1917
- },
1918
-
1919
- // Contents
1920
- "empty": function( elem ) {
1921
- // http://www.w3.org/TR/selectors/#empty-pseudo
1922
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1923
- // but not by others (comment: 8; processing instruction: 7; etc.)
1924
- // nodeType < 6 works because attributes (2) do not appear as children
1925
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1926
- if ( elem.nodeType < 6 ) {
1927
- return false;
1928
- }
1929
- }
1930
- return true;
1931
- },
1932
-
1933
- "parent": function( elem ) {
1934
- return !Expr.pseudos["empty"]( elem );
1935
- },
1936
-
1937
- // Element/input types
1938
- "header": function( elem ) {
1939
- return rheader.test( elem.nodeName );
1940
- },
1941
-
1942
- "input": function( elem ) {
1943
- return rinputs.test( elem.nodeName );
1944
- },
1945
-
1946
- "button": function( elem ) {
1947
- var name = elem.nodeName.toLowerCase();
1948
- return name === "input" && elem.type === "button" || name === "button";
1949
- },
1950
-
1951
- "text": function( elem ) {
1952
- var attr;
1953
- return elem.nodeName.toLowerCase() === "input" &&
1954
- elem.type === "text" &&
1955
-
1956
- // Support: IE<8
1957
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1958
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1959
- },
1960
-
1961
- // Position-in-collection
1962
- "first": createPositionalPseudo(function() {
1963
- return [ 0 ];
1964
- }),
1965
-
1966
- "last": createPositionalPseudo(function( matchIndexes, length ) {
1967
- return [ length - 1 ];
1968
- }),
1969
-
1970
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1971
- return [ argument < 0 ? argument + length : argument ];
1972
- }),
1973
-
1974
- "even": createPositionalPseudo(function( matchIndexes, length ) {
1975
- var i = 0;
1976
- for ( ; i < length; i += 2 ) {
1977
- matchIndexes.push( i );
1978
- }
1979
- return matchIndexes;
1980
- }),
1981
-
1982
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
1983
- var i = 1;
1984
- for ( ; i < length; i += 2 ) {
1985
- matchIndexes.push( i );
1986
- }
1987
- return matchIndexes;
1988
- }),
1989
-
1990
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1991
- var i = argument < 0 ? argument + length : argument;
1992
- for ( ; --i >= 0; ) {
1993
- matchIndexes.push( i );
1994
- }
1995
- return matchIndexes;
1996
- }),
1997
-
1998
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1999
- var i = argument < 0 ? argument + length : argument;
2000
- for ( ; ++i < length; ) {
2001
- matchIndexes.push( i );
2002
- }
2003
- return matchIndexes;
2004
- })
2005
- }
2006
- };
2007
-
2008
- Expr.pseudos["nth"] = Expr.pseudos["eq"];
2009
-
2010
- // Add button/input type pseudos
2011
- for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2012
- Expr.pseudos[ i ] = createInputPseudo( i );
2013
- }
2014
- for ( i in { submit: true, reset: true } ) {
2015
- Expr.pseudos[ i ] = createButtonPseudo( i );
2016
- }
2017
-
2018
- // Easy API for creating new setFilters
2019
- function setFilters() {}
2020
- setFilters.prototype = Expr.filters = Expr.pseudos;
2021
- Expr.setFilters = new setFilters();
2022
-
2023
- function tokenize( selector, parseOnly ) {
2024
- var matched, match, tokens, type,
2025
- soFar, groups, preFilters,
2026
- cached = tokenCache[ selector + " " ];
2027
-
2028
- if ( cached ) {
2029
- return parseOnly ? 0 : cached.slice( 0 );
2030
- }
2031
-
2032
- soFar = selector;
2033
- groups = [];
2034
- preFilters = Expr.preFilter;
2035
-
2036
- while ( soFar ) {
2037
-
2038
- // Comma and first run
2039
- if ( !matched || (match = rcomma.exec( soFar )) ) {
2040
- if ( match ) {
2041
- // Don't consume trailing commas as valid
2042
- soFar = soFar.slice( match[0].length ) || soFar;
2043
- }
2044
- groups.push( (tokens = []) );
2045
- }
2046
-
2047
- matched = false;
2048
-
2049
- // Combinators
2050
- if ( (match = rcombinators.exec( soFar )) ) {
2051
- matched = match.shift();
2052
- tokens.push({
2053
- value: matched,
2054
- // Cast descendant combinators to space
2055
- type: match[0].replace( rtrim, " " )
2056
- });
2057
- soFar = soFar.slice( matched.length );
2058
- }
2059
-
2060
- // Filters
2061
- for ( type in Expr.filter ) {
2062
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2063
- (match = preFilters[ type ]( match ))) ) {
2064
- matched = match.shift();
2065
- tokens.push({
2066
- value: matched,
2067
- type: type,
2068
- matches: match
2069
- });
2070
- soFar = soFar.slice( matched.length );
2071
- }
2072
- }
2073
-
2074
- if ( !matched ) {
2075
- break;
2076
- }
2077
- }
2078
-
2079
- // Return the length of the invalid excess
2080
- // if we're just parsing
2081
- // Otherwise, throw an error or return tokens
2082
- return parseOnly ?
2083
- soFar.length :
2084
- soFar ?
2085
- Sizzle.error( selector ) :
2086
- // Cache the tokens
2087
- tokenCache( selector, groups ).slice( 0 );
2088
- }
2089
-
2090
- function toSelector( tokens ) {
2091
- var i = 0,
2092
- len = tokens.length,
2093
- selector = "";
2094
- for ( ; i < len; i++ ) {
2095
- selector += tokens[i].value;
2096
- }
2097
- return selector;
2098
- }
2099
-
2100
- function addCombinator( matcher, combinator, base ) {
2101
- var dir = combinator.dir,
2102
- checkNonElements = base && dir === "parentNode",
2103
- doneName = done++;
2104
-
2105
- return combinator.first ?
2106
- // Check against closest ancestor/preceding element
2107
- function( elem, context, xml ) {
2108
- while ( (elem = elem[ dir ]) ) {
2109
- if ( elem.nodeType === 1 || checkNonElements ) {
2110
- return matcher( elem, context, xml );
2111
- }
2112
- }
2113
- } :
2114
-
2115
- // Check against all ancestor/preceding elements
2116
- function( elem, context, xml ) {
2117
- var oldCache, outerCache,
2118
- newCache = [ dirruns, doneName ];
2119
-
2120
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2121
- if ( xml ) {
2122
- while ( (elem = elem[ dir ]) ) {
2123
- if ( elem.nodeType === 1 || checkNonElements ) {
2124
- if ( matcher( elem, context, xml ) ) {
2125
- return true;
2126
- }
2127
- }
2128
- }
2129
- } else {
2130
- while ( (elem = elem[ dir ]) ) {
2131
- if ( elem.nodeType === 1 || checkNonElements ) {
2132
- outerCache = elem[ expando ] || (elem[ expando ] = {});
2133
- if ( (oldCache = outerCache[ dir ]) &&
2134
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2135
-
2136
- // Assign to newCache so results back-propagate to previous elements
2137
- return (newCache[ 2 ] = oldCache[ 2 ]);
2138
- } else {
2139
- // Reuse newcache so results back-propagate to previous elements
2140
- outerCache[ dir ] = newCache;
2141
-
2142
- // A match means we're done; a fail means we have to keep checking
2143
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2144
- return true;
2145
- }
2146
- }
2147
- }
2148
- }
2149
- }
2150
- };
2151
- }
2152
-
2153
- function elementMatcher( matchers ) {
2154
- return matchers.length > 1 ?
2155
- function( elem, context, xml ) {
2156
- var i = matchers.length;
2157
- while ( i-- ) {
2158
- if ( !matchers[i]( elem, context, xml ) ) {
2159
- return false;
2160
- }
2161
- }
2162
- return true;
2163
- } :
2164
- matchers[0];
2165
- }
2166
-
2167
- function condense( unmatched, map, filter, context, xml ) {
2168
- var elem,
2169
- newUnmatched = [],
2170
- i = 0,
2171
- len = unmatched.length,
2172
- mapped = map != null;
2173
-
2174
- for ( ; i < len; i++ ) {
2175
- if ( (elem = unmatched[i]) ) {
2176
- if ( !filter || filter( elem, context, xml ) ) {
2177
- newUnmatched.push( elem );
2178
- if ( mapped ) {
2179
- map.push( i );
2180
- }
2181
- }
2182
- }
2183
- }
2184
-
2185
- return newUnmatched;
2186
- }
2187
-
2188
- function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2189
- if ( postFilter && !postFilter[ expando ] ) {
2190
- postFilter = setMatcher( postFilter );
2191
- }
2192
- if ( postFinder && !postFinder[ expando ] ) {
2193
- postFinder = setMatcher( postFinder, postSelector );
2194
- }
2195
- return markFunction(function( seed, results, context, xml ) {
2196
- var temp, i, elem,
2197
- preMap = [],
2198
- postMap = [],
2199
- preexisting = results.length,
2200
-
2201
- // Get initial elements from seed or context
2202
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2203
-
2204
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
2205
- matcherIn = preFilter && ( seed || !selector ) ?
2206
- condense( elems, preMap, preFilter, context, xml ) :
2207
- elems,
2208
-
2209
- matcherOut = matcher ?
2210
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2211
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2212
-
2213
- // ...intermediate processing is necessary
2214
- [] :
2215
-
2216
- // ...otherwise use results directly
2217
- results :
2218
- matcherIn;
2219
-
2220
- // Find primary matches
2221
- if ( matcher ) {
2222
- matcher( matcherIn, matcherOut, context, xml );
2223
- }
2224
-
2225
- // Apply postFilter
2226
- if ( postFilter ) {
2227
- temp = condense( matcherOut, postMap );
2228
- postFilter( temp, [], context, xml );
2229
-
2230
- // Un-match failing elements by moving them back to matcherIn
2231
- i = temp.length;
2232
- while ( i-- ) {
2233
- if ( (elem = temp[i]) ) {
2234
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2235
- }
2236
- }
2237
- }
2238
-
2239
- if ( seed ) {
2240
- if ( postFinder || preFilter ) {
2241
- if ( postFinder ) {
2242
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
2243
- temp = [];
2244
- i = matcherOut.length;
2245
- while ( i-- ) {
2246
- if ( (elem = matcherOut[i]) ) {
2247
- // Restore matcherIn since elem is not yet a final match
2248
- temp.push( (matcherIn[i] = elem) );
2249
- }
2250
- }
2251
- postFinder( null, (matcherOut = []), temp, xml );
2252
- }
2253
-
2254
- // Move matched elements from seed to results to keep them synchronized
2255
- i = matcherOut.length;
2256
- while ( i-- ) {
2257
- if ( (elem = matcherOut[i]) &&
2258
- (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2259
-
2260
- seed[temp] = !(results[temp] = elem);
2261
- }
2262
- }
2263
- }
2264
-
2265
- // Add elements to results, through postFinder if defined
2266
- } else {
2267
- matcherOut = condense(
2268
- matcherOut === results ?
2269
- matcherOut.splice( preexisting, matcherOut.length ) :
2270
- matcherOut
2271
- );
2272
- if ( postFinder ) {
2273
- postFinder( null, results, matcherOut, xml );
2274
- } else {
2275
- push.apply( results, matcherOut );
2276
- }
2277
- }
2278
- });
2279
- }
2280
-
2281
- function matcherFromTokens( tokens ) {
2282
- var checkContext, matcher, j,
2283
- len = tokens.length,
2284
- leadingRelative = Expr.relative[ tokens[0].type ],
2285
- implicitRelative = leadingRelative || Expr.relative[" "],
2286
- i = leadingRelative ? 1 : 0,
2287
-
2288
- // The foundational matcher ensures that elements are reachable from top-level context(s)
2289
- matchContext = addCombinator( function( elem ) {
2290
- return elem === checkContext;
2291
- }, implicitRelative, true ),
2292
- matchAnyContext = addCombinator( function( elem ) {
2293
- return indexOf.call( checkContext, elem ) > -1;
2294
- }, implicitRelative, true ),
2295
- matchers = [ function( elem, context, xml ) {
2296
- return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2297
- (checkContext = context).nodeType ?
2298
- matchContext( elem, context, xml ) :
2299
- matchAnyContext( elem, context, xml ) );
2300
- } ];
2301
-
2302
- for ( ; i < len; i++ ) {
2303
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2304
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2305
- } else {
2306
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2307
-
2308
- // Return special upon seeing a positional matcher
2309
- if ( matcher[ expando ] ) {
2310
- // Find the next relative operator (if any) for proper handling
2311
- j = ++i;
2312
- for ( ; j < len; j++ ) {
2313
- if ( Expr.relative[ tokens[j].type ] ) {
2314
- break;
2315
- }
2316
- }
2317
- return setMatcher(
2318
- i > 1 && elementMatcher( matchers ),
2319
- i > 1 && toSelector(
2320
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2321
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2322
- ).replace( rtrim, "$1" ),
2323
- matcher,
2324
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
2325
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2326
- j < len && toSelector( tokens )
2327
- );
2328
- }
2329
- matchers.push( matcher );
2330
- }
2331
- }
2332
-
2333
- return elementMatcher( matchers );
2334
- }
2335
-
2336
- function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2337
- var bySet = setMatchers.length > 0,
2338
- byElement = elementMatchers.length > 0,
2339
- superMatcher = function( seed, context, xml, results, outermost ) {
2340
- var elem, j, matcher,
2341
- matchedCount = 0,
2342
- i = "0",
2343
- unmatched = seed && [],
2344
- setMatched = [],
2345
- contextBackup = outermostContext,
2346
- // We must always have either seed elements or outermost context
2347
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2348
- // Use integer dirruns iff this is the outermost matcher
2349
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2350
- len = elems.length;
2351
-
2352
- if ( outermost ) {
2353
- outermostContext = context !== document && context;
2354
- }
2355
-
2356
- // Add elements passing elementMatchers directly to results
2357
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2358
- // Support: IE<9, Safari
2359
- // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2360
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2361
- if ( byElement && elem ) {
2362
- j = 0;
2363
- while ( (matcher = elementMatchers[j++]) ) {
2364
- if ( matcher( elem, context, xml ) ) {
2365
- results.push( elem );
2366
- break;
2367
- }
2368
- }
2369
- if ( outermost ) {
2370
- dirruns = dirrunsUnique;
2371
- }
2372
- }
2373
-
2374
- // Track unmatched elements for set filters
2375
- if ( bySet ) {
2376
- // They will have gone through all possible matchers
2377
- if ( (elem = !matcher && elem) ) {
2378
- matchedCount--;
2379
- }
2380
-
2381
- // Lengthen the array for every element, matched or not
2382
- if ( seed ) {
2383
- unmatched.push( elem );
2384
- }
2385
- }
2386
- }
2387
-
2388
- // Apply set filters to unmatched elements
2389
- matchedCount += i;
2390
- if ( bySet && i !== matchedCount ) {
2391
- j = 0;
2392
- while ( (matcher = setMatchers[j++]) ) {
2393
- matcher( unmatched, setMatched, context, xml );
2394
- }
2395
-
2396
- if ( seed ) {
2397
- // Reintegrate element matches to eliminate the need for sorting
2398
- if ( matchedCount > 0 ) {
2399
- while ( i-- ) {
2400
- if ( !(unmatched[i] || setMatched[i]) ) {
2401
- setMatched[i] = pop.call( results );
2402
- }
2403
- }
2404
- }
2405
-
2406
- // Discard index placeholder values to get only actual matches
2407
- setMatched = condense( setMatched );
2408
- }
2409
-
2410
- // Add matches to results
2411
- push.apply( results, setMatched );
2412
-
2413
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
2414
- if ( outermost && !seed && setMatched.length > 0 &&
2415
- ( matchedCount + setMatchers.length ) > 1 ) {
2416
-
2417
- Sizzle.uniqueSort( results );
2418
- }
2419
- }
2420
-
2421
- // Override manipulation of globals by nested matchers
2422
- if ( outermost ) {
2423
- dirruns = dirrunsUnique;
2424
- outermostContext = contextBackup;
2425
- }
2426
-
2427
- return unmatched;
2428
- };
2429
-
2430
- return bySet ?
2431
- markFunction( superMatcher ) :
2432
- superMatcher;
2433
- }
2434
-
2435
- compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
2436
- var i,
2437
- setMatchers = [],
2438
- elementMatchers = [],
2439
- cached = compilerCache[ selector + " " ];
2440
-
2441
- if ( !cached ) {
2442
- // Generate a function of recursive functions that can be used to check each element
2443
- if ( !group ) {
2444
- group = tokenize( selector );
2445
- }
2446
- i = group.length;
2447
- while ( i-- ) {
2448
- cached = matcherFromTokens( group[i] );
2449
- if ( cached[ expando ] ) {
2450
- setMatchers.push( cached );
2451
- } else {
2452
- elementMatchers.push( cached );
2453
- }
2454
- }
2455
-
2456
- // Cache the compiled function
2457
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2458
- }
2459
- return cached;
2460
- };
2461
-
2462
- function multipleContexts( selector, contexts, results ) {
2463
- var i = 0,
2464
- len = contexts.length;
2465
- for ( ; i < len; i++ ) {
2466
- Sizzle( selector, contexts[i], results );
2467
- }
2468
- return results;
2469
- }
2470
-
2471
- function select( selector, context, results, seed ) {
2472
- var i, tokens, token, type, find,
2473
- match = tokenize( selector );
2474
-
2475
- if ( !seed ) {
2476
- // Try to minimize operations if there is only one group
2477
- if ( match.length === 1 ) {
2478
-
2479
- // Take a shortcut and set the context if the root selector is an ID
2480
- tokens = match[0] = match[0].slice( 0 );
2481
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2482
- support.getById && context.nodeType === 9 && documentIsHTML &&
2483
- Expr.relative[ tokens[1].type ] ) {
2484
-
2485
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2486
- if ( !context ) {
2487
- return results;
2488
- }
2489
- selector = selector.slice( tokens.shift().value.length );
2490
- }
2491
-
2492
- // Fetch a seed set for right-to-left matching
2493
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2494
- while ( i-- ) {
2495
- token = tokens[i];
2496
-
2497
- // Abort if we hit a combinator
2498
- if ( Expr.relative[ (type = token.type) ] ) {
2499
- break;
2500
- }
2501
- if ( (find = Expr.find[ type ]) ) {
2502
- // Search, expanding context for leading sibling combinators
2503
- if ( (seed = find(
2504
- token.matches[0].replace( runescape, funescape ),
2505
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2506
- )) ) {
2507
-
2508
- // If seed is empty or no tokens remain, we can return early
2509
- tokens.splice( i, 1 );
2510
- selector = seed.length && toSelector( tokens );
2511
- if ( !selector ) {
2512
- push.apply( results, seed );
2513
- return results;
2514
- }
2515
-
2516
- break;
2517
- }
2518
- }
2519
- }
2520
- }
2521
- }
2522
-
2523
- // Compile and execute a filtering function
2524
- // Provide `match` to avoid retokenization if we modified the selector above
2525
- compile( selector, match )(
2526
- seed,
2527
- context,
2528
- !documentIsHTML,
2529
- results,
2530
- rsibling.test( selector ) && testContext( context.parentNode ) || context
2531
- );
2532
- return results;
2533
- }
2534
-
2535
- // One-time assignments
2536
-
2537
- // Sort stability
2538
- support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2539
-
2540
- // Support: Chrome<14
2541
- // Always assume duplicates if they aren't passed to the comparison function
2542
- support.detectDuplicates = !!hasDuplicate;
2543
-
2544
- // Initialize against the default document
2545
- setDocument();
2546
-
2547
- // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2548
- // Detached nodes confoundingly follow *each other*
2549
- support.sortDetached = assert(function( div1 ) {
2550
- // Should return 1, but returns 4 (following)
2551
- return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2552
- });
2553
-
2554
- // Support: IE<8
2555
- // Prevent attribute/property "interpolation"
2556
- // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2557
- if ( !assert(function( div ) {
2558
- div.innerHTML = "<a href='#'></a>";
2559
- return div.firstChild.getAttribute("href") === "#" ;
2560
- }) ) {
2561
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
2562
- if ( !isXML ) {
2563
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2564
- }
2565
- });
2566
- }
2567
-
2568
- // Support: IE<9
2569
- // Use defaultValue in place of getAttribute("value")
2570
- if ( !support.attributes || !assert(function( div ) {
2571
- div.innerHTML = "<input/>";
2572
- div.firstChild.setAttribute( "value", "" );
2573
- return div.firstChild.getAttribute( "value" ) === "";
2574
- }) ) {
2575
- addHandle( "value", function( elem, name, isXML ) {
2576
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2577
- return elem.defaultValue;
2578
- }
2579
- });
2580
- }
2581
-
2582
- // Support: IE<9
2583
- // Use getAttributeNode to fetch booleans when getAttribute lies
2584
- if ( !assert(function( div ) {
2585
- return div.getAttribute("disabled") == null;
2586
- }) ) {
2587
- addHandle( booleans, function( elem, name, isXML ) {
2588
- var val;
2589
- if ( !isXML ) {
2590
- return elem[ name ] === true ? name.toLowerCase() :
2591
- (val = elem.getAttributeNode( name )) && val.specified ?
2592
- val.value :
2593
- null;
2594
- }
2595
- });
2596
- }
2597
-
2598
- return Sizzle;
2599
-
2600
- })( window );
2601
-
2602
-
2603
-
2604
- jQuery.find = Sizzle;
2605
- jQuery.expr = Sizzle.selectors;
2606
- jQuery.expr[":"] = jQuery.expr.pseudos;
2607
- jQuery.unique = Sizzle.uniqueSort;
2608
- jQuery.text = Sizzle.getText;
2609
- jQuery.isXMLDoc = Sizzle.isXML;
2610
- jQuery.contains = Sizzle.contains;
2611
-
2612
-
2613
-
2614
- var rneedsContext = jQuery.expr.match.needsContext;
2615
-
2616
- var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2617
-
2618
-
2619
-
2620
- var risSimple = /^.[^:#\[\.,]*$/;
2621
-
2622
- // Implement the identical functionality for filter and not
2623
- function winnow( elements, qualifier, not ) {
2624
- if ( jQuery.isFunction( qualifier ) ) {
2625
- return jQuery.grep( elements, function( elem, i ) {
2626
- /* jshint -W018 */
2627
- return !!qualifier.call( elem, i, elem ) !== not;
2628
- });
2629
-
2630
- }
2631
-
2632
- if ( qualifier.nodeType ) {
2633
- return jQuery.grep( elements, function( elem ) {
2634
- return ( elem === qualifier ) !== not;
2635
- });
2636
-
2637
- }
2638
-
2639
- if ( typeof qualifier === "string" ) {
2640
- if ( risSimple.test( qualifier ) ) {
2641
- return jQuery.filter( qualifier, elements, not );
2642
- }
2643
-
2644
- qualifier = jQuery.filter( qualifier, elements );
2645
- }
2646
-
2647
- return jQuery.grep( elements, function( elem ) {
2648
- return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
2649
- });
2650
- }
2651
-
2652
- jQuery.filter = function( expr, elems, not ) {
2653
- var elem = elems[ 0 ];
2654
-
2655
- if ( not ) {
2656
- expr = ":not(" + expr + ")";
2657
- }
2658
-
2659
- return elems.length === 1 && elem.nodeType === 1 ?
2660
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2661
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2662
- return elem.nodeType === 1;
2663
- }));
2664
- };
2665
-
2666
- jQuery.fn.extend({
2667
- find: function( selector ) {
2668
- var i,
2669
- ret = [],
2670
- self = this,
2671
- len = self.length;
2672
-
2673
- if ( typeof selector !== "string" ) {
2674
- return this.pushStack( jQuery( selector ).filter(function() {
2675
- for ( i = 0; i < len; i++ ) {
2676
- if ( jQuery.contains( self[ i ], this ) ) {
2677
- return true;
2678
- }
2679
- }
2680
- }) );
2681
- }
2682
-
2683
- for ( i = 0; i < len; i++ ) {
2684
- jQuery.find( selector, self[ i ], ret );
2685
- }
2686
-
2687
- // Needed because $( selector, context ) becomes $( context ).find( selector )
2688
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2689
- ret.selector = this.selector ? this.selector + " " + selector : selector;
2690
- return ret;
2691
- },
2692
- filter: function( selector ) {
2693
- return this.pushStack( winnow(this, selector || [], false) );
2694
- },
2695
- not: function( selector ) {
2696
- return this.pushStack( winnow(this, selector || [], true) );
2697
- },
2698
- is: function( selector ) {
2699
- return !!winnow(
2700
- this,
2701
-
2702
- // If this is a positional/relative selector, check membership in the returned set
2703
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
2704
- typeof selector === "string" && rneedsContext.test( selector ) ?
2705
- jQuery( selector ) :
2706
- selector || [],
2707
- false
2708
- ).length;
2709
- }
2710
- });
2711
-
2712
-
2713
- // Initialize a jQuery object
2714
-
2715
-
2716
- // A central reference to the root jQuery(document)
2717
- var rootjQuery,
2718
-
2719
- // Use the correct document accordingly with window argument (sandbox)
2720
- document = window.document,
2721
-
2722
- // A simple way to check for HTML strings
2723
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2724
- // Strict HTML recognition (#11290: must start with <)
2725
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2726
-
2727
- init = jQuery.fn.init = function( selector, context ) {
2728
- var match, elem;
2729
-
2730
- // HANDLE: $(""), $(null), $(undefined), $(false)
2731
- if ( !selector ) {
2732
- return this;
2733
- }
2734
-
2735
- // Handle HTML strings
2736
- if ( typeof selector === "string" ) {
2737
- if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
2738
- // Assume that strings that start and end with <> are HTML and skip the regex check
2739
- match = [ null, selector, null ];
2740
-
2741
- } else {
2742
- match = rquickExpr.exec( selector );
2743
- }
2744
-
2745
- // Match html or make sure no context is specified for #id
2746
- if ( match && (match[1] || !context) ) {
2747
-
2748
- // HANDLE: $(html) -> $(array)
2749
- if ( match[1] ) {
2750
- context = context instanceof jQuery ? context[0] : context;
2751
-
2752
- // scripts is true for back-compat
2753
- // Intentionally let the error be thrown if parseHTML is not present
2754
- jQuery.merge( this, jQuery.parseHTML(
2755
- match[1],
2756
- context && context.nodeType ? context.ownerDocument || context : document,
2757
- true
2758
- ) );
2759
-
2760
- // HANDLE: $(html, props)
2761
- if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2762
- for ( match in context ) {
2763
- // Properties of context are called as methods if possible
2764
- if ( jQuery.isFunction( this[ match ] ) ) {
2765
- this[ match ]( context[ match ] );
2766
-
2767
- // ...and otherwise set as attributes
2768
- } else {
2769
- this.attr( match, context[ match ] );
2770
- }
2771
- }
2772
- }
2773
-
2774
- return this;
2775
-
2776
- // HANDLE: $(#id)
2777
- } else {
2778
- elem = document.getElementById( match[2] );
2779
-
2780
- // Check parentNode to catch when Blackberry 4.6 returns
2781
- // nodes that are no longer in the document #6963
2782
- if ( elem && elem.parentNode ) {
2783
- // Handle the case where IE and Opera return items
2784
- // by name instead of ID
2785
- if ( elem.id !== match[2] ) {
2786
- return rootjQuery.find( selector );
2787
- }
2788
-
2789
- // Otherwise, we inject the element directly into the jQuery object
2790
- this.length = 1;
2791
- this[0] = elem;
2792
- }
2793
-
2794
- this.context = document;
2795
- this.selector = selector;
2796
- return this;
2797
- }
2798
-
2799
- // HANDLE: $(expr, $(...))
2800
- } else if ( !context || context.jquery ) {
2801
- return ( context || rootjQuery ).find( selector );
2802
-
2803
- // HANDLE: $(expr, context)
2804
- // (which is just equivalent to: $(context).find(expr)
2805
- } else {
2806
- return this.constructor( context ).find( selector );
2807
- }
2808
-
2809
- // HANDLE: $(DOMElement)
2810
- } else if ( selector.nodeType ) {
2811
- this.context = this[0] = selector;
2812
- this.length = 1;
2813
- return this;
2814
-
2815
- // HANDLE: $(function)
2816
- // Shortcut for document ready
2817
- } else if ( jQuery.isFunction( selector ) ) {
2818
- return typeof rootjQuery.ready !== "undefined" ?
2819
- rootjQuery.ready( selector ) :
2820
- // Execute immediately if ready is not present
2821
- selector( jQuery );
2822
- }
2823
-
2824
- if ( selector.selector !== undefined ) {
2825
- this.selector = selector.selector;
2826
- this.context = selector.context;
2827
- }
2828
-
2829
- return jQuery.makeArray( selector, this );
2830
- };
2831
-
2832
- // Give the init function the jQuery prototype for later instantiation
2833
- init.prototype = jQuery.fn;
2834
-
2835
- // Initialize central reference
2836
- rootjQuery = jQuery( document );
2837
-
2838
-
2839
- var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2840
- // methods guaranteed to produce a unique set when starting from a unique set
2841
- guaranteedUnique = {
2842
- children: true,
2843
- contents: true,
2844
- next: true,
2845
- prev: true
2846
- };
2847
-
2848
- jQuery.extend({
2849
- dir: function( elem, dir, until ) {
2850
- var matched = [],
2851
- cur = elem[ dir ];
2852
-
2853
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
2854
- if ( cur.nodeType === 1 ) {
2855
- matched.push( cur );
2856
- }
2857
- cur = cur[dir];
2858
- }
2859
- return matched;
2860
- },
2861
-
2862
- sibling: function( n, elem ) {
2863
- var r = [];
2864
-
2865
- for ( ; n; n = n.nextSibling ) {
2866
- if ( n.nodeType === 1 && n !== elem ) {
2867
- r.push( n );
2868
- }
2869
- }
2870
-
2871
- return r;
2872
- }
2873
- });
2874
-
2875
- jQuery.fn.extend({
2876
- has: function( target ) {
2877
- var i,
2878
- targets = jQuery( target, this ),
2879
- len = targets.length;
2880
-
2881
- return this.filter(function() {
2882
- for ( i = 0; i < len; i++ ) {
2883
- if ( jQuery.contains( this, targets[i] ) ) {
2884
- return true;
2885
- }
2886
- }
2887
- });
2888
- },
2889
-
2890
- closest: function( selectors, context ) {
2891
- var cur,
2892
- i = 0,
2893
- l = this.length,
2894
- matched = [],
2895
- pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2896
- jQuery( selectors, context || this.context ) :
2897
- 0;
2898
-
2899
- for ( ; i < l; i++ ) {
2900
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2901
- // Always skip document fragments
2902
- if ( cur.nodeType < 11 && (pos ?
2903
- pos.index(cur) > -1 :
2904
-
2905
- // Don't pass non-elements to Sizzle
2906
- cur.nodeType === 1 &&
2907
- jQuery.find.matchesSelector(cur, selectors)) ) {
2908
-
2909
- matched.push( cur );
2910
- break;
2911
- }
2912
- }
2913
- }
2914
-
2915
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2916
- },
2917
-
2918
- // Determine the position of an element within
2919
- // the matched set of elements
2920
- index: function( elem ) {
2921
-
2922
- // No argument, return index in parent
2923
- if ( !elem ) {
2924
- return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
2925
- }
2926
-
2927
- // index in selector
2928
- if ( typeof elem === "string" ) {
2929
- return jQuery.inArray( this[0], jQuery( elem ) );
2930
- }
2931
-
2932
- // Locate the position of the desired element
2933
- return jQuery.inArray(
2934
- // If it receives a jQuery object, the first element is used
2935
- elem.jquery ? elem[0] : elem, this );
2936
- },
2937
-
2938
- add: function( selector, context ) {
2939
- return this.pushStack(
2940
- jQuery.unique(
2941
- jQuery.merge( this.get(), jQuery( selector, context ) )
2942
- )
2943
- );
2944
- },
2945
-
2946
- addBack: function( selector ) {
2947
- return this.add( selector == null ?
2948
- this.prevObject : this.prevObject.filter(selector)
2949
- );
2950
- }
2951
- });
2952
-
2953
- function sibling( cur, dir ) {
2954
- do {
2955
- cur = cur[ dir ];
2956
- } while ( cur && cur.nodeType !== 1 );
2957
-
2958
- return cur;
2959
- }
2960
-
2961
- jQuery.each({
2962
- parent: function( elem ) {
2963
- var parent = elem.parentNode;
2964
- return parent && parent.nodeType !== 11 ? parent : null;
2965
- },
2966
- parents: function( elem ) {
2967
- return jQuery.dir( elem, "parentNode" );
2968
- },
2969
- parentsUntil: function( elem, i, until ) {
2970
- return jQuery.dir( elem, "parentNode", until );
2971
- },
2972
- next: function( elem ) {
2973
- return sibling( elem, "nextSibling" );
2974
- },
2975
- prev: function( elem ) {
2976
- return sibling( elem, "previousSibling" );
2977
- },
2978
- nextAll: function( elem ) {
2979
- return jQuery.dir( elem, "nextSibling" );
2980
- },
2981
- prevAll: function( elem ) {
2982
- return jQuery.dir( elem, "previousSibling" );
2983
- },
2984
- nextUntil: function( elem, i, until ) {
2985
- return jQuery.dir( elem, "nextSibling", until );
2986
- },
2987
- prevUntil: function( elem, i, until ) {
2988
- return jQuery.dir( elem, "previousSibling", until );
2989
- },
2990
- siblings: function( elem ) {
2991
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2992
- },
2993
- children: function( elem ) {
2994
- return jQuery.sibling( elem.firstChild );
2995
- },
2996
- contents: function( elem ) {
2997
- return jQuery.nodeName( elem, "iframe" ) ?
2998
- elem.contentDocument || elem.contentWindow.document :
2999
- jQuery.merge( [], elem.childNodes );
3000
- }
3001
- }, function( name, fn ) {
3002
- jQuery.fn[ name ] = function( until, selector ) {
3003
- var ret = jQuery.map( this, fn, until );
3004
-
3005
- if ( name.slice( -5 ) !== "Until" ) {
3006
- selector = until;
3007
- }
3008
-
3009
- if ( selector && typeof selector === "string" ) {
3010
- ret = jQuery.filter( selector, ret );
3011
- }
3012
-
3013
- if ( this.length > 1 ) {
3014
- // Remove duplicates
3015
- if ( !guaranteedUnique[ name ] ) {
3016
- ret = jQuery.unique( ret );
3017
- }
3018
-
3019
- // Reverse order for parents* and prev-derivatives
3020
- if ( rparentsprev.test( name ) ) {
3021
- ret = ret.reverse();
3022
- }
3023
- }
3024
-
3025
- return this.pushStack( ret );
3026
- };
3027
- });
3028
- var rnotwhite = (/\S+/g);
3029
-
3030
-
3031
-
3032
- // String to Object options format cache
3033
- var optionsCache = {};
3034
-
3035
- // Convert String-formatted options into Object-formatted ones and store in cache
3036
- function createOptions( options ) {
3037
- var object = optionsCache[ options ] = {};
3038
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3039
- object[ flag ] = true;
3040
- });
3041
- return object;
3042
- }
3043
-
3044
- /*
3045
- * Create a callback list using the following parameters:
3046
- *
3047
- * options: an optional list of space-separated options that will change how
3048
- * the callback list behaves or a more traditional option object
3049
- *
3050
- * By default a callback list will act like an event callback list and can be
3051
- * "fired" multiple times.
3052
- *
3053
- * Possible options:
3054
- *
3055
- * once: will ensure the callback list can only be fired once (like a Deferred)
3056
- *
3057
- * memory: will keep track of previous values and will call any callback added
3058
- * after the list has been fired right away with the latest "memorized"
3059
- * values (like a Deferred)
3060
- *
3061
- * unique: will ensure a callback can only be added once (no duplicate in the list)
3062
- *
3063
- * stopOnFalse: interrupt callings when a callback returns false
3064
- *
3065
- */
3066
- jQuery.Callbacks = function( options ) {
3067
-
3068
- // Convert options from String-formatted to Object-formatted if needed
3069
- // (we check in cache first)
3070
- options = typeof options === "string" ?
3071
- ( optionsCache[ options ] || createOptions( options ) ) :
3072
- jQuery.extend( {}, options );
3073
-
3074
- var // Flag to know if list is currently firing
3075
- firing,
3076
- // Last fire value (for non-forgettable lists)
3077
- memory,
3078
- // Flag to know if list was already fired
3079
- fired,
3080
- // End of the loop when firing
3081
- firingLength,
3082
- // Index of currently firing callback (modified by remove if needed)
3083
- firingIndex,
3084
- // First callback to fire (used internally by add and fireWith)
3085
- firingStart,
3086
- // Actual callback list
3087
- list = [],
3088
- // Stack of fire calls for repeatable lists
3089
- stack = !options.once && [],
3090
- // Fire callbacks
3091
- fire = function( data ) {
3092
- memory = options.memory && data;
3093
- fired = true;
3094
- firingIndex = firingStart || 0;
3095
- firingStart = 0;
3096
- firingLength = list.length;
3097
- firing = true;
3098
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3099
- if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3100
- memory = false; // To prevent further calls using add
3101
- break;
3102
- }
3103
- }
3104
- firing = false;
3105
- if ( list ) {
3106
- if ( stack ) {
3107
- if ( stack.length ) {
3108
- fire( stack.shift() );
3109
- }
3110
- } else if ( memory ) {
3111
- list = [];
3112
- } else {
3113
- self.disable();
3114
- }
3115
- }
3116
- },
3117
- // Actual Callbacks object
3118
- self = {
3119
- // Add a callback or a collection of callbacks to the list
3120
- add: function() {
3121
- if ( list ) {
3122
- // First, we save the current length
3123
- var start = list.length;
3124
- (function add( args ) {
3125
- jQuery.each( args, function( _, arg ) {
3126
- var type = jQuery.type( arg );
3127
- if ( type === "function" ) {
3128
- if ( !options.unique || !self.has( arg ) ) {
3129
- list.push( arg );
3130
- }
3131
- } else if ( arg && arg.length && type !== "string" ) {
3132
- // Inspect recursively
3133
- add( arg );
3134
- }
3135
- });
3136
- })( arguments );
3137
- // Do we need to add the callbacks to the
3138
- // current firing batch?
3139
- if ( firing ) {
3140
- firingLength = list.length;
3141
- // With memory, if we're not firing then
3142
- // we should call right away
3143
- } else if ( memory ) {
3144
- firingStart = start;
3145
- fire( memory );
3146
- }
3147
- }
3148
- return this;
3149
- },
3150
- // Remove a callback from the list
3151
- remove: function() {
3152
- if ( list ) {
3153
- jQuery.each( arguments, function( _, arg ) {
3154
- var index;
3155
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3156
- list.splice( index, 1 );
3157
- // Handle firing indexes
3158
- if ( firing ) {
3159
- if ( index <= firingLength ) {
3160
- firingLength--;
3161
- }
3162
- if ( index <= firingIndex ) {
3163
- firingIndex--;
3164
- }
3165
- }
3166
- }
3167
- });
3168
- }
3169
- return this;
3170
- },
3171
- // Check if a given callback is in the list.
3172
- // If no argument is given, return whether or not list has callbacks attached.
3173
- has: function( fn ) {
3174
- return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3175
- },
3176
- // Remove all callbacks from the list
3177
- empty: function() {
3178
- list = [];
3179
- firingLength = 0;
3180
- return this;
3181
- },
3182
- // Have the list do nothing anymore
3183
- disable: function() {
3184
- list = stack = memory = undefined;
3185
- return this;
3186
- },
3187
- // Is it disabled?
3188
- disabled: function() {
3189
- return !list;
3190
- },
3191
- // Lock the list in its current state
3192
- lock: function() {
3193
- stack = undefined;
3194
- if ( !memory ) {
3195
- self.disable();
3196
- }
3197
- return this;
3198
- },
3199
- // Is it locked?
3200
- locked: function() {
3201
- return !stack;
3202
- },
3203
- // Call all callbacks with the given context and arguments
3204
- fireWith: function( context, args ) {
3205
- if ( list && ( !fired || stack ) ) {
3206
- args = args || [];
3207
- args = [ context, args.slice ? args.slice() : args ];
3208
- if ( firing ) {
3209
- stack.push( args );
3210
- } else {
3211
- fire( args );
3212
- }
3213
- }
3214
- return this;
3215
- },
3216
- // Call all the callbacks with the given arguments
3217
- fire: function() {
3218
- self.fireWith( this, arguments );
3219
- return this;
3220
- },
3221
- // To know if the callbacks have already been called at least once
3222
- fired: function() {
3223
- return !!fired;
3224
- }
3225
- };
3226
-
3227
- return self;
3228
- };
3229
-
3230
-
3231
- jQuery.extend({
3232
-
3233
- Deferred: function( func ) {
3234
- var tuples = [
3235
- // action, add listener, listener list, final state
3236
- [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3237
- [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3238
- [ "notify", "progress", jQuery.Callbacks("memory") ]
3239
- ],
3240
- state = "pending",
3241
- promise = {
3242
- state: function() {
3243
- return state;
3244
- },
3245
- always: function() {
3246
- deferred.done( arguments ).fail( arguments );
3247
- return this;
3248
- },
3249
- then: function( /* fnDone, fnFail, fnProgress */ ) {
3250
- var fns = arguments;
3251
- return jQuery.Deferred(function( newDefer ) {
3252
- jQuery.each( tuples, function( i, tuple ) {
3253
- var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3254
- // deferred[ done | fail | progress ] for forwarding actions to newDefer
3255
- deferred[ tuple[1] ](function() {
3256
- var returned = fn && fn.apply( this, arguments );
3257
- if ( returned && jQuery.isFunction( returned.promise ) ) {
3258
- returned.promise()
3259
- .done( newDefer.resolve )
3260
- .fail( newDefer.reject )
3261
- .progress( newDefer.notify );
3262
- } else {
3263
- newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3264
- }
3265
- });
3266
- });
3267
- fns = null;
3268
- }).promise();
3269
- },
3270
- // Get a promise for this deferred
3271
- // If obj is provided, the promise aspect is added to the object
3272
- promise: function( obj ) {
3273
- return obj != null ? jQuery.extend( obj, promise ) : promise;
3274
- }
3275
- },
3276
- deferred = {};
3277
-
3278
- // Keep pipe for back-compat
3279
- promise.pipe = promise.then;
3280
-
3281
- // Add list-specific methods
3282
- jQuery.each( tuples, function( i, tuple ) {
3283
- var list = tuple[ 2 ],
3284
- stateString = tuple[ 3 ];
3285
-
3286
- // promise[ done | fail | progress ] = list.add
3287
- promise[ tuple[1] ] = list.add;
3288
-
3289
- // Handle state
3290
- if ( stateString ) {
3291
- list.add(function() {
3292
- // state = [ resolved | rejected ]
3293
- state = stateString;
3294
-
3295
- // [ reject_list | resolve_list ].disable; progress_list.lock
3296
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3297
- }
3298
-
3299
- // deferred[ resolve | reject | notify ]
3300
- deferred[ tuple[0] ] = function() {
3301
- deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3302
- return this;
3303
- };
3304
- deferred[ tuple[0] + "With" ] = list.fireWith;
3305
- });
3306
-
3307
- // Make the deferred a promise
3308
- promise.promise( deferred );
3309
-
3310
- // Call given func if any
3311
- if ( func ) {
3312
- func.call( deferred, deferred );
3313
- }
3314
-
3315
- // All done!
3316
- return deferred;
3317
- },
3318
-
3319
- // Deferred helper
3320
- when: function( subordinate /* , ..., subordinateN */ ) {
3321
- var i = 0,
3322
- resolveValues = slice.call( arguments ),
3323
- length = resolveValues.length,
3324
-
3325
- // the count of uncompleted subordinates
3326
- remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3327
-
3328
- // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3329
- deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3330
-
3331
- // Update function for both resolve and progress values
3332
- updateFunc = function( i, contexts, values ) {
3333
- return function( value ) {
3334
- contexts[ i ] = this;
3335
- values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3336
- if ( values === progressValues ) {
3337
- deferred.notifyWith( contexts, values );
3338
-
3339
- } else if ( !(--remaining) ) {
3340
- deferred.resolveWith( contexts, values );
3341
- }
3342
- };
3343
- },
3344
-
3345
- progressValues, progressContexts, resolveContexts;
3346
-
3347
- // add listeners to Deferred subordinates; treat others as resolved
3348
- if ( length > 1 ) {
3349
- progressValues = new Array( length );
3350
- progressContexts = new Array( length );
3351
- resolveContexts = new Array( length );
3352
- for ( ; i < length; i++ ) {
3353
- if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3354
- resolveValues[ i ].promise()
3355
- .done( updateFunc( i, resolveContexts, resolveValues ) )
3356
- .fail( deferred.reject )
3357
- .progress( updateFunc( i, progressContexts, progressValues ) );
3358
- } else {
3359
- --remaining;
3360
- }
3361
- }
3362
- }
3363
-
3364
- // if we're not waiting on anything, resolve the master
3365
- if ( !remaining ) {
3366
- deferred.resolveWith( resolveContexts, resolveValues );
3367
- }
3368
-
3369
- return deferred.promise();
3370
- }
3371
- });
3372
-
3373
-
3374
- // The deferred used on DOM ready
3375
- var readyList;
3376
-
3377
- jQuery.fn.ready = function( fn ) {
3378
- // Add the callback
3379
- jQuery.ready.promise().done( fn );
3380
-
3381
- return this;
3382
- };
3383
-
3384
- jQuery.extend({
3385
- // Is the DOM ready to be used? Set to true once it occurs.
3386
- isReady: false,
3387
-
3388
- // A counter to track how many items to wait for before
3389
- // the ready event fires. See #6781
3390
- readyWait: 1,
3391
-
3392
- // Hold (or release) the ready event
3393
- holdReady: function( hold ) {
3394
- if ( hold ) {
3395
- jQuery.readyWait++;
3396
- } else {
3397
- jQuery.ready( true );
3398
- }
3399
- },
3400
-
3401
- // Handle when the DOM is ready
3402
- ready: function( wait ) {
3403
-
3404
- // Abort if there are pending holds or we're already ready
3405
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3406
- return;
3407
- }
3408
-
3409
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
3410
- if ( !document.body ) {
3411
- return setTimeout( jQuery.ready );
3412
- }
3413
-
3414
- // Remember that the DOM is ready
3415
- jQuery.isReady = true;
3416
-
3417
- // If a normal DOM Ready event fired, decrement, and wait if need be
3418
- if ( wait !== true && --jQuery.readyWait > 0 ) {
3419
- return;
3420
- }
3421
-
3422
- // If there are functions bound, to execute
3423
- readyList.resolveWith( document, [ jQuery ] );
3424
-
3425
- // Trigger any bound ready events
3426
- if ( jQuery.fn.trigger ) {
3427
- jQuery( document ).trigger("ready").off("ready");
3428
- }
3429
- }
3430
- });
3431
-
3432
- /**
3433
- * Clean-up method for dom ready events
3434
- */
3435
- function detach() {
3436
- if ( document.addEventListener ) {
3437
- document.removeEventListener( "DOMContentLoaded", completed, false );
3438
- window.removeEventListener( "load", completed, false );
3439
-
3440
- } else {
3441
- document.detachEvent( "onreadystatechange", completed );
3442
- window.detachEvent( "onload", completed );
3443
- }
3444
- }
3445
-
3446
- /**
3447
- * The ready event handler and self cleanup method
3448
- */
3449
- function completed() {
3450
- // readyState === "complete" is good enough for us to call the dom ready in oldIE
3451
- if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
3452
- detach();
3453
- jQuery.ready();
3454
- }
3455
- }
3456
-
3457
- jQuery.ready.promise = function( obj ) {
3458
- if ( !readyList ) {
3459
-
3460
- readyList = jQuery.Deferred();
3461
-
3462
- // Catch cases where $(document).ready() is called after the browser event has already occurred.
3463
- // we once tried to use readyState "interactive" here, but it caused issues like the one
3464
- // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3465
- if ( document.readyState === "complete" ) {
3466
- // Handle it asynchronously to allow scripts the opportunity to delay ready
3467
- setTimeout( jQuery.ready );
3468
-
3469
- // Standards-based browsers support DOMContentLoaded
3470
- } else if ( document.addEventListener ) {
3471
- // Use the handy event callback
3472
- document.addEventListener( "DOMContentLoaded", completed, false );
3473
-
3474
- // A fallback to window.onload, that will always work
3475
- window.addEventListener( "load", completed, false );
3476
-
3477
- // If IE event model is used
3478
- } else {
3479
- // Ensure firing before onload, maybe late but safe also for iframes
3480
- document.attachEvent( "onreadystatechange", completed );
3481
-
3482
- // A fallback to window.onload, that will always work
3483
- window.attachEvent( "onload", completed );
3484
-
3485
- // If IE and not a frame
3486
- // continually check to see if the document is ready
3487
- var top = false;
3488
-
3489
- try {
3490
- top = window.frameElement == null && document.documentElement;
3491
- } catch(e) {}
3492
-
3493
- if ( top && top.doScroll ) {
3494
- (function doScrollCheck() {
3495
- if ( !jQuery.isReady ) {
3496
-
3497
- try {
3498
- // Use the trick by Diego Perini
3499
- // http://javascript.nwbox.com/IEContentLoaded/
3500
- top.doScroll("left");
3501
- } catch(e) {
3502
- return setTimeout( doScrollCheck, 50 );
3503
- }
3504
-
3505
- // detach all dom ready events
3506
- detach();
3507
-
3508
- // and execute any waiting functions
3509
- jQuery.ready();
3510
- }
3511
- })();
3512
- }
3513
- }
3514
- }
3515
- return readyList.promise( obj );
3516
- };
3517
-
3518
-
3519
- var strundefined = typeof undefined;
3520
-
3521
-
3522
-
3523
- // Support: IE<9
3524
- // Iteration over object's inherited properties before its own
3525
- var i;
3526
- for ( i in jQuery( support ) ) {
3527
- break;
3528
- }
3529
- support.ownLast = i !== "0";
3530
-
3531
- // Note: most support tests are defined in their respective modules.
3532
- // false until the test is run
3533
- support.inlineBlockNeedsLayout = false;
3534
-
3535
- jQuery(function() {
3536
- // We need to execute this one support test ASAP because we need to know
3537
- // if body.style.zoom needs to be set.
3538
-
3539
- var container, div,
3540
- body = document.getElementsByTagName("body")[0];
3541
-
3542
- if ( !body ) {
3543
- // Return for frameset docs that don't have a body
3544
- return;
3545
- }
3546
-
3547
- // Setup
3548
- container = document.createElement( "div" );
3549
- container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
3550
-
3551
- div = document.createElement( "div" );
3552
- body.appendChild( container ).appendChild( div );
3553
-
3554
- if ( typeof div.style.zoom !== strundefined ) {
3555
- // Support: IE<8
3556
- // Check if natively block-level elements act like inline-block
3557
- // elements when setting their display to 'inline' and giving
3558
- // them layout
3559
- div.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1";
3560
-
3561
- if ( (support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 )) ) {
3562
- // Prevent IE 6 from affecting layout for positioned elements #11048
3563
- // Prevent IE from shrinking the body in IE 7 mode #12869
3564
- // Support: IE<8
3565
- body.style.zoom = 1;
3566
- }
3567
- }
3568
-
3569
- body.removeChild( container );
3570
-
3571
- // Null elements to avoid leaks in IE
3572
- container = div = null;
3573
- });
3574
-
3575
-
3576
-
3577
-
3578
- (function() {
3579
- var div = document.createElement( "div" );
3580
-
3581
- // Execute the test only if not already executed in another module.
3582
- if (support.deleteExpando == null) {
3583
- // Support: IE<9
3584
- support.deleteExpando = true;
3585
- try {
3586
- delete div.test;
3587
- } catch( e ) {
3588
- support.deleteExpando = false;
3589
- }
3590
- }
3591
-
3592
- // Null elements to avoid leaks in IE.
3593
- div = null;
3594
- })();
3595
-
3596
-
3597
- /**
3598
- * Determines whether an object can have data
3599
- */
3600
- jQuery.acceptData = function( elem ) {
3601
- var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
3602
- nodeType = +elem.nodeType || 1;
3603
-
3604
- // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3605
- return nodeType !== 1 && nodeType !== 9 ?
3606
- false :
3607
-
3608
- // Nodes accept data unless otherwise specified; rejection can be conditional
3609
- !noData || noData !== true && elem.getAttribute("classid") === noData;
3610
- };
3611
-
3612
-
3613
- var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3614
- rmultiDash = /([A-Z])/g;
3615
-
3616
- function dataAttr( elem, key, data ) {
3617
- // If nothing was found internally, try to fetch any
3618
- // data from the HTML5 data-* attribute
3619
- if ( data === undefined && elem.nodeType === 1 ) {
3620
-
3621
- var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3622
-
3623
- data = elem.getAttribute( name );
3624
-
3625
- if ( typeof data === "string" ) {
3626
- try {
3627
- data = data === "true" ? true :
3628
- data === "false" ? false :
3629
- data === "null" ? null :
3630
- // Only convert to a number if it doesn't change the string
3631
- +data + "" === data ? +data :
3632
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
3633
- data;
3634
- } catch( e ) {}
3635
-
3636
- // Make sure we set the data so it isn't changed later
3637
- jQuery.data( elem, key, data );
3638
-
3639
- } else {
3640
- data = undefined;
3641
- }
3642
- }
3643
-
3644
- return data;
3645
- }
3646
-
3647
- // checks a cache object for emptiness
3648
- function isEmptyDataObject( obj ) {
3649
- var name;
3650
- for ( name in obj ) {
3651
-
3652
- // if the public data object is empty, the private is still empty
3653
- if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
3654
- continue;
3655
- }
3656
- if ( name !== "toJSON" ) {
3657
- return false;
3658
- }
3659
- }
3660
-
3661
- return true;
3662
- }
3663
-
3664
- function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3665
- if ( !jQuery.acceptData( elem ) ) {
3666
- return;
3667
- }
3668
-
3669
- var ret, thisCache,
3670
- internalKey = jQuery.expando,
3671
-
3672
- // We have to handle DOM nodes and JS objects differently because IE6-7
3673
- // can't GC object references properly across the DOM-JS boundary
3674
- isNode = elem.nodeType,
3675
-
3676
- // Only DOM nodes need the global jQuery cache; JS object data is
3677
- // attached directly to the object so GC can occur automatically
3678
- cache = isNode ? jQuery.cache : elem,
3679
-
3680
- // Only defining an ID for JS objects if its cache already exists allows
3681
- // the code to shortcut on the same path as a DOM node with no cache
3682
- id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3683
-
3684
- // Avoid doing any more work than we need to when trying to get data on an
3685
- // object that has no data at all
3686
- if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
3687
- return;
3688
- }
3689
-
3690
- if ( !id ) {
3691
- // Only DOM nodes need a new unique ID for each element since their data
3692
- // ends up in the global cache
3693
- if ( isNode ) {
3694
- id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3695
- } else {
3696
- id = internalKey;
3697
- }
3698
- }
3699
-
3700
- if ( !cache[ id ] ) {
3701
- // Avoid exposing jQuery metadata on plain JS objects when the object
3702
- // is serialized using JSON.stringify
3703
- cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3704
- }
3705
-
3706
- // An object can be passed to jQuery.data instead of a key/value pair; this gets
3707
- // shallow copied over onto the existing cache
3708
- if ( typeof name === "object" || typeof name === "function" ) {
3709
- if ( pvt ) {
3710
- cache[ id ] = jQuery.extend( cache[ id ], name );
3711
- } else {
3712
- cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3713
- }
3714
- }
3715
-
3716
- thisCache = cache[ id ];
3717
-
3718
- // jQuery data() is stored in a separate object inside the object's internal data
3719
- // cache in order to avoid key collisions between internal data and user-defined
3720
- // data.
3721
- if ( !pvt ) {
3722
- if ( !thisCache.data ) {
3723
- thisCache.data = {};
3724
- }
3725
-
3726
- thisCache = thisCache.data;
3727
- }
3728
-
3729
- if ( data !== undefined ) {
3730
- thisCache[ jQuery.camelCase( name ) ] = data;
3731
- }
3732
-
3733
- // Check for both converted-to-camel and non-converted data property names
3734
- // If a data property was specified
3735
- if ( typeof name === "string" ) {
3736
-
3737
- // First Try to find as-is property data
3738
- ret = thisCache[ name ];
3739
-
3740
- // Test for null|undefined property data
3741
- if ( ret == null ) {
3742
-
3743
- // Try to find the camelCased property
3744
- ret = thisCache[ jQuery.camelCase( name ) ];
3745
- }
3746
- } else {
3747
- ret = thisCache;
3748
- }
3749
-
3750
- return ret;
3751
- }
3752
-
3753
- function internalRemoveData( elem, name, pvt ) {
3754
- if ( !jQuery.acceptData( elem ) ) {
3755
- return;
3756
- }
3757
-
3758
- var thisCache, i,
3759
- isNode = elem.nodeType,
3760
-
3761
- // See jQuery.data for more information
3762
- cache = isNode ? jQuery.cache : elem,
3763
- id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3764
-
3765
- // If there is already no cache entry for this object, there is no
3766
- // purpose in continuing
3767
- if ( !cache[ id ] ) {
3768
- return;
3769
- }
3770
-
3771
- if ( name ) {
3772
-
3773
- thisCache = pvt ? cache[ id ] : cache[ id ].data;
3774
-
3775
- if ( thisCache ) {
3776
-
3777
- // Support array or space separated string names for data keys
3778
- if ( !jQuery.isArray( name ) ) {
3779
-
3780
- // try the string as a key before any manipulation
3781
- if ( name in thisCache ) {
3782
- name = [ name ];
3783
- } else {
3784
-
3785
- // split the camel cased version by spaces unless a key with the spaces exists
3786
- name = jQuery.camelCase( name );
3787
- if ( name in thisCache ) {
3788
- name = [ name ];
3789
- } else {
3790
- name = name.split(" ");
3791
- }
3792
- }
3793
- } else {
3794
- // If "name" is an array of keys...
3795
- // When data is initially created, via ("key", "val") signature,
3796
- // keys will be converted to camelCase.
3797
- // Since there is no way to tell _how_ a key was added, remove
3798
- // both plain key and camelCase key. #12786
3799
- // This will only penalize the array argument path.
3800
- name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3801
- }
3802
-
3803
- i = name.length;
3804
- while ( i-- ) {
3805
- delete thisCache[ name[i] ];
3806
- }
3807
-
3808
- // If there is no data left in the cache, we want to continue
3809
- // and let the cache object itself get destroyed
3810
- if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
3811
- return;
3812
- }
3813
- }
3814
- }
3815
-
3816
- // See jQuery.data for more information
3817
- if ( !pvt ) {
3818
- delete cache[ id ].data;
3819
-
3820
- // Don't destroy the parent cache unless the internal data object
3821
- // had been the only thing left in it
3822
- if ( !isEmptyDataObject( cache[ id ] ) ) {
3823
- return;
3824
- }
3825
- }
3826
-
3827
- // Destroy the cache
3828
- if ( isNode ) {
3829
- jQuery.cleanData( [ elem ], true );
3830
-
3831
- // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
3832
- /* jshint eqeqeq: false */
3833
- } else if ( support.deleteExpando || cache != cache.window ) {
3834
- /* jshint eqeqeq: true */
3835
- delete cache[ id ];
3836
-
3837
- // When all else fails, null
3838
- } else {
3839
- cache[ id ] = null;
3840
- }
3841
- }
3842
-
3843
- jQuery.extend({
3844
- cache: {},
3845
-
3846
- // The following elements (space-suffixed to avoid Object.prototype collisions)
3847
- // throw uncatchable exceptions if you attempt to set expando properties
3848
- noData: {
3849
- "applet ": true,
3850
- "embed ": true,
3851
- // ...but Flash objects (which have this classid) *can* handle expandos
3852
- "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
3853
- },
3854
-
3855
- hasData: function( elem ) {
3856
- elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
3857
- return !!elem && !isEmptyDataObject( elem );
3858
- },
3859
-
3860
- data: function( elem, name, data ) {
3861
- return internalData( elem, name, data );
3862
- },
3863
-
3864
- removeData: function( elem, name ) {
3865
- return internalRemoveData( elem, name );
3866
- },
3867
-
3868
- // For internal use only.
3869
- _data: function( elem, name, data ) {
3870
- return internalData( elem, name, data, true );
3871
- },
3872
-
3873
- _removeData: function( elem, name ) {
3874
- return internalRemoveData( elem, name, true );
3875
- }
3876
- });
3877
-
3878
- jQuery.fn.extend({
3879
- data: function( key, value ) {
3880
- var i, name, data,
3881
- elem = this[0],
3882
- attrs = elem && elem.attributes;
3883
-
3884
- // Special expections of .data basically thwart jQuery.access,
3885
- // so implement the relevant behavior ourselves
3886
-
3887
- // Gets all values
3888
- if ( key === undefined ) {
3889
- if ( this.length ) {
3890
- data = jQuery.data( elem );
3891
-
3892
- if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
3893
- i = attrs.length;
3894
- while ( i-- ) {
3895
- name = attrs[i].name;
3896
-
3897
- if ( name.indexOf("data-") === 0 ) {
3898
- name = jQuery.camelCase( name.slice(5) );
3899
-
3900
- dataAttr( elem, name, data[ name ] );
3901
- }
3902
- }
3903
- jQuery._data( elem, "parsedAttrs", true );
3904
- }
3905
- }
3906
-
3907
- return data;
3908
- }
3909
-
3910
- // Sets multiple values
3911
- if ( typeof key === "object" ) {
3912
- return this.each(function() {
3913
- jQuery.data( this, key );
3914
- });
3915
- }
3916
-
3917
- return arguments.length > 1 ?
3918
-
3919
- // Sets one value
3920
- this.each(function() {
3921
- jQuery.data( this, key, value );
3922
- }) :
3923
-
3924
- // Gets one value
3925
- // Try to fetch any internally stored data first
3926
- elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
3927
- },
3928
-
3929
- removeData: function( key ) {
3930
- return this.each(function() {
3931
- jQuery.removeData( this, key );
3932
- });
3933
- }
3934
- });
3935
-
3936
-
3937
- jQuery.extend({
3938
- queue: function( elem, type, data ) {
3939
- var queue;
3940
-
3941
- if ( elem ) {
3942
- type = ( type || "fx" ) + "queue";
3943
- queue = jQuery._data( elem, type );
3944
-
3945
- // Speed up dequeue by getting out quickly if this is just a lookup
3946
- if ( data ) {
3947
- if ( !queue || jQuery.isArray(data) ) {
3948
- queue = jQuery._data( elem, type, jQuery.makeArray(data) );
3949
- } else {
3950
- queue.push( data );
3951
- }
3952
- }
3953
- return queue || [];
3954
- }
3955
- },
3956
-
3957
- dequeue: function( elem, type ) {
3958
- type = type || "fx";
3959
-
3960
- var queue = jQuery.queue( elem, type ),
3961
- startLength = queue.length,
3962
- fn = queue.shift(),
3963
- hooks = jQuery._queueHooks( elem, type ),
3964
- next = function() {
3965
- jQuery.dequeue( elem, type );
3966
- };
3967
-
3968
- // If the fx queue is dequeued, always remove the progress sentinel
3969
- if ( fn === "inprogress" ) {
3970
- fn = queue.shift();
3971
- startLength--;
3972
- }
3973
-
3974
- if ( fn ) {
3975
-
3976
- // Add a progress sentinel to prevent the fx queue from being
3977
- // automatically dequeued
3978
- if ( type === "fx" ) {
3979
- queue.unshift( "inprogress" );
3980
- }
3981
-
3982
- // clear up the last queue stop function
3983
- delete hooks.stop;
3984
- fn.call( elem, next, hooks );
3985
- }
3986
-
3987
- if ( !startLength && hooks ) {
3988
- hooks.empty.fire();
3989
- }
3990
- },
3991
-
3992
- // not intended for public consumption - generates a queueHooks object, or returns the current one
3993
- _queueHooks: function( elem, type ) {
3994
- var key = type + "queueHooks";
3995
- return jQuery._data( elem, key ) || jQuery._data( elem, key, {
3996
- empty: jQuery.Callbacks("once memory").add(function() {
3997
- jQuery._removeData( elem, type + "queue" );
3998
- jQuery._removeData( elem, key );
3999
- })
4000
- });
4001
- }
4002
- });
4003
-
4004
- jQuery.fn.extend({
4005
- queue: function( type, data ) {
4006
- var setter = 2;
4007
-
4008
- if ( typeof type !== "string" ) {
4009
- data = type;
4010
- type = "fx";
4011
- setter--;
4012
- }
4013
-
4014
- if ( arguments.length < setter ) {
4015
- return jQuery.queue( this[0], type );
4016
- }
4017
-
4018
- return data === undefined ?
4019
- this :
4020
- this.each(function() {
4021
- var queue = jQuery.queue( this, type, data );
4022
-
4023
- // ensure a hooks for this queue
4024
- jQuery._queueHooks( this, type );
4025
-
4026
- if ( type === "fx" && queue[0] !== "inprogress" ) {
4027
- jQuery.dequeue( this, type );
4028
- }
4029
- });
4030
- },
4031
- dequeue: function( type ) {
4032
- return this.each(function() {
4033
- jQuery.dequeue( this, type );
4034
- });
4035
- },
4036
- clearQueue: function( type ) {
4037
- return this.queue( type || "fx", [] );
4038
- },
4039
- // Get a promise resolved when queues of a certain type
4040
- // are emptied (fx is the type by default)
4041
- promise: function( type, obj ) {
4042
- var tmp,
4043
- count = 1,
4044
- defer = jQuery.Deferred(),
4045
- elements = this,
4046
- i = this.length,
4047
- resolve = function() {
4048
- if ( !( --count ) ) {
4049
- defer.resolveWith( elements, [ elements ] );
4050
- }
4051
- };
4052
-
4053
- if ( typeof type !== "string" ) {
4054
- obj = type;
4055
- type = undefined;
4056
- }
4057
- type = type || "fx";
4058
-
4059
- while ( i-- ) {
4060
- tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4061
- if ( tmp && tmp.empty ) {
4062
- count++;
4063
- tmp.empty.add( resolve );
4064
- }
4065
- }
4066
- resolve();
4067
- return defer.promise( obj );
4068
- }
4069
- });
4070
- var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4071
-
4072
- var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4073
-
4074
- var isHidden = function( elem, el ) {
4075
- // isHidden might be called from jQuery#filter function;
4076
- // in that case, element will be second argument
4077
- elem = el || elem;
4078
- return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4079
- };
4080
-
4081
-
4082
-
4083
- // Multifunctional method to get and set values of a collection
4084
- // The value/s can optionally be executed if it's a function
4085
- var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4086
- var i = 0,
4087
- length = elems.length,
4088
- bulk = key == null;
4089
-
4090
- // Sets many values
4091
- if ( jQuery.type( key ) === "object" ) {
4092
- chainable = true;
4093
- for ( i in key ) {
4094
- jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
4095
- }
4096
-
4097
- // Sets one value
4098
- } else if ( value !== undefined ) {
4099
- chainable = true;
4100
-
4101
- if ( !jQuery.isFunction( value ) ) {
4102
- raw = true;
4103
- }
4104
-
4105
- if ( bulk ) {
4106
- // Bulk operations run against the entire set
4107
- if ( raw ) {
4108
- fn.call( elems, value );
4109
- fn = null;
4110
-
4111
- // ...except when executing function values
4112
- } else {
4113
- bulk = fn;
4114
- fn = function( elem, key, value ) {
4115
- return bulk.call( jQuery( elem ), value );
4116
- };
4117
- }
4118
- }
4119
-
4120
- if ( fn ) {
4121
- for ( ; i < length; i++ ) {
4122
- fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
4123
- }
4124
- }
4125
- }
4126
-
4127
- return chainable ?
4128
- elems :
4129
-
4130
- // Gets
4131
- bulk ?
4132
- fn.call( elems ) :
4133
- length ? fn( elems[0], key ) : emptyGet;
4134
- };
4135
- var rcheckableType = (/^(?:checkbox|radio)$/i);
4136
-
4137
-
4138
-
4139
- (function() {
4140
- var fragment = document.createDocumentFragment(),
4141
- div = document.createElement("div"),
4142
- input = document.createElement("input");
4143
-
4144
- // Setup
4145
- div.setAttribute( "className", "t" );
4146
- div.innerHTML = " <link/><table></table><a href='/a'>a</a>";
4147
-
4148
- // IE strips leading whitespace when .innerHTML is used
4149
- support.leadingWhitespace = div.firstChild.nodeType === 3;
4150
-
4151
- // Make sure that tbody elements aren't automatically inserted
4152
- // IE will insert them into empty tables
4153
- support.tbody = !div.getElementsByTagName( "tbody" ).length;
4154
-
4155
- // Make sure that link elements get serialized correctly by innerHTML
4156
- // This requires a wrapper element in IE
4157
- support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4158
-
4159
- // Makes sure cloning an html5 element does not cause problems
4160
- // Where outerHTML is undefined, this still works
4161
- support.html5Clone =
4162
- document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4163
-
4164
- // Check if a disconnected checkbox will retain its checked
4165
- // value of true after appended to the DOM (IE6/7)
4166
- input.type = "checkbox";
4167
- input.checked = true;
4168
- fragment.appendChild( input );
4169
- support.appendChecked = input.checked;
4170
-
4171
- // Make sure textarea (and checkbox) defaultValue is properly cloned
4172
- // Support: IE6-IE11+
4173
- div.innerHTML = "<textarea>x</textarea>";
4174
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4175
-
4176
- // #11217 - WebKit loses check when the name is after the checked attribute
4177
- fragment.appendChild( div );
4178
- div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
4179
-
4180
- // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4181
- // old WebKit doesn't clone checked state correctly in fragments
4182
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4183
-
4184
- // Support: IE<9
4185
- // Opera does not clone events (and typeof div.attachEvent === undefined).
4186
- // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
4187
- support.noCloneEvent = true;
4188
- if ( div.attachEvent ) {
4189
- div.attachEvent( "onclick", function() {
4190
- support.noCloneEvent = false;
4191
- });
4192
-
4193
- div.cloneNode( true ).click();
4194
- }
4195
-
4196
- // Execute the test only if not already executed in another module.
4197
- if (support.deleteExpando == null) {
4198
- // Support: IE<9
4199
- support.deleteExpando = true;
4200
- try {
4201
- delete div.test;
4202
- } catch( e ) {
4203
- support.deleteExpando = false;
4204
- }
4205
- }
4206
-
4207
- // Null elements to avoid leaks in IE.
4208
- fragment = div = input = null;
4209
- })();
4210
-
4211
-
4212
- (function() {
4213
- var i, eventName,
4214
- div = document.createElement( "div" );
4215
-
4216
- // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
4217
- for ( i in { submit: true, change: true, focusin: true }) {
4218
- eventName = "on" + i;
4219
-
4220
- if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
4221
- // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4222
- div.setAttribute( eventName, "t" );
4223
- support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
4224
- }
4225
- }
4226
-
4227
- // Null elements to avoid leaks in IE.
4228
- div = null;
4229
- })();
4230
-
4231
-
4232
- var rformElems = /^(?:input|select|textarea)$/i,
4233
- rkeyEvent = /^key/,
4234
- rmouseEvent = /^(?:mouse|contextmenu)|click/,
4235
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4236
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4237
-
4238
- function returnTrue() {
4239
- return true;
4240
- }
4241
-
4242
- function returnFalse() {
4243
- return false;
4244
- }
4245
-
4246
- function safeActiveElement() {
4247
- try {
4248
- return document.activeElement;
4249
- } catch ( err ) { }
4250
- }
4251
-
4252
- /*
4253
- * Helper functions for managing events -- not part of the public interface.
4254
- * Props to Dean Edwards' addEvent library for many of the ideas.
4255
- */
4256
- jQuery.event = {
4257
-
4258
- global: {},
4259
-
4260
- add: function( elem, types, handler, data, selector ) {
4261
- var tmp, events, t, handleObjIn,
4262
- special, eventHandle, handleObj,
4263
- handlers, type, namespaces, origType,
4264
- elemData = jQuery._data( elem );
4265
-
4266
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
4267
- if ( !elemData ) {
4268
- return;
4269
- }
4270
-
4271
- // Caller can pass in an object of custom data in lieu of the handler
4272
- if ( handler.handler ) {
4273
- handleObjIn = handler;
4274
- handler = handleObjIn.handler;
4275
- selector = handleObjIn.selector;
4276
- }
4277
-
4278
- // Make sure that the handler has a unique ID, used to find/remove it later
4279
- if ( !handler.guid ) {
4280
- handler.guid = jQuery.guid++;
4281
- }
4282
-
4283
- // Init the element's event structure and main handler, if this is the first
4284
- if ( !(events = elemData.events) ) {
4285
- events = elemData.events = {};
4286
- }
4287
- if ( !(eventHandle = elemData.handle) ) {
4288
- eventHandle = elemData.handle = function( e ) {
4289
- // Discard the second event of a jQuery.event.trigger() and
4290
- // when an event is called after a page has unloaded
4291
- return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
4292
- jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4293
- undefined;
4294
- };
4295
- // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
4296
- eventHandle.elem = elem;
4297
- }
4298
-
4299
- // Handle multiple events separated by a space
4300
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
4301
- t = types.length;
4302
- while ( t-- ) {
4303
- tmp = rtypenamespace.exec( types[t] ) || [];
4304
- type = origType = tmp[1];
4305
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
4306
-
4307
- // There *must* be a type, no attaching namespace-only handlers
4308
- if ( !type ) {
4309
- continue;
4310
- }
4311
-
4312
- // If event changes its type, use the special event handlers for the changed type
4313
- special = jQuery.event.special[ type ] || {};
4314
-
4315
- // If selector defined, determine special event api type, otherwise given type
4316
- type = ( selector ? special.delegateType : special.bindType ) || type;
4317
-
4318
- // Update special based on newly reset type
4319
- special = jQuery.event.special[ type ] || {};
4320
-
4321
- // handleObj is passed to all event handlers
4322
- handleObj = jQuery.extend({
4323
- type: type,
4324
- origType: origType,
4325
- data: data,
4326
- handler: handler,
4327
- guid: handler.guid,
4328
- selector: selector,
4329
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4330
- namespace: namespaces.join(".")
4331
- }, handleObjIn );
4332
-
4333
- // Init the event handler queue if we're the first
4334
- if ( !(handlers = events[ type ]) ) {
4335
- handlers = events[ type ] = [];
4336
- handlers.delegateCount = 0;
4337
-
4338
- // Only use addEventListener/attachEvent if the special events handler returns false
4339
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4340
- // Bind the global event handler to the element
4341
- if ( elem.addEventListener ) {
4342
- elem.addEventListener( type, eventHandle, false );
4343
-
4344
- } else if ( elem.attachEvent ) {
4345
- elem.attachEvent( "on" + type, eventHandle );
4346
- }
4347
- }
4348
- }
4349
-
4350
- if ( special.add ) {
4351
- special.add.call( elem, handleObj );
4352
-
4353
- if ( !handleObj.handler.guid ) {
4354
- handleObj.handler.guid = handler.guid;
4355
- }
4356
- }
4357
-
4358
- // Add to the element's handler list, delegates in front
4359
- if ( selector ) {
4360
- handlers.splice( handlers.delegateCount++, 0, handleObj );
4361
- } else {
4362
- handlers.push( handleObj );
4363
- }
4364
-
4365
- // Keep track of which events have ever been used, for event optimization
4366
- jQuery.event.global[ type ] = true;
4367
- }
4368
-
4369
- // Nullify elem to prevent memory leaks in IE
4370
- elem = null;
4371
- },
4372
-
4373
- // Detach an event or set of events from an element
4374
- remove: function( elem, types, handler, selector, mappedTypes ) {
4375
- var j, handleObj, tmp,
4376
- origCount, t, events,
4377
- special, handlers, type,
4378
- namespaces, origType,
4379
- elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4380
-
4381
- if ( !elemData || !(events = elemData.events) ) {
4382
- return;
4383
- }
4384
-
4385
- // Once for each type.namespace in types; type may be omitted
4386
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
4387
- t = types.length;
4388
- while ( t-- ) {
4389
- tmp = rtypenamespace.exec( types[t] ) || [];
4390
- type = origType = tmp[1];
4391
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
4392
-
4393
- // Unbind all events (on this namespace, if provided) for the element
4394
- if ( !type ) {
4395
- for ( type in events ) {
4396
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4397
- }
4398
- continue;
4399
- }
4400
-
4401
- special = jQuery.event.special[ type ] || {};
4402
- type = ( selector ? special.delegateType : special.bindType ) || type;
4403
- handlers = events[ type ] || [];
4404
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4405
-
4406
- // Remove matching events
4407
- origCount = j = handlers.length;
4408
- while ( j-- ) {
4409
- handleObj = handlers[ j ];
4410
-
4411
- if ( ( mappedTypes || origType === handleObj.origType ) &&
4412
- ( !handler || handler.guid === handleObj.guid ) &&
4413
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
4414
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4415
- handlers.splice( j, 1 );
4416
-
4417
- if ( handleObj.selector ) {
4418
- handlers.delegateCount--;
4419
- }
4420
- if ( special.remove ) {
4421
- special.remove.call( elem, handleObj );
4422
- }
4423
- }
4424
- }
4425
-
4426
- // Remove generic event handler if we removed something and no more handlers exist
4427
- // (avoids potential for endless recursion during removal of special event handlers)
4428
- if ( origCount && !handlers.length ) {
4429
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4430
- jQuery.removeEvent( elem, type, elemData.handle );
4431
- }
4432
-
4433
- delete events[ type ];
4434
- }
4435
- }
4436
-
4437
- // Remove the expando if it's no longer used
4438
- if ( jQuery.isEmptyObject( events ) ) {
4439
- delete elemData.handle;
4440
-
4441
- // removeData also checks for emptiness and clears the expando if empty
4442
- // so use it instead of delete
4443
- jQuery._removeData( elem, "events" );
4444
- }
4445
- },
4446
-
4447
- trigger: function( event, data, elem, onlyHandlers ) {
4448
- var handle, ontype, cur,
4449
- bubbleType, special, tmp, i,
4450
- eventPath = [ elem || document ],
4451
- type = hasOwn.call( event, "type" ) ? event.type : event,
4452
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4453
-
4454
- cur = tmp = elem = elem || document;
4455
-
4456
- // Don't do events on text and comment nodes
4457
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4458
- return;
4459
- }
4460
-
4461
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
4462
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4463
- return;
4464
- }
4465
-
4466
- if ( type.indexOf(".") >= 0 ) {
4467
- // Namespaced trigger; create a regexp to match event type in handle()
4468
- namespaces = type.split(".");
4469
- type = namespaces.shift();
4470
- namespaces.sort();
4471
- }
4472
- ontype = type.indexOf(":") < 0 && "on" + type;
4473
-
4474
- // Caller can pass in a jQuery.Event object, Object, or just an event type string
4475
- event = event[ jQuery.expando ] ?
4476
- event :
4477
- new jQuery.Event( type, typeof event === "object" && event );
4478
-
4479
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4480
- event.isTrigger = onlyHandlers ? 2 : 3;
4481
- event.namespace = namespaces.join(".");
4482
- event.namespace_re = event.namespace ?
4483
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4484
- null;
4485
-
4486
- // Clean up the event in case it is being reused
4487
- event.result = undefined;
4488
- if ( !event.target ) {
4489
- event.target = elem;
4490
- }
4491
-
4492
- // Clone any incoming data and prepend the event, creating the handler arg list
4493
- data = data == null ?
4494
- [ event ] :
4495
- jQuery.makeArray( data, [ event ] );
4496
-
4497
- // Allow special events to draw outside the lines
4498
- special = jQuery.event.special[ type ] || {};
4499
- if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4500
- return;
4501
- }
4502
-
4503
- // Determine event propagation path in advance, per W3C events spec (#9951)
4504
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4505
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4506
-
4507
- bubbleType = special.delegateType || type;
4508
- if ( !rfocusMorph.test( bubbleType + type ) ) {
4509
- cur = cur.parentNode;
4510
- }
4511
- for ( ; cur; cur = cur.parentNode ) {
4512
- eventPath.push( cur );
4513
- tmp = cur;
4514
- }
4515
-
4516
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
4517
- if ( tmp === (elem.ownerDocument || document) ) {
4518
- eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4519
- }
4520
- }
4521
-
4522
- // Fire handlers on the event path
4523
- i = 0;
4524
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4525
-
4526
- event.type = i > 1 ?
4527
- bubbleType :
4528
- special.bindType || type;
4529
-
4530
- // jQuery handler
4531
- handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
4532
- if ( handle ) {
4533
- handle.apply( cur, data );
4534
- }
4535
-
4536
- // Native handler
4537
- handle = ontype && cur[ ontype ];
4538
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4539
- event.result = handle.apply( cur, data );
4540
- if ( event.result === false ) {
4541
- event.preventDefault();
4542
- }
4543
- }
4544
- }
4545
- event.type = type;
4546
-
4547
- // If nobody prevented the default action, do it now
4548
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4549
-
4550
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4551
- jQuery.acceptData( elem ) ) {
4552
-
4553
- // Call a native DOM method on the target with the same name name as the event.
4554
- // Can't use an .isFunction() check here because IE6/7 fails that test.
4555
- // Don't do default actions on window, that's where global variables be (#6170)
4556
- if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
4557
-
4558
- // Don't re-trigger an onFOO event when we call its FOO() method
4559
- tmp = elem[ ontype ];
4560
-
4561
- if ( tmp ) {
4562
- elem[ ontype ] = null;
4563
- }
4564
-
4565
- // Prevent re-triggering of the same event, since we already bubbled it above
4566
- jQuery.event.triggered = type;
4567
- try {
4568
- elem[ type ]();
4569
- } catch ( e ) {
4570
- // IE<9 dies on focus/blur to hidden element (#1486,#12518)
4571
- // only reproducible on winXP IE8 native, not IE9 in IE8 mode
4572
- }
4573
- jQuery.event.triggered = undefined;
4574
-
4575
- if ( tmp ) {
4576
- elem[ ontype ] = tmp;
4577
- }
4578
- }
4579
- }
4580
- }
4581
-
4582
- return event.result;
4583
- },
4584
-
4585
- dispatch: function( event ) {
4586
-
4587
- // Make a writable jQuery.Event from the native event object
4588
- event = jQuery.event.fix( event );
4589
-
4590
- var i, ret, handleObj, matched, j,
4591
- handlerQueue = [],
4592
- args = slice.call( arguments ),
4593
- handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
4594
- special = jQuery.event.special[ event.type ] || {};
4595
-
4596
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
4597
- args[0] = event;
4598
- event.delegateTarget = this;
4599
-
4600
- // Call the preDispatch hook for the mapped type, and let it bail if desired
4601
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4602
- return;
4603
- }
4604
-
4605
- // Determine handlers
4606
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4607
-
4608
- // Run delegates first; they may want to stop propagation beneath us
4609
- i = 0;
4610
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4611
- event.currentTarget = matched.elem;
4612
-
4613
- j = 0;
4614
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4615
-
4616
- // Triggered event must either 1) have no namespace, or
4617
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4618
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4619
-
4620
- event.handleObj = handleObj;
4621
- event.data = handleObj.data;
4622
-
4623
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4624
- .apply( matched.elem, args );
4625
-
4626
- if ( ret !== undefined ) {
4627
- if ( (event.result = ret) === false ) {
4628
- event.preventDefault();
4629
- event.stopPropagation();
4630
- }
4631
- }
4632
- }
4633
- }
4634
- }
4635
-
4636
- // Call the postDispatch hook for the mapped type
4637
- if ( special.postDispatch ) {
4638
- special.postDispatch.call( this, event );
4639
- }
4640
-
4641
- return event.result;
4642
- },
4643
-
4644
- handlers: function( event, handlers ) {
4645
- var sel, handleObj, matches, i,
4646
- handlerQueue = [],
4647
- delegateCount = handlers.delegateCount,
4648
- cur = event.target;
4649
-
4650
- // Find delegate handlers
4651
- // Black-hole SVG <use> instance trees (#13180)
4652
- // Avoid non-left-click bubbling in Firefox (#3861)
4653
- if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4654
-
4655
- /* jshint eqeqeq: false */
4656
- for ( ; cur != this; cur = cur.parentNode || this ) {
4657
- /* jshint eqeqeq: true */
4658
-
4659
- // Don't check non-elements (#13208)
4660
- // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4661
- if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
4662
- matches = [];
4663
- for ( i = 0; i < delegateCount; i++ ) {
4664
- handleObj = handlers[ i ];
4665
-
4666
- // Don't conflict with Object.prototype properties (#13203)
4667
- sel = handleObj.selector + " ";
4668
-
4669
- if ( matches[ sel ] === undefined ) {
4670
- matches[ sel ] = handleObj.needsContext ?
4671
- jQuery( sel, this ).index( cur ) >= 0 :
4672
- jQuery.find( sel, this, null, [ cur ] ).length;
4673
- }
4674
- if ( matches[ sel ] ) {
4675
- matches.push( handleObj );
4676
- }
4677
- }
4678
- if ( matches.length ) {
4679
- handlerQueue.push({ elem: cur, handlers: matches });
4680
- }
4681
- }
4682
- }
4683
- }
4684
-
4685
- // Add the remaining (directly-bound) handlers
4686
- if ( delegateCount < handlers.length ) {
4687
- handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4688
- }
4689
-
4690
- return handlerQueue;
4691
- },
4692
-
4693
- fix: function( event ) {
4694
- if ( event[ jQuery.expando ] ) {
4695
- return event;
4696
- }
4697
-
4698
- // Create a writable copy of the event object and normalize some properties
4699
- var i, prop, copy,
4700
- type = event.type,
4701
- originalEvent = event,
4702
- fixHook = this.fixHooks[ type ];
4703
-
4704
- if ( !fixHook ) {
4705
- this.fixHooks[ type ] = fixHook =
4706
- rmouseEvent.test( type ) ? this.mouseHooks :
4707
- rkeyEvent.test( type ) ? this.keyHooks :
4708
- {};
4709
- }
4710
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4711
-
4712
- event = new jQuery.Event( originalEvent );
4713
-
4714
- i = copy.length;
4715
- while ( i-- ) {
4716
- prop = copy[ i ];
4717
- event[ prop ] = originalEvent[ prop ];
4718
- }
4719
-
4720
- // Support: IE<9
4721
- // Fix target property (#1925)
4722
- if ( !event.target ) {
4723
- event.target = originalEvent.srcElement || document;
4724
- }
4725
-
4726
- // Support: Chrome 23+, Safari?
4727
- // Target should not be a text node (#504, #13143)
4728
- if ( event.target.nodeType === 3 ) {
4729
- event.target = event.target.parentNode;
4730
- }
4731
-
4732
- // Support: IE<9
4733
- // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
4734
- event.metaKey = !!event.metaKey;
4735
-
4736
- return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4737
- },
4738
-
4739
- // Includes some event props shared by KeyEvent and MouseEvent
4740
- props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4741
-
4742
- fixHooks: {},
4743
-
4744
- keyHooks: {
4745
- props: "char charCode key keyCode".split(" "),
4746
- filter: function( event, original ) {
4747
-
4748
- // Add which for key events
4749
- if ( event.which == null ) {
4750
- event.which = original.charCode != null ? original.charCode : original.keyCode;
4751
- }
4752
-
4753
- return event;
4754
- }
4755
- },
4756
-
4757
- mouseHooks: {
4758
- props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4759
- filter: function( event, original ) {
4760
- var body, eventDoc, doc,
4761
- button = original.button,
4762
- fromElement = original.fromElement;
4763
-
4764
- // Calculate pageX/Y if missing and clientX/Y available
4765
- if ( event.pageX == null && original.clientX != null ) {
4766
- eventDoc = event.target.ownerDocument || document;
4767
- doc = eventDoc.documentElement;
4768
- body = eventDoc.body;
4769
-
4770
- event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4771
- event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
4772
- }
4773
-
4774
- // Add relatedTarget, if necessary
4775
- if ( !event.relatedTarget && fromElement ) {
4776
- event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
4777
- }
4778
-
4779
- // Add which for click: 1 === left; 2 === middle; 3 === right
4780
- // Note: button is not normalized, so don't use it
4781
- if ( !event.which && button !== undefined ) {
4782
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4783
- }
4784
-
4785
- return event;
4786
- }
4787
- },
4788
-
4789
- special: {
4790
- load: {
4791
- // Prevent triggered image.load events from bubbling to window.load
4792
- noBubble: true
4793
- },
4794
- focus: {
4795
- // Fire native event if possible so blur/focus sequence is correct
4796
- trigger: function() {
4797
- if ( this !== safeActiveElement() && this.focus ) {
4798
- try {
4799
- this.focus();
4800
- return false;
4801
- } catch ( e ) {
4802
- // Support: IE<9
4803
- // If we error on focus to hidden element (#1486, #12518),
4804
- // let .trigger() run the handlers
4805
- }
4806
- }
4807
- },
4808
- delegateType: "focusin"
4809
- },
4810
- blur: {
4811
- trigger: function() {
4812
- if ( this === safeActiveElement() && this.blur ) {
4813
- this.blur();
4814
- return false;
4815
- }
4816
- },
4817
- delegateType: "focusout"
4818
- },
4819
- click: {
4820
- // For checkbox, fire native event so checked state will be right
4821
- trigger: function() {
4822
- if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
4823
- this.click();
4824
- return false;
4825
- }
4826
- },
4827
-
4828
- // For cross-browser consistency, don't fire native .click() on links
4829
- _default: function( event ) {
4830
- return jQuery.nodeName( event.target, "a" );
4831
- }
4832
- },
4833
-
4834
- beforeunload: {
4835
- postDispatch: function( event ) {
4836
-
4837
- // Even when returnValue equals to undefined Firefox will still show alert
4838
- if ( event.result !== undefined ) {
4839
- event.originalEvent.returnValue = event.result;
4840
- }
4841
- }
4842
- }
4843
- },
4844
-
4845
- simulate: function( type, elem, event, bubble ) {
4846
- // Piggyback on a donor event to simulate a different one.
4847
- // Fake originalEvent to avoid donor's stopPropagation, but if the
4848
- // simulated event prevents default then we do the same on the donor.
4849
- var e = jQuery.extend(
4850
- new jQuery.Event(),
4851
- event,
4852
- {
4853
- type: type,
4854
- isSimulated: true,
4855
- originalEvent: {}
4856
- }
4857
- );
4858
- if ( bubble ) {
4859
- jQuery.event.trigger( e, null, elem );
4860
- } else {
4861
- jQuery.event.dispatch.call( elem, e );
4862
- }
4863
- if ( e.isDefaultPrevented() ) {
4864
- event.preventDefault();
4865
- }
4866
- }
4867
- };
4868
-
4869
- jQuery.removeEvent = document.removeEventListener ?
4870
- function( elem, type, handle ) {
4871
- if ( elem.removeEventListener ) {
4872
- elem.removeEventListener( type, handle, false );
4873
- }
4874
- } :
4875
- function( elem, type, handle ) {
4876
- var name = "on" + type;
4877
-
4878
- if ( elem.detachEvent ) {
4879
-
4880
- // #8545, #7054, preventing memory leaks for custom events in IE6-8
4881
- // detachEvent needed property on element, by name of that event, to properly expose it to GC
4882
- if ( typeof elem[ name ] === strundefined ) {
4883
- elem[ name ] = null;
4884
- }
4885
-
4886
- elem.detachEvent( name, handle );
4887
- }
4888
- };
4889
-
4890
- jQuery.Event = function( src, props ) {
4891
- // Allow instantiation without the 'new' keyword
4892
- if ( !(this instanceof jQuery.Event) ) {
4893
- return new jQuery.Event( src, props );
4894
- }
4895
-
4896
- // Event object
4897
- if ( src && src.type ) {
4898
- this.originalEvent = src;
4899
- this.type = src.type;
4900
-
4901
- // Events bubbling up the document may have been marked as prevented
4902
- // by a handler lower down the tree; reflect the correct value.
4903
- this.isDefaultPrevented = src.defaultPrevented ||
4904
- src.defaultPrevented === undefined && (
4905
- // Support: IE < 9
4906
- src.returnValue === false ||
4907
- // Support: Android < 4.0
4908
- src.getPreventDefault && src.getPreventDefault() ) ?
4909
- returnTrue :
4910
- returnFalse;
4911
-
4912
- // Event type
4913
- } else {
4914
- this.type = src;
4915
- }
4916
-
4917
- // Put explicitly provided properties onto the event object
4918
- if ( props ) {
4919
- jQuery.extend( this, props );
4920
- }
4921
-
4922
- // Create a timestamp if incoming event doesn't have one
4923
- this.timeStamp = src && src.timeStamp || jQuery.now();
4924
-
4925
- // Mark it as fixed
4926
- this[ jQuery.expando ] = true;
4927
- };
4928
-
4929
- // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4930
- // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4931
- jQuery.Event.prototype = {
4932
- isDefaultPrevented: returnFalse,
4933
- isPropagationStopped: returnFalse,
4934
- isImmediatePropagationStopped: returnFalse,
4935
-
4936
- preventDefault: function() {
4937
- var e = this.originalEvent;
4938
-
4939
- this.isDefaultPrevented = returnTrue;
4940
- if ( !e ) {
4941
- return;
4942
- }
4943
-
4944
- // If preventDefault exists, run it on the original event
4945
- if ( e.preventDefault ) {
4946
- e.preventDefault();
4947
-
4948
- // Support: IE
4949
- // Otherwise set the returnValue property of the original event to false
4950
- } else {
4951
- e.returnValue = false;
4952
- }
4953
- },
4954
- stopPropagation: function() {
4955
- var e = this.originalEvent;
4956
-
4957
- this.isPropagationStopped = returnTrue;
4958
- if ( !e ) {
4959
- return;
4960
- }
4961
- // If stopPropagation exists, run it on the original event
4962
- if ( e.stopPropagation ) {
4963
- e.stopPropagation();
4964
- }
4965
-
4966
- // Support: IE
4967
- // Set the cancelBubble property of the original event to true
4968
- e.cancelBubble = true;
4969
- },
4970
- stopImmediatePropagation: function() {
4971
- this.isImmediatePropagationStopped = returnTrue;
4972
- this.stopPropagation();
4973
- }
4974
- };
4975
-
4976
- // Create mouseenter/leave events using mouseover/out and event-time checks
4977
- jQuery.each({
4978
- mouseenter: "mouseover",
4979
- mouseleave: "mouseout"
4980
- }, function( orig, fix ) {
4981
- jQuery.event.special[ orig ] = {
4982
- delegateType: fix,
4983
- bindType: fix,
4984
-
4985
- handle: function( event ) {
4986
- var ret,
4987
- target = this,
4988
- related = event.relatedTarget,
4989
- handleObj = event.handleObj;
4990
-
4991
- // For mousenter/leave call the handler if related is outside the target.
4992
- // NB: No relatedTarget if the mouse left/entered the browser window
4993
- if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4994
- event.type = handleObj.origType;
4995
- ret = handleObj.handler.apply( this, arguments );
4996
- event.type = fix;
4997
- }
4998
- return ret;
4999
- }
5000
- };
5001
- });
5002
-
5003
- // IE submit delegation
5004
- if ( !support.submitBubbles ) {
5005
-
5006
- jQuery.event.special.submit = {
5007
- setup: function() {
5008
- // Only need this for delegated form submit events
5009
- if ( jQuery.nodeName( this, "form" ) ) {
5010
- return false;
5011
- }
5012
-
5013
- // Lazy-add a submit handler when a descendant form may potentially be submitted
5014
- jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5015
- // Node name check avoids a VML-related crash in IE (#9807)
5016
- var elem = e.target,
5017
- form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
5018
- if ( form && !jQuery._data( form, "submitBubbles" ) ) {
5019
- jQuery.event.add( form, "submit._submit", function( event ) {
5020
- event._submit_bubble = true;
5021
- });
5022
- jQuery._data( form, "submitBubbles", true );
5023
- }
5024
- });
5025
- // return undefined since we don't need an event listener
5026
- },
5027
-
5028
- postDispatch: function( event ) {
5029
- // If form was submitted by the user, bubble the event up the tree
5030
- if ( event._submit_bubble ) {
5031
- delete event._submit_bubble;
5032
- if ( this.parentNode && !event.isTrigger ) {
5033
- jQuery.event.simulate( "submit", this.parentNode, event, true );
5034
- }
5035
- }
5036
- },
5037
-
5038
- teardown: function() {
5039
- // Only need this for delegated form submit events
5040
- if ( jQuery.nodeName( this, "form" ) ) {
5041
- return false;
5042
- }
5043
-
5044
- // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5045
- jQuery.event.remove( this, "._submit" );
5046
- }
5047
- };
5048
- }
5049
-
5050
- // IE change delegation and checkbox/radio fix
5051
- if ( !support.changeBubbles ) {
5052
-
5053
- jQuery.event.special.change = {
5054
-
5055
- setup: function() {
5056
-
5057
- if ( rformElems.test( this.nodeName ) ) {
5058
- // IE doesn't fire change on a check/radio until blur; trigger it on click
5059
- // after a propertychange. Eat the blur-change in special.change.handle.
5060
- // This still fires onchange a second time for check/radio after blur.
5061
- if ( this.type === "checkbox" || this.type === "radio" ) {
5062
- jQuery.event.add( this, "propertychange._change", function( event ) {
5063
- if ( event.originalEvent.propertyName === "checked" ) {
5064
- this._just_changed = true;
5065
- }
5066
- });
5067
- jQuery.event.add( this, "click._change", function( event ) {
5068
- if ( this._just_changed && !event.isTrigger ) {
5069
- this._just_changed = false;
5070
- }
5071
- // Allow triggered, simulated change events (#11500)
5072
- jQuery.event.simulate( "change", this, event, true );
5073
- });
5074
- }
5075
- return false;
5076
- }
5077
- // Delegated event; lazy-add a change handler on descendant inputs
5078
- jQuery.event.add( this, "beforeactivate._change", function( e ) {
5079
- var elem = e.target;
5080
-
5081
- if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
5082
- jQuery.event.add( elem, "change._change", function( event ) {
5083
- if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5084
- jQuery.event.simulate( "change", this.parentNode, event, true );
5085
- }
5086
- });
5087
- jQuery._data( elem, "changeBubbles", true );
5088
- }
5089
- });
5090
- },
5091
-
5092
- handle: function( event ) {
5093
- var elem = event.target;
5094
-
5095
- // Swallow native change events from checkbox/radio, we already triggered them above
5096
- if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
5097
- return event.handleObj.handler.apply( this, arguments );
5098
- }
5099
- },
5100
-
5101
- teardown: function() {
5102
- jQuery.event.remove( this, "._change" );
5103
-
5104
- return !rformElems.test( this.nodeName );
5105
- }
5106
- };
5107
- }
5108
-
5109
- // Create "bubbling" focus and blur events
5110
- if ( !support.focusinBubbles ) {
5111
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5112
-
5113
- // Attach a single capturing handler on the document while someone wants focusin/focusout
5114
- var handler = function( event ) {
5115
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
5116
- };
5117
-
5118
- jQuery.event.special[ fix ] = {
5119
- setup: function() {
5120
- var doc = this.ownerDocument || this,
5121
- attaches = jQuery._data( doc, fix );
5122
-
5123
- if ( !attaches ) {
5124
- doc.addEventListener( orig, handler, true );
5125
- }
5126
- jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5127
- },
5128
- teardown: function() {
5129
- var doc = this.ownerDocument || this,
5130
- attaches = jQuery._data( doc, fix ) - 1;
5131
-
5132
- if ( !attaches ) {
5133
- doc.removeEventListener( orig, handler, true );
5134
- jQuery._removeData( doc, fix );
5135
- } else {
5136
- jQuery._data( doc, fix, attaches );
5137
- }
5138
- }
5139
- };
5140
- });
5141
- }
5142
-
5143
- jQuery.fn.extend({
5144
-
5145
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
5146
- var type, origFn;
5147
-
5148
- // Types can be a map of types/handlers
5149
- if ( typeof types === "object" ) {
5150
- // ( types-Object, selector, data )
5151
- if ( typeof selector !== "string" ) {
5152
- // ( types-Object, data )
5153
- data = data || selector;
5154
- selector = undefined;
5155
- }
5156
- for ( type in types ) {
5157
- this.on( type, selector, data, types[ type ], one );
5158
- }
5159
- return this;
5160
- }
5161
-
5162
- if ( data == null && fn == null ) {
5163
- // ( types, fn )
5164
- fn = selector;
5165
- data = selector = undefined;
5166
- } else if ( fn == null ) {
5167
- if ( typeof selector === "string" ) {
5168
- // ( types, selector, fn )
5169
- fn = data;
5170
- data = undefined;
5171
- } else {
5172
- // ( types, data, fn )
5173
- fn = data;
5174
- data = selector;
5175
- selector = undefined;
5176
- }
5177
- }
5178
- if ( fn === false ) {
5179
- fn = returnFalse;
5180
- } else if ( !fn ) {
5181
- return this;
5182
- }
5183
-
5184
- if ( one === 1 ) {
5185
- origFn = fn;
5186
- fn = function( event ) {
5187
- // Can use an empty set, since event contains the info
5188
- jQuery().off( event );
5189
- return origFn.apply( this, arguments );
5190
- };
5191
- // Use same guid so caller can remove using origFn
5192
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5193
- }
5194
- return this.each( function() {
5195
- jQuery.event.add( this, types, fn, data, selector );
5196
- });
5197
- },
5198
- one: function( types, selector, data, fn ) {
5199
- return this.on( types, selector, data, fn, 1 );
5200
- },
5201
- off: function( types, selector, fn ) {
5202
- var handleObj, type;
5203
- if ( types && types.preventDefault && types.handleObj ) {
5204
- // ( event ) dispatched jQuery.Event
5205
- handleObj = types.handleObj;
5206
- jQuery( types.delegateTarget ).off(
5207
- handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
5208
- handleObj.selector,
5209
- handleObj.handler
5210
- );
5211
- return this;
5212
- }
5213
- if ( typeof types === "object" ) {
5214
- // ( types-object [, selector] )
5215
- for ( type in types ) {
5216
- this.off( type, selector, types[ type ] );
5217
- }
5218
- return this;
5219
- }
5220
- if ( selector === false || typeof selector === "function" ) {
5221
- // ( types [, fn] )
5222
- fn = selector;
5223
- selector = undefined;
5224
- }
5225
- if ( fn === false ) {
5226
- fn = returnFalse;
5227
- }
5228
- return this.each(function() {
5229
- jQuery.event.remove( this, types, fn, selector );
5230
- });
5231
- },
5232
-
5233
- trigger: function( type, data ) {
5234
- return this.each(function() {
5235
- jQuery.event.trigger( type, data, this );
5236
- });
5237
- },
5238
- triggerHandler: function( type, data ) {
5239
- var elem = this[0];
5240
- if ( elem ) {
5241
- return jQuery.event.trigger( type, data, elem, true );
5242
- }
5243
- }
5244
- });
5245
-
5246
-
5247
- function createSafeFragment( document ) {
5248
- var list = nodeNames.split( "|" ),
5249
- safeFrag = document.createDocumentFragment();
5250
-
5251
- if ( safeFrag.createElement ) {
5252
- while ( list.length ) {
5253
- safeFrag.createElement(
5254
- list.pop()
5255
- );
5256
- }
5257
- }
5258
- return safeFrag;
5259
- }
5260
-
5261
- var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5262
- "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5263
- rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5264
- rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5265
- rleadingWhitespace = /^\s+/,
5266
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5267
- rtagName = /<([\w:]+)/,
5268
- rtbody = /<tbody/i,
5269
- rhtml = /<|&#?\w+;/,
5270
- rnoInnerhtml = /<(?:script|style|link)/i,
5271
- // checked="checked" or checked
5272
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5273
- rscriptType = /^$|\/(?:java|ecma)script/i,
5274
- rscriptTypeMasked = /^true\/(.*)/,
5275
- rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5276
-
5277
- // We have to close these tags to support XHTML (#13200)
5278
- wrapMap = {
5279
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
5280
- legend: [ 1, "<fieldset>", "</fieldset>" ],
5281
- area: [ 1, "<map>", "</map>" ],
5282
- param: [ 1, "<object>", "</object>" ],
5283
- thead: [ 1, "<table>", "</table>" ],
5284
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5285
- col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5286
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5287
-
5288
- // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5289
- // unless wrapped in a div with non-breaking characters in front of it.
5290
- _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
5291
- },
5292
- safeFragment = createSafeFragment( document ),
5293
- fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5294
-
5295
- wrapMap.optgroup = wrapMap.option;
5296
- wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5297
- wrapMap.th = wrapMap.td;
5298
-
5299
- function getAll( context, tag ) {
5300
- var elems, elem,
5301
- i = 0,
5302
- found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
5303
- typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
5304
- undefined;
5305
-
5306
- if ( !found ) {
5307
- for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
5308
- if ( !tag || jQuery.nodeName( elem, tag ) ) {
5309
- found.push( elem );
5310
- } else {
5311
- jQuery.merge( found, getAll( elem, tag ) );
5312
- }
5313
- }
5314
- }
5315
-
5316
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5317
- jQuery.merge( [ context ], found ) :
5318
- found;
5319
- }
5320
-
5321
- // Used in buildFragment, fixes the defaultChecked property
5322
- function fixDefaultChecked( elem ) {
5323
- if ( rcheckableType.test( elem.type ) ) {
5324
- elem.defaultChecked = elem.checked;
5325
- }
5326
- }
5327
-
5328
- // Support: IE<8
5329
- // Manipulating tables requires a tbody
5330
- function manipulationTarget( elem, content ) {
5331
- return jQuery.nodeName( elem, "table" ) &&
5332
- jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5333
-
5334
- elem.getElementsByTagName("tbody")[0] ||
5335
- elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
5336
- elem;
5337
- }
5338
-
5339
- // Replace/restore the type attribute of script elements for safe DOM manipulation
5340
- function disableScript( elem ) {
5341
- elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
5342
- return elem;
5343
- }
5344
- function restoreScript( elem ) {
5345
- var match = rscriptTypeMasked.exec( elem.type );
5346
- if ( match ) {
5347
- elem.type = match[1];
5348
- } else {
5349
- elem.removeAttribute("type");
5350
- }
5351
- return elem;
5352
- }
5353
-
5354
- // Mark scripts as having already been evaluated
5355
- function setGlobalEval( elems, refElements ) {
5356
- var elem,
5357
- i = 0;
5358
- for ( ; (elem = elems[i]) != null; i++ ) {
5359
- jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
5360
- }
5361
- }
5362
-
5363
- function cloneCopyEvent( src, dest ) {
5364
-
5365
- if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5366
- return;
5367
- }
5368
-
5369
- var type, i, l,
5370
- oldData = jQuery._data( src ),
5371
- curData = jQuery._data( dest, oldData ),
5372
- events = oldData.events;
5373
-
5374
- if ( events ) {
5375
- delete curData.handle;
5376
- curData.events = {};
5377
-
5378
- for ( type in events ) {
5379
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5380
- jQuery.event.add( dest, type, events[ type ][ i ] );
5381
- }
5382
- }
5383
- }
5384
-
5385
- // make the cloned public data object a copy from the original
5386
- if ( curData.data ) {
5387
- curData.data = jQuery.extend( {}, curData.data );
5388
- }
5389
- }
5390
-
5391
- function fixCloneNodeIssues( src, dest ) {
5392
- var nodeName, e, data;
5393
-
5394
- // We do not need to do anything for non-Elements
5395
- if ( dest.nodeType !== 1 ) {
5396
- return;
5397
- }
5398
-
5399
- nodeName = dest.nodeName.toLowerCase();
5400
-
5401
- // IE6-8 copies events bound via attachEvent when using cloneNode.
5402
- if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5403
- data = jQuery._data( dest );
5404
-
5405
- for ( e in data.events ) {
5406
- jQuery.removeEvent( dest, e, data.handle );
5407
- }
5408
-
5409
- // Event data gets referenced instead of copied if the expando gets copied too
5410
- dest.removeAttribute( jQuery.expando );
5411
- }
5412
-
5413
- // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5414
- if ( nodeName === "script" && dest.text !== src.text ) {
5415
- disableScript( dest ).text = src.text;
5416
- restoreScript( dest );
5417
-
5418
- // IE6-10 improperly clones children of object elements using classid.
5419
- // IE10 throws NoModificationAllowedError if parent is null, #12132.
5420
- } else if ( nodeName === "object" ) {
5421
- if ( dest.parentNode ) {
5422
- dest.outerHTML = src.outerHTML;
5423
- }
5424
-
5425
- // This path appears unavoidable for IE9. When cloning an object
5426
- // element in IE9, the outerHTML strategy above is not sufficient.
5427
- // If the src has innerHTML and the destination does not,
5428
- // copy the src.innerHTML into the dest.innerHTML. #10324
5429
- if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
5430
- dest.innerHTML = src.innerHTML;
5431
- }
5432
-
5433
- } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5434
- // IE6-8 fails to persist the checked state of a cloned checkbox
5435
- // or radio button. Worse, IE6-7 fail to give the cloned element
5436
- // a checked appearance if the defaultChecked value isn't also set
5437
-
5438
- dest.defaultChecked = dest.checked = src.checked;
5439
-
5440
- // IE6-7 get confused and end up setting the value of a cloned
5441
- // checkbox/radio button to an empty string instead of "on"
5442
- if ( dest.value !== src.value ) {
5443
- dest.value = src.value;
5444
- }
5445
-
5446
- // IE6-8 fails to return the selected option to the default selected
5447
- // state when cloning options
5448
- } else if ( nodeName === "option" ) {
5449
- dest.defaultSelected = dest.selected = src.defaultSelected;
5450
-
5451
- // IE6-8 fails to set the defaultValue to the correct value when
5452
- // cloning other types of input fields
5453
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
5454
- dest.defaultValue = src.defaultValue;
5455
- }
5456
- }
5457
-
5458
- jQuery.extend({
5459
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5460
- var destElements, node, clone, i, srcElements,
5461
- inPage = jQuery.contains( elem.ownerDocument, elem );
5462
-
5463
- if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
5464
- clone = elem.cloneNode( true );
5465
-
5466
- // IE<=8 does not properly clone detached, unknown element nodes
5467
- } else {
5468
- fragmentDiv.innerHTML = elem.outerHTML;
5469
- fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
5470
- }
5471
-
5472
- if ( (!support.noCloneEvent || !support.noCloneChecked) &&
5473
- (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5474
-
5475
- // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5476
- destElements = getAll( clone );
5477
- srcElements = getAll( elem );
5478
-
5479
- // Fix all IE cloning issues
5480
- for ( i = 0; (node = srcElements[i]) != null; ++i ) {
5481
- // Ensure that the destination node is not null; Fixes #9587
5482
- if ( destElements[i] ) {
5483
- fixCloneNodeIssues( node, destElements[i] );
5484
- }
5485
- }
5486
- }
5487
-
5488
- // Copy the events from the original to the clone
5489
- if ( dataAndEvents ) {
5490
- if ( deepDataAndEvents ) {
5491
- srcElements = srcElements || getAll( elem );
5492
- destElements = destElements || getAll( clone );
5493
-
5494
- for ( i = 0; (node = srcElements[i]) != null; i++ ) {
5495
- cloneCopyEvent( node, destElements[i] );
5496
- }
5497
- } else {
5498
- cloneCopyEvent( elem, clone );
5499
- }
5500
- }
5501
-
5502
- // Preserve script evaluation history
5503
- destElements = getAll( clone, "script" );
5504
- if ( destElements.length > 0 ) {
5505
- setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5506
- }
5507
-
5508
- destElements = srcElements = node = null;
5509
-
5510
- // Return the cloned set
5511
- return clone;
5512
- },
5513
-
5514
- buildFragment: function( elems, context, scripts, selection ) {
5515
- var j, elem, contains,
5516
- tmp, tag, tbody, wrap,
5517
- l = elems.length,
5518
-
5519
- // Ensure a safe fragment
5520
- safe = createSafeFragment( context ),
5521
-
5522
- nodes = [],
5523
- i = 0;
5524
-
5525
- for ( ; i < l; i++ ) {
5526
- elem = elems[ i ];
5527
-
5528
- if ( elem || elem === 0 ) {
5529
-
5530
- // Add nodes directly
5531
- if ( jQuery.type( elem ) === "object" ) {
5532
- jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5533
-
5534
- // Convert non-html into a text node
5535
- } else if ( !rhtml.test( elem ) ) {
5536
- nodes.push( context.createTextNode( elem ) );
5537
-
5538
- // Convert html into DOM nodes
5539
- } else {
5540
- tmp = tmp || safe.appendChild( context.createElement("div") );
5541
-
5542
- // Deserialize a standard representation
5543
- tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
5544
- wrap = wrapMap[ tag ] || wrapMap._default;
5545
-
5546
- tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
5547
-
5548
- // Descend through wrappers to the right content
5549
- j = wrap[0];
5550
- while ( j-- ) {
5551
- tmp = tmp.lastChild;
5552
- }
5553
-
5554
- // Manually add leading whitespace removed by IE
5555
- if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5556
- nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
5557
- }
5558
-
5559
- // Remove IE's autoinserted <tbody> from table fragments
5560
- if ( !support.tbody ) {
5561
-
5562
- // String was a <table>, *may* have spurious <tbody>
5563
- elem = tag === "table" && !rtbody.test( elem ) ?
5564
- tmp.firstChild :
5565
-
5566
- // String was a bare <thead> or <tfoot>
5567
- wrap[1] === "<table>" && !rtbody.test( elem ) ?
5568
- tmp :
5569
- 0;
5570
-
5571
- j = elem && elem.childNodes.length;
5572
- while ( j-- ) {
5573
- if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
5574
- elem.removeChild( tbody );
5575
- }
5576
- }
5577
- }
5578
-
5579
- jQuery.merge( nodes, tmp.childNodes );
5580
-
5581
- // Fix #12392 for WebKit and IE > 9
5582
- tmp.textContent = "";
5583
-
5584
- // Fix #12392 for oldIE
5585
- while ( tmp.firstChild ) {
5586
- tmp.removeChild( tmp.firstChild );
5587
- }
5588
-
5589
- // Remember the top-level container for proper cleanup
5590
- tmp = safe.lastChild;
5591
- }
5592
- }
5593
- }
5594
-
5595
- // Fix #11356: Clear elements from fragment
5596
- if ( tmp ) {
5597
- safe.removeChild( tmp );
5598
- }
5599
-
5600
- // Reset defaultChecked for any radios and checkboxes
5601
- // about to be appended to the DOM in IE 6/7 (#8060)
5602
- if ( !support.appendChecked ) {
5603
- jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
5604
- }
5605
-
5606
- i = 0;
5607
- while ( (elem = nodes[ i++ ]) ) {
5608
-
5609
- // #4087 - If origin and destination elements are the same, and this is
5610
- // that element, do not do anything
5611
- if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5612
- continue;
5613
- }
5614
-
5615
- contains = jQuery.contains( elem.ownerDocument, elem );
5616
-
5617
- // Append to fragment
5618
- tmp = getAll( safe.appendChild( elem ), "script" );
5619
-
5620
- // Preserve script evaluation history
5621
- if ( contains ) {
5622
- setGlobalEval( tmp );
5623
- }
5624
-
5625
- // Capture executables
5626
- if ( scripts ) {
5627
- j = 0;
5628
- while ( (elem = tmp[ j++ ]) ) {
5629
- if ( rscriptType.test( elem.type || "" ) ) {
5630
- scripts.push( elem );
5631
- }
5632
- }
5633
- }
5634
- }
5635
-
5636
- tmp = null;
5637
-
5638
- return safe;
5639
- },
5640
-
5641
- cleanData: function( elems, /* internal */ acceptData ) {
5642
- var elem, type, id, data,
5643
- i = 0,
5644
- internalKey = jQuery.expando,
5645
- cache = jQuery.cache,
5646
- deleteExpando = support.deleteExpando,
5647
- special = jQuery.event.special;
5648
-
5649
- for ( ; (elem = elems[i]) != null; i++ ) {
5650
- if ( acceptData || jQuery.acceptData( elem ) ) {
5651
-
5652
- id = elem[ internalKey ];
5653
- data = id && cache[ id ];
5654
-
5655
- if ( data ) {
5656
- if ( data.events ) {
5657
- for ( type in data.events ) {
5658
- if ( special[ type ] ) {
5659
- jQuery.event.remove( elem, type );
5660
-
5661
- // This is a shortcut to avoid jQuery.event.remove's overhead
5662
- } else {
5663
- jQuery.removeEvent( elem, type, data.handle );
5664
- }
5665
- }
5666
- }
5667
-
5668
- // Remove cache only if it was not already removed by jQuery.event.remove
5669
- if ( cache[ id ] ) {
5670
-
5671
- delete cache[ id ];
5672
-
5673
- // IE does not allow us to delete expando properties from nodes,
5674
- // nor does it have a removeAttribute function on Document nodes;
5675
- // we must handle all of these cases
5676
- if ( deleteExpando ) {
5677
- delete elem[ internalKey ];
5678
-
5679
- } else if ( typeof elem.removeAttribute !== strundefined ) {
5680
- elem.removeAttribute( internalKey );
5681
-
5682
- } else {
5683
- elem[ internalKey ] = null;
5684
- }
5685
-
5686
- deletedIds.push( id );
5687
- }
5688
- }
5689
- }
5690
- }
5691
- }
5692
- });
5693
-
5694
- jQuery.fn.extend({
5695
- text: function( value ) {
5696
- return access( this, function( value ) {
5697
- return value === undefined ?
5698
- jQuery.text( this ) :
5699
- this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5700
- }, null, value, arguments.length );
5701
- },
5702
-
5703
- append: function() {
5704
- return this.domManip( arguments, function( elem ) {
5705
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5706
- var target = manipulationTarget( this, elem );
5707
- target.appendChild( elem );
5708
- }
5709
- });
5710
- },
5711
-
5712
- prepend: function() {
5713
- return this.domManip( arguments, function( elem ) {
5714
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5715
- var target = manipulationTarget( this, elem );
5716
- target.insertBefore( elem, target.firstChild );
5717
- }
5718
- });
5719
- },
5720
-
5721
- before: function() {
5722
- return this.domManip( arguments, function( elem ) {
5723
- if ( this.parentNode ) {
5724
- this.parentNode.insertBefore( elem, this );
5725
- }
5726
- });
5727
- },
5728
-
5729
- after: function() {
5730
- return this.domManip( arguments, function( elem ) {
5731
- if ( this.parentNode ) {
5732
- this.parentNode.insertBefore( elem, this.nextSibling );
5733
- }
5734
- });
5735
- },
5736
-
5737
- remove: function( selector, keepData /* Internal Use Only */ ) {
5738
- var elem,
5739
- elems = selector ? jQuery.filter( selector, this ) : this,
5740
- i = 0;
5741
-
5742
- for ( ; (elem = elems[i]) != null; i++ ) {
5743
-
5744
- if ( !keepData && elem.nodeType === 1 ) {
5745
- jQuery.cleanData( getAll( elem ) );
5746
- }
5747
-
5748
- if ( elem.parentNode ) {
5749
- if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5750
- setGlobalEval( getAll( elem, "script" ) );
5751
- }
5752
- elem.parentNode.removeChild( elem );
5753
- }
5754
- }
5755
-
5756
- return this;
5757
- },
5758
-
5759
- empty: function() {
5760
- var elem,
5761
- i = 0;
5762
-
5763
- for ( ; (elem = this[i]) != null; i++ ) {
5764
- // Remove element nodes and prevent memory leaks
5765
- if ( elem.nodeType === 1 ) {
5766
- jQuery.cleanData( getAll( elem, false ) );
5767
- }
5768
-
5769
- // Remove any remaining nodes
5770
- while ( elem.firstChild ) {
5771
- elem.removeChild( elem.firstChild );
5772
- }
5773
-
5774
- // If this is a select, ensure that it displays empty (#12336)
5775
- // Support: IE<9
5776
- if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
5777
- elem.options.length = 0;
5778
- }
5779
- }
5780
-
5781
- return this;
5782
- },
5783
-
5784
- clone: function( dataAndEvents, deepDataAndEvents ) {
5785
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5786
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5787
-
5788
- return this.map(function() {
5789
- return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5790
- });
5791
- },
5792
-
5793
- html: function( value ) {
5794
- return access( this, function( value ) {
5795
- var elem = this[ 0 ] || {},
5796
- i = 0,
5797
- l = this.length;
5798
-
5799
- if ( value === undefined ) {
5800
- return elem.nodeType === 1 ?
5801
- elem.innerHTML.replace( rinlinejQuery, "" ) :
5802
- undefined;
5803
- }
5804
-
5805
- // See if we can take a shortcut and just use innerHTML
5806
- if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5807
- ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
5808
- ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5809
- !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
5810
-
5811
- value = value.replace( rxhtmlTag, "<$1></$2>" );
5812
-
5813
- try {
5814
- for (; i < l; i++ ) {
5815
- // Remove element nodes and prevent memory leaks
5816
- elem = this[i] || {};
5817
- if ( elem.nodeType === 1 ) {
5818
- jQuery.cleanData( getAll( elem, false ) );
5819
- elem.innerHTML = value;
5820
- }
5821
- }
5822
-
5823
- elem = 0;
5824
-
5825
- // If using innerHTML throws an exception, use the fallback method
5826
- } catch(e) {}
5827
- }
5828
-
5829
- if ( elem ) {
5830
- this.empty().append( value );
5831
- }
5832
- }, null, value, arguments.length );
5833
- },
5834
-
5835
- replaceWith: function() {
5836
- var arg = arguments[ 0 ];
5837
-
5838
- // Make the changes, replacing each context element with the new content
5839
- this.domManip( arguments, function( elem ) {
5840
- arg = this.parentNode;
5841
-
5842
- jQuery.cleanData( getAll( this ) );
5843
-
5844
- if ( arg ) {
5845
- arg.replaceChild( elem, this );
5846
- }
5847
- });
5848
-
5849
- // Force removal if there was no new content (e.g., from empty arguments)
5850
- return arg && (arg.length || arg.nodeType) ? this : this.remove();
5851
- },
5852
-
5853
- detach: function( selector ) {
5854
- return this.remove( selector, true );
5855
- },
5856
-
5857
- domManip: function( args, callback ) {
5858
-
5859
- // Flatten any nested arrays
5860
- args = concat.apply( [], args );
5861
-
5862
- var first, node, hasScripts,
5863
- scripts, doc, fragment,
5864
- i = 0,
5865
- l = this.length,
5866
- set = this,
5867
- iNoClone = l - 1,
5868
- value = args[0],
5869
- isFunction = jQuery.isFunction( value );
5870
-
5871
- // We can't cloneNode fragments that contain checked, in WebKit
5872
- if ( isFunction ||
5873
- ( l > 1 && typeof value === "string" &&
5874
- !support.checkClone && rchecked.test( value ) ) ) {
5875
- return this.each(function( index ) {
5876
- var self = set.eq( index );
5877
- if ( isFunction ) {
5878
- args[0] = value.call( this, index, self.html() );
5879
- }
5880
- self.domManip( args, callback );
5881
- });
5882
- }
5883
-
5884
- if ( l ) {
5885
- fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5886
- first = fragment.firstChild;
5887
-
5888
- if ( fragment.childNodes.length === 1 ) {
5889
- fragment = first;
5890
- }
5891
-
5892
- if ( first ) {
5893
- scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5894
- hasScripts = scripts.length;
5895
-
5896
- // Use the original fragment for the last item instead of the first because it can end up
5897
- // being emptied incorrectly in certain situations (#8070).
5898
- for ( ; i < l; i++ ) {
5899
- node = fragment;
5900
-
5901
- if ( i !== iNoClone ) {
5902
- node = jQuery.clone( node, true, true );
5903
-
5904
- // Keep references to cloned scripts for later restoration
5905
- if ( hasScripts ) {
5906
- jQuery.merge( scripts, getAll( node, "script" ) );
5907
- }
5908
- }
5909
-
5910
- callback.call( this[i], node, i );
5911
- }
5912
-
5913
- if ( hasScripts ) {
5914
- doc = scripts[ scripts.length - 1 ].ownerDocument;
5915
-
5916
- // Reenable scripts
5917
- jQuery.map( scripts, restoreScript );
5918
-
5919
- // Evaluate executable scripts on first document insertion
5920
- for ( i = 0; i < hasScripts; i++ ) {
5921
- node = scripts[ i ];
5922
- if ( rscriptType.test( node.type || "" ) &&
5923
- !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5924
-
5925
- if ( node.src ) {
5926
- // Optional AJAX dependency, but won't run scripts if not present
5927
- if ( jQuery._evalUrl ) {
5928
- jQuery._evalUrl( node.src );
5929
- }
5930
- } else {
5931
- jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
5932
- }
5933
- }
5934
- }
5935
- }
5936
-
5937
- // Fix #11809: Avoid leaking memory
5938
- fragment = first = null;
5939
- }
5940
- }
5941
-
5942
- return this;
5943
- }
5944
- });
5945
-
5946
- jQuery.each({
5947
- appendTo: "append",
5948
- prependTo: "prepend",
5949
- insertBefore: "before",
5950
- insertAfter: "after",
5951
- replaceAll: "replaceWith"
5952
- }, function( name, original ) {
5953
- jQuery.fn[ name ] = function( selector ) {
5954
- var elems,
5955
- i = 0,
5956
- ret = [],
5957
- insert = jQuery( selector ),
5958
- last = insert.length - 1;
5959
-
5960
- for ( ; i <= last; i++ ) {
5961
- elems = i === last ? this : this.clone(true);
5962
- jQuery( insert[i] )[ original ]( elems );
5963
-
5964
- // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
5965
- push.apply( ret, elems.get() );
5966
- }
5967
-
5968
- return this.pushStack( ret );
5969
- };
5970
- });
5971
-
5972
-
5973
- var iframe,
5974
- elemdisplay = {};
5975
-
5976
- /**
5977
- * Retrieve the actual display of a element
5978
- * @param {String} name nodeName of the element
5979
- * @param {Object} doc Document object
5980
- */
5981
- // Called only from within defaultDisplay
5982
- function actualDisplay( name, doc ) {
5983
- var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5984
-
5985
- // getDefaultComputedStyle might be reliably used only on attached element
5986
- display = window.getDefaultComputedStyle ?
5987
-
5988
- // Use of this method is a temporary fix (more like optmization) until something better comes along,
5989
- // since it was removed from specification and supported only in FF
5990
- window.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], "display" );
5991
-
5992
- // We don't have any data stored on the element,
5993
- // so use "detach" method as fast way to get rid of the element
5994
- elem.detach();
5995
-
5996
- return display;
5997
- }
5998
-
5999
- /**
6000
- * Try to determine the default display value of an element
6001
- * @param {String} nodeName
6002
- */
6003
- function defaultDisplay( nodeName ) {
6004
- var doc = document,
6005
- display = elemdisplay[ nodeName ];
6006
-
6007
- if ( !display ) {
6008
- display = actualDisplay( nodeName, doc );
6009
-
6010
- // If the simple way fails, read from inside an iframe
6011
- if ( display === "none" || !display ) {
6012
-
6013
- // Use the already-created iframe if possible
6014
- iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
6015
-
6016
- // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6017
- doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6018
-
6019
- // Support: IE
6020
- doc.write();
6021
- doc.close();
6022
-
6023
- display = actualDisplay( nodeName, doc );
6024
- iframe.detach();
6025
- }
6026
-
6027
- // Store the correct default display
6028
- elemdisplay[ nodeName ] = display;
6029
- }
6030
-
6031
- return display;
6032
- }
6033
-
6034
-
6035
- (function() {
6036
- var a, shrinkWrapBlocksVal,
6037
- div = document.createElement( "div" ),
6038
- divReset =
6039
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;" +
6040
- "display:block;padding:0;margin:0;border:0";
6041
-
6042
- // Setup
6043
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6044
- a = div.getElementsByTagName( "a" )[ 0 ];
6045
-
6046
- a.style.cssText = "float:left;opacity:.5";
6047
-
6048
- // Make sure that element opacity exists
6049
- // (IE uses filter instead)
6050
- // Use a regex to work around a WebKit issue. See #5145
6051
- support.opacity = /^0.5/.test( a.style.opacity );
6052
-
6053
- // Verify style float existence
6054
- // (IE uses styleFloat instead of cssFloat)
6055
- support.cssFloat = !!a.style.cssFloat;
6056
-
6057
- div.style.backgroundClip = "content-box";
6058
- div.cloneNode( true ).style.backgroundClip = "";
6059
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
6060
-
6061
- // Null elements to avoid leaks in IE.
6062
- a = div = null;
6063
-
6064
- support.shrinkWrapBlocks = function() {
6065
- var body, container, div, containerStyles;
6066
-
6067
- if ( shrinkWrapBlocksVal == null ) {
6068
- body = document.getElementsByTagName( "body" )[ 0 ];
6069
- if ( !body ) {
6070
- // Test fired too early or in an unsupported environment, exit.
6071
- return;
6072
- }
6073
-
6074
- containerStyles = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px";
6075
- container = document.createElement( "div" );
6076
- div = document.createElement( "div" );
6077
-
6078
- body.appendChild( container ).appendChild( div );
6079
-
6080
- // Will be changed later if needed.
6081
- shrinkWrapBlocksVal = false;
6082
-
6083
- if ( typeof div.style.zoom !== strundefined ) {
6084
- // Support: IE6
6085
- // Check if elements with layout shrink-wrap their children
6086
- div.style.cssText = divReset + ";width:1px;padding:1px;zoom:1";
6087
- div.innerHTML = "<div></div>";
6088
- div.firstChild.style.width = "5px";
6089
- shrinkWrapBlocksVal = div.offsetWidth !== 3;
6090
- }
6091
-
6092
- body.removeChild( container );
6093
-
6094
- // Null elements to avoid leaks in IE.
6095
- body = container = div = null;
6096
- }
6097
-
6098
- return shrinkWrapBlocksVal;
6099
- };
6100
-
6101
- })();
6102
- var rmargin = (/^margin/);
6103
-
6104
- var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6105
-
6106
-
6107
-
6108
- var getStyles, curCSS,
6109
- rposition = /^(top|right|bottom|left)$/;
6110
-
6111
- if ( window.getComputedStyle ) {
6112
- getStyles = function( elem ) {
6113
- return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
6114
- };
6115
-
6116
- curCSS = function( elem, name, computed ) {
6117
- var width, minWidth, maxWidth, ret,
6118
- style = elem.style;
6119
-
6120
- computed = computed || getStyles( elem );
6121
-
6122
- // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6123
- ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6124
-
6125
- if ( computed ) {
6126
-
6127
- if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6128
- ret = jQuery.style( elem, name );
6129
- }
6130
-
6131
- // A tribute to the "awesome hack by Dean Edwards"
6132
- // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6133
- // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6134
- // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6135
- if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6136
-
6137
- // Remember the original values
6138
- width = style.width;
6139
- minWidth = style.minWidth;
6140
- maxWidth = style.maxWidth;
6141
-
6142
- // Put in the new values to get a computed value out
6143
- style.minWidth = style.maxWidth = style.width = ret;
6144
- ret = computed.width;
6145
-
6146
- // Revert the changed values
6147
- style.width = width;
6148
- style.minWidth = minWidth;
6149
- style.maxWidth = maxWidth;
6150
- }
6151
- }
6152
-
6153
- // Support: IE
6154
- // IE returns zIndex value as an integer.
6155
- return ret === undefined ?
6156
- ret :
6157
- ret + "";
6158
- };
6159
- } else if ( document.documentElement.currentStyle ) {
6160
- getStyles = function( elem ) {
6161
- return elem.currentStyle;
6162
- };
6163
-
6164
- curCSS = function( elem, name, computed ) {
6165
- var left, rs, rsLeft, ret,
6166
- style = elem.style;
6167
-
6168
- computed = computed || getStyles( elem );
6169
- ret = computed ? computed[ name ] : undefined;
6170
-
6171
- // Avoid setting ret to empty string here
6172
- // so we don't default to auto
6173
- if ( ret == null && style && style[ name ] ) {
6174
- ret = style[ name ];
6175
- }
6176
-
6177
- // From the awesome hack by Dean Edwards
6178
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6179
-
6180
- // If we're not dealing with a regular pixel number
6181
- // but a number that has a weird ending, we need to convert it to pixels
6182
- // but not position css attributes, as those are proportional to the parent element instead
6183
- // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6184
- if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6185
-
6186
- // Remember the original values
6187
- left = style.left;
6188
- rs = elem.runtimeStyle;
6189
- rsLeft = rs && rs.left;
6190
-
6191
- // Put in the new values to get a computed value out
6192
- if ( rsLeft ) {
6193
- rs.left = elem.currentStyle.left;
6194
- }
6195
- style.left = name === "fontSize" ? "1em" : ret;
6196
- ret = style.pixelLeft + "px";
6197
-
6198
- // Revert the changed values
6199
- style.left = left;
6200
- if ( rsLeft ) {
6201
- rs.left = rsLeft;
6202
- }
6203
- }
6204
-
6205
- // Support: IE
6206
- // IE returns zIndex value as an integer.
6207
- return ret === undefined ?
6208
- ret :
6209
- ret + "" || "auto";
6210
- };
6211
- }
6212
-
6213
-
6214
-
6215
-
6216
- function addGetHookIf( conditionFn, hookFn ) {
6217
- // Define the hook, we'll check on the first run if it's really needed.
6218
- return {
6219
- get: function() {
6220
- var condition = conditionFn();
6221
-
6222
- if ( condition == null ) {
6223
- // The test was not ready at this point; screw the hook this time
6224
- // but check again when needed next time.
6225
- return;
6226
- }
6227
-
6228
- if ( condition ) {
6229
- // Hook not needed (or it's not possible to use it due to missing dependency),
6230
- // remove it.
6231
- // Since there are no other hooks for marginRight, remove the whole object.
6232
- delete this.get;
6233
- return;
6234
- }
6235
-
6236
- // Hook needed; redefine it so that the support test is not executed again.
6237
-
6238
- return (this.get = hookFn).apply( this, arguments );
6239
- }
6240
- };
6241
- }
6242
-
6243
-
6244
- (function() {
6245
- var a, reliableHiddenOffsetsVal, boxSizingVal, boxSizingReliableVal,
6246
- pixelPositionVal, reliableMarginRightVal,
6247
- div = document.createElement( "div" ),
6248
- containerStyles = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px",
6249
- divReset =
6250
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;" +
6251
- "display:block;padding:0;margin:0;border:0";
6252
-
6253
- // Setup
6254
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6255
- a = div.getElementsByTagName( "a" )[ 0 ];
6256
-
6257
- a.style.cssText = "float:left;opacity:.5";
6258
-
6259
- // Make sure that element opacity exists
6260
- // (IE uses filter instead)
6261
- // Use a regex to work around a WebKit issue. See #5145
6262
- support.opacity = /^0.5/.test( a.style.opacity );
6263
-
6264
- // Verify style float existence
6265
- // (IE uses styleFloat instead of cssFloat)
6266
- support.cssFloat = !!a.style.cssFloat;
6267
-
6268
- div.style.backgroundClip = "content-box";
6269
- div.cloneNode( true ).style.backgroundClip = "";
6270
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
6271
-
6272
- // Null elements to avoid leaks in IE.
6273
- a = div = null;
6274
-
6275
- jQuery.extend(support, {
6276
- reliableHiddenOffsets: function() {
6277
- if ( reliableHiddenOffsetsVal != null ) {
6278
- return reliableHiddenOffsetsVal;
6279
- }
6280
-
6281
- var container, tds, isSupported,
6282
- div = document.createElement( "div" ),
6283
- body = document.getElementsByTagName( "body" )[ 0 ];
6284
-
6285
- if ( !body ) {
6286
- // Return for frameset docs that don't have a body
6287
- return;
6288
- }
6289
-
6290
- // Setup
6291
- div.setAttribute( "className", "t" );
6292
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6293
-
6294
- container = document.createElement( "div" );
6295
- container.style.cssText = containerStyles;
6296
-
6297
- body.appendChild( container ).appendChild( div );
6298
-
6299
- // Support: IE8
6300
- // Check if table cells still have offsetWidth/Height when they are set
6301
- // to display:none and there are still other visible table cells in a
6302
- // table row; if so, offsetWidth/Height are not reliable for use when
6303
- // determining if an element has been hidden directly using
6304
- // display:none (it is still safe to use offsets if a parent element is
6305
- // hidden; don safety goggles and see bug #4512 for more information).
6306
- div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6307
- tds = div.getElementsByTagName( "td" );
6308
- tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
6309
- isSupported = ( tds[ 0 ].offsetHeight === 0 );
6310
-
6311
- tds[ 0 ].style.display = "";
6312
- tds[ 1 ].style.display = "none";
6313
-
6314
- // Support: IE8
6315
- // Check if empty table cells still have offsetWidth/Height
6316
- reliableHiddenOffsetsVal = isSupported && ( tds[ 0 ].offsetHeight === 0 );
6317
-
6318
- body.removeChild( container );
6319
-
6320
- // Null elements to avoid leaks in IE.
6321
- div = body = null;
6322
-
6323
- return reliableHiddenOffsetsVal;
6324
- },
6325
-
6326
- boxSizing: function() {
6327
- if ( boxSizingVal == null ) {
6328
- computeStyleTests();
6329
- }
6330
- return boxSizingVal;
6331
- },
6332
-
6333
- boxSizingReliable: function() {
6334
- if ( boxSizingReliableVal == null ) {
6335
- computeStyleTests();
6336
- }
6337
- return boxSizingReliableVal;
6338
- },
6339
-
6340
- pixelPosition: function() {
6341
- if ( pixelPositionVal == null ) {
6342
- computeStyleTests();
6343
- }
6344
- return pixelPositionVal;
6345
- },
6346
-
6347
- reliableMarginRight: function() {
6348
- var body, container, div, marginDiv;
6349
-
6350
- // Use window.getComputedStyle because jsdom on node.js will break without it.
6351
- if ( reliableMarginRightVal == null && window.getComputedStyle ) {
6352
- body = document.getElementsByTagName( "body" )[ 0 ];
6353
- if ( !body ) {
6354
- // Test fired too early or in an unsupported environment, exit.
6355
- return;
6356
- }
6357
-
6358
- container = document.createElement( "div" );
6359
- div = document.createElement( "div" );
6360
- container.style.cssText = containerStyles;
6361
-
6362
- body.appendChild( container ).appendChild( div );
6363
-
6364
- // Check if div with explicit width and no margin-right incorrectly
6365
- // gets computed margin-right based on width of container. (#3333)
6366
- // Fails in WebKit before Feb 2011 nightlies
6367
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6368
- marginDiv = div.appendChild( document.createElement( "div" ) );
6369
- marginDiv.style.cssText = div.style.cssText = divReset;
6370
- marginDiv.style.marginRight = marginDiv.style.width = "0";
6371
- div.style.width = "1px";
6372
-
6373
- reliableMarginRightVal =
6374
- !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
6375
-
6376
- body.removeChild( container );
6377
- }
6378
-
6379
- return reliableMarginRightVal;
6380
- }
6381
- });
6382
-
6383
- function computeStyleTests() {
6384
- var container, div,
6385
- body = document.getElementsByTagName( "body" )[ 0 ];
6386
-
6387
- if ( !body ) {
6388
- // Test fired too early or in an unsupported environment, exit.
6389
- return;
6390
- }
6391
-
6392
- container = document.createElement( "div" );
6393
- div = document.createElement( "div" );
6394
- container.style.cssText = containerStyles;
6395
-
6396
- body.appendChild( container ).appendChild( div );
6397
-
6398
- div.style.cssText =
6399
- "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
6400
- "position:absolute;display:block;padding:1px;border:1px;width:4px;" +
6401
- "margin-top:1%;top:1%";
6402
-
6403
- // Workaround failing boxSizing test due to offsetWidth returning wrong value
6404
- // with some non-1 values of body zoom, ticket #13543
6405
- jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
6406
- boxSizingVal = div.offsetWidth === 4;
6407
- });
6408
-
6409
- // Will be changed later if needed.
6410
- boxSizingReliableVal = true;
6411
- pixelPositionVal = false;
6412
- reliableMarginRightVal = true;
6413
-
6414
- // Use window.getComputedStyle because jsdom on node.js will break without it.
6415
- if ( window.getComputedStyle ) {
6416
- pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
6417
- boxSizingReliableVal =
6418
- ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
6419
- }
6420
-
6421
- body.removeChild( container );
6422
-
6423
- // Null elements to avoid leaks in IE.
6424
- div = body = null;
6425
- }
6426
-
6427
- })();
6428
-
6429
-
6430
- // A method for quickly swapping in/out CSS properties to get correct calculations.
6431
- jQuery.swap = function( elem, options, callback, args ) {
6432
- var ret, name,
6433
- old = {};
6434
-
6435
- // Remember the old values, and insert the new ones
6436
- for ( name in options ) {
6437
- old[ name ] = elem.style[ name ];
6438
- elem.style[ name ] = options[ name ];
6439
- }
6440
-
6441
- ret = callback.apply( elem, args || [] );
6442
-
6443
- // Revert the old values
6444
- for ( name in options ) {
6445
- elem.style[ name ] = old[ name ];
6446
- }
6447
-
6448
- return ret;
6449
- };
6450
-
6451
-
6452
- var
6453
- ralpha = /alpha\([^)]*\)/i,
6454
- ropacity = /opacity\s*=\s*([^)]*)/,
6455
-
6456
- // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6457
- // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6458
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6459
- rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6460
- rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
6461
-
6462
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6463
- cssNormalTransform = {
6464
- letterSpacing: 0,
6465
- fontWeight: 400
6466
- },
6467
-
6468
- cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
6469
-
6470
-
6471
- // return a css property mapped to a potentially vendor prefixed property
6472
- function vendorPropName( style, name ) {
6473
-
6474
- // shortcut for names that are not vendor prefixed
6475
- if ( name in style ) {
6476
- return name;
6477
- }
6478
-
6479
- // check for vendor prefixed names
6480
- var capName = name.charAt(0).toUpperCase() + name.slice(1),
6481
- origName = name,
6482
- i = cssPrefixes.length;
6483
-
6484
- while ( i-- ) {
6485
- name = cssPrefixes[ i ] + capName;
6486
- if ( name in style ) {
6487
- return name;
6488
- }
6489
- }
6490
-
6491
- return origName;
6492
- }
6493
-
6494
- function showHide( elements, show ) {
6495
- var display, elem, hidden,
6496
- values = [],
6497
- index = 0,
6498
- length = elements.length;
6499
-
6500
- for ( ; index < length; index++ ) {
6501
- elem = elements[ index ];
6502
- if ( !elem.style ) {
6503
- continue;
6504
- }
6505
-
6506
- values[ index ] = jQuery._data( elem, "olddisplay" );
6507
- display = elem.style.display;
6508
- if ( show ) {
6509
- // Reset the inline display of this element to learn if it is
6510
- // being hidden by cascaded rules or not
6511
- if ( !values[ index ] && display === "none" ) {
6512
- elem.style.display = "";
6513
- }
6514
-
6515
- // Set elements which have been overridden with display: none
6516
- // in a stylesheet to whatever the default browser style is
6517
- // for such an element
6518
- if ( elem.style.display === "" && isHidden( elem ) ) {
6519
- values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
6520
- }
6521
- } else {
6522
-
6523
- if ( !values[ index ] ) {
6524
- hidden = isHidden( elem );
6525
-
6526
- if ( display && display !== "none" || !hidden ) {
6527
- jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
6528
- }
6529
- }
6530
- }
6531
- }
6532
-
6533
- // Set the display of most of the elements in a second loop
6534
- // to avoid the constant reflow
6535
- for ( index = 0; index < length; index++ ) {
6536
- elem = elements[ index ];
6537
- if ( !elem.style ) {
6538
- continue;
6539
- }
6540
- if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6541
- elem.style.display = show ? values[ index ] || "" : "none";
6542
- }
6543
- }
6544
-
6545
- return elements;
6546
- }
6547
-
6548
- function setPositiveNumber( elem, value, subtract ) {
6549
- var matches = rnumsplit.exec( value );
6550
- return matches ?
6551
- // Guard against undefined "subtract", e.g., when used as in cssHooks
6552
- Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6553
- value;
6554
- }
6555
-
6556
- function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6557
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
6558
- // If we already have the right measurement, avoid augmentation
6559
- 4 :
6560
- // Otherwise initialize for horizontal or vertical properties
6561
- name === "width" ? 1 : 0,
6562
-
6563
- val = 0;
6564
-
6565
- for ( ; i < 4; i += 2 ) {
6566
- // both box models exclude margin, so add it if we want it
6567
- if ( extra === "margin" ) {
6568
- val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6569
- }
6570
-
6571
- if ( isBorderBox ) {
6572
- // border-box includes padding, so remove it if we want content
6573
- if ( extra === "content" ) {
6574
- val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6575
- }
6576
-
6577
- // at this point, extra isn't border nor margin, so remove border
6578
- if ( extra !== "margin" ) {
6579
- val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6580
- }
6581
- } else {
6582
- // at this point, extra isn't content, so add padding
6583
- val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6584
-
6585
- // at this point, extra isn't content nor padding, so add border
6586
- if ( extra !== "padding" ) {
6587
- val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6588
- }
6589
- }
6590
- }
6591
-
6592
- return val;
6593
- }
6594
-
6595
- function getWidthOrHeight( elem, name, extra ) {
6596
-
6597
- // Start with offset property, which is equivalent to the border-box value
6598
- var valueIsBorderBox = true,
6599
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6600
- styles = getStyles( elem ),
6601
- isBorderBox = support.boxSizing() && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6602
-
6603
- // some non-html elements return undefined for offsetWidth, so check for null/undefined
6604
- // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6605
- // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6606
- if ( val <= 0 || val == null ) {
6607
- // Fall back to computed then uncomputed css if necessary
6608
- val = curCSS( elem, name, styles );
6609
- if ( val < 0 || val == null ) {
6610
- val = elem.style[ name ];
6611
- }
6612
-
6613
- // Computed unit is not pixels. Stop here and return.
6614
- if ( rnumnonpx.test(val) ) {
6615
- return val;
6616
- }
6617
-
6618
- // we need the check for style in case a browser which returns unreliable values
6619
- // for getComputedStyle silently falls back to the reliable elem.style
6620
- valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
6621
-
6622
- // Normalize "", auto, and prepare for extra
6623
- val = parseFloat( val ) || 0;
6624
- }
6625
-
6626
- // use the active box-sizing model to add/subtract irrelevant styles
6627
- return ( val +
6628
- augmentWidthOrHeight(
6629
- elem,
6630
- name,
6631
- extra || ( isBorderBox ? "border" : "content" ),
6632
- valueIsBorderBox,
6633
- styles
6634
- )
6635
- ) + "px";
6636
- }
6637
-
6638
- jQuery.extend({
6639
- // Add in style property hooks for overriding the default
6640
- // behavior of getting and setting a style property
6641
- cssHooks: {
6642
- opacity: {
6643
- get: function( elem, computed ) {
6644
- if ( computed ) {
6645
- // We should always get a number back from opacity
6646
- var ret = curCSS( elem, "opacity" );
6647
- return ret === "" ? "1" : ret;
6648
- }
6649
- }
6650
- }
6651
- },
6652
-
6653
- // Don't automatically add "px" to these possibly-unitless properties
6654
- cssNumber: {
6655
- "columnCount": true,
6656
- "fillOpacity": true,
6657
- "fontWeight": true,
6658
- "lineHeight": true,
6659
- "opacity": true,
6660
- "order": true,
6661
- "orphans": true,
6662
- "widows": true,
6663
- "zIndex": true,
6664
- "zoom": true
6665
- },
6666
-
6667
- // Add in properties whose names you wish to fix before
6668
- // setting or getting the value
6669
- cssProps: {
6670
- // normalize float css property
6671
- "float": support.cssFloat ? "cssFloat" : "styleFloat"
6672
- },
6673
-
6674
- // Get and set the style property on a DOM Node
6675
- style: function( elem, name, value, extra ) {
6676
- // Don't set styles on text and comment nodes
6677
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6678
- return;
6679
- }
6680
-
6681
- // Make sure that we're working with the right name
6682
- var ret, type, hooks,
6683
- origName = jQuery.camelCase( name ),
6684
- style = elem.style;
6685
-
6686
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6687
-
6688
- // gets hook for the prefixed version
6689
- // followed by the unprefixed version
6690
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6691
-
6692
- // Check if we're setting a value
6693
- if ( value !== undefined ) {
6694
- type = typeof value;
6695
-
6696
- // convert relative number strings (+= or -=) to relative numbers. #7345
6697
- if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6698
- value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6699
- // Fixes bug #9237
6700
- type = "number";
6701
- }
6702
-
6703
- // Make sure that null and NaN values aren't set. See: #7116
6704
- if ( value == null || value !== value ) {
6705
- return;
6706
- }
6707
-
6708
- // If a number was passed in, add 'px' to the (except for certain CSS properties)
6709
- if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6710
- value += "px";
6711
- }
6712
-
6713
- // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
6714
- // but it would mean to define eight (for every problematic property) identical functions
6715
- if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
6716
- style[ name ] = "inherit";
6717
- }
6718
-
6719
- // If a hook was provided, use that value, otherwise just set the specified value
6720
- if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6721
-
6722
- // Support: IE
6723
- // Swallow errors from 'invalid' CSS values (#5509)
6724
- try {
6725
- // Support: Chrome, Safari
6726
- // Setting style to blank string required to delete "style: x !important;"
6727
- style[ name ] = "";
6728
- style[ name ] = value;
6729
- } catch(e) {}
6730
- }
6731
-
6732
- } else {
6733
- // If a hook was provided get the non-computed value from there
6734
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6735
- return ret;
6736
- }
6737
-
6738
- // Otherwise just get the value from the style object
6739
- return style[ name ];
6740
- }
6741
- },
6742
-
6743
- css: function( elem, name, extra, styles ) {
6744
- var num, val, hooks,
6745
- origName = jQuery.camelCase( name );
6746
-
6747
- // Make sure that we're working with the right name
6748
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6749
-
6750
- // gets hook for the prefixed version
6751
- // followed by the unprefixed version
6752
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6753
-
6754
- // If a hook was provided get the computed value from there
6755
- if ( hooks && "get" in hooks ) {
6756
- val = hooks.get( elem, true, extra );
6757
- }
6758
-
6759
- // Otherwise, if a way to get the computed value exists, use that
6760
- if ( val === undefined ) {
6761
- val = curCSS( elem, name, styles );
6762
- }
6763
-
6764
- //convert "normal" to computed value
6765
- if ( val === "normal" && name in cssNormalTransform ) {
6766
- val = cssNormalTransform[ name ];
6767
- }
6768
-
6769
- // Return, converting to number if forced or a qualifier was provided and val looks numeric
6770
- if ( extra === "" || extra ) {
6771
- num = parseFloat( val );
6772
- return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6773
- }
6774
- return val;
6775
- }
6776
- });
6777
-
6778
- jQuery.each([ "height", "width" ], function( i, name ) {
6779
- jQuery.cssHooks[ name ] = {
6780
- get: function( elem, computed, extra ) {
6781
- if ( computed ) {
6782
- // certain elements can have dimension info if we invisibly show them
6783
- // however, it must have a current display style that would benefit from this
6784
- return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
6785
- jQuery.swap( elem, cssShow, function() {
6786
- return getWidthOrHeight( elem, name, extra );
6787
- }) :
6788
- getWidthOrHeight( elem, name, extra );
6789
- }
6790
- },
6791
-
6792
- set: function( elem, value, extra ) {
6793
- var styles = extra && getStyles( elem );
6794
- return setPositiveNumber( elem, value, extra ?
6795
- augmentWidthOrHeight(
6796
- elem,
6797
- name,
6798
- extra,
6799
- support.boxSizing() && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6800
- styles
6801
- ) : 0
6802
- );
6803
- }
6804
- };
6805
- });
6806
-
6807
- if ( !support.opacity ) {
6808
- jQuery.cssHooks.opacity = {
6809
- get: function( elem, computed ) {
6810
- // IE uses filters for opacity
6811
- return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6812
- ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
6813
- computed ? "1" : "";
6814
- },
6815
-
6816
- set: function( elem, value ) {
6817
- var style = elem.style,
6818
- currentStyle = elem.currentStyle,
6819
- opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6820
- filter = currentStyle && currentStyle.filter || style.filter || "";
6821
-
6822
- // IE has trouble with opacity if it does not have layout
6823
- // Force it by setting the zoom level
6824
- style.zoom = 1;
6825
-
6826
- // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6827
- // if value === "", then remove inline opacity #12685
6828
- if ( ( value >= 1 || value === "" ) &&
6829
- jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
6830
- style.removeAttribute ) {
6831
-
6832
- // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6833
- // if "filter:" is present at all, clearType is disabled, we want to avoid this
6834
- // style.removeAttribute is IE Only, but so apparently is this code path...
6835
- style.removeAttribute( "filter" );
6836
-
6837
- // if there is no filter style applied in a css rule or unset inline opacity, we are done
6838
- if ( value === "" || currentStyle && !currentStyle.filter ) {
6839
- return;
6840
- }
6841
- }
6842
-
6843
- // otherwise, set new filter values
6844
- style.filter = ralpha.test( filter ) ?
6845
- filter.replace( ralpha, opacity ) :
6846
- filter + " " + opacity;
6847
- }
6848
- };
6849
- }
6850
-
6851
- jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6852
- function( elem, computed ) {
6853
- if ( computed ) {
6854
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6855
- // Work around by temporarily setting element display to inline-block
6856
- return jQuery.swap( elem, { "display": "inline-block" },
6857
- curCSS, [ elem, "marginRight" ] );
6858
- }
6859
- }
6860
- );
6861
-
6862
- // These hooks are used by animate to expand properties
6863
- jQuery.each({
6864
- margin: "",
6865
- padding: "",
6866
- border: "Width"
6867
- }, function( prefix, suffix ) {
6868
- jQuery.cssHooks[ prefix + suffix ] = {
6869
- expand: function( value ) {
6870
- var i = 0,
6871
- expanded = {},
6872
-
6873
- // assumes a single number if not a string
6874
- parts = typeof value === "string" ? value.split(" ") : [ value ];
6875
-
6876
- for ( ; i < 4; i++ ) {
6877
- expanded[ prefix + cssExpand[ i ] + suffix ] =
6878
- parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6879
- }
6880
-
6881
- return expanded;
6882
- }
6883
- };
6884
-
6885
- if ( !rmargin.test( prefix ) ) {
6886
- jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6887
- }
6888
- });
6889
-
6890
- jQuery.fn.extend({
6891
- css: function( name, value ) {
6892
- return access( this, function( elem, name, value ) {
6893
- var styles, len,
6894
- map = {},
6895
- i = 0;
6896
-
6897
- if ( jQuery.isArray( name ) ) {
6898
- styles = getStyles( elem );
6899
- len = name.length;
6900
-
6901
- for ( ; i < len; i++ ) {
6902
- map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6903
- }
6904
-
6905
- return map;
6906
- }
6907
-
6908
- return value !== undefined ?
6909
- jQuery.style( elem, name, value ) :
6910
- jQuery.css( elem, name );
6911
- }, name, value, arguments.length > 1 );
6912
- },
6913
- show: function() {
6914
- return showHide( this, true );
6915
- },
6916
- hide: function() {
6917
- return showHide( this );
6918
- },
6919
- toggle: function( state ) {
6920
- if ( typeof state === "boolean" ) {
6921
- return state ? this.show() : this.hide();
6922
- }
6923
-
6924
- return this.each(function() {
6925
- if ( isHidden( this ) ) {
6926
- jQuery( this ).show();
6927
- } else {
6928
- jQuery( this ).hide();
6929
- }
6930
- });
6931
- }
6932
- });
6933
-
6934
-
6935
- function Tween( elem, options, prop, end, easing ) {
6936
- return new Tween.prototype.init( elem, options, prop, end, easing );
6937
- }
6938
- jQuery.Tween = Tween;
6939
-
6940
- Tween.prototype = {
6941
- constructor: Tween,
6942
- init: function( elem, options, prop, end, easing, unit ) {
6943
- this.elem = elem;
6944
- this.prop = prop;
6945
- this.easing = easing || "swing";
6946
- this.options = options;
6947
- this.start = this.now = this.cur();
6948
- this.end = end;
6949
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6950
- },
6951
- cur: function() {
6952
- var hooks = Tween.propHooks[ this.prop ];
6953
-
6954
- return hooks && hooks.get ?
6955
- hooks.get( this ) :
6956
- Tween.propHooks._default.get( this );
6957
- },
6958
- run: function( percent ) {
6959
- var eased,
6960
- hooks = Tween.propHooks[ this.prop ];
6961
-
6962
- if ( this.options.duration ) {
6963
- this.pos = eased = jQuery.easing[ this.easing ](
6964
- percent, this.options.duration * percent, 0, 1, this.options.duration
6965
- );
6966
- } else {
6967
- this.pos = eased = percent;
6968
- }
6969
- this.now = ( this.end - this.start ) * eased + this.start;
6970
-
6971
- if ( this.options.step ) {
6972
- this.options.step.call( this.elem, this.now, this );
6973
- }
6974
-
6975
- if ( hooks && hooks.set ) {
6976
- hooks.set( this );
6977
- } else {
6978
- Tween.propHooks._default.set( this );
6979
- }
6980
- return this;
6981
- }
6982
- };
6983
-
6984
- Tween.prototype.init.prototype = Tween.prototype;
6985
-
6986
- Tween.propHooks = {
6987
- _default: {
6988
- get: function( tween ) {
6989
- var result;
6990
-
6991
- if ( tween.elem[ tween.prop ] != null &&
6992
- (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6993
- return tween.elem[ tween.prop ];
6994
- }
6995
-
6996
- // passing an empty string as a 3rd parameter to .css will automatically
6997
- // attempt a parseFloat and fallback to a string if the parse fails
6998
- // so, simple values such as "10px" are parsed to Float.
6999
- // complex values such as "rotate(1rad)" are returned as is.
7000
- result = jQuery.css( tween.elem, tween.prop, "" );
7001
- // Empty strings, null, undefined and "auto" are converted to 0.
7002
- return !result || result === "auto" ? 0 : result;
7003
- },
7004
- set: function( tween ) {
7005
- // use step hook for back compat - use cssHook if its there - use .style if its
7006
- // available and use plain properties where available
7007
- if ( jQuery.fx.step[ tween.prop ] ) {
7008
- jQuery.fx.step[ tween.prop ]( tween );
7009
- } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
7010
- jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7011
- } else {
7012
- tween.elem[ tween.prop ] = tween.now;
7013
- }
7014
- }
7015
- }
7016
- };
7017
-
7018
- // Support: IE <=9
7019
- // Panic based approach to setting things on disconnected nodes
7020
-
7021
- Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7022
- set: function( tween ) {
7023
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
7024
- tween.elem[ tween.prop ] = tween.now;
7025
- }
7026
- }
7027
- };
7028
-
7029
- jQuery.easing = {
7030
- linear: function( p ) {
7031
- return p;
7032
- },
7033
- swing: function( p ) {
7034
- return 0.5 - Math.cos( p * Math.PI ) / 2;
7035
- }
7036
- };
7037
-
7038
- jQuery.fx = Tween.prototype.init;
7039
-
7040
- // Back Compat <1.8 extension point
7041
- jQuery.fx.step = {};
7042
-
7043
-
7044
-
7045
-
7046
- var
7047
- fxNow, timerId,
7048
- rfxtypes = /^(?:toggle|show|hide)$/,
7049
- rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
7050
- rrun = /queueHooks$/,
7051
- animationPrefilters = [ defaultPrefilter ],
7052
- tweeners = {
7053
- "*": [ function( prop, value ) {
7054
- var tween = this.createTween( prop, value ),
7055
- target = tween.cur(),
7056
- parts = rfxnum.exec( value ),
7057
- unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
7058
-
7059
- // Starting value computation is required for potential unit mismatches
7060
- start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
7061
- rfxnum.exec( jQuery.css( tween.elem, prop ) ),
7062
- scale = 1,
7063
- maxIterations = 20;
7064
-
7065
- if ( start && start[ 3 ] !== unit ) {
7066
- // Trust units reported by jQuery.css
7067
- unit = unit || start[ 3 ];
7068
-
7069
- // Make sure we update the tween properties later on
7070
- parts = parts || [];
7071
-
7072
- // Iteratively approximate from a nonzero starting point
7073
- start = +target || 1;
7074
-
7075
- do {
7076
- // If previous iteration zeroed out, double until we get *something*
7077
- // Use a string for doubling factor so we don't accidentally see scale as unchanged below
7078
- scale = scale || ".5";
7079
-
7080
- // Adjust and apply
7081
- start = start / scale;
7082
- jQuery.style( tween.elem, prop, start + unit );
7083
-
7084
- // Update scale, tolerating zero or NaN from tween.cur()
7085
- // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
7086
- } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
7087
- }
7088
-
7089
- // Update tween properties
7090
- if ( parts ) {
7091
- start = tween.start = +start || +target || 0;
7092
- tween.unit = unit;
7093
- // If a +=/-= token was provided, we're doing a relative animation
7094
- tween.end = parts[ 1 ] ?
7095
- start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
7096
- +parts[ 2 ];
7097
- }
7098
-
7099
- return tween;
7100
- } ]
7101
- };
7102
-
7103
- // Animations created synchronously will run synchronously
7104
- function createFxNow() {
7105
- setTimeout(function() {
7106
- fxNow = undefined;
7107
- });
7108
- return ( fxNow = jQuery.now() );
7109
- }
7110
-
7111
- // Generate parameters to create a standard animation
7112
- function genFx( type, includeWidth ) {
7113
- var which,
7114
- attrs = { height: type },
7115
- i = 0;
7116
-
7117
- // if we include width, step value is 1 to do all cssExpand values,
7118
- // if we don't include width, step value is 2 to skip over Left and Right
7119
- includeWidth = includeWidth ? 1 : 0;
7120
- for ( ; i < 4 ; i += 2 - includeWidth ) {
7121
- which = cssExpand[ i ];
7122
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7123
- }
7124
-
7125
- if ( includeWidth ) {
7126
- attrs.opacity = attrs.width = type;
7127
- }
7128
-
7129
- return attrs;
7130
- }
7131
-
7132
- function createTween( value, prop, animation ) {
7133
- var tween,
7134
- collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
7135
- index = 0,
7136
- length = collection.length;
7137
- for ( ; index < length; index++ ) {
7138
- if ( (tween = collection[ index ].call( animation, prop, value )) ) {
7139
-
7140
- // we're done with this property
7141
- return tween;
7142
- }
7143
- }
7144
- }
7145
-
7146
- function defaultPrefilter( elem, props, opts ) {
7147
- /* jshint validthis: true */
7148
- var prop, value, toggle, tween, hooks, oldfire, display, dDisplay,
7149
- anim = this,
7150
- orig = {},
7151
- style = elem.style,
7152
- hidden = elem.nodeType && isHidden( elem ),
7153
- dataShow = jQuery._data( elem, "fxshow" );
7154
-
7155
- // handle queue: false promises
7156
- if ( !opts.queue ) {
7157
- hooks = jQuery._queueHooks( elem, "fx" );
7158
- if ( hooks.unqueued == null ) {
7159
- hooks.unqueued = 0;
7160
- oldfire = hooks.empty.fire;
7161
- hooks.empty.fire = function() {
7162
- if ( !hooks.unqueued ) {
7163
- oldfire();
7164
- }
7165
- };
7166
- }
7167
- hooks.unqueued++;
7168
-
7169
- anim.always(function() {
7170
- // doing this makes sure that the complete handler will be called
7171
- // before this completes
7172
- anim.always(function() {
7173
- hooks.unqueued--;
7174
- if ( !jQuery.queue( elem, "fx" ).length ) {
7175
- hooks.empty.fire();
7176
- }
7177
- });
7178
- });
7179
- }
7180
-
7181
- // height/width overflow pass
7182
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7183
- // Make sure that nothing sneaks out
7184
- // Record all 3 overflow attributes because IE does not
7185
- // change the overflow attribute when overflowX and
7186
- // overflowY are set to the same value
7187
- opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7188
-
7189
- // Set display property to inline-block for height/width
7190
- // animations on inline elements that are having width/height animated
7191
- display = jQuery.css( elem, "display" );
7192
- dDisplay = defaultDisplay( elem.nodeName );
7193
- if ( display === "none" ) {
7194
- display = dDisplay;
7195
- }
7196
- if ( display === "inline" &&
7197
- jQuery.css( elem, "float" ) === "none" ) {
7198
-
7199
- // inline-level elements accept inline-block;
7200
- // block-level elements need to be inline with layout
7201
- if ( !support.inlineBlockNeedsLayout || dDisplay === "inline" ) {
7202
- style.display = "inline-block";
7203
- } else {
7204
- style.zoom = 1;
7205
- }
7206
- }
7207
- }
7208
-
7209
- if ( opts.overflow ) {
7210
- style.overflow = "hidden";
7211
- if ( !support.shrinkWrapBlocks() ) {
7212
- anim.always(function() {
7213
- style.overflow = opts.overflow[ 0 ];
7214
- style.overflowX = opts.overflow[ 1 ];
7215
- style.overflowY = opts.overflow[ 2 ];
7216
- });
7217
- }
7218
- }
7219
-
7220
- // show/hide pass
7221
- for ( prop in props ) {
7222
- value = props[ prop ];
7223
- if ( rfxtypes.exec( value ) ) {
7224
- delete props[ prop ];
7225
- toggle = toggle || value === "toggle";
7226
- if ( value === ( hidden ? "hide" : "show" ) ) {
7227
-
7228
- // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
7229
- if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7230
- hidden = true;
7231
- } else {
7232
- continue;
7233
- }
7234
- }
7235
- orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7236
- }
7237
- }
7238
-
7239
- if ( !jQuery.isEmptyObject( orig ) ) {
7240
- if ( dataShow ) {
7241
- if ( "hidden" in dataShow ) {
7242
- hidden = dataShow.hidden;
7243
- }
7244
- } else {
7245
- dataShow = jQuery._data( elem, "fxshow", {} );
7246
- }
7247
-
7248
- // store state if its toggle - enables .stop().toggle() to "reverse"
7249
- if ( toggle ) {
7250
- dataShow.hidden = !hidden;
7251
- }
7252
- if ( hidden ) {
7253
- jQuery( elem ).show();
7254
- } else {
7255
- anim.done(function() {
7256
- jQuery( elem ).hide();
7257
- });
7258
- }
7259
- anim.done(function() {
7260
- var prop;
7261
- jQuery._removeData( elem, "fxshow" );
7262
- for ( prop in orig ) {
7263
- jQuery.style( elem, prop, orig[ prop ] );
7264
- }
7265
- });
7266
- for ( prop in orig ) {
7267
- tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7268
-
7269
- if ( !( prop in dataShow ) ) {
7270
- dataShow[ prop ] = tween.start;
7271
- if ( hidden ) {
7272
- tween.end = tween.start;
7273
- tween.start = prop === "width" || prop === "height" ? 1 : 0;
7274
- }
7275
- }
7276
- }
7277
- }
7278
- }
7279
-
7280
- function propFilter( props, specialEasing ) {
7281
- var index, name, easing, value, hooks;
7282
-
7283
- // camelCase, specialEasing and expand cssHook pass
7284
- for ( index in props ) {
7285
- name = jQuery.camelCase( index );
7286
- easing = specialEasing[ name ];
7287
- value = props[ index ];
7288
- if ( jQuery.isArray( value ) ) {
7289
- easing = value[ 1 ];
7290
- value = props[ index ] = value[ 0 ];
7291
- }
7292
-
7293
- if ( index !== name ) {
7294
- props[ name ] = value;
7295
- delete props[ index ];
7296
- }
7297
-
7298
- hooks = jQuery.cssHooks[ name ];
7299
- if ( hooks && "expand" in hooks ) {
7300
- value = hooks.expand( value );
7301
- delete props[ name ];
7302
-
7303
- // not quite $.extend, this wont overwrite keys already present.
7304
- // also - reusing 'index' from above because we have the correct "name"
7305
- for ( index in value ) {
7306
- if ( !( index in props ) ) {
7307
- props[ index ] = value[ index ];
7308
- specialEasing[ index ] = easing;
7309
- }
7310
- }
7311
- } else {
7312
- specialEasing[ name ] = easing;
7313
- }
7314
- }
7315
- }
7316
-
7317
- function Animation( elem, properties, options ) {
7318
- var result,
7319
- stopped,
7320
- index = 0,
7321
- length = animationPrefilters.length,
7322
- deferred = jQuery.Deferred().always( function() {
7323
- // don't match elem in the :animated selector
7324
- delete tick.elem;
7325
- }),
7326
- tick = function() {
7327
- if ( stopped ) {
7328
- return false;
7329
- }
7330
- var currentTime = fxNow || createFxNow(),
7331
- remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7332
- // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
7333
- temp = remaining / animation.duration || 0,
7334
- percent = 1 - temp,
7335
- index = 0,
7336
- length = animation.tweens.length;
7337
-
7338
- for ( ; index < length ; index++ ) {
7339
- animation.tweens[ index ].run( percent );
7340
- }
7341
-
7342
- deferred.notifyWith( elem, [ animation, percent, remaining ]);
7343
-
7344
- if ( percent < 1 && length ) {
7345
- return remaining;
7346
- } else {
7347
- deferred.resolveWith( elem, [ animation ] );
7348
- return false;
7349
- }
7350
- },
7351
- animation = deferred.promise({
7352
- elem: elem,
7353
- props: jQuery.extend( {}, properties ),
7354
- opts: jQuery.extend( true, { specialEasing: {} }, options ),
7355
- originalProperties: properties,
7356
- originalOptions: options,
7357
- startTime: fxNow || createFxNow(),
7358
- duration: options.duration,
7359
- tweens: [],
7360
- createTween: function( prop, end ) {
7361
- var tween = jQuery.Tween( elem, animation.opts, prop, end,
7362
- animation.opts.specialEasing[ prop ] || animation.opts.easing );
7363
- animation.tweens.push( tween );
7364
- return tween;
7365
- },
7366
- stop: function( gotoEnd ) {
7367
- var index = 0,
7368
- // if we are going to the end, we want to run all the tweens
7369
- // otherwise we skip this part
7370
- length = gotoEnd ? animation.tweens.length : 0;
7371
- if ( stopped ) {
7372
- return this;
7373
- }
7374
- stopped = true;
7375
- for ( ; index < length ; index++ ) {
7376
- animation.tweens[ index ].run( 1 );
7377
- }
7378
-
7379
- // resolve when we played the last frame
7380
- // otherwise, reject
7381
- if ( gotoEnd ) {
7382
- deferred.resolveWith( elem, [ animation, gotoEnd ] );
7383
- } else {
7384
- deferred.rejectWith( elem, [ animation, gotoEnd ] );
7385
- }
7386
- return this;
7387
- }
7388
- }),
7389
- props = animation.props;
7390
-
7391
- propFilter( props, animation.opts.specialEasing );
7392
-
7393
- for ( ; index < length ; index++ ) {
7394
- result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
7395
- if ( result ) {
7396
- return result;
7397
- }
7398
- }
7399
-
7400
- jQuery.map( props, createTween, animation );
7401
-
7402
- if ( jQuery.isFunction( animation.opts.start ) ) {
7403
- animation.opts.start.call( elem, animation );
7404
- }
7405
-
7406
- jQuery.fx.timer(
7407
- jQuery.extend( tick, {
7408
- elem: elem,
7409
- anim: animation,
7410
- queue: animation.opts.queue
7411
- })
7412
- );
7413
-
7414
- // attach callbacks from options
7415
- return animation.progress( animation.opts.progress )
7416
- .done( animation.opts.done, animation.opts.complete )
7417
- .fail( animation.opts.fail )
7418
- .always( animation.opts.always );
7419
- }
7420
-
7421
- jQuery.Animation = jQuery.extend( Animation, {
7422
- tweener: function( props, callback ) {
7423
- if ( jQuery.isFunction( props ) ) {
7424
- callback = props;
7425
- props = [ "*" ];
7426
- } else {
7427
- props = props.split(" ");
7428
- }
7429
-
7430
- var prop,
7431
- index = 0,
7432
- length = props.length;
7433
-
7434
- for ( ; index < length ; index++ ) {
7435
- prop = props[ index ];
7436
- tweeners[ prop ] = tweeners[ prop ] || [];
7437
- tweeners[ prop ].unshift( callback );
7438
- }
7439
- },
7440
-
7441
- prefilter: function( callback, prepend ) {
7442
- if ( prepend ) {
7443
- animationPrefilters.unshift( callback );
7444
- } else {
7445
- animationPrefilters.push( callback );
7446
- }
7447
- }
7448
- });
7449
-
7450
- jQuery.speed = function( speed, easing, fn ) {
7451
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7452
- complete: fn || !fn && easing ||
7453
- jQuery.isFunction( speed ) && speed,
7454
- duration: speed,
7455
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7456
- };
7457
-
7458
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7459
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7460
-
7461
- // normalize opt.queue - true/undefined/null -> "fx"
7462
- if ( opt.queue == null || opt.queue === true ) {
7463
- opt.queue = "fx";
7464
- }
7465
-
7466
- // Queueing
7467
- opt.old = opt.complete;
7468
-
7469
- opt.complete = function() {
7470
- if ( jQuery.isFunction( opt.old ) ) {
7471
- opt.old.call( this );
7472
- }
7473
-
7474
- if ( opt.queue ) {
7475
- jQuery.dequeue( this, opt.queue );
7476
- }
7477
- };
7478
-
7479
- return opt;
7480
- };
7481
-
7482
- jQuery.fn.extend({
7483
- fadeTo: function( speed, to, easing, callback ) {
7484
-
7485
- // show any hidden elements after setting opacity to 0
7486
- return this.filter( isHidden ).css( "opacity", 0 ).show()
7487
-
7488
- // animate to the value specified
7489
- .end().animate({ opacity: to }, speed, easing, callback );
7490
- },
7491
- animate: function( prop, speed, easing, callback ) {
7492
- var empty = jQuery.isEmptyObject( prop ),
7493
- optall = jQuery.speed( speed, easing, callback ),
7494
- doAnimation = function() {
7495
- // Operate on a copy of prop so per-property easing won't be lost
7496
- var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7497
-
7498
- // Empty animations, or finishing resolves immediately
7499
- if ( empty || jQuery._data( this, "finish" ) ) {
7500
- anim.stop( true );
7501
- }
7502
- };
7503
- doAnimation.finish = doAnimation;
7504
-
7505
- return empty || optall.queue === false ?
7506
- this.each( doAnimation ) :
7507
- this.queue( optall.queue, doAnimation );
7508
- },
7509
- stop: function( type, clearQueue, gotoEnd ) {
7510
- var stopQueue = function( hooks ) {
7511
- var stop = hooks.stop;
7512
- delete hooks.stop;
7513
- stop( gotoEnd );
7514
- };
7515
-
7516
- if ( typeof type !== "string" ) {
7517
- gotoEnd = clearQueue;
7518
- clearQueue = type;
7519
- type = undefined;
7520
- }
7521
- if ( clearQueue && type !== false ) {
7522
- this.queue( type || "fx", [] );
7523
- }
7524
-
7525
- return this.each(function() {
7526
- var dequeue = true,
7527
- index = type != null && type + "queueHooks",
7528
- timers = jQuery.timers,
7529
- data = jQuery._data( this );
7530
-
7531
- if ( index ) {
7532
- if ( data[ index ] && data[ index ].stop ) {
7533
- stopQueue( data[ index ] );
7534
- }
7535
- } else {
7536
- for ( index in data ) {
7537
- if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7538
- stopQueue( data[ index ] );
7539
- }
7540
- }
7541
- }
7542
-
7543
- for ( index = timers.length; index--; ) {
7544
- if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
7545
- timers[ index ].anim.stop( gotoEnd );
7546
- dequeue = false;
7547
- timers.splice( index, 1 );
7548
- }
7549
- }
7550
-
7551
- // start the next in the queue if the last step wasn't forced
7552
- // timers currently will call their complete callbacks, which will dequeue
7553
- // but only if they were gotoEnd
7554
- if ( dequeue || !gotoEnd ) {
7555
- jQuery.dequeue( this, type );
7556
- }
7557
- });
7558
- },
7559
- finish: function( type ) {
7560
- if ( type !== false ) {
7561
- type = type || "fx";
7562
- }
7563
- return this.each(function() {
7564
- var index,
7565
- data = jQuery._data( this ),
7566
- queue = data[ type + "queue" ],
7567
- hooks = data[ type + "queueHooks" ],
7568
- timers = jQuery.timers,
7569
- length = queue ? queue.length : 0;
7570
-
7571
- // enable finishing flag on private data
7572
- data.finish = true;
7573
-
7574
- // empty the queue first
7575
- jQuery.queue( this, type, [] );
7576
-
7577
- if ( hooks && hooks.stop ) {
7578
- hooks.stop.call( this, true );
7579
- }
7580
-
7581
- // look for any active animations, and finish them
7582
- for ( index = timers.length; index--; ) {
7583
- if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7584
- timers[ index ].anim.stop( true );
7585
- timers.splice( index, 1 );
7586
- }
7587
- }
7588
-
7589
- // look for any animations in the old queue and finish them
7590
- for ( index = 0; index < length; index++ ) {
7591
- if ( queue[ index ] && queue[ index ].finish ) {
7592
- queue[ index ].finish.call( this );
7593
- }
7594
- }
7595
-
7596
- // turn off finishing flag
7597
- delete data.finish;
7598
- });
7599
- }
7600
- });
7601
-
7602
- jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
7603
- var cssFn = jQuery.fn[ name ];
7604
- jQuery.fn[ name ] = function( speed, easing, callback ) {
7605
- return speed == null || typeof speed === "boolean" ?
7606
- cssFn.apply( this, arguments ) :
7607
- this.animate( genFx( name, true ), speed, easing, callback );
7608
- };
7609
- });
7610
-
7611
- // Generate shortcuts for custom animations
7612
- jQuery.each({
7613
- slideDown: genFx("show"),
7614
- slideUp: genFx("hide"),
7615
- slideToggle: genFx("toggle"),
7616
- fadeIn: { opacity: "show" },
7617
- fadeOut: { opacity: "hide" },
7618
- fadeToggle: { opacity: "toggle" }
7619
- }, function( name, props ) {
7620
- jQuery.fn[ name ] = function( speed, easing, callback ) {
7621
- return this.animate( props, speed, easing, callback );
7622
- };
7623
- });
7624
-
7625
- jQuery.timers = [];
7626
- jQuery.fx.tick = function() {
7627
- var timer,
7628
- timers = jQuery.timers,
7629
- i = 0;
7630
-
7631
- fxNow = jQuery.now();
7632
-
7633
- for ( ; i < timers.length; i++ ) {
7634
- timer = timers[ i ];
7635
- // Checks the timer has not already been removed
7636
- if ( !timer() && timers[ i ] === timer ) {
7637
- timers.splice( i--, 1 );
7638
- }
7639
- }
7640
-
7641
- if ( !timers.length ) {
7642
- jQuery.fx.stop();
7643
- }
7644
- fxNow = undefined;
7645
- };
7646
-
7647
- jQuery.fx.timer = function( timer ) {
7648
- jQuery.timers.push( timer );
7649
- if ( timer() ) {
7650
- jQuery.fx.start();
7651
- } else {
7652
- jQuery.timers.pop();
7653
- }
7654
- };
7655
-
7656
- jQuery.fx.interval = 13;
7657
-
7658
- jQuery.fx.start = function() {
7659
- if ( !timerId ) {
7660
- timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
7661
- }
7662
- };
7663
-
7664
- jQuery.fx.stop = function() {
7665
- clearInterval( timerId );
7666
- timerId = null;
7667
- };
7668
-
7669
- jQuery.fx.speeds = {
7670
- slow: 600,
7671
- fast: 200,
7672
- // Default speed
7673
- _default: 400
7674
- };
7675
-
7676
-
7677
- // Based off of the plugin by Clint Helfers, with permission.
7678
- // http://blindsignals.com/index.php/2009/07/jquery-delay/
7679
- jQuery.fn.delay = function( time, type ) {
7680
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7681
- type = type || "fx";
7682
-
7683
- return this.queue( type, function( next, hooks ) {
7684
- var timeout = setTimeout( next, time );
7685
- hooks.stop = function() {
7686
- clearTimeout( timeout );
7687
- };
7688
- });
7689
- };
7690
-
7691
-
7692
- (function() {
7693
- var a, input, select, opt,
7694
- div = document.createElement("div" );
7695
-
7696
- // Setup
7697
- div.setAttribute( "className", "t" );
7698
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
7699
- a = div.getElementsByTagName("a")[ 0 ];
7700
-
7701
- // First batch of tests.
7702
- select = document.createElement("select");
7703
- opt = select.appendChild( document.createElement("option") );
7704
- input = div.getElementsByTagName("input")[ 0 ];
7705
-
7706
- a.style.cssText = "top:1px";
7707
-
7708
- // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
7709
- support.getSetAttribute = div.className !== "t";
7710
-
7711
- // Get the style information from getAttribute
7712
- // (IE uses .cssText instead)
7713
- support.style = /top/.test( a.getAttribute("style") );
7714
-
7715
- // Make sure that URLs aren't manipulated
7716
- // (IE normalizes it by default)
7717
- support.hrefNormalized = a.getAttribute("href") === "/a";
7718
-
7719
- // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
7720
- support.checkOn = !!input.value;
7721
-
7722
- // Make sure that a selected-by-default option has a working selected property.
7723
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
7724
- support.optSelected = opt.selected;
7725
-
7726
- // Tests for enctype support on a form (#6743)
7727
- support.enctype = !!document.createElement("form").enctype;
7728
-
7729
- // Make sure that the options inside disabled selects aren't marked as disabled
7730
- // (WebKit marks them as disabled)
7731
- select.disabled = true;
7732
- support.optDisabled = !opt.disabled;
7733
-
7734
- // Support: IE8 only
7735
- // Check if we can trust getAttribute("value")
7736
- input = document.createElement( "input" );
7737
- input.setAttribute( "value", "" );
7738
- support.input = input.getAttribute( "value" ) === "";
7739
-
7740
- // Check if an input maintains its value after becoming a radio
7741
- input.value = "t";
7742
- input.setAttribute( "type", "radio" );
7743
- support.radioValue = input.value === "t";
7744
-
7745
- // Null elements to avoid leaks in IE.
7746
- a = input = select = opt = div = null;
7747
- })();
7748
-
7749
-
7750
- var rreturn = /\r/g;
7751
-
7752
- jQuery.fn.extend({
7753
- val: function( value ) {
7754
- var hooks, ret, isFunction,
7755
- elem = this[0];
7756
-
7757
- if ( !arguments.length ) {
7758
- if ( elem ) {
7759
- hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7760
-
7761
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7762
- return ret;
7763
- }
7764
-
7765
- ret = elem.value;
7766
-
7767
- return typeof ret === "string" ?
7768
- // handle most common string cases
7769
- ret.replace(rreturn, "") :
7770
- // handle cases where value is null/undef or number
7771
- ret == null ? "" : ret;
7772
- }
7773
-
7774
- return;
7775
- }
7776
-
7777
- isFunction = jQuery.isFunction( value );
7778
-
7779
- return this.each(function( i ) {
7780
- var val;
7781
-
7782
- if ( this.nodeType !== 1 ) {
7783
- return;
7784
- }
7785
-
7786
- if ( isFunction ) {
7787
- val = value.call( this, i, jQuery( this ).val() );
7788
- } else {
7789
- val = value;
7790
- }
7791
-
7792
- // Treat null/undefined as ""; convert numbers to string
7793
- if ( val == null ) {
7794
- val = "";
7795
- } else if ( typeof val === "number" ) {
7796
- val += "";
7797
- } else if ( jQuery.isArray( val ) ) {
7798
- val = jQuery.map( val, function( value ) {
7799
- return value == null ? "" : value + "";
7800
- });
7801
- }
7802
-
7803
- hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7804
-
7805
- // If set returns undefined, fall back to normal setting
7806
- if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7807
- this.value = val;
7808
- }
7809
- });
7810
- }
7811
- });
7812
-
7813
- jQuery.extend({
7814
- valHooks: {
7815
- option: {
7816
- get: function( elem ) {
7817
- var val = jQuery.find.attr( elem, "value" );
7818
- return val != null ?
7819
- val :
7820
- jQuery.text( elem );
7821
- }
7822
- },
7823
- select: {
7824
- get: function( elem ) {
7825
- var value, option,
7826
- options = elem.options,
7827
- index = elem.selectedIndex,
7828
- one = elem.type === "select-one" || index < 0,
7829
- values = one ? null : [],
7830
- max = one ? index + 1 : options.length,
7831
- i = index < 0 ?
7832
- max :
7833
- one ? index : 0;
7834
-
7835
- // Loop through all the selected options
7836
- for ( ; i < max; i++ ) {
7837
- option = options[ i ];
7838
-
7839
- // oldIE doesn't update selected after form reset (#2551)
7840
- if ( ( option.selected || i === index ) &&
7841
- // Don't return options that are disabled or in a disabled optgroup
7842
- ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
7843
- ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7844
-
7845
- // Get the specific value for the option
7846
- value = jQuery( option ).val();
7847
-
7848
- // We don't need an array for one selects
7849
- if ( one ) {
7850
- return value;
7851
- }
7852
-
7853
- // Multi-Selects return an array
7854
- values.push( value );
7855
- }
7856
- }
7857
-
7858
- return values;
7859
- },
7860
-
7861
- set: function( elem, value ) {
7862
- var optionSet, option,
7863
- options = elem.options,
7864
- values = jQuery.makeArray( value ),
7865
- i = options.length;
7866
-
7867
- while ( i-- ) {
7868
- option = options[ i ];
7869
-
7870
- if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
7871
-
7872
- // Support: IE6
7873
- // When new option element is added to select box we need to
7874
- // force reflow of newly added node in order to workaround delay
7875
- // of initialization properties
7876
- try {
7877
- option.selected = optionSet = true;
7878
-
7879
- } catch ( _ ) {
7880
-
7881
- // Will be executed only in IE6
7882
- option.scrollHeight;
7883
- }
7884
-
7885
- } else {
7886
- option.selected = false;
7887
- }
7888
- }
7889
-
7890
- // Force browsers to behave consistently when non-matching value is set
7891
- if ( !optionSet ) {
7892
- elem.selectedIndex = -1;
7893
- }
7894
-
7895
- return options;
7896
- }
7897
- }
7898
- }
7899
- });
7900
-
7901
- // Radios and checkboxes getter/setter
7902
- jQuery.each([ "radio", "checkbox" ], function() {
7903
- jQuery.valHooks[ this ] = {
7904
- set: function( elem, value ) {
7905
- if ( jQuery.isArray( value ) ) {
7906
- return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7907
- }
7908
- }
7909
- };
7910
- if ( !support.checkOn ) {
7911
- jQuery.valHooks[ this ].get = function( elem ) {
7912
- // Support: Webkit
7913
- // "" is returned instead of "on" if a value isn't specified
7914
- return elem.getAttribute("value") === null ? "on" : elem.value;
7915
- };
7916
- }
7917
- });
7918
-
7919
-
7920
-
7921
-
7922
- var nodeHook, boolHook,
7923
- attrHandle = jQuery.expr.attrHandle,
7924
- ruseDefault = /^(?:checked|selected)$/i,
7925
- getSetAttribute = support.getSetAttribute,
7926
- getSetInput = support.input;
7927
-
7928
- jQuery.fn.extend({
7929
- attr: function( name, value ) {
7930
- return access( this, jQuery.attr, name, value, arguments.length > 1 );
7931
- },
7932
-
7933
- removeAttr: function( name ) {
7934
- return this.each(function() {
7935
- jQuery.removeAttr( this, name );
7936
- });
7937
- }
7938
- });
7939
-
7940
- jQuery.extend({
7941
- attr: function( elem, name, value ) {
7942
- var hooks, ret,
7943
- nType = elem.nodeType;
7944
-
7945
- // don't get/set attributes on text, comment and attribute nodes
7946
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7947
- return;
7948
- }
7949
-
7950
- // Fallback to prop when attributes are not supported
7951
- if ( typeof elem.getAttribute === strundefined ) {
7952
- return jQuery.prop( elem, name, value );
7953
- }
7954
-
7955
- // All attributes are lowercase
7956
- // Grab necessary hook if one is defined
7957
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7958
- name = name.toLowerCase();
7959
- hooks = jQuery.attrHooks[ name ] ||
7960
- ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
7961
- }
7962
-
7963
- if ( value !== undefined ) {
7964
-
7965
- if ( value === null ) {
7966
- jQuery.removeAttr( elem, name );
7967
-
7968
- } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
7969
- return ret;
7970
-
7971
- } else {
7972
- elem.setAttribute( name, value + "" );
7973
- return value;
7974
- }
7975
-
7976
- } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
7977
- return ret;
7978
-
7979
- } else {
7980
- ret = jQuery.find.attr( elem, name );
7981
-
7982
- // Non-existent attributes return null, we normalize to undefined
7983
- return ret == null ?
7984
- undefined :
7985
- ret;
7986
- }
7987
- },
7988
-
7989
- removeAttr: function( elem, value ) {
7990
- var name, propName,
7991
- i = 0,
7992
- attrNames = value && value.match( rnotwhite );
7993
-
7994
- if ( attrNames && elem.nodeType === 1 ) {
7995
- while ( (name = attrNames[i++]) ) {
7996
- propName = jQuery.propFix[ name ] || name;
7997
-
7998
- // Boolean attributes get special treatment (#10870)
7999
- if ( jQuery.expr.match.bool.test( name ) ) {
8000
- // Set corresponding property to false
8001
- if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8002
- elem[ propName ] = false;
8003
- // Support: IE<9
8004
- // Also clear defaultChecked/defaultSelected (if appropriate)
8005
- } else {
8006
- elem[ jQuery.camelCase( "default-" + name ) ] =
8007
- elem[ propName ] = false;
8008
- }
8009
-
8010
- // See #9699 for explanation of this approach (setting first, then removal)
8011
- } else {
8012
- jQuery.attr( elem, name, "" );
8013
- }
8014
-
8015
- elem.removeAttribute( getSetAttribute ? name : propName );
8016
- }
8017
- }
8018
- },
8019
-
8020
- attrHooks: {
8021
- type: {
8022
- set: function( elem, value ) {
8023
- if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
8024
- // Setting the type on a radio button after the value resets the value in IE6-9
8025
- // Reset value to default in case type is set after value during creation
8026
- var val = elem.value;
8027
- elem.setAttribute( "type", value );
8028
- if ( val ) {
8029
- elem.value = val;
8030
- }
8031
- return value;
8032
- }
8033
- }
8034
- }
8035
- }
8036
- });
8037
-
8038
- // Hook for boolean attributes
8039
- boolHook = {
8040
- set: function( elem, value, name ) {
8041
- if ( value === false ) {
8042
- // Remove boolean attributes when set to false
8043
- jQuery.removeAttr( elem, name );
8044
- } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8045
- // IE<8 needs the *property* name
8046
- elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8047
-
8048
- // Use defaultChecked and defaultSelected for oldIE
8049
- } else {
8050
- elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8051
- }
8052
-
8053
- return name;
8054
- }
8055
- };
8056
-
8057
- // Retrieve booleans specially
8058
- jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8059
-
8060
- var getter = attrHandle[ name ] || jQuery.find.attr;
8061
-
8062
- attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
8063
- function( elem, name, isXML ) {
8064
- var ret, handle;
8065
- if ( !isXML ) {
8066
- // Avoid an infinite loop by temporarily removing this function from the getter
8067
- handle = attrHandle[ name ];
8068
- attrHandle[ name ] = ret;
8069
- ret = getter( elem, name, isXML ) != null ?
8070
- name.toLowerCase() :
8071
- null;
8072
- attrHandle[ name ] = handle;
8073
- }
8074
- return ret;
8075
- } :
8076
- function( elem, name, isXML ) {
8077
- if ( !isXML ) {
8078
- return elem[ jQuery.camelCase( "default-" + name ) ] ?
8079
- name.toLowerCase() :
8080
- null;
8081
- }
8082
- };
8083
- });
8084
-
8085
- // fix oldIE attroperties
8086
- if ( !getSetInput || !getSetAttribute ) {
8087
- jQuery.attrHooks.value = {
8088
- set: function( elem, value, name ) {
8089
- if ( jQuery.nodeName( elem, "input" ) ) {
8090
- // Does not return so that setAttribute is also used
8091
- elem.defaultValue = value;
8092
- } else {
8093
- // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8094
- return nodeHook && nodeHook.set( elem, value, name );
8095
- }
8096
- }
8097
- };
8098
- }
8099
-
8100
- // IE6/7 do not support getting/setting some attributes with get/setAttribute
8101
- if ( !getSetAttribute ) {
8102
-
8103
- // Use this for any attribute in IE6/7
8104
- // This fixes almost every IE6/7 issue
8105
- nodeHook = {
8106
- set: function( elem, value, name ) {
8107
- // Set the existing or create a new attribute node
8108
- var ret = elem.getAttributeNode( name );
8109
- if ( !ret ) {
8110
- elem.setAttributeNode(
8111
- (ret = elem.ownerDocument.createAttribute( name ))
8112
- );
8113
- }
8114
-
8115
- ret.value = value += "";
8116
-
8117
- // Break association with cloned elements by also using setAttribute (#9646)
8118
- if ( name === "value" || value === elem.getAttribute( name ) ) {
8119
- return value;
8120
- }
8121
- }
8122
- };
8123
-
8124
- // Some attributes are constructed with empty-string values when not defined
8125
- attrHandle.id = attrHandle.name = attrHandle.coords =
8126
- function( elem, name, isXML ) {
8127
- var ret;
8128
- if ( !isXML ) {
8129
- return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
8130
- ret.value :
8131
- null;
8132
- }
8133
- };
8134
-
8135
- // Fixing value retrieval on a button requires this module
8136
- jQuery.valHooks.button = {
8137
- get: function( elem, name ) {
8138
- var ret = elem.getAttributeNode( name );
8139
- if ( ret && ret.specified ) {
8140
- return ret.value;
8141
- }
8142
- },
8143
- set: nodeHook.set
8144
- };
8145
-
8146
- // Set contenteditable to false on removals(#10429)
8147
- // Setting to empty string throws an error as an invalid value
8148
- jQuery.attrHooks.contenteditable = {
8149
- set: function( elem, value, name ) {
8150
- nodeHook.set( elem, value === "" ? false : value, name );
8151
- }
8152
- };
8153
-
8154
- // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8155
- // This is for removals
8156
- jQuery.each([ "width", "height" ], function( i, name ) {
8157
- jQuery.attrHooks[ name ] = {
8158
- set: function( elem, value ) {
8159
- if ( value === "" ) {
8160
- elem.setAttribute( name, "auto" );
8161
- return value;
8162
- }
8163
- }
8164
- };
8165
- });
8166
- }
8167
-
8168
- if ( !support.style ) {
8169
- jQuery.attrHooks.style = {
8170
- get: function( elem ) {
8171
- // Return undefined in the case of empty string
8172
- // Note: IE uppercases css property names, but if we were to .toLowerCase()
8173
- // .cssText, that would destroy case senstitivity in URL's, like in "background"
8174
- return elem.style.cssText || undefined;
8175
- },
8176
- set: function( elem, value ) {
8177
- return ( elem.style.cssText = value + "" );
8178
- }
8179
- };
8180
- }
8181
-
8182
-
8183
-
8184
-
8185
- var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8186
- rclickable = /^(?:a|area)$/i;
8187
-
8188
- jQuery.fn.extend({
8189
- prop: function( name, value ) {
8190
- return access( this, jQuery.prop, name, value, arguments.length > 1 );
8191
- },
8192
-
8193
- removeProp: function( name ) {
8194
- name = jQuery.propFix[ name ] || name;
8195
- return this.each(function() {
8196
- // try/catch handles cases where IE balks (such as removing a property on window)
8197
- try {
8198
- this[ name ] = undefined;
8199
- delete this[ name ];
8200
- } catch( e ) {}
8201
- });
8202
- }
8203
- });
8204
-
8205
- jQuery.extend({
8206
- propFix: {
8207
- "for": "htmlFor",
8208
- "class": "className"
8209
- },
8210
-
8211
- prop: function( elem, name, value ) {
8212
- var ret, hooks, notxml,
8213
- nType = elem.nodeType;
8214
-
8215
- // don't get/set properties on text, comment and attribute nodes
8216
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
8217
- return;
8218
- }
8219
-
8220
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
8221
-
8222
- if ( notxml ) {
8223
- // Fix name and attach hooks
8224
- name = jQuery.propFix[ name ] || name;
8225
- hooks = jQuery.propHooks[ name ];
8226
- }
8227
-
8228
- if ( value !== undefined ) {
8229
- return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
8230
- ret :
8231
- ( elem[ name ] = value );
8232
-
8233
- } else {
8234
- return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
8235
- ret :
8236
- elem[ name ];
8237
- }
8238
- },
8239
-
8240
- propHooks: {
8241
- tabIndex: {
8242
- get: function( elem ) {
8243
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
8244
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8245
- // Use proper attribute retrieval(#12072)
8246
- var tabindex = jQuery.find.attr( elem, "tabindex" );
8247
-
8248
- return tabindex ?
8249
- parseInt( tabindex, 10 ) :
8250
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
8251
- 0 :
8252
- -1;
8253
- }
8254
- }
8255
- }
8256
- });
8257
-
8258
- // Some attributes require a special call on IE
8259
- // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8260
- if ( !support.hrefNormalized ) {
8261
- // href/src property should get the full normalized URL (#10299/#12915)
8262
- jQuery.each([ "href", "src" ], function( i, name ) {
8263
- jQuery.propHooks[ name ] = {
8264
- get: function( elem ) {
8265
- return elem.getAttribute( name, 4 );
8266
- }
8267
- };
8268
- });
8269
- }
8270
-
8271
- // Support: Safari, IE9+
8272
- // mis-reports the default selected property of an option
8273
- // Accessing the parent's selectedIndex property fixes it
8274
- if ( !support.optSelected ) {
8275
- jQuery.propHooks.selected = {
8276
- get: function( elem ) {
8277
- var parent = elem.parentNode;
8278
-
8279
- if ( parent ) {
8280
- parent.selectedIndex;
8281
-
8282
- // Make sure that it also works with optgroups, see #5701
8283
- if ( parent.parentNode ) {
8284
- parent.parentNode.selectedIndex;
8285
- }
8286
- }
8287
- return null;
8288
- }
8289
- };
8290
- }
8291
-
8292
- jQuery.each([
8293
- "tabIndex",
8294
- "readOnly",
8295
- "maxLength",
8296
- "cellSpacing",
8297
- "cellPadding",
8298
- "rowSpan",
8299
- "colSpan",
8300
- "useMap",
8301
- "frameBorder",
8302
- "contentEditable"
8303
- ], function() {
8304
- jQuery.propFix[ this.toLowerCase() ] = this;
8305
- });
8306
-
8307
- // IE6/7 call enctype encoding
8308
- if ( !support.enctype ) {
8309
- jQuery.propFix.enctype = "encoding";
8310
- }
8311
-
8312
-
8313
-
8314
-
8315
- var rclass = /[\t\r\n\f]/g;
8316
-
8317
- jQuery.fn.extend({
8318
- addClass: function( value ) {
8319
- var classes, elem, cur, clazz, j, finalValue,
8320
- i = 0,
8321
- len = this.length,
8322
- proceed = typeof value === "string" && value;
8323
-
8324
- if ( jQuery.isFunction( value ) ) {
8325
- return this.each(function( j ) {
8326
- jQuery( this ).addClass( value.call( this, j, this.className ) );
8327
- });
8328
- }
8329
-
8330
- if ( proceed ) {
8331
- // The disjunction here is for better compressibility (see removeClass)
8332
- classes = ( value || "" ).match( rnotwhite ) || [];
8333
-
8334
- for ( ; i < len; i++ ) {
8335
- elem = this[ i ];
8336
- cur = elem.nodeType === 1 && ( elem.className ?
8337
- ( " " + elem.className + " " ).replace( rclass, " " ) :
8338
- " "
8339
- );
8340
-
8341
- if ( cur ) {
8342
- j = 0;
8343
- while ( (clazz = classes[j++]) ) {
8344
- if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8345
- cur += clazz + " ";
8346
- }
8347
- }
8348
-
8349
- // only assign if different to avoid unneeded rendering.
8350
- finalValue = jQuery.trim( cur );
8351
- if ( elem.className !== finalValue ) {
8352
- elem.className = finalValue;
8353
- }
8354
- }
8355
- }
8356
- }
8357
-
8358
- return this;
8359
- },
8360
-
8361
- removeClass: function( value ) {
8362
- var classes, elem, cur, clazz, j, finalValue,
8363
- i = 0,
8364
- len = this.length,
8365
- proceed = arguments.length === 0 || typeof value === "string" && value;
8366
-
8367
- if ( jQuery.isFunction( value ) ) {
8368
- return this.each(function( j ) {
8369
- jQuery( this ).removeClass( value.call( this, j, this.className ) );
8370
- });
8371
- }
8372
- if ( proceed ) {
8373
- classes = ( value || "" ).match( rnotwhite ) || [];
8374
-
8375
- for ( ; i < len; i++ ) {
8376
- elem = this[ i ];
8377
- // This expression is here for better compressibility (see addClass)
8378
- cur = elem.nodeType === 1 && ( elem.className ?
8379
- ( " " + elem.className + " " ).replace( rclass, " " ) :
8380
- ""
8381
- );
8382
-
8383
- if ( cur ) {
8384
- j = 0;
8385
- while ( (clazz = classes[j++]) ) {
8386
- // Remove *all* instances
8387
- while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
8388
- cur = cur.replace( " " + clazz + " ", " " );
8389
- }
8390
- }
8391
-
8392
- // only assign if different to avoid unneeded rendering.
8393
- finalValue = value ? jQuery.trim( cur ) : "";
8394
- if ( elem.className !== finalValue ) {
8395
- elem.className = finalValue;
8396
- }
8397
- }
8398
- }
8399
- }
8400
-
8401
- return this;
8402
- },
8403
-
8404
- toggleClass: function( value, stateVal ) {
8405
- var type = typeof value;
8406
-
8407
- if ( typeof stateVal === "boolean" && type === "string" ) {
8408
- return stateVal ? this.addClass( value ) : this.removeClass( value );
8409
- }
8410
-
8411
- if ( jQuery.isFunction( value ) ) {
8412
- return this.each(function( i ) {
8413
- jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
8414
- });
8415
- }
8416
-
8417
- return this.each(function() {
8418
- if ( type === "string" ) {
8419
- // toggle individual class names
8420
- var className,
8421
- i = 0,
8422
- self = jQuery( this ),
8423
- classNames = value.match( rnotwhite ) || [];
8424
-
8425
- while ( (className = classNames[ i++ ]) ) {
8426
- // check each className given, space separated list
8427
- if ( self.hasClass( className ) ) {
8428
- self.removeClass( className );
8429
- } else {
8430
- self.addClass( className );
8431
- }
8432
- }
8433
-
8434
- // Toggle whole class name
8435
- } else if ( type === strundefined || type === "boolean" ) {
8436
- if ( this.className ) {
8437
- // store className if set
8438
- jQuery._data( this, "__className__", this.className );
8439
- }
8440
-
8441
- // If the element has a class name or if we're passed "false",
8442
- // then remove the whole classname (if there was one, the above saved it).
8443
- // Otherwise bring back whatever was previously saved (if anything),
8444
- // falling back to the empty string if nothing was stored.
8445
- this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
8446
- }
8447
- });
8448
- },
8449
-
8450
- hasClass: function( selector ) {
8451
- var className = " " + selector + " ",
8452
- i = 0,
8453
- l = this.length;
8454
- for ( ; i < l; i++ ) {
8455
- if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
8456
- return true;
8457
- }
8458
- }
8459
-
8460
- return false;
8461
- }
8462
- });
8463
-
8464
-
8465
-
8466
-
8467
- // Return jQuery for attributes-only inclusion
8468
-
8469
-
8470
- jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
8471
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8472
- "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
8473
-
8474
- // Handle event binding
8475
- jQuery.fn[ name ] = function( data, fn ) {
8476
- return arguments.length > 0 ?
8477
- this.on( name, null, data, fn ) :
8478
- this.trigger( name );
8479
- };
8480
- });
8481
-
8482
- jQuery.fn.extend({
8483
- hover: function( fnOver, fnOut ) {
8484
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8485
- },
8486
-
8487
- bind: function( types, data, fn ) {
8488
- return this.on( types, null, data, fn );
8489
- },
8490
- unbind: function( types, fn ) {
8491
- return this.off( types, null, fn );
8492
- },
8493
-
8494
- delegate: function( selector, types, data, fn ) {
8495
- return this.on( types, selector, data, fn );
8496
- },
8497
- undelegate: function( selector, types, fn ) {
8498
- // ( namespace ) or ( selector, types [, fn] )
8499
- return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
8500
- }
8501
- });
8502
-
8503
-
8504
- var nonce = jQuery.now();
8505
-
8506
- var rquery = (/\?/);
8507
-
8508
-
8509
-
8510
- var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
8511
-
8512
- jQuery.parseJSON = function( data ) {
8513
- // Attempt to parse using the native JSON parser first
8514
- if ( window.JSON && window.JSON.parse ) {
8515
- // Support: Android 2.3
8516
- // Workaround failure to string-cast null input
8517
- return window.JSON.parse( data + "" );
8518
- }
8519
-
8520
- var requireNonComma,
8521
- depth = null,
8522
- str = jQuery.trim( data + "" );
8523
-
8524
- // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
8525
- // after removing valid tokens
8526
- return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
8527
-
8528
- // Force termination if we see a misplaced comma
8529
- if ( requireNonComma && comma ) {
8530
- depth = 0;
8531
- }
8532
-
8533
- // Perform no more replacements after returning to outermost depth
8534
- if ( depth === 0 ) {
8535
- return token;
8536
- }
8537
-
8538
- // Commas must not follow "[", "{", or ","
8539
- requireNonComma = open || comma;
8540
-
8541
- // Determine new depth
8542
- // array/object open ("[" or "{"): depth += true - false (increment)
8543
- // array/object close ("]" or "}"): depth += false - true (decrement)
8544
- // other cases ("," or primitive): depth += true - true (numeric cast)
8545
- depth += !close - !open;
8546
-
8547
- // Remove this token
8548
- return "";
8549
- }) ) ?
8550
- ( Function( "return " + str ) )() :
8551
- jQuery.error( "Invalid JSON: " + data );
8552
- };
8553
-
8554
-
8555
- // Cross-browser xml parsing
8556
- jQuery.parseXML = function( data ) {
8557
- var xml, tmp;
8558
- if ( !data || typeof data !== "string" ) {
8559
- return null;
8560
- }
8561
- try {
8562
- if ( window.DOMParser ) { // Standard
8563
- tmp = new DOMParser();
8564
- xml = tmp.parseFromString( data, "text/xml" );
8565
- } else { // IE
8566
- xml = new ActiveXObject( "Microsoft.XMLDOM" );
8567
- xml.async = "false";
8568
- xml.loadXML( data );
8569
- }
8570
- } catch( e ) {
8571
- xml = undefined;
8572
- }
8573
- if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
8574
- jQuery.error( "Invalid XML: " + data );
8575
- }
8576
- return xml;
8577
- };
8578
-
8579
-
8580
- var
8581
- // Document location
8582
- ajaxLocParts,
8583
- ajaxLocation,
8584
-
8585
- rhash = /#.*$/,
8586
- rts = /([?&])_=[^&]*/,
8587
- rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
8588
- // #7653, #8125, #8152: local protocol detection
8589
- rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8590
- rnoContent = /^(?:GET|HEAD)$/,
8591
- rprotocol = /^\/\//,
8592
- rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
8593
-
8594
- /* Prefilters
8595
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8596
- * 2) These are called:
8597
- * - BEFORE asking for a transport
8598
- * - AFTER param serialization (s.data is a string if s.processData is true)
8599
- * 3) key is the dataType
8600
- * 4) the catchall symbol "*" can be used
8601
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8602
- */
8603
- prefilters = {},
8604
-
8605
- /* Transports bindings
8606
- * 1) key is the dataType
8607
- * 2) the catchall symbol "*" can be used
8608
- * 3) selection will start with transport dataType and THEN go to "*" if needed
8609
- */
8610
- transports = {},
8611
-
8612
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8613
- allTypes = "*/".concat("*");
8614
-
8615
- // #8138, IE may throw an exception when accessing
8616
- // a field from window.location if document.domain has been set
8617
- try {
8618
- ajaxLocation = location.href;
8619
- } catch( e ) {
8620
- // Use the href attribute of an A element
8621
- // since IE will modify it given document.location
8622
- ajaxLocation = document.createElement( "a" );
8623
- ajaxLocation.href = "";
8624
- ajaxLocation = ajaxLocation.href;
8625
- }
8626
-
8627
- // Segment location into parts
8628
- ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
8629
-
8630
- // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8631
- function addToPrefiltersOrTransports( structure ) {
8632
-
8633
- // dataTypeExpression is optional and defaults to "*"
8634
- return function( dataTypeExpression, func ) {
8635
-
8636
- if ( typeof dataTypeExpression !== "string" ) {
8637
- func = dataTypeExpression;
8638
- dataTypeExpression = "*";
8639
- }
8640
-
8641
- var dataType,
8642
- i = 0,
8643
- dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8644
-
8645
- if ( jQuery.isFunction( func ) ) {
8646
- // For each dataType in the dataTypeExpression
8647
- while ( (dataType = dataTypes[i++]) ) {
8648
- // Prepend if requested
8649
- if ( dataType.charAt( 0 ) === "+" ) {
8650
- dataType = dataType.slice( 1 ) || "*";
8651
- (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
8652
-
8653
- // Otherwise append
8654
- } else {
8655
- (structure[ dataType ] = structure[ dataType ] || []).push( func );
8656
- }
8657
- }
8658
- }
8659
- };
8660
- }
8661
-
8662
- // Base inspection function for prefilters and transports
8663
- function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8664
-
8665
- var inspected = {},
8666
- seekingTransport = ( structure === transports );
8667
-
8668
- function inspect( dataType ) {
8669
- var selected;
8670
- inspected[ dataType ] = true;
8671
- jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8672
- var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8673
- if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8674
- options.dataTypes.unshift( dataTypeOrTransport );
8675
- inspect( dataTypeOrTransport );
8676
- return false;
8677
- } else if ( seekingTransport ) {
8678
- return !( selected = dataTypeOrTransport );
8679
- }
8680
- });
8681
- return selected;
8682
- }
8683
-
8684
- return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8685
- }
8686
-
8687
- // A special extend for ajax options
8688
- // that takes "flat" options (not to be deep extended)
8689
- // Fixes #9887
8690
- function ajaxExtend( target, src ) {
8691
- var deep, key,
8692
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
8693
-
8694
- for ( key in src ) {
8695
- if ( src[ key ] !== undefined ) {
8696
- ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
8697
- }
8698
- }
8699
- if ( deep ) {
8700
- jQuery.extend( true, target, deep );
8701
- }
8702
-
8703
- return target;
8704
- }
8705
-
8706
- /* Handles responses to an ajax request:
8707
- * - finds the right dataType (mediates between content-type and expected dataType)
8708
- * - returns the corresponding response
8709
- */
8710
- function ajaxHandleResponses( s, jqXHR, responses ) {
8711
- var firstDataType, ct, finalDataType, type,
8712
- contents = s.contents,
8713
- dataTypes = s.dataTypes;
8714
-
8715
- // Remove auto dataType and get content-type in the process
8716
- while ( dataTypes[ 0 ] === "*" ) {
8717
- dataTypes.shift();
8718
- if ( ct === undefined ) {
8719
- ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8720
- }
8721
- }
8722
-
8723
- // Check if we're dealing with a known content-type
8724
- if ( ct ) {
8725
- for ( type in contents ) {
8726
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
8727
- dataTypes.unshift( type );
8728
- break;
8729
- }
8730
- }
8731
- }
8732
-
8733
- // Check to see if we have a response for the expected dataType
8734
- if ( dataTypes[ 0 ] in responses ) {
8735
- finalDataType = dataTypes[ 0 ];
8736
- } else {
8737
- // Try convertible dataTypes
8738
- for ( type in responses ) {
8739
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8740
- finalDataType = type;
8741
- break;
8742
- }
8743
- if ( !firstDataType ) {
8744
- firstDataType = type;
8745
- }
8746
- }
8747
- // Or just use first one
8748
- finalDataType = finalDataType || firstDataType;
8749
- }
8750
-
8751
- // If we found a dataType
8752
- // We add the dataType to the list if needed
8753
- // and return the corresponding response
8754
- if ( finalDataType ) {
8755
- if ( finalDataType !== dataTypes[ 0 ] ) {
8756
- dataTypes.unshift( finalDataType );
8757
- }
8758
- return responses[ finalDataType ];
8759
- }
8760
- }
8761
-
8762
- /* Chain conversions given the request and the original response
8763
- * Also sets the responseXXX fields on the jqXHR instance
8764
- */
8765
- function ajaxConvert( s, response, jqXHR, isSuccess ) {
8766
- var conv2, current, conv, tmp, prev,
8767
- converters = {},
8768
- // Work with a copy of dataTypes in case we need to modify it for conversion
8769
- dataTypes = s.dataTypes.slice();
8770
-
8771
- // Create converters map with lowercased keys
8772
- if ( dataTypes[ 1 ] ) {
8773
- for ( conv in s.converters ) {
8774
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
8775
- }
8776
- }
8777
-
8778
- current = dataTypes.shift();
8779
-
8780
- // Convert to each sequential dataType
8781
- while ( current ) {
8782
-
8783
- if ( s.responseFields[ current ] ) {
8784
- jqXHR[ s.responseFields[ current ] ] = response;
8785
- }
8786
-
8787
- // Apply the dataFilter if provided
8788
- if ( !prev && isSuccess && s.dataFilter ) {
8789
- response = s.dataFilter( response, s.dataType );
8790
- }
8791
-
8792
- prev = current;
8793
- current = dataTypes.shift();
8794
-
8795
- if ( current ) {
8796
-
8797
- // There's only work to do if current dataType is non-auto
8798
- if ( current === "*" ) {
8799
-
8800
- current = prev;
8801
-
8802
- // Convert response if prev dataType is non-auto and differs from current
8803
- } else if ( prev !== "*" && prev !== current ) {
8804
-
8805
- // Seek a direct converter
8806
- conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8807
-
8808
- // If none found, seek a pair
8809
- if ( !conv ) {
8810
- for ( conv2 in converters ) {
8811
-
8812
- // If conv2 outputs current
8813
- tmp = conv2.split( " " );
8814
- if ( tmp[ 1 ] === current ) {
8815
-
8816
- // If prev can be converted to accepted input
8817
- conv = converters[ prev + " " + tmp[ 0 ] ] ||
8818
- converters[ "* " + tmp[ 0 ] ];
8819
- if ( conv ) {
8820
- // Condense equivalence converters
8821
- if ( conv === true ) {
8822
- conv = converters[ conv2 ];
8823
-
8824
- // Otherwise, insert the intermediate dataType
8825
- } else if ( converters[ conv2 ] !== true ) {
8826
- current = tmp[ 0 ];
8827
- dataTypes.unshift( tmp[ 1 ] );
8828
- }
8829
- break;
8830
- }
8831
- }
8832
- }
8833
- }
8834
-
8835
- // Apply converter (if not an equivalence)
8836
- if ( conv !== true ) {
8837
-
8838
- // Unless errors are allowed to bubble, catch and return them
8839
- if ( conv && s[ "throws" ] ) {
8840
- response = conv( response );
8841
- } else {
8842
- try {
8843
- response = conv( response );
8844
- } catch ( e ) {
8845
- return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8846
- }
8847
- }
8848
- }
8849
- }
8850
- }
8851
- }
8852
-
8853
- return { state: "success", data: response };
8854
- }
8855
-
8856
- jQuery.extend({
8857
-
8858
- // Counter for holding the number of active queries
8859
- active: 0,
8860
-
8861
- // Last-Modified header cache for next request
8862
- lastModified: {},
8863
- etag: {},
8864
-
8865
- ajaxSettings: {
8866
- url: ajaxLocation,
8867
- type: "GET",
8868
- isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
8869
- global: true,
8870
- processData: true,
8871
- async: true,
8872
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8873
- /*
8874
- timeout: 0,
8875
- data: null,
8876
- dataType: null,
8877
- username: null,
8878
- password: null,
8879
- cache: null,
8880
- throws: false,
8881
- traditional: false,
8882
- headers: {},
8883
- */
8884
-
8885
- accepts: {
8886
- "*": allTypes,
8887
- text: "text/plain",
8888
- html: "text/html",
8889
- xml: "application/xml, text/xml",
8890
- json: "application/json, text/javascript"
8891
- },
8892
-
8893
- contents: {
8894
- xml: /xml/,
8895
- html: /html/,
8896
- json: /json/
8897
- },
8898
-
8899
- responseFields: {
8900
- xml: "responseXML",
8901
- text: "responseText",
8902
- json: "responseJSON"
8903
- },
8904
-
8905
- // Data converters
8906
- // Keys separate source (or catchall "*") and destination types with a single space
8907
- converters: {
8908
-
8909
- // Convert anything to text
8910
- "* text": String,
8911
-
8912
- // Text to html (true = no transformation)
8913
- "text html": true,
8914
-
8915
- // Evaluate text as a json expression
8916
- "text json": jQuery.parseJSON,
8917
-
8918
- // Parse text as xml
8919
- "text xml": jQuery.parseXML
8920
- },
8921
-
8922
- // For options that shouldn't be deep extended:
8923
- // you can add your own custom options here if
8924
- // and when you create one that shouldn't be
8925
- // deep extended (see ajaxExtend)
8926
- flatOptions: {
8927
- url: true,
8928
- context: true
8929
- }
8930
- },
8931
-
8932
- // Creates a full fledged settings object into target
8933
- // with both ajaxSettings and settings fields.
8934
- // If target is omitted, writes into ajaxSettings.
8935
- ajaxSetup: function( target, settings ) {
8936
- return settings ?
8937
-
8938
- // Building a settings object
8939
- ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8940
-
8941
- // Extending ajaxSettings
8942
- ajaxExtend( jQuery.ajaxSettings, target );
8943
- },
8944
-
8945
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8946
- ajaxTransport: addToPrefiltersOrTransports( transports ),
8947
-
8948
- // Main method
8949
- ajax: function( url, options ) {
8950
-
8951
- // If url is an object, simulate pre-1.5 signature
8952
- if ( typeof url === "object" ) {
8953
- options = url;
8954
- url = undefined;
8955
- }
8956
-
8957
- // Force options to be an object
8958
- options = options || {};
8959
-
8960
- var // Cross-domain detection vars
8961
- parts,
8962
- // Loop variable
8963
- i,
8964
- // URL without anti-cache param
8965
- cacheURL,
8966
- // Response headers as string
8967
- responseHeadersString,
8968
- // timeout handle
8969
- timeoutTimer,
8970
-
8971
- // To know if global events are to be dispatched
8972
- fireGlobals,
8973
-
8974
- transport,
8975
- // Response headers
8976
- responseHeaders,
8977
- // Create the final options object
8978
- s = jQuery.ajaxSetup( {}, options ),
8979
- // Callbacks context
8980
- callbackContext = s.context || s,
8981
- // Context for global events is callbackContext if it is a DOM node or jQuery collection
8982
- globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
8983
- jQuery( callbackContext ) :
8984
- jQuery.event,
8985
- // Deferreds
8986
- deferred = jQuery.Deferred(),
8987
- completeDeferred = jQuery.Callbacks("once memory"),
8988
- // Status-dependent callbacks
8989
- statusCode = s.statusCode || {},
8990
- // Headers (they are sent all at once)
8991
- requestHeaders = {},
8992
- requestHeadersNames = {},
8993
- // The jqXHR state
8994
- state = 0,
8995
- // Default abort message
8996
- strAbort = "canceled",
8997
- // Fake xhr
8998
- jqXHR = {
8999
- readyState: 0,
9000
-
9001
- // Builds headers hashtable if needed
9002
- getResponseHeader: function( key ) {
9003
- var match;
9004
- if ( state === 2 ) {
9005
- if ( !responseHeaders ) {
9006
- responseHeaders = {};
9007
- while ( (match = rheaders.exec( responseHeadersString )) ) {
9008
- responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
9009
- }
9010
- }
9011
- match = responseHeaders[ key.toLowerCase() ];
9012
- }
9013
- return match == null ? null : match;
9014
- },
9015
-
9016
- // Raw string
9017
- getAllResponseHeaders: function() {
9018
- return state === 2 ? responseHeadersString : null;
9019
- },
9020
-
9021
- // Caches the header
9022
- setRequestHeader: function( name, value ) {
9023
- var lname = name.toLowerCase();
9024
- if ( !state ) {
9025
- name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9026
- requestHeaders[ name ] = value;
9027
- }
9028
- return this;
9029
- },
9030
-
9031
- // Overrides response content-type header
9032
- overrideMimeType: function( type ) {
9033
- if ( !state ) {
9034
- s.mimeType = type;
9035
- }
9036
- return this;
9037
- },
9038
-
9039
- // Status-dependent callbacks
9040
- statusCode: function( map ) {
9041
- var code;
9042
- if ( map ) {
9043
- if ( state < 2 ) {
9044
- for ( code in map ) {
9045
- // Lazy-add the new callback in a way that preserves old ones
9046
- statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9047
- }
9048
- } else {
9049
- // Execute the appropriate callbacks
9050
- jqXHR.always( map[ jqXHR.status ] );
9051
- }
9052
- }
9053
- return this;
9054
- },
9055
-
9056
- // Cancel the request
9057
- abort: function( statusText ) {
9058
- var finalText = statusText || strAbort;
9059
- if ( transport ) {
9060
- transport.abort( finalText );
9061
- }
9062
- done( 0, finalText );
9063
- return this;
9064
- }
9065
- };
9066
-
9067
- // Attach deferreds
9068
- deferred.promise( jqXHR ).complete = completeDeferred.add;
9069
- jqXHR.success = jqXHR.done;
9070
- jqXHR.error = jqXHR.fail;
9071
-
9072
- // Remove hash character (#7531: and string promotion)
9073
- // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9074
- // Handle falsy url in the settings object (#10093: consistency with old signature)
9075
- // We also use the url parameter if available
9076
- s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9077
-
9078
- // Alias method option to type as per ticket #12004
9079
- s.type = options.method || options.type || s.method || s.type;
9080
-
9081
- // Extract dataTypes list
9082
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9083
-
9084
- // A cross-domain request is in order when we have a protocol:host:port mismatch
9085
- if ( s.crossDomain == null ) {
9086
- parts = rurl.exec( s.url.toLowerCase() );
9087
- s.crossDomain = !!( parts &&
9088
- ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9089
- ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9090
- ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9091
- );
9092
- }
9093
-
9094
- // Convert data if not already a string
9095
- if ( s.data && s.processData && typeof s.data !== "string" ) {
9096
- s.data = jQuery.param( s.data, s.traditional );
9097
- }
9098
-
9099
- // Apply prefilters
9100
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9101
-
9102
- // If request was aborted inside a prefilter, stop there
9103
- if ( state === 2 ) {
9104
- return jqXHR;
9105
- }
9106
-
9107
- // We can fire global events as of now if asked to
9108
- fireGlobals = s.global;
9109
-
9110
- // Watch for a new set of requests
9111
- if ( fireGlobals && jQuery.active++ === 0 ) {
9112
- jQuery.event.trigger("ajaxStart");
9113
- }
9114
-
9115
- // Uppercase the type
9116
- s.type = s.type.toUpperCase();
9117
-
9118
- // Determine if request has content
9119
- s.hasContent = !rnoContent.test( s.type );
9120
-
9121
- // Save the URL in case we're toying with the If-Modified-Since
9122
- // and/or If-None-Match header later on
9123
- cacheURL = s.url;
9124
-
9125
- // More options handling for requests with no content
9126
- if ( !s.hasContent ) {
9127
-
9128
- // If data is available, append data to url
9129
- if ( s.data ) {
9130
- cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9131
- // #9682: remove data so that it's not used in an eventual retry
9132
- delete s.data;
9133
- }
9134
-
9135
- // Add anti-cache in url if needed
9136
- if ( s.cache === false ) {
9137
- s.url = rts.test( cacheURL ) ?
9138
-
9139
- // If there is already a '_' parameter, set its value
9140
- cacheURL.replace( rts, "$1_=" + nonce++ ) :
9141
-
9142
- // Otherwise add one to the end
9143
- cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9144
- }
9145
- }
9146
-
9147
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9148
- if ( s.ifModified ) {
9149
- if ( jQuery.lastModified[ cacheURL ] ) {
9150
- jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9151
- }
9152
- if ( jQuery.etag[ cacheURL ] ) {
9153
- jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9154
- }
9155
- }
9156
-
9157
- // Set the correct header, if data is being sent
9158
- if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9159
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
9160
- }
9161
-
9162
- // Set the Accepts header for the server, depending on the dataType
9163
- jqXHR.setRequestHeader(
9164
- "Accept",
9165
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
9166
- s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9167
- s.accepts[ "*" ]
9168
- );
9169
-
9170
- // Check for headers option
9171
- for ( i in s.headers ) {
9172
- jqXHR.setRequestHeader( i, s.headers[ i ] );
9173
- }
9174
-
9175
- // Allow custom headers/mimetypes and early abort
9176
- if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9177
- // Abort if not done already and return
9178
- return jqXHR.abort();
9179
- }
9180
-
9181
- // aborting is no longer a cancellation
9182
- strAbort = "abort";
9183
-
9184
- // Install callbacks on deferreds
9185
- for ( i in { success: 1, error: 1, complete: 1 } ) {
9186
- jqXHR[ i ]( s[ i ] );
9187
- }
9188
-
9189
- // Get transport
9190
- transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9191
-
9192
- // If no transport, we auto-abort
9193
- if ( !transport ) {
9194
- done( -1, "No Transport" );
9195
- } else {
9196
- jqXHR.readyState = 1;
9197
-
9198
- // Send global event
9199
- if ( fireGlobals ) {
9200
- globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9201
- }
9202
- // Timeout
9203
- if ( s.async && s.timeout > 0 ) {
9204
- timeoutTimer = setTimeout(function() {
9205
- jqXHR.abort("timeout");
9206
- }, s.timeout );
9207
- }
9208
-
9209
- try {
9210
- state = 1;
9211
- transport.send( requestHeaders, done );
9212
- } catch ( e ) {
9213
- // Propagate exception as error if not done
9214
- if ( state < 2 ) {
9215
- done( -1, e );
9216
- // Simply rethrow otherwise
9217
- } else {
9218
- throw e;
9219
- }
9220
- }
9221
- }
9222
-
9223
- // Callback for when everything is done
9224
- function done( status, nativeStatusText, responses, headers ) {
9225
- var isSuccess, success, error, response, modified,
9226
- statusText = nativeStatusText;
9227
-
9228
- // Called once
9229
- if ( state === 2 ) {
9230
- return;
9231
- }
9232
-
9233
- // State is "done" now
9234
- state = 2;
9235
-
9236
- // Clear timeout if it exists
9237
- if ( timeoutTimer ) {
9238
- clearTimeout( timeoutTimer );
9239
- }
9240
-
9241
- // Dereference transport for early garbage collection
9242
- // (no matter how long the jqXHR object will be used)
9243
- transport = undefined;
9244
-
9245
- // Cache response headers
9246
- responseHeadersString = headers || "";
9247
-
9248
- // Set readyState
9249
- jqXHR.readyState = status > 0 ? 4 : 0;
9250
-
9251
- // Determine if successful
9252
- isSuccess = status >= 200 && status < 300 || status === 304;
9253
-
9254
- // Get response data
9255
- if ( responses ) {
9256
- response = ajaxHandleResponses( s, jqXHR, responses );
9257
- }
9258
-
9259
- // Convert no matter what (that way responseXXX fields are always set)
9260
- response = ajaxConvert( s, response, jqXHR, isSuccess );
9261
-
9262
- // If successful, handle type chaining
9263
- if ( isSuccess ) {
9264
-
9265
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9266
- if ( s.ifModified ) {
9267
- modified = jqXHR.getResponseHeader("Last-Modified");
9268
- if ( modified ) {
9269
- jQuery.lastModified[ cacheURL ] = modified;
9270
- }
9271
- modified = jqXHR.getResponseHeader("etag");
9272
- if ( modified ) {
9273
- jQuery.etag[ cacheURL ] = modified;
9274
- }
9275
- }
9276
-
9277
- // if no content
9278
- if ( status === 204 || s.type === "HEAD" ) {
9279
- statusText = "nocontent";
9280
-
9281
- // if not modified
9282
- } else if ( status === 304 ) {
9283
- statusText = "notmodified";
9284
-
9285
- // If we have data, let's convert it
9286
- } else {
9287
- statusText = response.state;
9288
- success = response.data;
9289
- error = response.error;
9290
- isSuccess = !error;
9291
- }
9292
- } else {
9293
- // We extract error from statusText
9294
- // then normalize statusText and status for non-aborts
9295
- error = statusText;
9296
- if ( status || !statusText ) {
9297
- statusText = "error";
9298
- if ( status < 0 ) {
9299
- status = 0;
9300
- }
9301
- }
9302
- }
9303
-
9304
- // Set data for the fake xhr object
9305
- jqXHR.status = status;
9306
- jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9307
-
9308
- // Success/Error
9309
- if ( isSuccess ) {
9310
- deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9311
- } else {
9312
- deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9313
- }
9314
-
9315
- // Status-dependent callbacks
9316
- jqXHR.statusCode( statusCode );
9317
- statusCode = undefined;
9318
-
9319
- if ( fireGlobals ) {
9320
- globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9321
- [ jqXHR, s, isSuccess ? success : error ] );
9322
- }
9323
-
9324
- // Complete
9325
- completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9326
-
9327
- if ( fireGlobals ) {
9328
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9329
- // Handle the global AJAX counter
9330
- if ( !( --jQuery.active ) ) {
9331
- jQuery.event.trigger("ajaxStop");
9332
- }
9333
- }
9334
- }
9335
-
9336
- return jqXHR;
9337
- },
9338
-
9339
- getJSON: function( url, data, callback ) {
9340
- return jQuery.get( url, data, callback, "json" );
9341
- },
9342
-
9343
- getScript: function( url, callback ) {
9344
- return jQuery.get( url, undefined, callback, "script" );
9345
- }
9346
- });
9347
-
9348
- jQuery.each( [ "get", "post" ], function( i, method ) {
9349
- jQuery[ method ] = function( url, data, callback, type ) {
9350
- // shift arguments if data argument was omitted
9351
- if ( jQuery.isFunction( data ) ) {
9352
- type = type || callback;
9353
- callback = data;
9354
- data = undefined;
9355
- }
9356
-
9357
- return jQuery.ajax({
9358
- url: url,
9359
- type: method,
9360
- dataType: type,
9361
- data: data,
9362
- success: callback
9363
- });
9364
- };
9365
- });
9366
-
9367
- // Attach a bunch of functions for handling common AJAX events
9368
- jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
9369
- jQuery.fn[ type ] = function( fn ) {
9370
- return this.on( type, fn );
9371
- };
9372
- });
9373
-
9374
-
9375
- jQuery._evalUrl = function( url ) {
9376
- return jQuery.ajax({
9377
- url: url,
9378
- type: "GET",
9379
- dataType: "script",
9380
- async: false,
9381
- global: false,
9382
- "throws": true
9383
- });
9384
- };
9385
-
9386
-
9387
- jQuery.fn.extend({
9388
- wrapAll: function( html ) {
9389
- if ( jQuery.isFunction( html ) ) {
9390
- return this.each(function(i) {
9391
- jQuery(this).wrapAll( html.call(this, i) );
9392
- });
9393
- }
9394
-
9395
- if ( this[0] ) {
9396
- // The elements to wrap the target around
9397
- var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
9398
-
9399
- if ( this[0].parentNode ) {
9400
- wrap.insertBefore( this[0] );
9401
- }
9402
-
9403
- wrap.map(function() {
9404
- var elem = this;
9405
-
9406
- while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9407
- elem = elem.firstChild;
9408
- }
9409
-
9410
- return elem;
9411
- }).append( this );
9412
- }
9413
-
9414
- return this;
9415
- },
9416
-
9417
- wrapInner: function( html ) {
9418
- if ( jQuery.isFunction( html ) ) {
9419
- return this.each(function(i) {
9420
- jQuery(this).wrapInner( html.call(this, i) );
9421
- });
9422
- }
9423
-
9424
- return this.each(function() {
9425
- var self = jQuery( this ),
9426
- contents = self.contents();
9427
-
9428
- if ( contents.length ) {
9429
- contents.wrapAll( html );
9430
-
9431
- } else {
9432
- self.append( html );
9433
- }
9434
- });
9435
- },
9436
-
9437
- wrap: function( html ) {
9438
- var isFunction = jQuery.isFunction( html );
9439
-
9440
- return this.each(function(i) {
9441
- jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
9442
- });
9443
- },
9444
-
9445
- unwrap: function() {
9446
- return this.parent().each(function() {
9447
- if ( !jQuery.nodeName( this, "body" ) ) {
9448
- jQuery( this ).replaceWith( this.childNodes );
9449
- }
9450
- }).end();
9451
- }
9452
- });
9453
-
9454
-
9455
- jQuery.expr.filters.hidden = function( elem ) {
9456
- // Support: Opera <= 12.12
9457
- // Opera reports offsetWidths and offsetHeights less than zero on some elements
9458
- return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
9459
- (!support.reliableHiddenOffsets() &&
9460
- ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
9461
- };
9462
-
9463
- jQuery.expr.filters.visible = function( elem ) {
9464
- return !jQuery.expr.filters.hidden( elem );
9465
- };
9466
-
9467
-
9468
-
9469
-
9470
- var r20 = /%20/g,
9471
- rbracket = /\[\]$/,
9472
- rCRLF = /\r?\n/g,
9473
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9474
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
9475
-
9476
- function buildParams( prefix, obj, traditional, add ) {
9477
- var name;
9478
-
9479
- if ( jQuery.isArray( obj ) ) {
9480
- // Serialize array item.
9481
- jQuery.each( obj, function( i, v ) {
9482
- if ( traditional || rbracket.test( prefix ) ) {
9483
- // Treat each array item as a scalar.
9484
- add( prefix, v );
9485
-
9486
- } else {
9487
- // Item is non-scalar (array or object), encode its numeric index.
9488
- buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
9489
- }
9490
- });
9491
-
9492
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
9493
- // Serialize object item.
9494
- for ( name in obj ) {
9495
- buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9496
- }
9497
-
9498
- } else {
9499
- // Serialize scalar item.
9500
- add( prefix, obj );
9501
- }
9502
- }
9503
-
9504
- // Serialize an array of form elements or a set of
9505
- // key/values into a query string
9506
- jQuery.param = function( a, traditional ) {
9507
- var prefix,
9508
- s = [],
9509
- add = function( key, value ) {
9510
- // If value is a function, invoke it and return its value
9511
- value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
9512
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
9513
- };
9514
-
9515
- // Set traditional to true for jQuery <= 1.3.2 behavior.
9516
- if ( traditional === undefined ) {
9517
- traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
9518
- }
9519
-
9520
- // If an array was passed in, assume that it is an array of form elements.
9521
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9522
- // Serialize the form elements
9523
- jQuery.each( a, function() {
9524
- add( this.name, this.value );
9525
- });
9526
-
9527
- } else {
9528
- // If traditional, encode the "old" way (the way 1.3.2 or older
9529
- // did it), otherwise encode params recursively.
9530
- for ( prefix in a ) {
9531
- buildParams( prefix, a[ prefix ], traditional, add );
9532
- }
9533
- }
9534
-
9535
- // Return the resulting serialization
9536
- return s.join( "&" ).replace( r20, "+" );
9537
- };
9538
-
9539
- jQuery.fn.extend({
9540
- serialize: function() {
9541
- return jQuery.param( this.serializeArray() );
9542
- },
9543
- serializeArray: function() {
9544
- return this.map(function() {
9545
- // Can add propHook for "elements" to filter or add form elements
9546
- var elements = jQuery.prop( this, "elements" );
9547
- return elements ? jQuery.makeArray( elements ) : this;
9548
- })
9549
- .filter(function() {
9550
- var type = this.type;
9551
- // Use .is(":disabled") so that fieldset[disabled] works
9552
- return this.name && !jQuery( this ).is( ":disabled" ) &&
9553
- rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9554
- ( this.checked || !rcheckableType.test( type ) );
9555
- })
9556
- .map(function( i, elem ) {
9557
- var val = jQuery( this ).val();
9558
-
9559
- return val == null ?
9560
- null :
9561
- jQuery.isArray( val ) ?
9562
- jQuery.map( val, function( val ) {
9563
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9564
- }) :
9565
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9566
- }).get();
9567
- }
9568
- });
9569
-
9570
-
9571
- // Create the request object
9572
- // (This is still attached to ajaxSettings for backward compatibility)
9573
- jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
9574
- // Support: IE6+
9575
- function() {
9576
-
9577
- // XHR cannot access local files, always use ActiveX for that case
9578
- return !this.isLocal &&
9579
-
9580
- // Support: IE7-8
9581
- // oldIE XHR does not support non-RFC2616 methods (#13240)
9582
- // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
9583
- // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
9584
- // Although this check for six methods instead of eight
9585
- // since IE also does not support "trace" and "connect"
9586
- /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
9587
-
9588
- createStandardXHR() || createActiveXHR();
9589
- } :
9590
- // For all other browsers, use the standard XMLHttpRequest object
9591
- createStandardXHR;
9592
-
9593
- var xhrId = 0,
9594
- xhrCallbacks = {},
9595
- xhrSupported = jQuery.ajaxSettings.xhr();
9596
-
9597
- // Support: IE<10
9598
- // Open requests must be manually aborted on unload (#5280)
9599
- if ( window.ActiveXObject ) {
9600
- jQuery( window ).on( "unload", function() {
9601
- for ( var key in xhrCallbacks ) {
9602
- xhrCallbacks[ key ]( undefined, true );
9603
- }
9604
- });
9605
- }
9606
-
9607
- // Determine support properties
9608
- support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9609
- xhrSupported = support.ajax = !!xhrSupported;
9610
-
9611
- // Create transport if the browser can provide an xhr
9612
- if ( xhrSupported ) {
9613
-
9614
- jQuery.ajaxTransport(function( options ) {
9615
- // Cross domain only allowed if supported through XMLHttpRequest
9616
- if ( !options.crossDomain || support.cors ) {
9617
-
9618
- var callback;
9619
-
9620
- return {
9621
- send: function( headers, complete ) {
9622
- var i,
9623
- xhr = options.xhr(),
9624
- id = ++xhrId;
9625
-
9626
- // Open the socket
9627
- xhr.open( options.type, options.url, options.async, options.username, options.password );
9628
-
9629
- // Apply custom fields if provided
9630
- if ( options.xhrFields ) {
9631
- for ( i in options.xhrFields ) {
9632
- xhr[ i ] = options.xhrFields[ i ];
9633
- }
9634
- }
9635
-
9636
- // Override mime type if needed
9637
- if ( options.mimeType && xhr.overrideMimeType ) {
9638
- xhr.overrideMimeType( options.mimeType );
9639
- }
9640
-
9641
- // X-Requested-With header
9642
- // For cross-domain requests, seeing as conditions for a preflight are
9643
- // akin to a jigsaw puzzle, we simply never set it to be sure.
9644
- // (it can always be set on a per-request basis or even using ajaxSetup)
9645
- // For same-domain requests, won't change header if already provided.
9646
- if ( !options.crossDomain && !headers["X-Requested-With"] ) {
9647
- headers["X-Requested-With"] = "XMLHttpRequest";
9648
- }
9649
-
9650
- // Set headers
9651
- for ( i in headers ) {
9652
- // Support: IE<9
9653
- // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
9654
- // request header to a null-value.
9655
- //
9656
- // To keep consistent with other XHR implementations, cast the value
9657
- // to string and ignore `undefined`.
9658
- if ( headers[ i ] !== undefined ) {
9659
- xhr.setRequestHeader( i, headers[ i ] + "" );
9660
- }
9661
- }
9662
-
9663
- // Do send the request
9664
- // This may raise an exception which is actually
9665
- // handled in jQuery.ajax (so no try/catch here)
9666
- xhr.send( ( options.hasContent && options.data ) || null );
9667
-
9668
- // Listener
9669
- callback = function( _, isAbort ) {
9670
- var status, statusText, responses;
9671
-
9672
- // Was never called and is aborted or complete
9673
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
9674
- // Clean up
9675
- delete xhrCallbacks[ id ];
9676
- callback = undefined;
9677
- xhr.onreadystatechange = jQuery.noop;
9678
-
9679
- // Abort manually if needed
9680
- if ( isAbort ) {
9681
- if ( xhr.readyState !== 4 ) {
9682
- xhr.abort();
9683
- }
9684
- } else {
9685
- responses = {};
9686
- status = xhr.status;
9687
-
9688
- // Support: IE<10
9689
- // Accessing binary-data responseText throws an exception
9690
- // (#11426)
9691
- if ( typeof xhr.responseText === "string" ) {
9692
- responses.text = xhr.responseText;
9693
- }
9694
-
9695
- // Firefox throws an exception when accessing
9696
- // statusText for faulty cross-domain requests
9697
- try {
9698
- statusText = xhr.statusText;
9699
- } catch( e ) {
9700
- // We normalize with Webkit giving an empty statusText
9701
- statusText = "";
9702
- }
9703
-
9704
- // Filter status for non standard behaviors
9705
-
9706
- // If the request is local and we have data: assume a success
9707
- // (success with no data won't get notified, that's the best we
9708
- // can do given current implementations)
9709
- if ( !status && options.isLocal && !options.crossDomain ) {
9710
- status = responses.text ? 200 : 404;
9711
- // IE - #1450: sometimes returns 1223 when it should be 204
9712
- } else if ( status === 1223 ) {
9713
- status = 204;
9714
- }
9715
- }
9716
- }
9717
-
9718
- // Call complete if needed
9719
- if ( responses ) {
9720
- complete( status, statusText, responses, xhr.getAllResponseHeaders() );
9721
- }
9722
- };
9723
-
9724
- if ( !options.async ) {
9725
- // if we're in sync mode we fire the callback
9726
- callback();
9727
- } else if ( xhr.readyState === 4 ) {
9728
- // (IE6 & IE7) if it's in cache and has been
9729
- // retrieved directly we need to fire the callback
9730
- setTimeout( callback );
9731
- } else {
9732
- // Add to the list of active xhr callbacks
9733
- xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
9734
- }
9735
- },
9736
-
9737
- abort: function() {
9738
- if ( callback ) {
9739
- callback( undefined, true );
9740
- }
9741
- }
9742
- };
9743
- }
9744
- });
9745
- }
9746
-
9747
- // Functions to create xhrs
9748
- function createStandardXHR() {
9749
- try {
9750
- return new window.XMLHttpRequest();
9751
- } catch( e ) {}
9752
- }
9753
-
9754
- function createActiveXHR() {
9755
- try {
9756
- return new window.ActiveXObject( "Microsoft.XMLHTTP" );
9757
- } catch( e ) {}
9758
- }
9759
-
9760
-
9761
-
9762
-
9763
- // Install script dataType
9764
- jQuery.ajaxSetup({
9765
- accepts: {
9766
- script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
9767
- },
9768
- contents: {
9769
- script: /(?:java|ecma)script/
9770
- },
9771
- converters: {
9772
- "text script": function( text ) {
9773
- jQuery.globalEval( text );
9774
- return text;
9775
- }
9776
- }
9777
- });
9778
-
9779
- // Handle cache's special case and global
9780
- jQuery.ajaxPrefilter( "script", function( s ) {
9781
- if ( s.cache === undefined ) {
9782
- s.cache = false;
9783
- }
9784
- if ( s.crossDomain ) {
9785
- s.type = "GET";
9786
- s.global = false;
9787
- }
9788
- });
9789
-
9790
- // Bind script tag hack transport
9791
- jQuery.ajaxTransport( "script", function(s) {
9792
-
9793
- // This transport only deals with cross domain requests
9794
- if ( s.crossDomain ) {
9795
-
9796
- var script,
9797
- head = document.head || jQuery("head")[0] || document.documentElement;
9798
-
9799
- return {
9800
-
9801
- send: function( _, callback ) {
9802
-
9803
- script = document.createElement("script");
9804
-
9805
- script.async = true;
9806
-
9807
- if ( s.scriptCharset ) {
9808
- script.charset = s.scriptCharset;
9809
- }
9810
-
9811
- script.src = s.url;
9812
-
9813
- // Attach handlers for all browsers
9814
- script.onload = script.onreadystatechange = function( _, isAbort ) {
9815
-
9816
- if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
9817
-
9818
- // Handle memory leak in IE
9819
- script.onload = script.onreadystatechange = null;
9820
-
9821
- // Remove the script
9822
- if ( script.parentNode ) {
9823
- script.parentNode.removeChild( script );
9824
- }
9825
-
9826
- // Dereference the script
9827
- script = null;
9828
-
9829
- // Callback if not abort
9830
- if ( !isAbort ) {
9831
- callback( 200, "success" );
9832
- }
9833
- }
9834
- };
9835
-
9836
- // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
9837
- // Use native DOM manipulation to avoid our domManip AJAX trickery
9838
- head.insertBefore( script, head.firstChild );
9839
- },
9840
-
9841
- abort: function() {
9842
- if ( script ) {
9843
- script.onload( undefined, true );
9844
- }
9845
- }
9846
- };
9847
- }
9848
- });
9849
-
9850
-
9851
-
9852
-
9853
- var oldCallbacks = [],
9854
- rjsonp = /(=)\?(?=&|$)|\?\?/;
9855
-
9856
- // Default jsonp settings
9857
- jQuery.ajaxSetup({
9858
- jsonp: "callback",
9859
- jsonpCallback: function() {
9860
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9861
- this[ callback ] = true;
9862
- return callback;
9863
- }
9864
- });
9865
-
9866
- // Detect, normalize options and install callbacks for jsonp requests
9867
- jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9868
-
9869
- var callbackName, overwritten, responseContainer,
9870
- jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9871
- "url" :
9872
- typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
9873
- );
9874
-
9875
- // Handle iff the expected data type is "jsonp" or we have a parameter to set
9876
- if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9877
-
9878
- // Get callback name, remembering preexisting value associated with it
9879
- callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9880
- s.jsonpCallback() :
9881
- s.jsonpCallback;
9882
-
9883
- // Insert callback into url or form data
9884
- if ( jsonProp ) {
9885
- s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9886
- } else if ( s.jsonp !== false ) {
9887
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9888
- }
9889
-
9890
- // Use data converter to retrieve json after script execution
9891
- s.converters["script json"] = function() {
9892
- if ( !responseContainer ) {
9893
- jQuery.error( callbackName + " was not called" );
9894
- }
9895
- return responseContainer[ 0 ];
9896
- };
9897
-
9898
- // force json dataType
9899
- s.dataTypes[ 0 ] = "json";
9900
-
9901
- // Install callback
9902
- overwritten = window[ callbackName ];
9903
- window[ callbackName ] = function() {
9904
- responseContainer = arguments;
9905
- };
9906
-
9907
- // Clean-up function (fires after converters)
9908
- jqXHR.always(function() {
9909
- // Restore preexisting value
9910
- window[ callbackName ] = overwritten;
9911
-
9912
- // Save back as free
9913
- if ( s[ callbackName ] ) {
9914
- // make sure that re-using the options doesn't screw things around
9915
- s.jsonpCallback = originalSettings.jsonpCallback;
9916
-
9917
- // save the callback name for future use
9918
- oldCallbacks.push( callbackName );
9919
- }
9920
-
9921
- // Call if it was a function and we have a response
9922
- if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9923
- overwritten( responseContainer[ 0 ] );
9924
- }
9925
-
9926
- responseContainer = overwritten = undefined;
9927
- });
9928
-
9929
- // Delegate to script
9930
- return "script";
9931
- }
9932
- });
9933
-
9934
-
9935
-
9936
-
9937
- // data: string of html
9938
- // context (optional): If specified, the fragment will be created in this context, defaults to document
9939
- // keepScripts (optional): If true, will include scripts passed in the html string
9940
- jQuery.parseHTML = function( data, context, keepScripts ) {
9941
- if ( !data || typeof data !== "string" ) {
9942
- return null;
9943
- }
9944
- if ( typeof context === "boolean" ) {
9945
- keepScripts = context;
9946
- context = false;
9947
- }
9948
- context = context || document;
9949
-
9950
- var parsed = rsingleTag.exec( data ),
9951
- scripts = !keepScripts && [];
9952
-
9953
- // Single tag
9954
- if ( parsed ) {
9955
- return [ context.createElement( parsed[1] ) ];
9956
- }
9957
-
9958
- parsed = jQuery.buildFragment( [ data ], context, scripts );
9959
-
9960
- if ( scripts && scripts.length ) {
9961
- jQuery( scripts ).remove();
9962
- }
9963
-
9964
- return jQuery.merge( [], parsed.childNodes );
9965
- };
9966
-
9967
-
9968
- // Keep a copy of the old load method
9969
- var _load = jQuery.fn.load;
9970
-
9971
- /**
9972
- * Load a url into a page
9973
- */
9974
- jQuery.fn.load = function( url, params, callback ) {
9975
- if ( typeof url !== "string" && _load ) {
9976
- return _load.apply( this, arguments );
9977
- }
9978
-
9979
- var selector, response, type,
9980
- self = this,
9981
- off = url.indexOf(" ");
9982
-
9983
- if ( off >= 0 ) {
9984
- selector = url.slice( off, url.length );
9985
- url = url.slice( 0, off );
9986
- }
9987
-
9988
- // If it's a function
9989
- if ( jQuery.isFunction( params ) ) {
9990
-
9991
- // We assume that it's the callback
9992
- callback = params;
9993
- params = undefined;
9994
-
9995
- // Otherwise, build a param string
9996
- } else if ( params && typeof params === "object" ) {
9997
- type = "POST";
9998
- }
9999
-
10000
- // If we have elements to modify, make the request
10001
- if ( self.length > 0 ) {
10002
- jQuery.ajax({
10003
- url: url,
10004
-
10005
- // if "type" variable is undefined, then "GET" method will be used
10006
- type: type,
10007
- dataType: "html",
10008
- data: params
10009
- }).done(function( responseText ) {
10010
-
10011
- // Save response for use in complete callback
10012
- response = arguments;
10013
-
10014
- self.html( selector ?
10015
-
10016
- // If a selector was specified, locate the right elements in a dummy div
10017
- // Exclude scripts to avoid IE 'Permission Denied' errors
10018
- jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
10019
-
10020
- // Otherwise use the full result
10021
- responseText );
10022
-
10023
- }).complete( callback && function( jqXHR, status ) {
10024
- self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
10025
- });
10026
- }
10027
-
10028
- return this;
10029
- };
10030
-
10031
-
10032
-
10033
-
10034
- jQuery.expr.filters.animated = function( elem ) {
10035
- return jQuery.grep(jQuery.timers, function( fn ) {
10036
- return elem === fn.elem;
10037
- }).length;
10038
- };
10039
-
10040
-
10041
-
10042
-
10043
-
10044
- var docElem = window.document.documentElement;
10045
-
10046
- /**
10047
- * Gets a window from an element
10048
- */
10049
- function getWindow( elem ) {
10050
- return jQuery.isWindow( elem ) ?
10051
- elem :
10052
- elem.nodeType === 9 ?
10053
- elem.defaultView || elem.parentWindow :
10054
- false;
10055
- }
10056
-
10057
- jQuery.offset = {
10058
- setOffset: function( elem, options, i ) {
10059
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10060
- position = jQuery.css( elem, "position" ),
10061
- curElem = jQuery( elem ),
10062
- props = {};
10063
-
10064
- // set position first, in-case top/left are set even on static elem
10065
- if ( position === "static" ) {
10066
- elem.style.position = "relative";
10067
- }
10068
-
10069
- curOffset = curElem.offset();
10070
- curCSSTop = jQuery.css( elem, "top" );
10071
- curCSSLeft = jQuery.css( elem, "left" );
10072
- calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10073
- jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
10074
-
10075
- // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
10076
- if ( calculatePosition ) {
10077
- curPosition = curElem.position();
10078
- curTop = curPosition.top;
10079
- curLeft = curPosition.left;
10080
- } else {
10081
- curTop = parseFloat( curCSSTop ) || 0;
10082
- curLeft = parseFloat( curCSSLeft ) || 0;
10083
- }
10084
-
10085
- if ( jQuery.isFunction( options ) ) {
10086
- options = options.call( elem, i, curOffset );
10087
- }
10088
-
10089
- if ( options.top != null ) {
10090
- props.top = ( options.top - curOffset.top ) + curTop;
10091
- }
10092
- if ( options.left != null ) {
10093
- props.left = ( options.left - curOffset.left ) + curLeft;
10094
- }
10095
-
10096
- if ( "using" in options ) {
10097
- options.using.call( elem, props );
10098
- } else {
10099
- curElem.css( props );
10100
- }
10101
- }
10102
- };
10103
-
10104
- jQuery.fn.extend({
10105
- offset: function( options ) {
10106
- if ( arguments.length ) {
10107
- return options === undefined ?
10108
- this :
10109
- this.each(function( i ) {
10110
- jQuery.offset.setOffset( this, options, i );
10111
- });
10112
- }
10113
-
10114
- var docElem, win,
10115
- box = { top: 0, left: 0 },
10116
- elem = this[ 0 ],
10117
- doc = elem && elem.ownerDocument;
10118
-
10119
- if ( !doc ) {
10120
- return;
10121
- }
10122
-
10123
- docElem = doc.documentElement;
10124
-
10125
- // Make sure it's not a disconnected DOM node
10126
- if ( !jQuery.contains( docElem, elem ) ) {
10127
- return box;
10128
- }
10129
-
10130
- // If we don't have gBCR, just use 0,0 rather than error
10131
- // BlackBerry 5, iOS 3 (original iPhone)
10132
- if ( typeof elem.getBoundingClientRect !== strundefined ) {
10133
- box = elem.getBoundingClientRect();
10134
- }
10135
- win = getWindow( doc );
10136
- return {
10137
- top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10138
- left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10139
- };
10140
- },
10141
-
10142
- position: function() {
10143
- if ( !this[ 0 ] ) {
10144
- return;
10145
- }
10146
-
10147
- var offsetParent, offset,
10148
- parentOffset = { top: 0, left: 0 },
10149
- elem = this[ 0 ];
10150
-
10151
- // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
10152
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
10153
- // we assume that getBoundingClientRect is available when computed position is fixed
10154
- offset = elem.getBoundingClientRect();
10155
- } else {
10156
- // Get *real* offsetParent
10157
- offsetParent = this.offsetParent();
10158
-
10159
- // Get correct offsets
10160
- offset = this.offset();
10161
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10162
- parentOffset = offsetParent.offset();
10163
- }
10164
-
10165
- // Add offsetParent borders
10166
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10167
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10168
- }
10169
-
10170
- // Subtract parent offsets and element margins
10171
- // note: when an element has margin: auto the offsetLeft and marginLeft
10172
- // are the same in Safari causing offset.left to incorrectly be 0
10173
- return {
10174
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10175
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
10176
- };
10177
- },
10178
-
10179
- offsetParent: function() {
10180
- return this.map(function() {
10181
- var offsetParent = this.offsetParent || docElem;
10182
-
10183
- while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
10184
- offsetParent = offsetParent.offsetParent;
10185
- }
10186
- return offsetParent || docElem;
10187
- });
10188
- }
10189
- });
10190
-
10191
- // Create scrollLeft and scrollTop methods
10192
- jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10193
- var top = /Y/.test( prop );
10194
-
10195
- jQuery.fn[ method ] = function( val ) {
10196
- return access( this, function( elem, method, val ) {
10197
- var win = getWindow( elem );
10198
-
10199
- if ( val === undefined ) {
10200
- return win ? (prop in win) ? win[ prop ] :
10201
- win.document.documentElement[ method ] :
10202
- elem[ method ];
10203
- }
10204
-
10205
- if ( win ) {
10206
- win.scrollTo(
10207
- !top ? val : jQuery( win ).scrollLeft(),
10208
- top ? val : jQuery( win ).scrollTop()
10209
- );
10210
-
10211
- } else {
10212
- elem[ method ] = val;
10213
- }
10214
- }, method, val, arguments.length, null );
10215
- };
10216
- });
10217
-
10218
- // Add the top/left cssHooks using jQuery.fn.position
10219
- // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10220
- // getComputedStyle returns percent when specified for top/left/bottom/right
10221
- // rather than make the css module depend on the offset module, we just check for it here
10222
- jQuery.each( [ "top", "left" ], function( i, prop ) {
10223
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10224
- function( elem, computed ) {
10225
- if ( computed ) {
10226
- computed = curCSS( elem, prop );
10227
- // if curCSS returns percentage, fallback to offset
10228
- return rnumnonpx.test( computed ) ?
10229
- jQuery( elem ).position()[ prop ] + "px" :
10230
- computed;
10231
- }
10232
- }
10233
- );
10234
- });
10235
-
10236
-
10237
- // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10238
- jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10239
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
10240
- // margin is only for outerHeight, outerWidth
10241
- jQuery.fn[ funcName ] = function( margin, value ) {
10242
- var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10243
- extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10244
-
10245
- return access( this, function( elem, type, value ) {
10246
- var doc;
10247
-
10248
- if ( jQuery.isWindow( elem ) ) {
10249
- // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10250
- // isn't a whole lot we can do. See pull request at this URL for discussion:
10251
- // https://github.com/jquery/jquery/pull/764
10252
- return elem.document.documentElement[ "client" + name ];
10253
- }
10254
-
10255
- // Get document width or height
10256
- if ( elem.nodeType === 9 ) {
10257
- doc = elem.documentElement;
10258
-
10259
- // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
10260
- // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
10261
- return Math.max(
10262
- elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10263
- elem.body[ "offset" + name ], doc[ "offset" + name ],
10264
- doc[ "client" + name ]
10265
- );
10266
- }
10267
-
10268
- return value === undefined ?
10269
- // Get width or height on the element, requesting but not forcing parseFloat
10270
- jQuery.css( elem, type, extra ) :
10271
-
10272
- // Set width or height on the element
10273
- jQuery.style( elem, type, value, extra );
10274
- }, type, chainable ? margin : undefined, chainable, null );
10275
- };
10276
- });
10277
- });
10278
-
10279
-
10280
- // The number of elements contained in the matched element set
10281
- jQuery.fn.size = function() {
10282
- return this.length;
10283
- };
10284
-
10285
- jQuery.fn.andSelf = jQuery.fn.addBack;
10286
-
10287
-
10288
-
10289
-
10290
- // Register as a named AMD module, since jQuery can be concatenated with other
10291
- // files that may use define, but not via a proper concatenation script that
10292
- // understands anonymous AMD modules. A named AMD is safest and most robust
10293
- // way to register. Lowercase jquery is used because AMD module names are
10294
- // derived from file names, and jQuery is normally delivered in a lowercase
10295
- // file name. Do this after creating the global so that if an AMD module wants
10296
- // to call noConflict to hide this version of jQuery, it will work.
10297
- if ( typeof define === "function" && define.amd ) {
10298
- define( "jquery", [], function() {
10299
- return jQuery;
10300
- });
10301
- }
10302
-
10303
-
10304
-
10305
-
10306
- var
10307
- // Map over jQuery in case of overwrite
10308
- _jQuery = window.jQuery,
10309
-
10310
- // Map over the $ in case of overwrite
10311
- _$ = window.$;
10312
-
10313
- jQuery.noConflict = function( deep ) {
10314
- if ( window.$ === jQuery ) {
10315
- window.$ = _$;
10316
- }
10317
-
10318
- if ( deep && window.jQuery === jQuery ) {
10319
- window.jQuery = _jQuery;
10320
- }
10321
-
10322
- return jQuery;
10323
- };
10324
-
10325
- // Expose jQuery and $ identifiers, even in
10326
- // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10327
- // and CommonJS for browser emulators (#13566)
10328
- if ( typeof noGlobal === strundefined ) {
10329
- window.jQuery = window.$ = jQuery;
10330
- }
10331
-
10332
-
10333
-
10334
-
10335
- return jQuery;
10336
-
10337
- }));
1
+ /*!
2
+ * jQuery JavaScript Library v1.11.0
3
+ * http://jquery.com/
4
+ *
5
+ * Includes Sizzle.js
6
+ * http://sizzlejs.com/
7
+ *
8
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9
+ * Released under the MIT license
10
+ * http://jquery.org/license
11
+ *
12
+ * Date: 2014-01-23T21:02Z
13
+ */
14
+
15
+ (function( global, factory ) {
16
+
17
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
18
+ // For CommonJS and CommonJS-like environments where a proper window is present,
19
+ // execute the factory and get jQuery
20
+ // For environments that do not inherently posses a window with a document
21
+ // (such as Node.js), expose a jQuery-making factory as module.exports
22
+ // This accentuates the need for the creation of a real window
23
+ // e.g. var jQuery = require("jquery")(window);
24
+ // See ticket #14549 for more info
25
+ module.exports = global.document ?
26
+ factory( global, true ) :
27
+ function( w ) {
28
+ if ( !w.document ) {
29
+ throw new Error( "jQuery requires a window with a document" );
30
+ }
31
+ return factory( w );
32
+ };
33
+ } else {
34
+ factory( global );
35
+ }
36
+
37
+ // Pass this if window is not defined yet
38
+ }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
+
40
+ // Can't do this because several apps including ASP.NET trace
41
+ // the stack via arguments.caller.callee and Firefox dies if
42
+ // you try to trace through "use strict" call chains. (#13335)
43
+ // Support: Firefox 18+
44
+ //
45
+
46
+ var deletedIds = [];
47
+
48
+ var slice = deletedIds.slice;
49
+
50
+ var concat = deletedIds.concat;
51
+
52
+ var push = deletedIds.push;
53
+
54
+ var indexOf = deletedIds.indexOf;
55
+
56
+ var class2type = {};
57
+
58
+ var toString = class2type.toString;
59
+
60
+ var hasOwn = class2type.hasOwnProperty;
61
+
62
+ var trim = "".trim;
63
+
64
+ var support = {};
65
+
66
+
67
+
68
+ var
69
+ version = "1.11.0",
70
+
71
+ // Define a local copy of jQuery
72
+ jQuery = function( selector, context ) {
73
+ // The jQuery object is actually just the init constructor 'enhanced'
74
+ // Need init if jQuery is called (just allow error to be thrown if not included)
75
+ return new jQuery.fn.init( selector, context );
76
+ },
77
+
78
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
79
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
80
+
81
+ // Matches dashed string for camelizing
82
+ rmsPrefix = /^-ms-/,
83
+ rdashAlpha = /-([\da-z])/gi,
84
+
85
+ // Used by jQuery.camelCase as callback to replace()
86
+ fcamelCase = function( all, letter ) {
87
+ return letter.toUpperCase();
88
+ };
89
+
90
+ jQuery.fn = jQuery.prototype = {
91
+ // The current version of jQuery being used
92
+ jquery: version,
93
+
94
+ constructor: jQuery,
95
+
96
+ // Start with an empty selector
97
+ selector: "",
98
+
99
+ // The default length of a jQuery object is 0
100
+ length: 0,
101
+
102
+ toArray: function() {
103
+ return slice.call( this );
104
+ },
105
+
106
+ // Get the Nth element in the matched element set OR
107
+ // Get the whole matched element set as a clean array
108
+ get: function( num ) {
109
+ return num != null ?
110
+
111
+ // Return a 'clean' array
112
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
113
+
114
+ // Return just the object
115
+ slice.call( this );
116
+ },
117
+
118
+ // Take an array of elements and push it onto the stack
119
+ // (returning the new matched element set)
120
+ pushStack: function( elems ) {
121
+
122
+ // Build a new jQuery matched element set
123
+ var ret = jQuery.merge( this.constructor(), elems );
124
+
125
+ // Add the old object onto the stack (as a reference)
126
+ ret.prevObject = this;
127
+ ret.context = this.context;
128
+
129
+ // Return the newly-formed element set
130
+ return ret;
131
+ },
132
+
133
+ // Execute a callback for every element in the matched set.
134
+ // (You can seed the arguments with an array of args, but this is
135
+ // only used internally.)
136
+ each: function( callback, args ) {
137
+ return jQuery.each( this, callback, args );
138
+ },
139
+
140
+ map: function( callback ) {
141
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
142
+ return callback.call( elem, i, elem );
143
+ }));
144
+ },
145
+
146
+ slice: function() {
147
+ return this.pushStack( slice.apply( this, arguments ) );
148
+ },
149
+
150
+ first: function() {
151
+ return this.eq( 0 );
152
+ },
153
+
154
+ last: function() {
155
+ return this.eq( -1 );
156
+ },
157
+
158
+ eq: function( i ) {
159
+ var len = this.length,
160
+ j = +i + ( i < 0 ? len : 0 );
161
+ return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
162
+ },
163
+
164
+ end: function() {
165
+ return this.prevObject || this.constructor(null);
166
+ },
167
+
168
+ // For internal use only.
169
+ // Behaves like an Array's method, not like a jQuery method.
170
+ push: push,
171
+ sort: deletedIds.sort,
172
+ splice: deletedIds.splice
173
+ };
174
+
175
+ jQuery.extend = jQuery.fn.extend = function() {
176
+ var src, copyIsArray, copy, name, options, clone,
177
+ target = arguments[0] || {},
178
+ i = 1,
179
+ length = arguments.length,
180
+ deep = false;
181
+
182
+ // Handle a deep copy situation
183
+ if ( typeof target === "boolean" ) {
184
+ deep = target;
185
+
186
+ // skip the boolean and the target
187
+ target = arguments[ i ] || {};
188
+ i++;
189
+ }
190
+
191
+ // Handle case when target is a string or something (possible in deep copy)
192
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
193
+ target = {};
194
+ }
195
+
196
+ // extend jQuery itself if only one argument is passed
197
+ if ( i === length ) {
198
+ target = this;
199
+ i--;
200
+ }
201
+
202
+ for ( ; i < length; i++ ) {
203
+ // Only deal with non-null/undefined values
204
+ if ( (options = arguments[ i ]) != null ) {
205
+ // Extend the base object
206
+ for ( name in options ) {
207
+ src = target[ name ];
208
+ copy = options[ name ];
209
+
210
+ // Prevent never-ending loop
211
+ if ( target === copy ) {
212
+ continue;
213
+ }
214
+
215
+ // Recurse if we're merging plain objects or arrays
216
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
217
+ if ( copyIsArray ) {
218
+ copyIsArray = false;
219
+ clone = src && jQuery.isArray(src) ? src : [];
220
+
221
+ } else {
222
+ clone = src && jQuery.isPlainObject(src) ? src : {};
223
+ }
224
+
225
+ // Never move original objects, clone them
226
+ target[ name ] = jQuery.extend( deep, clone, copy );
227
+
228
+ // Don't bring in undefined values
229
+ } else if ( copy !== undefined ) {
230
+ target[ name ] = copy;
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ // Return the modified object
237
+ return target;
238
+ };
239
+
240
+ jQuery.extend({
241
+ // Unique for each copy of jQuery on the page
242
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
243
+
244
+ // Assume jQuery is ready without the ready module
245
+ isReady: true,
246
+
247
+ error: function( msg ) {
248
+ throw new Error( msg );
249
+ },
250
+
251
+ noop: function() {},
252
+
253
+ // See test/unit/core.js for details concerning isFunction.
254
+ // Since version 1.3, DOM methods and functions like alert
255
+ // aren't supported. They return false on IE (#2968).
256
+ isFunction: function( obj ) {
257
+ return jQuery.type(obj) === "function";
258
+ },
259
+
260
+ isArray: Array.isArray || function( obj ) {
261
+ return jQuery.type(obj) === "array";
262
+ },
263
+
264
+ isWindow: function( obj ) {
265
+ /* jshint eqeqeq: false */
266
+ return obj != null && obj == obj.window;
267
+ },
268
+
269
+ isNumeric: function( obj ) {
270
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
271
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
272
+ // subtraction forces infinities to NaN
273
+ return obj - parseFloat( obj ) >= 0;
274
+ },
275
+
276
+ isEmptyObject: function( obj ) {
277
+ var name;
278
+ for ( name in obj ) {
279
+ return false;
280
+ }
281
+ return true;
282
+ },
283
+
284
+ isPlainObject: function( obj ) {
285
+ var key;
286
+
287
+ // Must be an Object.
288
+ // Because of IE, we also have to check the presence of the constructor property.
289
+ // Make sure that DOM nodes and window objects don't pass through, as well
290
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
291
+ return false;
292
+ }
293
+
294
+ try {
295
+ // Not own constructor property must be Object
296
+ if ( obj.constructor &&
297
+ !hasOwn.call(obj, "constructor") &&
298
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
299
+ return false;
300
+ }
301
+ } catch ( e ) {
302
+ // IE8,9 Will throw exceptions on certain host objects #9897
303
+ return false;
304
+ }
305
+
306
+ // Support: IE<9
307
+ // Handle iteration over inherited properties before own properties.
308
+ if ( support.ownLast ) {
309
+ for ( key in obj ) {
310
+ return hasOwn.call( obj, key );
311
+ }
312
+ }
313
+
314
+ // Own properties are enumerated firstly, so to speed up,
315
+ // if last one is own, then all properties are own.
316
+ for ( key in obj ) {}
317
+
318
+ return key === undefined || hasOwn.call( obj, key );
319
+ },
320
+
321
+ type: function( obj ) {
322
+ if ( obj == null ) {
323
+ return obj + "";
324
+ }
325
+ return typeof obj === "object" || typeof obj === "function" ?
326
+ class2type[ toString.call(obj) ] || "object" :
327
+ typeof obj;
328
+ },
329
+
330
+ // Evaluates a script in a global context
331
+ // Workarounds based on findings by Jim Driscoll
332
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
333
+ globalEval: function( data ) {
334
+ if ( data && jQuery.trim( data ) ) {
335
+ // We use execScript on Internet Explorer
336
+ // We use an anonymous function so that context is window
337
+ // rather than jQuery in Firefox
338
+ ( window.execScript || function( data ) {
339
+ window[ "eval" ].call( window, data );
340
+ } )( data );
341
+ }
342
+ },
343
+
344
+ // Convert dashed to camelCase; used by the css and data modules
345
+ // Microsoft forgot to hump their vendor prefix (#9572)
346
+ camelCase: function( string ) {
347
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
348
+ },
349
+
350
+ nodeName: function( elem, name ) {
351
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
352
+ },
353
+
354
+ // args is for internal usage only
355
+ each: function( obj, callback, args ) {
356
+ var value,
357
+ i = 0,
358
+ length = obj.length,
359
+ isArray = isArraylike( obj );
360
+
361
+ if ( args ) {
362
+ if ( isArray ) {
363
+ for ( ; i < length; i++ ) {
364
+ value = callback.apply( obj[ i ], args );
365
+
366
+ if ( value === false ) {
367
+ break;
368
+ }
369
+ }
370
+ } else {
371
+ for ( i in obj ) {
372
+ value = callback.apply( obj[ i ], args );
373
+
374
+ if ( value === false ) {
375
+ break;
376
+ }
377
+ }
378
+ }
379
+
380
+ // A special, fast, case for the most common use of each
381
+ } else {
382
+ if ( isArray ) {
383
+ for ( ; i < length; i++ ) {
384
+ value = callback.call( obj[ i ], i, obj[ i ] );
385
+
386
+ if ( value === false ) {
387
+ break;
388
+ }
389
+ }
390
+ } else {
391
+ for ( i in obj ) {
392
+ value = callback.call( obj[ i ], i, obj[ i ] );
393
+
394
+ if ( value === false ) {
395
+ break;
396
+ }
397
+ }
398
+ }
399
+ }
400
+
401
+ return obj;
402
+ },
403
+
404
+ // Use native String.trim function wherever possible
405
+ trim: trim && !trim.call("\uFEFF\xA0") ?
406
+ function( text ) {
407
+ return text == null ?
408
+ "" :
409
+ trim.call( text );
410
+ } :
411
+
412
+ // Otherwise use our own trimming functionality
413
+ function( text ) {
414
+ return text == null ?
415
+ "" :
416
+ ( text + "" ).replace( rtrim, "" );
417
+ },
418
+
419
+ // results is for internal usage only
420
+ makeArray: function( arr, results ) {
421
+ var ret = results || [];
422
+
423
+ if ( arr != null ) {
424
+ if ( isArraylike( Object(arr) ) ) {
425
+ jQuery.merge( ret,
426
+ typeof arr === "string" ?
427
+ [ arr ] : arr
428
+ );
429
+ } else {
430
+ push.call( ret, arr );
431
+ }
432
+ }
433
+
434
+ return ret;
435
+ },
436
+
437
+ inArray: function( elem, arr, i ) {
438
+ var len;
439
+
440
+ if ( arr ) {
441
+ if ( indexOf ) {
442
+ return indexOf.call( arr, elem, i );
443
+ }
444
+
445
+ len = arr.length;
446
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
447
+
448
+ for ( ; i < len; i++ ) {
449
+ // Skip accessing in sparse arrays
450
+ if ( i in arr && arr[ i ] === elem ) {
451
+ return i;
452
+ }
453
+ }
454
+ }
455
+
456
+ return -1;
457
+ },
458
+
459
+ merge: function( first, second ) {
460
+ var len = +second.length,
461
+ j = 0,
462
+ i = first.length;
463
+
464
+ while ( j < len ) {
465
+ first[ i++ ] = second[ j++ ];
466
+ }
467
+
468
+ // Support: IE<9
469
+ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
470
+ if ( len !== len ) {
471
+ while ( second[j] !== undefined ) {
472
+ first[ i++ ] = second[ j++ ];
473
+ }
474
+ }
475
+
476
+ first.length = i;
477
+
478
+ return first;
479
+ },
480
+
481
+ grep: function( elems, callback, invert ) {
482
+ var callbackInverse,
483
+ matches = [],
484
+ i = 0,
485
+ length = elems.length,
486
+ callbackExpect = !invert;
487
+
488
+ // Go through the array, only saving the items
489
+ // that pass the validator function
490
+ for ( ; i < length; i++ ) {
491
+ callbackInverse = !callback( elems[ i ], i );
492
+ if ( callbackInverse !== callbackExpect ) {
493
+ matches.push( elems[ i ] );
494
+ }
495
+ }
496
+
497
+ return matches;
498
+ },
499
+
500
+ // arg is for internal usage only
501
+ map: function( elems, callback, arg ) {
502
+ var value,
503
+ i = 0,
504
+ length = elems.length,
505
+ isArray = isArraylike( elems ),
506
+ ret = [];
507
+
508
+ // Go through the array, translating each of the items to their new values
509
+ if ( isArray ) {
510
+ for ( ; i < length; i++ ) {
511
+ value = callback( elems[ i ], i, arg );
512
+
513
+ if ( value != null ) {
514
+ ret.push( value );
515
+ }
516
+ }
517
+
518
+ // Go through every key on the object,
519
+ } else {
520
+ for ( i in elems ) {
521
+ value = callback( elems[ i ], i, arg );
522
+
523
+ if ( value != null ) {
524
+ ret.push( value );
525
+ }
526
+ }
527
+ }
528
+
529
+ // Flatten any nested arrays
530
+ return concat.apply( [], ret );
531
+ },
532
+
533
+ // A global GUID counter for objects
534
+ guid: 1,
535
+
536
+ // Bind a function to a context, optionally partially applying any
537
+ // arguments.
538
+ proxy: function( fn, context ) {
539
+ var args, proxy, tmp;
540
+
541
+ if ( typeof context === "string" ) {
542
+ tmp = fn[ context ];
543
+ context = fn;
544
+ fn = tmp;
545
+ }
546
+
547
+ // Quick check to determine if target is callable, in the spec
548
+ // this throws a TypeError, but we will just return undefined.
549
+ if ( !jQuery.isFunction( fn ) ) {
550
+ return undefined;
551
+ }
552
+
553
+ // Simulated bind
554
+ args = slice.call( arguments, 2 );
555
+ proxy = function() {
556
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
557
+ };
558
+
559
+ // Set the guid of unique handler to the same of original handler, so it can be removed
560
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
561
+
562
+ return proxy;
563
+ },
564
+
565
+ now: function() {
566
+ return +( new Date() );
567
+ },
568
+
569
+ // jQuery.support is not used in Core but other projects attach their
570
+ // properties to it so it needs to exist.
571
+ support: support
572
+ });
573
+
574
+ // Populate the class2type map
575
+ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
576
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
577
+ });
578
+
579
+ function isArraylike( obj ) {
580
+ var length = obj.length,
581
+ type = jQuery.type( obj );
582
+
583
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
584
+ return false;
585
+ }
586
+
587
+ if ( obj.nodeType === 1 && length ) {
588
+ return true;
589
+ }
590
+
591
+ return type === "array" || length === 0 ||
592
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
593
+ }
594
+ var Sizzle =
595
+ /*!
596
+ * Sizzle CSS Selector Engine v1.10.16
597
+ * http://sizzlejs.com/
598
+ *
599
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
600
+ * Released under the MIT license
601
+ * http://jquery.org/license
602
+ *
603
+ * Date: 2014-01-13
604
+ */
605
+ (function( window ) {
606
+
607
+ var i,
608
+ support,
609
+ Expr,
610
+ getText,
611
+ isXML,
612
+ compile,
613
+ outermostContext,
614
+ sortInput,
615
+ hasDuplicate,
616
+
617
+ // Local document vars
618
+ setDocument,
619
+ document,
620
+ docElem,
621
+ documentIsHTML,
622
+ rbuggyQSA,
623
+ rbuggyMatches,
624
+ matches,
625
+ contains,
626
+
627
+ // Instance-specific data
628
+ expando = "sizzle" + -(new Date()),
629
+ preferredDoc = window.document,
630
+ dirruns = 0,
631
+ done = 0,
632
+ classCache = createCache(),
633
+ tokenCache = createCache(),
634
+ compilerCache = createCache(),
635
+ sortOrder = function( a, b ) {
636
+ if ( a === b ) {
637
+ hasDuplicate = true;
638
+ }
639
+ return 0;
640
+ },
641
+
642
+ // General-purpose constants
643
+ strundefined = typeof undefined,
644
+ MAX_NEGATIVE = 1 << 31,
645
+
646
+ // Instance methods
647
+ hasOwn = ({}).hasOwnProperty,
648
+ arr = [],
649
+ pop = arr.pop,
650
+ push_native = arr.push,
651
+ push = arr.push,
652
+ slice = arr.slice,
653
+ // Use a stripped-down indexOf if we can't use a native one
654
+ indexOf = arr.indexOf || function( elem ) {
655
+ var i = 0,
656
+ len = this.length;
657
+ for ( ; i < len; i++ ) {
658
+ if ( this[i] === elem ) {
659
+ return i;
660
+ }
661
+ }
662
+ return -1;
663
+ },
664
+
665
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
666
+
667
+ // Regular expressions
668
+
669
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
670
+ whitespace = "[\\x20\\t\\r\\n\\f]",
671
+ // http://www.w3.org/TR/css3-syntax/#characters
672
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
673
+
674
+ // Loosely modeled on CSS identifier characters
675
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
676
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
677
+ identifier = characterEncoding.replace( "w", "w#" ),
678
+
679
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
680
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
681
+ "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
682
+
683
+ // Prefer arguments quoted,
684
+ // then not containing pseudos/brackets,
685
+ // then attribute selectors/non-parenthetical expressions,
686
+ // then anything else
687
+ // These preferences are here to reduce the number of selectors
688
+ // needing tokenize in the PSEUDO preFilter
689
+ pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
690
+
691
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
692
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
693
+
694
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
695
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
696
+
697
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
698
+
699
+ rpseudo = new RegExp( pseudos ),
700
+ ridentifier = new RegExp( "^" + identifier + "$" ),
701
+
702
+ matchExpr = {
703
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
704
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
705
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
706
+ "ATTR": new RegExp( "^" + attributes ),
707
+ "PSEUDO": new RegExp( "^" + pseudos ),
708
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
709
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
710
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
711
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
712
+ // For use in libraries implementing .is()
713
+ // We use this for POS matching in `select`
714
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
715
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
716
+ },
717
+
718
+ rinputs = /^(?:input|select|textarea|button)$/i,
719
+ rheader = /^h\d$/i,
720
+
721
+ rnative = /^[^{]+\{\s*\[native \w/,
722
+
723
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
724
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
725
+
726
+ rsibling = /[+~]/,
727
+ rescape = /'|\\/g,
728
+
729
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
730
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
731
+ funescape = function( _, escaped, escapedWhitespace ) {
732
+ var high = "0x" + escaped - 0x10000;
733
+ // NaN means non-codepoint
734
+ // Support: Firefox
735
+ // Workaround erroneous numeric interpretation of +"0x"
736
+ return high !== high || escapedWhitespace ?
737
+ escaped :
738
+ high < 0 ?
739
+ // BMP codepoint
740
+ String.fromCharCode( high + 0x10000 ) :
741
+ // Supplemental Plane codepoint (surrogate pair)
742
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
743
+ };
744
+
745
+ // Optimize for push.apply( _, NodeList )
746
+ try {
747
+ push.apply(
748
+ (arr = slice.call( preferredDoc.childNodes )),
749
+ preferredDoc.childNodes
750
+ );
751
+ // Support: Android<4.0
752
+ // Detect silently failing push.apply
753
+ arr[ preferredDoc.childNodes.length ].nodeType;
754
+ } catch ( e ) {
755
+ push = { apply: arr.length ?
756
+
757
+ // Leverage slice if possible
758
+ function( target, els ) {
759
+ push_native.apply( target, slice.call(els) );
760
+ } :
761
+
762
+ // Support: IE<9
763
+ // Otherwise append directly
764
+ function( target, els ) {
765
+ var j = target.length,
766
+ i = 0;
767
+ // Can't trust NodeList.length
768
+ while ( (target[j++] = els[i++]) ) {}
769
+ target.length = j - 1;
770
+ }
771
+ };
772
+ }
773
+
774
+ function Sizzle( selector, context, results, seed ) {
775
+ var match, elem, m, nodeType,
776
+ // QSA vars
777
+ i, groups, old, nid, newContext, newSelector;
778
+
779
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
780
+ setDocument( context );
781
+ }
782
+
783
+ context = context || document;
784
+ results = results || [];
785
+
786
+ if ( !selector || typeof selector !== "string" ) {
787
+ return results;
788
+ }
789
+
790
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
791
+ return [];
792
+ }
793
+
794
+ if ( documentIsHTML && !seed ) {
795
+
796
+ // Shortcuts
797
+ if ( (match = rquickExpr.exec( selector )) ) {
798
+ // Speed-up: Sizzle("#ID")
799
+ if ( (m = match[1]) ) {
800
+ if ( nodeType === 9 ) {
801
+ elem = context.getElementById( m );
802
+ // Check parentNode to catch when Blackberry 4.6 returns
803
+ // nodes that are no longer in the document (jQuery #6963)
804
+ if ( elem && elem.parentNode ) {
805
+ // Handle the case where IE, Opera, and Webkit return items
806
+ // by name instead of ID
807
+ if ( elem.id === m ) {
808
+ results.push( elem );
809
+ return results;
810
+ }
811
+ } else {
812
+ return results;
813
+ }
814
+ } else {
815
+ // Context is not a document
816
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
817
+ contains( context, elem ) && elem.id === m ) {
818
+ results.push( elem );
819
+ return results;
820
+ }
821
+ }
822
+
823
+ // Speed-up: Sizzle("TAG")
824
+ } else if ( match[2] ) {
825
+ push.apply( results, context.getElementsByTagName( selector ) );
826
+ return results;
827
+
828
+ // Speed-up: Sizzle(".CLASS")
829
+ } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
830
+ push.apply( results, context.getElementsByClassName( m ) );
831
+ return results;
832
+ }
833
+ }
834
+
835
+ // QSA path
836
+ if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
837
+ nid = old = expando;
838
+ newContext = context;
839
+ newSelector = nodeType === 9 && selector;
840
+
841
+ // qSA works strangely on Element-rooted queries
842
+ // We can work around this by specifying an extra ID on the root
843
+ // and working up from there (Thanks to Andrew Dupont for the technique)
844
+ // IE 8 doesn't work on object elements
845
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
846
+ groups = tokenize( selector );
847
+
848
+ if ( (old = context.getAttribute("id")) ) {
849
+ nid = old.replace( rescape, "\\$&" );
850
+ } else {
851
+ context.setAttribute( "id", nid );
852
+ }
853
+ nid = "[id='" + nid + "'] ";
854
+
855
+ i = groups.length;
856
+ while ( i-- ) {
857
+ groups[i] = nid + toSelector( groups[i] );
858
+ }
859
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
860
+ newSelector = groups.join(",");
861
+ }
862
+
863
+ if ( newSelector ) {
864
+ try {
865
+ push.apply( results,
866
+ newContext.querySelectorAll( newSelector )
867
+ );
868
+ return results;
869
+ } catch(qsaError) {
870
+ } finally {
871
+ if ( !old ) {
872
+ context.removeAttribute("id");
873
+ }
874
+ }
875
+ }
876
+ }
877
+ }
878
+
879
+ // All others
880
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
881
+ }
882
+
883
+ /**
884
+ * Create key-value caches of limited size
885
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
886
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
887
+ * deleting the oldest entry
888
+ */
889
+ function createCache() {
890
+ var keys = [];
891
+
892
+ function cache( key, value ) {
893
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
894
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
895
+ // Only keep the most recent entries
896
+ delete cache[ keys.shift() ];
897
+ }
898
+ return (cache[ key + " " ] = value);
899
+ }
900
+ return cache;
901
+ }
902
+
903
+ /**
904
+ * Mark a function for special use by Sizzle
905
+ * @param {Function} fn The function to mark
906
+ */
907
+ function markFunction( fn ) {
908
+ fn[ expando ] = true;
909
+ return fn;
910
+ }
911
+
912
+ /**
913
+ * Support testing using an element
914
+ * @param {Function} fn Passed the created div and expects a boolean result
915
+ */
916
+ function assert( fn ) {
917
+ var div = document.createElement("div");
918
+
919
+ try {
920
+ return !!fn( div );
921
+ } catch (e) {
922
+ return false;
923
+ } finally {
924
+ // Remove from its parent by default
925
+ if ( div.parentNode ) {
926
+ div.parentNode.removeChild( div );
927
+ }
928
+ // release memory in IE
929
+ div = null;
930
+ }
931
+ }
932
+
933
+ /**
934
+ * Adds the same handler for all of the specified attrs
935
+ * @param {String} attrs Pipe-separated list of attributes
936
+ * @param {Function} handler The method that will be applied
937
+ */
938
+ function addHandle( attrs, handler ) {
939
+ var arr = attrs.split("|"),
940
+ i = attrs.length;
941
+
942
+ while ( i-- ) {
943
+ Expr.attrHandle[ arr[i] ] = handler;
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Checks document order of two siblings
949
+ * @param {Element} a
950
+ * @param {Element} b
951
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
952
+ */
953
+ function siblingCheck( a, b ) {
954
+ var cur = b && a,
955
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
956
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
957
+ ( ~a.sourceIndex || MAX_NEGATIVE );
958
+
959
+ // Use IE sourceIndex if available on both nodes
960
+ if ( diff ) {
961
+ return diff;
962
+ }
963
+
964
+ // Check if b follows a
965
+ if ( cur ) {
966
+ while ( (cur = cur.nextSibling) ) {
967
+ if ( cur === b ) {
968
+ return -1;
969
+ }
970
+ }
971
+ }
972
+
973
+ return a ? 1 : -1;
974
+ }
975
+
976
+ /**
977
+ * Returns a function to use in pseudos for input types
978
+ * @param {String} type
979
+ */
980
+ function createInputPseudo( type ) {
981
+ return function( elem ) {
982
+ var name = elem.nodeName.toLowerCase();
983
+ return name === "input" && elem.type === type;
984
+ };
985
+ }
986
+
987
+ /**
988
+ * Returns a function to use in pseudos for buttons
989
+ * @param {String} type
990
+ */
991
+ function createButtonPseudo( type ) {
992
+ return function( elem ) {
993
+ var name = elem.nodeName.toLowerCase();
994
+ return (name === "input" || name === "button") && elem.type === type;
995
+ };
996
+ }
997
+
998
+ /**
999
+ * Returns a function to use in pseudos for positionals
1000
+ * @param {Function} fn
1001
+ */
1002
+ function createPositionalPseudo( fn ) {
1003
+ return markFunction(function( argument ) {
1004
+ argument = +argument;
1005
+ return markFunction(function( seed, matches ) {
1006
+ var j,
1007
+ matchIndexes = fn( [], seed.length, argument ),
1008
+ i = matchIndexes.length;
1009
+
1010
+ // Match elements found at the specified indexes
1011
+ while ( i-- ) {
1012
+ if ( seed[ (j = matchIndexes[i]) ] ) {
1013
+ seed[j] = !(matches[j] = seed[j]);
1014
+ }
1015
+ }
1016
+ });
1017
+ });
1018
+ }
1019
+
1020
+ /**
1021
+ * Checks a node for validity as a Sizzle context
1022
+ * @param {Element|Object=} context
1023
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1024
+ */
1025
+ function testContext( context ) {
1026
+ return context && typeof context.getElementsByTagName !== strundefined && context;
1027
+ }
1028
+
1029
+ // Expose support vars for convenience
1030
+ support = Sizzle.support = {};
1031
+
1032
+ /**
1033
+ * Detects XML nodes
1034
+ * @param {Element|Object} elem An element or a document
1035
+ * @returns {Boolean} True iff elem is a non-HTML XML node
1036
+ */
1037
+ isXML = Sizzle.isXML = function( elem ) {
1038
+ // documentElement is verified for cases where it doesn't yet exist
1039
+ // (such as loading iframes in IE - #4833)
1040
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1041
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
1042
+ };
1043
+
1044
+ /**
1045
+ * Sets document-related variables once based on the current document
1046
+ * @param {Element|Object} [doc] An element or document object to use to set the document
1047
+ * @returns {Object} Returns the current document
1048
+ */
1049
+ setDocument = Sizzle.setDocument = function( node ) {
1050
+ var hasCompare,
1051
+ doc = node ? node.ownerDocument || node : preferredDoc,
1052
+ parent = doc.defaultView;
1053
+
1054
+ // If no document and documentElement is available, return
1055
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1056
+ return document;
1057
+ }
1058
+
1059
+ // Set our document
1060
+ document = doc;
1061
+ docElem = doc.documentElement;
1062
+
1063
+ // Support tests
1064
+ documentIsHTML = !isXML( doc );
1065
+
1066
+ // Support: IE>8
1067
+ // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1068
+ // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1069
+ // IE6-8 do not support the defaultView property so parent will be undefined
1070
+ if ( parent && parent !== parent.top ) {
1071
+ // IE11 does not have attachEvent, so all must suffer
1072
+ if ( parent.addEventListener ) {
1073
+ parent.addEventListener( "unload", function() {
1074
+ setDocument();
1075
+ }, false );
1076
+ } else if ( parent.attachEvent ) {
1077
+ parent.attachEvent( "onunload", function() {
1078
+ setDocument();
1079
+ });
1080
+ }
1081
+ }
1082
+
1083
+ /* Attributes
1084
+ ---------------------------------------------------------------------- */
1085
+
1086
+ // Support: IE<8
1087
+ // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1088
+ support.attributes = assert(function( div ) {
1089
+ div.className = "i";
1090
+ return !div.getAttribute("className");
1091
+ });
1092
+
1093
+ /* getElement(s)By*
1094
+ ---------------------------------------------------------------------- */
1095
+
1096
+ // Check if getElementsByTagName("*") returns only elements
1097
+ support.getElementsByTagName = assert(function( div ) {
1098
+ div.appendChild( doc.createComment("") );
1099
+ return !div.getElementsByTagName("*").length;
1100
+ });
1101
+
1102
+ // Check if getElementsByClassName can be trusted
1103
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1104
+ div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1105
+
1106
+ // Support: Safari<4
1107
+ // Catch class over-caching
1108
+ div.firstChild.className = "i";
1109
+ // Support: Opera<10
1110
+ // Catch gEBCN failure to find non-leading classes
1111
+ return div.getElementsByClassName("i").length === 2;
1112
+ });
1113
+
1114
+ // Support: IE<10
1115
+ // Check if getElementById returns elements by name
1116
+ // The broken getElementById methods don't pick up programatically-set names,
1117
+ // so use a roundabout getElementsByName test
1118
+ support.getById = assert(function( div ) {
1119
+ docElem.appendChild( div ).id = expando;
1120
+ return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1121
+ });
1122
+
1123
+ // ID find and filter
1124
+ if ( support.getById ) {
1125
+ Expr.find["ID"] = function( id, context ) {
1126
+ if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1127
+ var m = context.getElementById( id );
1128
+ // Check parentNode to catch when Blackberry 4.6 returns
1129
+ // nodes that are no longer in the document #6963
1130
+ return m && m.parentNode ? [m] : [];
1131
+ }
1132
+ };
1133
+ Expr.filter["ID"] = function( id ) {
1134
+ var attrId = id.replace( runescape, funescape );
1135
+ return function( elem ) {
1136
+ return elem.getAttribute("id") === attrId;
1137
+ };
1138
+ };
1139
+ } else {
1140
+ // Support: IE6/7
1141
+ // getElementById is not reliable as a find shortcut
1142
+ delete Expr.find["ID"];
1143
+
1144
+ Expr.filter["ID"] = function( id ) {
1145
+ var attrId = id.replace( runescape, funescape );
1146
+ return function( elem ) {
1147
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1148
+ return node && node.value === attrId;
1149
+ };
1150
+ };
1151
+ }
1152
+
1153
+ // Tag
1154
+ Expr.find["TAG"] = support.getElementsByTagName ?
1155
+ function( tag, context ) {
1156
+ if ( typeof context.getElementsByTagName !== strundefined ) {
1157
+ return context.getElementsByTagName( tag );
1158
+ }
1159
+ } :
1160
+ function( tag, context ) {
1161
+ var elem,
1162
+ tmp = [],
1163
+ i = 0,
1164
+ results = context.getElementsByTagName( tag );
1165
+
1166
+ // Filter out possible comments
1167
+ if ( tag === "*" ) {
1168
+ while ( (elem = results[i++]) ) {
1169
+ if ( elem.nodeType === 1 ) {
1170
+ tmp.push( elem );
1171
+ }
1172
+ }
1173
+
1174
+ return tmp;
1175
+ }
1176
+ return results;
1177
+ };
1178
+
1179
+ // Class
1180
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1181
+ if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1182
+ return context.getElementsByClassName( className );
1183
+ }
1184
+ };
1185
+
1186
+ /* QSA/matchesSelector
1187
+ ---------------------------------------------------------------------- */
1188
+
1189
+ // QSA and matchesSelector support
1190
+
1191
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1192
+ rbuggyMatches = [];
1193
+
1194
+ // qSa(:focus) reports false when true (Chrome 21)
1195
+ // We allow this because of a bug in IE8/9 that throws an error
1196
+ // whenever `document.activeElement` is accessed on an iframe
1197
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
1198
+ // See http://bugs.jquery.com/ticket/13378
1199
+ rbuggyQSA = [];
1200
+
1201
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1202
+ // Build QSA regex
1203
+ // Regex strategy adopted from Diego Perini
1204
+ assert(function( div ) {
1205
+ // Select is set to empty string on purpose
1206
+ // This is to test IE's treatment of not explicitly
1207
+ // setting a boolean content attribute,
1208
+ // since its presence should be enough
1209
+ // http://bugs.jquery.com/ticket/12359
1210
+ div.innerHTML = "<select t=''><option selected=''></option></select>";
1211
+
1212
+ // Support: IE8, Opera 10-12
1213
+ // Nothing should be selected when empty strings follow ^= or $= or *=
1214
+ if ( div.querySelectorAll("[t^='']").length ) {
1215
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1216
+ }
1217
+
1218
+ // Support: IE8
1219
+ // Boolean attributes and "value" are not treated correctly
1220
+ if ( !div.querySelectorAll("[selected]").length ) {
1221
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1222
+ }
1223
+
1224
+ // Webkit/Opera - :checked should return selected option elements
1225
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1226
+ // IE8 throws error here and will not see later tests
1227
+ if ( !div.querySelectorAll(":checked").length ) {
1228
+ rbuggyQSA.push(":checked");
1229
+ }
1230
+ });
1231
+
1232
+ assert(function( div ) {
1233
+ // Support: Windows 8 Native Apps
1234
+ // The type and name attributes are restricted during .innerHTML assignment
1235
+ var input = doc.createElement("input");
1236
+ input.setAttribute( "type", "hidden" );
1237
+ div.appendChild( input ).setAttribute( "name", "D" );
1238
+
1239
+ // Support: IE8
1240
+ // Enforce case-sensitivity of name attribute
1241
+ if ( div.querySelectorAll("[name=d]").length ) {
1242
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1243
+ }
1244
+
1245
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1246
+ // IE8 throws error here and will not see later tests
1247
+ if ( !div.querySelectorAll(":enabled").length ) {
1248
+ rbuggyQSA.push( ":enabled", ":disabled" );
1249
+ }
1250
+
1251
+ // Opera 10-11 does not throw on post-comma invalid pseudos
1252
+ div.querySelectorAll("*,:x");
1253
+ rbuggyQSA.push(",.*:");
1254
+ });
1255
+ }
1256
+
1257
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1258
+ docElem.mozMatchesSelector ||
1259
+ docElem.oMatchesSelector ||
1260
+ docElem.msMatchesSelector) )) ) {
1261
+
1262
+ assert(function( div ) {
1263
+ // Check to see if it's possible to do matchesSelector
1264
+ // on a disconnected node (IE 9)
1265
+ support.disconnectedMatch = matches.call( div, "div" );
1266
+
1267
+ // This should fail with an exception
1268
+ // Gecko does not error, returns false instead
1269
+ matches.call( div, "[s!='']:x" );
1270
+ rbuggyMatches.push( "!=", pseudos );
1271
+ });
1272
+ }
1273
+
1274
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1275
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1276
+
1277
+ /* Contains
1278
+ ---------------------------------------------------------------------- */
1279
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
1280
+
1281
+ // Element contains another
1282
+ // Purposefully does not implement inclusive descendent
1283
+ // As in, an element does not contain itself
1284
+ contains = hasCompare || rnative.test( docElem.contains ) ?
1285
+ function( a, b ) {
1286
+ var adown = a.nodeType === 9 ? a.documentElement : a,
1287
+ bup = b && b.parentNode;
1288
+ return a === bup || !!( bup && bup.nodeType === 1 && (
1289
+ adown.contains ?
1290
+ adown.contains( bup ) :
1291
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1292
+ ));
1293
+ } :
1294
+ function( a, b ) {
1295
+ if ( b ) {
1296
+ while ( (b = b.parentNode) ) {
1297
+ if ( b === a ) {
1298
+ return true;
1299
+ }
1300
+ }
1301
+ }
1302
+ return false;
1303
+ };
1304
+
1305
+ /* Sorting
1306
+ ---------------------------------------------------------------------- */
1307
+
1308
+ // Document order sorting
1309
+ sortOrder = hasCompare ?
1310
+ function( a, b ) {
1311
+
1312
+ // Flag for duplicate removal
1313
+ if ( a === b ) {
1314
+ hasDuplicate = true;
1315
+ return 0;
1316
+ }
1317
+
1318
+ // Sort on method existence if only one input has compareDocumentPosition
1319
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1320
+ if ( compare ) {
1321
+ return compare;
1322
+ }
1323
+
1324
+ // Calculate position if both inputs belong to the same document
1325
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1326
+ a.compareDocumentPosition( b ) :
1327
+
1328
+ // Otherwise we know they are disconnected
1329
+ 1;
1330
+
1331
+ // Disconnected nodes
1332
+ if ( compare & 1 ||
1333
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1334
+
1335
+ // Choose the first element that is related to our preferred document
1336
+ if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1337
+ return -1;
1338
+ }
1339
+ if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1340
+ return 1;
1341
+ }
1342
+
1343
+ // Maintain original order
1344
+ return sortInput ?
1345
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1346
+ 0;
1347
+ }
1348
+
1349
+ return compare & 4 ? -1 : 1;
1350
+ } :
1351
+ function( a, b ) {
1352
+ // Exit early if the nodes are identical
1353
+ if ( a === b ) {
1354
+ hasDuplicate = true;
1355
+ return 0;
1356
+ }
1357
+
1358
+ var cur,
1359
+ i = 0,
1360
+ aup = a.parentNode,
1361
+ bup = b.parentNode,
1362
+ ap = [ a ],
1363
+ bp = [ b ];
1364
+
1365
+ // Parentless nodes are either documents or disconnected
1366
+ if ( !aup || !bup ) {
1367
+ return a === doc ? -1 :
1368
+ b === doc ? 1 :
1369
+ aup ? -1 :
1370
+ bup ? 1 :
1371
+ sortInput ?
1372
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1373
+ 0;
1374
+
1375
+ // If the nodes are siblings, we can do a quick check
1376
+ } else if ( aup === bup ) {
1377
+ return siblingCheck( a, b );
1378
+ }
1379
+
1380
+ // Otherwise we need full lists of their ancestors for comparison
1381
+ cur = a;
1382
+ while ( (cur = cur.parentNode) ) {
1383
+ ap.unshift( cur );
1384
+ }
1385
+ cur = b;
1386
+ while ( (cur = cur.parentNode) ) {
1387
+ bp.unshift( cur );
1388
+ }
1389
+
1390
+ // Walk down the tree looking for a discrepancy
1391
+ while ( ap[i] === bp[i] ) {
1392
+ i++;
1393
+ }
1394
+
1395
+ return i ?
1396
+ // Do a sibling check if the nodes have a common ancestor
1397
+ siblingCheck( ap[i], bp[i] ) :
1398
+
1399
+ // Otherwise nodes in our document sort first
1400
+ ap[i] === preferredDoc ? -1 :
1401
+ bp[i] === preferredDoc ? 1 :
1402
+ 0;
1403
+ };
1404
+
1405
+ return doc;
1406
+ };
1407
+
1408
+ Sizzle.matches = function( expr, elements ) {
1409
+ return Sizzle( expr, null, null, elements );
1410
+ };
1411
+
1412
+ Sizzle.matchesSelector = function( elem, expr ) {
1413
+ // Set document vars if needed
1414
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1415
+ setDocument( elem );
1416
+ }
1417
+
1418
+ // Make sure that attribute selectors are quoted
1419
+ expr = expr.replace( rattributeQuotes, "='$1']" );
1420
+
1421
+ if ( support.matchesSelector && documentIsHTML &&
1422
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1423
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1424
+
1425
+ try {
1426
+ var ret = matches.call( elem, expr );
1427
+
1428
+ // IE 9's matchesSelector returns false on disconnected nodes
1429
+ if ( ret || support.disconnectedMatch ||
1430
+ // As well, disconnected nodes are said to be in a document
1431
+ // fragment in IE 9
1432
+ elem.document && elem.document.nodeType !== 11 ) {
1433
+ return ret;
1434
+ }
1435
+ } catch(e) {}
1436
+ }
1437
+
1438
+ return Sizzle( expr, document, null, [elem] ).length > 0;
1439
+ };
1440
+
1441
+ Sizzle.contains = function( context, elem ) {
1442
+ // Set document vars if needed
1443
+ if ( ( context.ownerDocument || context ) !== document ) {
1444
+ setDocument( context );
1445
+ }
1446
+ return contains( context, elem );
1447
+ };
1448
+
1449
+ Sizzle.attr = function( elem, name ) {
1450
+ // Set document vars if needed
1451
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1452
+ setDocument( elem );
1453
+ }
1454
+
1455
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
1456
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
1457
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1458
+ fn( elem, name, !documentIsHTML ) :
1459
+ undefined;
1460
+
1461
+ return val !== undefined ?
1462
+ val :
1463
+ support.attributes || !documentIsHTML ?
1464
+ elem.getAttribute( name ) :
1465
+ (val = elem.getAttributeNode(name)) && val.specified ?
1466
+ val.value :
1467
+ null;
1468
+ };
1469
+
1470
+ Sizzle.error = function( msg ) {
1471
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
1472
+ };
1473
+
1474
+ /**
1475
+ * Document sorting and removing duplicates
1476
+ * @param {ArrayLike} results
1477
+ */
1478
+ Sizzle.uniqueSort = function( results ) {
1479
+ var elem,
1480
+ duplicates = [],
1481
+ j = 0,
1482
+ i = 0;
1483
+
1484
+ // Unless we *know* we can detect duplicates, assume their presence
1485
+ hasDuplicate = !support.detectDuplicates;
1486
+ sortInput = !support.sortStable && results.slice( 0 );
1487
+ results.sort( sortOrder );
1488
+
1489
+ if ( hasDuplicate ) {
1490
+ while ( (elem = results[i++]) ) {
1491
+ if ( elem === results[ i ] ) {
1492
+ j = duplicates.push( i );
1493
+ }
1494
+ }
1495
+ while ( j-- ) {
1496
+ results.splice( duplicates[ j ], 1 );
1497
+ }
1498
+ }
1499
+
1500
+ // Clear input after sorting to release objects
1501
+ // See https://github.com/jquery/sizzle/pull/225
1502
+ sortInput = null;
1503
+
1504
+ return results;
1505
+ };
1506
+
1507
+ /**
1508
+ * Utility function for retrieving the text value of an array of DOM nodes
1509
+ * @param {Array|Element} elem
1510
+ */
1511
+ getText = Sizzle.getText = function( elem ) {
1512
+ var node,
1513
+ ret = "",
1514
+ i = 0,
1515
+ nodeType = elem.nodeType;
1516
+
1517
+ if ( !nodeType ) {
1518
+ // If no nodeType, this is expected to be an array
1519
+ while ( (node = elem[i++]) ) {
1520
+ // Do not traverse comment nodes
1521
+ ret += getText( node );
1522
+ }
1523
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1524
+ // Use textContent for elements
1525
+ // innerText usage removed for consistency of new lines (jQuery #11153)
1526
+ if ( typeof elem.textContent === "string" ) {
1527
+ return elem.textContent;
1528
+ } else {
1529
+ // Traverse its children
1530
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1531
+ ret += getText( elem );
1532
+ }
1533
+ }
1534
+ } else if ( nodeType === 3 || nodeType === 4 ) {
1535
+ return elem.nodeValue;
1536
+ }
1537
+ // Do not include comment or processing instruction nodes
1538
+
1539
+ return ret;
1540
+ };
1541
+
1542
+ Expr = Sizzle.selectors = {
1543
+
1544
+ // Can be adjusted by the user
1545
+ cacheLength: 50,
1546
+
1547
+ createPseudo: markFunction,
1548
+
1549
+ match: matchExpr,
1550
+
1551
+ attrHandle: {},
1552
+
1553
+ find: {},
1554
+
1555
+ relative: {
1556
+ ">": { dir: "parentNode", first: true },
1557
+ " ": { dir: "parentNode" },
1558
+ "+": { dir: "previousSibling", first: true },
1559
+ "~": { dir: "previousSibling" }
1560
+ },
1561
+
1562
+ preFilter: {
1563
+ "ATTR": function( match ) {
1564
+ match[1] = match[1].replace( runescape, funescape );
1565
+
1566
+ // Move the given value to match[3] whether quoted or unquoted
1567
+ match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1568
+
1569
+ if ( match[2] === "~=" ) {
1570
+ match[3] = " " + match[3] + " ";
1571
+ }
1572
+
1573
+ return match.slice( 0, 4 );
1574
+ },
1575
+
1576
+ "CHILD": function( match ) {
1577
+ /* matches from matchExpr["CHILD"]
1578
+ 1 type (only|nth|...)
1579
+ 2 what (child|of-type)
1580
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1581
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
1582
+ 5 sign of xn-component
1583
+ 6 x of xn-component
1584
+ 7 sign of y-component
1585
+ 8 y of y-component
1586
+ */
1587
+ match[1] = match[1].toLowerCase();
1588
+
1589
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
1590
+ // nth-* requires argument
1591
+ if ( !match[3] ) {
1592
+ Sizzle.error( match[0] );
1593
+ }
1594
+
1595
+ // numeric x and y parameters for Expr.filter.CHILD
1596
+ // remember that false/true cast respectively to 0/1
1597
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1598
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1599
+
1600
+ // other types prohibit arguments
1601
+ } else if ( match[3] ) {
1602
+ Sizzle.error( match[0] );
1603
+ }
1604
+
1605
+ return match;
1606
+ },
1607
+
1608
+ "PSEUDO": function( match ) {
1609
+ var excess,
1610
+ unquoted = !match[5] && match[2];
1611
+
1612
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
1613
+ return null;
1614
+ }
1615
+
1616
+ // Accept quoted arguments as-is
1617
+ if ( match[3] && match[4] !== undefined ) {
1618
+ match[2] = match[4];
1619
+
1620
+ // Strip excess characters from unquoted arguments
1621
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
1622
+ // Get excess from tokenize (recursively)
1623
+ (excess = tokenize( unquoted, true )) &&
1624
+ // advance to the next closing parenthesis
1625
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1626
+
1627
+ // excess is a negative index
1628
+ match[0] = match[0].slice( 0, excess );
1629
+ match[2] = unquoted.slice( 0, excess );
1630
+ }
1631
+
1632
+ // Return only captures needed by the pseudo filter method (type and argument)
1633
+ return match.slice( 0, 3 );
1634
+ }
1635
+ },
1636
+
1637
+ filter: {
1638
+
1639
+ "TAG": function( nodeNameSelector ) {
1640
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1641
+ return nodeNameSelector === "*" ?
1642
+ function() { return true; } :
1643
+ function( elem ) {
1644
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1645
+ };
1646
+ },
1647
+
1648
+ "CLASS": function( className ) {
1649
+ var pattern = classCache[ className + " " ];
1650
+
1651
+ return pattern ||
1652
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1653
+ classCache( className, function( elem ) {
1654
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1655
+ });
1656
+ },
1657
+
1658
+ "ATTR": function( name, operator, check ) {
1659
+ return function( elem ) {
1660
+ var result = Sizzle.attr( elem, name );
1661
+
1662
+ if ( result == null ) {
1663
+ return operator === "!=";
1664
+ }
1665
+ if ( !operator ) {
1666
+ return true;
1667
+ }
1668
+
1669
+ result += "";
1670
+
1671
+ return operator === "=" ? result === check :
1672
+ operator === "!=" ? result !== check :
1673
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
1674
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
1675
+ operator === "$=" ? check && result.slice( -check.length ) === check :
1676
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1677
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1678
+ false;
1679
+ };
1680
+ },
1681
+
1682
+ "CHILD": function( type, what, argument, first, last ) {
1683
+ var simple = type.slice( 0, 3 ) !== "nth",
1684
+ forward = type.slice( -4 ) !== "last",
1685
+ ofType = what === "of-type";
1686
+
1687
+ return first === 1 && last === 0 ?
1688
+
1689
+ // Shortcut for :nth-*(n)
1690
+ function( elem ) {
1691
+ return !!elem.parentNode;
1692
+ } :
1693
+
1694
+ function( elem, context, xml ) {
1695
+ var cache, outerCache, node, diff, nodeIndex, start,
1696
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
1697
+ parent = elem.parentNode,
1698
+ name = ofType && elem.nodeName.toLowerCase(),
1699
+ useCache = !xml && !ofType;
1700
+
1701
+ if ( parent ) {
1702
+
1703
+ // :(first|last|only)-(child|of-type)
1704
+ if ( simple ) {
1705
+ while ( dir ) {
1706
+ node = elem;
1707
+ while ( (node = node[ dir ]) ) {
1708
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1709
+ return false;
1710
+ }
1711
+ }
1712
+ // Reverse direction for :only-* (if we haven't yet done so)
1713
+ start = dir = type === "only" && !start && "nextSibling";
1714
+ }
1715
+ return true;
1716
+ }
1717
+
1718
+ start = [ forward ? parent.firstChild : parent.lastChild ];
1719
+
1720
+ // non-xml :nth-child(...) stores cache data on `parent`
1721
+ if ( forward && useCache ) {
1722
+ // Seek `elem` from a previously-cached index
1723
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
1724
+ cache = outerCache[ type ] || [];
1725
+ nodeIndex = cache[0] === dirruns && cache[1];
1726
+ diff = cache[0] === dirruns && cache[2];
1727
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
1728
+
1729
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1730
+
1731
+ // Fallback to seeking `elem` from the start
1732
+ (diff = nodeIndex = 0) || start.pop()) ) {
1733
+
1734
+ // When found, cache indexes on `parent` and break
1735
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
1736
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1737
+ break;
1738
+ }
1739
+ }
1740
+
1741
+ // Use previously-cached element index if available
1742
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1743
+ diff = cache[1];
1744
+
1745
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1746
+ } else {
1747
+ // Use the same loop as above to seek `elem` from the start
1748
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1749
+ (diff = nodeIndex = 0) || start.pop()) ) {
1750
+
1751
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1752
+ // Cache the index of each encountered element
1753
+ if ( useCache ) {
1754
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1755
+ }
1756
+
1757
+ if ( node === elem ) {
1758
+ break;
1759
+ }
1760
+ }
1761
+ }
1762
+ }
1763
+
1764
+ // Incorporate the offset, then check against cycle size
1765
+ diff -= last;
1766
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
1767
+ }
1768
+ };
1769
+ },
1770
+
1771
+ "PSEUDO": function( pseudo, argument ) {
1772
+ // pseudo-class names are case-insensitive
1773
+ // http://www.w3.org/TR/selectors/#pseudo-classes
1774
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1775
+ // Remember that setFilters inherits from pseudos
1776
+ var args,
1777
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1778
+ Sizzle.error( "unsupported pseudo: " + pseudo );
1779
+
1780
+ // The user may use createPseudo to indicate that
1781
+ // arguments are needed to create the filter function
1782
+ // just as Sizzle does
1783
+ if ( fn[ expando ] ) {
1784
+ return fn( argument );
1785
+ }
1786
+
1787
+ // But maintain support for old signatures
1788
+ if ( fn.length > 1 ) {
1789
+ args = [ pseudo, pseudo, "", argument ];
1790
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1791
+ markFunction(function( seed, matches ) {
1792
+ var idx,
1793
+ matched = fn( seed, argument ),
1794
+ i = matched.length;
1795
+ while ( i-- ) {
1796
+ idx = indexOf.call( seed, matched[i] );
1797
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
1798
+ }
1799
+ }) :
1800
+ function( elem ) {
1801
+ return fn( elem, 0, args );
1802
+ };
1803
+ }
1804
+
1805
+ return fn;
1806
+ }
1807
+ },
1808
+
1809
+ pseudos: {
1810
+ // Potentially complex pseudos
1811
+ "not": markFunction(function( selector ) {
1812
+ // Trim the selector passed to compile
1813
+ // to avoid treating leading and trailing
1814
+ // spaces as combinators
1815
+ var input = [],
1816
+ results = [],
1817
+ matcher = compile( selector.replace( rtrim, "$1" ) );
1818
+
1819
+ return matcher[ expando ] ?
1820
+ markFunction(function( seed, matches, context, xml ) {
1821
+ var elem,
1822
+ unmatched = matcher( seed, null, xml, [] ),
1823
+ i = seed.length;
1824
+
1825
+ // Match elements unmatched by `matcher`
1826
+ while ( i-- ) {
1827
+ if ( (elem = unmatched[i]) ) {
1828
+ seed[i] = !(matches[i] = elem);
1829
+ }
1830
+ }
1831
+ }) :
1832
+ function( elem, context, xml ) {
1833
+ input[0] = elem;
1834
+ matcher( input, null, xml, results );
1835
+ return !results.pop();
1836
+ };
1837
+ }),
1838
+
1839
+ "has": markFunction(function( selector ) {
1840
+ return function( elem ) {
1841
+ return Sizzle( selector, elem ).length > 0;
1842
+ };
1843
+ }),
1844
+
1845
+ "contains": markFunction(function( text ) {
1846
+ return function( elem ) {
1847
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1848
+ };
1849
+ }),
1850
+
1851
+ // "Whether an element is represented by a :lang() selector
1852
+ // is based solely on the element's language value
1853
+ // being equal to the identifier C,
1854
+ // or beginning with the identifier C immediately followed by "-".
1855
+ // The matching of C against the element's language value is performed case-insensitively.
1856
+ // The identifier C does not have to be a valid language name."
1857
+ // http://www.w3.org/TR/selectors/#lang-pseudo
1858
+ "lang": markFunction( function( lang ) {
1859
+ // lang value must be a valid identifier
1860
+ if ( !ridentifier.test(lang || "") ) {
1861
+ Sizzle.error( "unsupported lang: " + lang );
1862
+ }
1863
+ lang = lang.replace( runescape, funescape ).toLowerCase();
1864
+ return function( elem ) {
1865
+ var elemLang;
1866
+ do {
1867
+ if ( (elemLang = documentIsHTML ?
1868
+ elem.lang :
1869
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1870
+
1871
+ elemLang = elemLang.toLowerCase();
1872
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1873
+ }
1874
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1875
+ return false;
1876
+ };
1877
+ }),
1878
+
1879
+ // Miscellaneous
1880
+ "target": function( elem ) {
1881
+ var hash = window.location && window.location.hash;
1882
+ return hash && hash.slice( 1 ) === elem.id;
1883
+ },
1884
+
1885
+ "root": function( elem ) {
1886
+ return elem === docElem;
1887
+ },
1888
+
1889
+ "focus": function( elem ) {
1890
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1891
+ },
1892
+
1893
+ // Boolean properties
1894
+ "enabled": function( elem ) {
1895
+ return elem.disabled === false;
1896
+ },
1897
+
1898
+ "disabled": function( elem ) {
1899
+ return elem.disabled === true;
1900
+ },
1901
+
1902
+ "checked": function( elem ) {
1903
+ // In CSS3, :checked should return both checked and selected elements
1904
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1905
+ var nodeName = elem.nodeName.toLowerCase();
1906
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1907
+ },
1908
+
1909
+ "selected": function( elem ) {
1910
+ // Accessing this property makes selected-by-default
1911
+ // options in Safari work properly
1912
+ if ( elem.parentNode ) {
1913
+ elem.parentNode.selectedIndex;
1914
+ }
1915
+
1916
+ return elem.selected === true;
1917
+ },
1918
+
1919
+ // Contents
1920
+ "empty": function( elem ) {
1921
+ // http://www.w3.org/TR/selectors/#empty-pseudo
1922
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1923
+ // but not by others (comment: 8; processing instruction: 7; etc.)
1924
+ // nodeType < 6 works because attributes (2) do not appear as children
1925
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1926
+ if ( elem.nodeType < 6 ) {
1927
+ return false;
1928
+ }
1929
+ }
1930
+ return true;
1931
+ },
1932
+
1933
+ "parent": function( elem ) {
1934
+ return !Expr.pseudos["empty"]( elem );
1935
+ },
1936
+
1937
+ // Element/input types
1938
+ "header": function( elem ) {
1939
+ return rheader.test( elem.nodeName );
1940
+ },
1941
+
1942
+ "input": function( elem ) {
1943
+ return rinputs.test( elem.nodeName );
1944
+ },
1945
+
1946
+ "button": function( elem ) {
1947
+ var name = elem.nodeName.toLowerCase();
1948
+ return name === "input" && elem.type === "button" || name === "button";
1949
+ },
1950
+
1951
+ "text": function( elem ) {
1952
+ var attr;
1953
+ return elem.nodeName.toLowerCase() === "input" &&
1954
+ elem.type === "text" &&
1955
+
1956
+ // Support: IE<8
1957
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1958
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1959
+ },
1960
+
1961
+ // Position-in-collection
1962
+ "first": createPositionalPseudo(function() {
1963
+ return [ 0 ];
1964
+ }),
1965
+
1966
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
1967
+ return [ length - 1 ];
1968
+ }),
1969
+
1970
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1971
+ return [ argument < 0 ? argument + length : argument ];
1972
+ }),
1973
+
1974
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
1975
+ var i = 0;
1976
+ for ( ; i < length; i += 2 ) {
1977
+ matchIndexes.push( i );
1978
+ }
1979
+ return matchIndexes;
1980
+ }),
1981
+
1982
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
1983
+ var i = 1;
1984
+ for ( ; i < length; i += 2 ) {
1985
+ matchIndexes.push( i );
1986
+ }
1987
+ return matchIndexes;
1988
+ }),
1989
+
1990
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1991
+ var i = argument < 0 ? argument + length : argument;
1992
+ for ( ; --i >= 0; ) {
1993
+ matchIndexes.push( i );
1994
+ }
1995
+ return matchIndexes;
1996
+ }),
1997
+
1998
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1999
+ var i = argument < 0 ? argument + length : argument;
2000
+ for ( ; ++i < length; ) {
2001
+ matchIndexes.push( i );
2002
+ }
2003
+ return matchIndexes;
2004
+ })
2005
+ }
2006
+ };
2007
+
2008
+ Expr.pseudos["nth"] = Expr.pseudos["eq"];
2009
+
2010
+ // Add button/input type pseudos
2011
+ for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2012
+ Expr.pseudos[ i ] = createInputPseudo( i );
2013
+ }
2014
+ for ( i in { submit: true, reset: true } ) {
2015
+ Expr.pseudos[ i ] = createButtonPseudo( i );
2016
+ }
2017
+
2018
+ // Easy API for creating new setFilters
2019
+ function setFilters() {}
2020
+ setFilters.prototype = Expr.filters = Expr.pseudos;
2021
+ Expr.setFilters = new setFilters();
2022
+
2023
+ function tokenize( selector, parseOnly ) {
2024
+ var matched, match, tokens, type,
2025
+ soFar, groups, preFilters,
2026
+ cached = tokenCache[ selector + " " ];
2027
+
2028
+ if ( cached ) {
2029
+ return parseOnly ? 0 : cached.slice( 0 );
2030
+ }
2031
+
2032
+ soFar = selector;
2033
+ groups = [];
2034
+ preFilters = Expr.preFilter;
2035
+
2036
+ while ( soFar ) {
2037
+
2038
+ // Comma and first run
2039
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
2040
+ if ( match ) {
2041
+ // Don't consume trailing commas as valid
2042
+ soFar = soFar.slice( match[0].length ) || soFar;
2043
+ }
2044
+ groups.push( (tokens = []) );
2045
+ }
2046
+
2047
+ matched = false;
2048
+
2049
+ // Combinators
2050
+ if ( (match = rcombinators.exec( soFar )) ) {
2051
+ matched = match.shift();
2052
+ tokens.push({
2053
+ value: matched,
2054
+ // Cast descendant combinators to space
2055
+ type: match[0].replace( rtrim, " " )
2056
+ });
2057
+ soFar = soFar.slice( matched.length );
2058
+ }
2059
+
2060
+ // Filters
2061
+ for ( type in Expr.filter ) {
2062
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2063
+ (match = preFilters[ type ]( match ))) ) {
2064
+ matched = match.shift();
2065
+ tokens.push({
2066
+ value: matched,
2067
+ type: type,
2068
+ matches: match
2069
+ });
2070
+ soFar = soFar.slice( matched.length );
2071
+ }
2072
+ }
2073
+
2074
+ if ( !matched ) {
2075
+ break;
2076
+ }
2077
+ }
2078
+
2079
+ // Return the length of the invalid excess
2080
+ // if we're just parsing
2081
+ // Otherwise, throw an error or return tokens
2082
+ return parseOnly ?
2083
+ soFar.length :
2084
+ soFar ?
2085
+ Sizzle.error( selector ) :
2086
+ // Cache the tokens
2087
+ tokenCache( selector, groups ).slice( 0 );
2088
+ }
2089
+
2090
+ function toSelector( tokens ) {
2091
+ var i = 0,
2092
+ len = tokens.length,
2093
+ selector = "";
2094
+ for ( ; i < len; i++ ) {
2095
+ selector += tokens[i].value;
2096
+ }
2097
+ return selector;
2098
+ }
2099
+
2100
+ function addCombinator( matcher, combinator, base ) {
2101
+ var dir = combinator.dir,
2102
+ checkNonElements = base && dir === "parentNode",
2103
+ doneName = done++;
2104
+
2105
+ return combinator.first ?
2106
+ // Check against closest ancestor/preceding element
2107
+ function( elem, context, xml ) {
2108
+ while ( (elem = elem[ dir ]) ) {
2109
+ if ( elem.nodeType === 1 || checkNonElements ) {
2110
+ return matcher( elem, context, xml );
2111
+ }
2112
+ }
2113
+ } :
2114
+
2115
+ // Check against all ancestor/preceding elements
2116
+ function( elem, context, xml ) {
2117
+ var oldCache, outerCache,
2118
+ newCache = [ dirruns, doneName ];
2119
+
2120
+ // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2121
+ if ( xml ) {
2122
+ while ( (elem = elem[ dir ]) ) {
2123
+ if ( elem.nodeType === 1 || checkNonElements ) {
2124
+ if ( matcher( elem, context, xml ) ) {
2125
+ return true;
2126
+ }
2127
+ }
2128
+ }
2129
+ } else {
2130
+ while ( (elem = elem[ dir ]) ) {
2131
+ if ( elem.nodeType === 1 || checkNonElements ) {
2132
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
2133
+ if ( (oldCache = outerCache[ dir ]) &&
2134
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2135
+
2136
+ // Assign to newCache so results back-propagate to previous elements
2137
+ return (newCache[ 2 ] = oldCache[ 2 ]);
2138
+ } else {
2139
+ // Reuse newcache so results back-propagate to previous elements
2140
+ outerCache[ dir ] = newCache;
2141
+
2142
+ // A match means we're done; a fail means we have to keep checking
2143
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2144
+ return true;
2145
+ }
2146
+ }
2147
+ }
2148
+ }
2149
+ }
2150
+ };
2151
+ }
2152
+
2153
+ function elementMatcher( matchers ) {
2154
+ return matchers.length > 1 ?
2155
+ function( elem, context, xml ) {
2156
+ var i = matchers.length;
2157
+ while ( i-- ) {
2158
+ if ( !matchers[i]( elem, context, xml ) ) {
2159
+ return false;
2160
+ }
2161
+ }
2162
+ return true;
2163
+ } :
2164
+ matchers[0];
2165
+ }
2166
+
2167
+ function condense( unmatched, map, filter, context, xml ) {
2168
+ var elem,
2169
+ newUnmatched = [],
2170
+ i = 0,
2171
+ len = unmatched.length,
2172
+ mapped = map != null;
2173
+
2174
+ for ( ; i < len; i++ ) {
2175
+ if ( (elem = unmatched[i]) ) {
2176
+ if ( !filter || filter( elem, context, xml ) ) {
2177
+ newUnmatched.push( elem );
2178
+ if ( mapped ) {
2179
+ map.push( i );
2180
+ }
2181
+ }
2182
+ }
2183
+ }
2184
+
2185
+ return newUnmatched;
2186
+ }
2187
+
2188
+ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2189
+ if ( postFilter && !postFilter[ expando ] ) {
2190
+ postFilter = setMatcher( postFilter );
2191
+ }
2192
+ if ( postFinder && !postFinder[ expando ] ) {
2193
+ postFinder = setMatcher( postFinder, postSelector );
2194
+ }
2195
+ return markFunction(function( seed, results, context, xml ) {
2196
+ var temp, i, elem,
2197
+ preMap = [],
2198
+ postMap = [],
2199
+ preexisting = results.length,
2200
+
2201
+ // Get initial elements from seed or context
2202
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2203
+
2204
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
2205
+ matcherIn = preFilter && ( seed || !selector ) ?
2206
+ condense( elems, preMap, preFilter, context, xml ) :
2207
+ elems,
2208
+
2209
+ matcherOut = matcher ?
2210
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2211
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2212
+
2213
+ // ...intermediate processing is necessary
2214
+ [] :
2215
+
2216
+ // ...otherwise use results directly
2217
+ results :
2218
+ matcherIn;
2219
+
2220
+ // Find primary matches
2221
+ if ( matcher ) {
2222
+ matcher( matcherIn, matcherOut, context, xml );
2223
+ }
2224
+
2225
+ // Apply postFilter
2226
+ if ( postFilter ) {
2227
+ temp = condense( matcherOut, postMap );
2228
+ postFilter( temp, [], context, xml );
2229
+
2230
+ // Un-match failing elements by moving them back to matcherIn
2231
+ i = temp.length;
2232
+ while ( i-- ) {
2233
+ if ( (elem = temp[i]) ) {
2234
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2235
+ }
2236
+ }
2237
+ }
2238
+
2239
+ if ( seed ) {
2240
+ if ( postFinder || preFilter ) {
2241
+ if ( postFinder ) {
2242
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
2243
+ temp = [];
2244
+ i = matcherOut.length;
2245
+ while ( i-- ) {
2246
+ if ( (elem = matcherOut[i]) ) {
2247
+ // Restore matcherIn since elem is not yet a final match
2248
+ temp.push( (matcherIn[i] = elem) );
2249
+ }
2250
+ }
2251
+ postFinder( null, (matcherOut = []), temp, xml );
2252
+ }
2253
+
2254
+ // Move matched elements from seed to results to keep them synchronized
2255
+ i = matcherOut.length;
2256
+ while ( i-- ) {
2257
+ if ( (elem = matcherOut[i]) &&
2258
+ (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2259
+
2260
+ seed[temp] = !(results[temp] = elem);
2261
+ }
2262
+ }
2263
+ }
2264
+
2265
+ // Add elements to results, through postFinder if defined
2266
+ } else {
2267
+ matcherOut = condense(
2268
+ matcherOut === results ?
2269
+ matcherOut.splice( preexisting, matcherOut.length ) :
2270
+ matcherOut
2271
+ );
2272
+ if ( postFinder ) {
2273
+ postFinder( null, results, matcherOut, xml );
2274
+ } else {
2275
+ push.apply( results, matcherOut );
2276
+ }
2277
+ }
2278
+ });
2279
+ }
2280
+
2281
+ function matcherFromTokens( tokens ) {
2282
+ var checkContext, matcher, j,
2283
+ len = tokens.length,
2284
+ leadingRelative = Expr.relative[ tokens[0].type ],
2285
+ implicitRelative = leadingRelative || Expr.relative[" "],
2286
+ i = leadingRelative ? 1 : 0,
2287
+
2288
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
2289
+ matchContext = addCombinator( function( elem ) {
2290
+ return elem === checkContext;
2291
+ }, implicitRelative, true ),
2292
+ matchAnyContext = addCombinator( function( elem ) {
2293
+ return indexOf.call( checkContext, elem ) > -1;
2294
+ }, implicitRelative, true ),
2295
+ matchers = [ function( elem, context, xml ) {
2296
+ return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2297
+ (checkContext = context).nodeType ?
2298
+ matchContext( elem, context, xml ) :
2299
+ matchAnyContext( elem, context, xml ) );
2300
+ } ];
2301
+
2302
+ for ( ; i < len; i++ ) {
2303
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2304
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2305
+ } else {
2306
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2307
+
2308
+ // Return special upon seeing a positional matcher
2309
+ if ( matcher[ expando ] ) {
2310
+ // Find the next relative operator (if any) for proper handling
2311
+ j = ++i;
2312
+ for ( ; j < len; j++ ) {
2313
+ if ( Expr.relative[ tokens[j].type ] ) {
2314
+ break;
2315
+ }
2316
+ }
2317
+ return setMatcher(
2318
+ i > 1 && elementMatcher( matchers ),
2319
+ i > 1 && toSelector(
2320
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2321
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2322
+ ).replace( rtrim, "$1" ),
2323
+ matcher,
2324
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
2325
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2326
+ j < len && toSelector( tokens )
2327
+ );
2328
+ }
2329
+ matchers.push( matcher );
2330
+ }
2331
+ }
2332
+
2333
+ return elementMatcher( matchers );
2334
+ }
2335
+
2336
+ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2337
+ var bySet = setMatchers.length > 0,
2338
+ byElement = elementMatchers.length > 0,
2339
+ superMatcher = function( seed, context, xml, results, outermost ) {
2340
+ var elem, j, matcher,
2341
+ matchedCount = 0,
2342
+ i = "0",
2343
+ unmatched = seed && [],
2344
+ setMatched = [],
2345
+ contextBackup = outermostContext,
2346
+ // We must always have either seed elements or outermost context
2347
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2348
+ // Use integer dirruns iff this is the outermost matcher
2349
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2350
+ len = elems.length;
2351
+
2352
+ if ( outermost ) {
2353
+ outermostContext = context !== document && context;
2354
+ }
2355
+
2356
+ // Add elements passing elementMatchers directly to results
2357
+ // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2358
+ // Support: IE<9, Safari
2359
+ // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2360
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2361
+ if ( byElement && elem ) {
2362
+ j = 0;
2363
+ while ( (matcher = elementMatchers[j++]) ) {
2364
+ if ( matcher( elem, context, xml ) ) {
2365
+ results.push( elem );
2366
+ break;
2367
+ }
2368
+ }
2369
+ if ( outermost ) {
2370
+ dirruns = dirrunsUnique;
2371
+ }
2372
+ }
2373
+
2374
+ // Track unmatched elements for set filters
2375
+ if ( bySet ) {
2376
+ // They will have gone through all possible matchers
2377
+ if ( (elem = !matcher && elem) ) {
2378
+ matchedCount--;
2379
+ }
2380
+
2381
+ // Lengthen the array for every element, matched or not
2382
+ if ( seed ) {
2383
+ unmatched.push( elem );
2384
+ }
2385
+ }
2386
+ }
2387
+
2388
+ // Apply set filters to unmatched elements
2389
+ matchedCount += i;
2390
+ if ( bySet && i !== matchedCount ) {
2391
+ j = 0;
2392
+ while ( (matcher = setMatchers[j++]) ) {
2393
+ matcher( unmatched, setMatched, context, xml );
2394
+ }
2395
+
2396
+ if ( seed ) {
2397
+ // Reintegrate element matches to eliminate the need for sorting
2398
+ if ( matchedCount > 0 ) {
2399
+ while ( i-- ) {
2400
+ if ( !(unmatched[i] || setMatched[i]) ) {
2401
+ setMatched[i] = pop.call( results );
2402
+ }
2403
+ }
2404
+ }
2405
+
2406
+ // Discard index placeholder values to get only actual matches
2407
+ setMatched = condense( setMatched );
2408
+ }
2409
+
2410
+ // Add matches to results
2411
+ push.apply( results, setMatched );
2412
+
2413
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
2414
+ if ( outermost && !seed && setMatched.length > 0 &&
2415
+ ( matchedCount + setMatchers.length ) > 1 ) {
2416
+
2417
+ Sizzle.uniqueSort( results );
2418
+ }
2419
+ }
2420
+
2421
+ // Override manipulation of globals by nested matchers
2422
+ if ( outermost ) {
2423
+ dirruns = dirrunsUnique;
2424
+ outermostContext = contextBackup;
2425
+ }
2426
+
2427
+ return unmatched;
2428
+ };
2429
+
2430
+ return bySet ?
2431
+ markFunction( superMatcher ) :
2432
+ superMatcher;
2433
+ }
2434
+
2435
+ compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
2436
+ var i,
2437
+ setMatchers = [],
2438
+ elementMatchers = [],
2439
+ cached = compilerCache[ selector + " " ];
2440
+
2441
+ if ( !cached ) {
2442
+ // Generate a function of recursive functions that can be used to check each element
2443
+ if ( !group ) {
2444
+ group = tokenize( selector );
2445
+ }
2446
+ i = group.length;
2447
+ while ( i-- ) {
2448
+ cached = matcherFromTokens( group[i] );
2449
+ if ( cached[ expando ] ) {
2450
+ setMatchers.push( cached );
2451
+ } else {
2452
+ elementMatchers.push( cached );
2453
+ }
2454
+ }
2455
+
2456
+ // Cache the compiled function
2457
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2458
+ }
2459
+ return cached;
2460
+ };
2461
+
2462
+ function multipleContexts( selector, contexts, results ) {
2463
+ var i = 0,
2464
+ len = contexts.length;
2465
+ for ( ; i < len; i++ ) {
2466
+ Sizzle( selector, contexts[i], results );
2467
+ }
2468
+ return results;
2469
+ }
2470
+
2471
+ function select( selector, context, results, seed ) {
2472
+ var i, tokens, token, type, find,
2473
+ match = tokenize( selector );
2474
+
2475
+ if ( !seed ) {
2476
+ // Try to minimize operations if there is only one group
2477
+ if ( match.length === 1 ) {
2478
+
2479
+ // Take a shortcut and set the context if the root selector is an ID
2480
+ tokens = match[0] = match[0].slice( 0 );
2481
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2482
+ support.getById && context.nodeType === 9 && documentIsHTML &&
2483
+ Expr.relative[ tokens[1].type ] ) {
2484
+
2485
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2486
+ if ( !context ) {
2487
+ return results;
2488
+ }
2489
+ selector = selector.slice( tokens.shift().value.length );
2490
+ }
2491
+
2492
+ // Fetch a seed set for right-to-left matching
2493
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2494
+ while ( i-- ) {
2495
+ token = tokens[i];
2496
+
2497
+ // Abort if we hit a combinator
2498
+ if ( Expr.relative[ (type = token.type) ] ) {
2499
+ break;
2500
+ }
2501
+ if ( (find = Expr.find[ type ]) ) {
2502
+ // Search, expanding context for leading sibling combinators
2503
+ if ( (seed = find(
2504
+ token.matches[0].replace( runescape, funescape ),
2505
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2506
+ )) ) {
2507
+
2508
+ // If seed is empty or no tokens remain, we can return early
2509
+ tokens.splice( i, 1 );
2510
+ selector = seed.length && toSelector( tokens );
2511
+ if ( !selector ) {
2512
+ push.apply( results, seed );
2513
+ return results;
2514
+ }
2515
+
2516
+ break;
2517
+ }
2518
+ }
2519
+ }
2520
+ }
2521
+ }
2522
+
2523
+ // Compile and execute a filtering function
2524
+ // Provide `match` to avoid retokenization if we modified the selector above
2525
+ compile( selector, match )(
2526
+ seed,
2527
+ context,
2528
+ !documentIsHTML,
2529
+ results,
2530
+ rsibling.test( selector ) && testContext( context.parentNode ) || context
2531
+ );
2532
+ return results;
2533
+ }
2534
+
2535
+ // One-time assignments
2536
+
2537
+ // Sort stability
2538
+ support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2539
+
2540
+ // Support: Chrome<14
2541
+ // Always assume duplicates if they aren't passed to the comparison function
2542
+ support.detectDuplicates = !!hasDuplicate;
2543
+
2544
+ // Initialize against the default document
2545
+ setDocument();
2546
+
2547
+ // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2548
+ // Detached nodes confoundingly follow *each other*
2549
+ support.sortDetached = assert(function( div1 ) {
2550
+ // Should return 1, but returns 4 (following)
2551
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2552
+ });
2553
+
2554
+ // Support: IE<8
2555
+ // Prevent attribute/property "interpolation"
2556
+ // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2557
+ if ( !assert(function( div ) {
2558
+ div.innerHTML = "<a href='#'></a>";
2559
+ return div.firstChild.getAttribute("href") === "#" ;
2560
+ }) ) {
2561
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
2562
+ if ( !isXML ) {
2563
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2564
+ }
2565
+ });
2566
+ }
2567
+
2568
+ // Support: IE<9
2569
+ // Use defaultValue in place of getAttribute("value")
2570
+ if ( !support.attributes || !assert(function( div ) {
2571
+ div.innerHTML = "<input/>";
2572
+ div.firstChild.setAttribute( "value", "" );
2573
+ return div.firstChild.getAttribute( "value" ) === "";
2574
+ }) ) {
2575
+ addHandle( "value", function( elem, name, isXML ) {
2576
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2577
+ return elem.defaultValue;
2578
+ }
2579
+ });
2580
+ }
2581
+
2582
+ // Support: IE<9
2583
+ // Use getAttributeNode to fetch booleans when getAttribute lies
2584
+ if ( !assert(function( div ) {
2585
+ return div.getAttribute("disabled") == null;
2586
+ }) ) {
2587
+ addHandle( booleans, function( elem, name, isXML ) {
2588
+ var val;
2589
+ if ( !isXML ) {
2590
+ return elem[ name ] === true ? name.toLowerCase() :
2591
+ (val = elem.getAttributeNode( name )) && val.specified ?
2592
+ val.value :
2593
+ null;
2594
+ }
2595
+ });
2596
+ }
2597
+
2598
+ return Sizzle;
2599
+
2600
+ })( window );
2601
+
2602
+
2603
+
2604
+ jQuery.find = Sizzle;
2605
+ jQuery.expr = Sizzle.selectors;
2606
+ jQuery.expr[":"] = jQuery.expr.pseudos;
2607
+ jQuery.unique = Sizzle.uniqueSort;
2608
+ jQuery.text = Sizzle.getText;
2609
+ jQuery.isXMLDoc = Sizzle.isXML;
2610
+ jQuery.contains = Sizzle.contains;
2611
+
2612
+
2613
+
2614
+ var rneedsContext = jQuery.expr.match.needsContext;
2615
+
2616
+ var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2617
+
2618
+
2619
+
2620
+ var risSimple = /^.[^:#\[\.,]*$/;
2621
+
2622
+ // Implement the identical functionality for filter and not
2623
+ function winnow( elements, qualifier, not ) {
2624
+ if ( jQuery.isFunction( qualifier ) ) {
2625
+ return jQuery.grep( elements, function( elem, i ) {
2626
+ /* jshint -W018 */
2627
+ return !!qualifier.call( elem, i, elem ) !== not;
2628
+ });
2629
+
2630
+ }
2631
+
2632
+ if ( qualifier.nodeType ) {
2633
+ return jQuery.grep( elements, function( elem ) {
2634
+ return ( elem === qualifier ) !== not;
2635
+ });
2636
+
2637
+ }
2638
+
2639
+ if ( typeof qualifier === "string" ) {
2640
+ if ( risSimple.test( qualifier ) ) {
2641
+ return jQuery.filter( qualifier, elements, not );
2642
+ }
2643
+
2644
+ qualifier = jQuery.filter( qualifier, elements );
2645
+ }
2646
+
2647
+ return jQuery.grep( elements, function( elem ) {
2648
+ return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
2649
+ });
2650
+ }
2651
+
2652
+ jQuery.filter = function( expr, elems, not ) {
2653
+ var elem = elems[ 0 ];
2654
+
2655
+ if ( not ) {
2656
+ expr = ":not(" + expr + ")";
2657
+ }
2658
+
2659
+ return elems.length === 1 && elem.nodeType === 1 ?
2660
+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2661
+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2662
+ return elem.nodeType === 1;
2663
+ }));
2664
+ };
2665
+
2666
+ jQuery.fn.extend({
2667
+ find: function( selector ) {
2668
+ var i,
2669
+ ret = [],
2670
+ self = this,
2671
+ len = self.length;
2672
+
2673
+ if ( typeof selector !== "string" ) {
2674
+ return this.pushStack( jQuery( selector ).filter(function() {
2675
+ for ( i = 0; i < len; i++ ) {
2676
+ if ( jQuery.contains( self[ i ], this ) ) {
2677
+ return true;
2678
+ }
2679
+ }
2680
+ }) );
2681
+ }
2682
+
2683
+ for ( i = 0; i < len; i++ ) {
2684
+ jQuery.find( selector, self[ i ], ret );
2685
+ }
2686
+
2687
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
2688
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2689
+ ret.selector = this.selector ? this.selector + " " + selector : selector;
2690
+ return ret;
2691
+ },
2692
+ filter: function( selector ) {
2693
+ return this.pushStack( winnow(this, selector || [], false) );
2694
+ },
2695
+ not: function( selector ) {
2696
+ return this.pushStack( winnow(this, selector || [], true) );
2697
+ },
2698
+ is: function( selector ) {
2699
+ return !!winnow(
2700
+ this,
2701
+
2702
+ // If this is a positional/relative selector, check membership in the returned set
2703
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
2704
+ typeof selector === "string" && rneedsContext.test( selector ) ?
2705
+ jQuery( selector ) :
2706
+ selector || [],
2707
+ false
2708
+ ).length;
2709
+ }
2710
+ });
2711
+
2712
+
2713
+ // Initialize a jQuery object
2714
+
2715
+
2716
+ // A central reference to the root jQuery(document)
2717
+ var rootjQuery,
2718
+
2719
+ // Use the correct document accordingly with window argument (sandbox)
2720
+ document = window.document,
2721
+
2722
+ // A simple way to check for HTML strings
2723
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2724
+ // Strict HTML recognition (#11290: must start with <)
2725
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2726
+
2727
+ init = jQuery.fn.init = function( selector, context ) {
2728
+ var match, elem;
2729
+
2730
+ // HANDLE: $(""), $(null), $(undefined), $(false)
2731
+ if ( !selector ) {
2732
+ return this;
2733
+ }
2734
+
2735
+ // Handle HTML strings
2736
+ if ( typeof selector === "string" ) {
2737
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
2738
+ // Assume that strings that start and end with <> are HTML and skip the regex check
2739
+ match = [ null, selector, null ];
2740
+
2741
+ } else {
2742
+ match = rquickExpr.exec( selector );
2743
+ }
2744
+
2745
+ // Match html or make sure no context is specified for #id
2746
+ if ( match && (match[1] || !context) ) {
2747
+
2748
+ // HANDLE: $(html) -> $(array)
2749
+ if ( match[1] ) {
2750
+ context = context instanceof jQuery ? context[0] : context;
2751
+
2752
+ // scripts is true for back-compat
2753
+ // Intentionally let the error be thrown if parseHTML is not present
2754
+ jQuery.merge( this, jQuery.parseHTML(
2755
+ match[1],
2756
+ context && context.nodeType ? context.ownerDocument || context : document,
2757
+ true
2758
+ ) );
2759
+
2760
+ // HANDLE: $(html, props)
2761
+ if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2762
+ for ( match in context ) {
2763
+ // Properties of context are called as methods if possible
2764
+ if ( jQuery.isFunction( this[ match ] ) ) {
2765
+ this[ match ]( context[ match ] );
2766
+
2767
+ // ...and otherwise set as attributes
2768
+ } else {
2769
+ this.attr( match, context[ match ] );
2770
+ }
2771
+ }
2772
+ }
2773
+
2774
+ return this;
2775
+
2776
+ // HANDLE: $(#id)
2777
+ } else {
2778
+ elem = document.getElementById( match[2] );
2779
+
2780
+ // Check parentNode to catch when Blackberry 4.6 returns
2781
+ // nodes that are no longer in the document #6963
2782
+ if ( elem && elem.parentNode ) {
2783
+ // Handle the case where IE and Opera return items
2784
+ // by name instead of ID
2785
+ if ( elem.id !== match[2] ) {
2786
+ return rootjQuery.find( selector );
2787
+ }
2788
+
2789
+ // Otherwise, we inject the element directly into the jQuery object
2790
+ this.length = 1;
2791
+ this[0] = elem;
2792
+ }
2793
+
2794
+ this.context = document;
2795
+ this.selector = selector;
2796
+ return this;
2797
+ }
2798
+
2799
+ // HANDLE: $(expr, $(...))
2800
+ } else if ( !context || context.jquery ) {
2801
+ return ( context || rootjQuery ).find( selector );
2802
+
2803
+ // HANDLE: $(expr, context)
2804
+ // (which is just equivalent to: $(context).find(expr)
2805
+ } else {
2806
+ return this.constructor( context ).find( selector );
2807
+ }
2808
+
2809
+ // HANDLE: $(DOMElement)
2810
+ } else if ( selector.nodeType ) {
2811
+ this.context = this[0] = selector;
2812
+ this.length = 1;
2813
+ return this;
2814
+
2815
+ // HANDLE: $(function)
2816
+ // Shortcut for document ready
2817
+ } else if ( jQuery.isFunction( selector ) ) {
2818
+ return typeof rootjQuery.ready !== "undefined" ?
2819
+ rootjQuery.ready( selector ) :
2820
+ // Execute immediately if ready is not present
2821
+ selector( jQuery );
2822
+ }
2823
+
2824
+ if ( selector.selector !== undefined ) {
2825
+ this.selector = selector.selector;
2826
+ this.context = selector.context;
2827
+ }
2828
+
2829
+ return jQuery.makeArray( selector, this );
2830
+ };
2831
+
2832
+ // Give the init function the jQuery prototype for later instantiation
2833
+ init.prototype = jQuery.fn;
2834
+
2835
+ // Initialize central reference
2836
+ rootjQuery = jQuery( document );
2837
+
2838
+
2839
+ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2840
+ // methods guaranteed to produce a unique set when starting from a unique set
2841
+ guaranteedUnique = {
2842
+ children: true,
2843
+ contents: true,
2844
+ next: true,
2845
+ prev: true
2846
+ };
2847
+
2848
+ jQuery.extend({
2849
+ dir: function( elem, dir, until ) {
2850
+ var matched = [],
2851
+ cur = elem[ dir ];
2852
+
2853
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
2854
+ if ( cur.nodeType === 1 ) {
2855
+ matched.push( cur );
2856
+ }
2857
+ cur = cur[dir];
2858
+ }
2859
+ return matched;
2860
+ },
2861
+
2862
+ sibling: function( n, elem ) {
2863
+ var r = [];
2864
+
2865
+ for ( ; n; n = n.nextSibling ) {
2866
+ if ( n.nodeType === 1 && n !== elem ) {
2867
+ r.push( n );
2868
+ }
2869
+ }
2870
+
2871
+ return r;
2872
+ }
2873
+ });
2874
+
2875
+ jQuery.fn.extend({
2876
+ has: function( target ) {
2877
+ var i,
2878
+ targets = jQuery( target, this ),
2879
+ len = targets.length;
2880
+
2881
+ return this.filter(function() {
2882
+ for ( i = 0; i < len; i++ ) {
2883
+ if ( jQuery.contains( this, targets[i] ) ) {
2884
+ return true;
2885
+ }
2886
+ }
2887
+ });
2888
+ },
2889
+
2890
+ closest: function( selectors, context ) {
2891
+ var cur,
2892
+ i = 0,
2893
+ l = this.length,
2894
+ matched = [],
2895
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2896
+ jQuery( selectors, context || this.context ) :
2897
+ 0;
2898
+
2899
+ for ( ; i < l; i++ ) {
2900
+ for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2901
+ // Always skip document fragments
2902
+ if ( cur.nodeType < 11 && (pos ?
2903
+ pos.index(cur) > -1 :
2904
+
2905
+ // Don't pass non-elements to Sizzle
2906
+ cur.nodeType === 1 &&
2907
+ jQuery.find.matchesSelector(cur, selectors)) ) {
2908
+
2909
+ matched.push( cur );
2910
+ break;
2911
+ }
2912
+ }
2913
+ }
2914
+
2915
+ return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2916
+ },
2917
+
2918
+ // Determine the position of an element within
2919
+ // the matched set of elements
2920
+ index: function( elem ) {
2921
+
2922
+ // No argument, return index in parent
2923
+ if ( !elem ) {
2924
+ return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
2925
+ }
2926
+
2927
+ // index in selector
2928
+ if ( typeof elem === "string" ) {
2929
+ return jQuery.inArray( this[0], jQuery( elem ) );
2930
+ }
2931
+
2932
+ // Locate the position of the desired element
2933
+ return jQuery.inArray(
2934
+ // If it receives a jQuery object, the first element is used
2935
+ elem.jquery ? elem[0] : elem, this );
2936
+ },
2937
+
2938
+ add: function( selector, context ) {
2939
+ return this.pushStack(
2940
+ jQuery.unique(
2941
+ jQuery.merge( this.get(), jQuery( selector, context ) )
2942
+ )
2943
+ );
2944
+ },
2945
+
2946
+ addBack: function( selector ) {
2947
+ return this.add( selector == null ?
2948
+ this.prevObject : this.prevObject.filter(selector)
2949
+ );
2950
+ }
2951
+ });
2952
+
2953
+ function sibling( cur, dir ) {
2954
+ do {
2955
+ cur = cur[ dir ];
2956
+ } while ( cur && cur.nodeType !== 1 );
2957
+
2958
+ return cur;
2959
+ }
2960
+
2961
+ jQuery.each({
2962
+ parent: function( elem ) {
2963
+ var parent = elem.parentNode;
2964
+ return parent && parent.nodeType !== 11 ? parent : null;
2965
+ },
2966
+ parents: function( elem ) {
2967
+ return jQuery.dir( elem, "parentNode" );
2968
+ },
2969
+ parentsUntil: function( elem, i, until ) {
2970
+ return jQuery.dir( elem, "parentNode", until );
2971
+ },
2972
+ next: function( elem ) {
2973
+ return sibling( elem, "nextSibling" );
2974
+ },
2975
+ prev: function( elem ) {
2976
+ return sibling( elem, "previousSibling" );
2977
+ },
2978
+ nextAll: function( elem ) {
2979
+ return jQuery.dir( elem, "nextSibling" );
2980
+ },
2981
+ prevAll: function( elem ) {
2982
+ return jQuery.dir( elem, "previousSibling" );
2983
+ },
2984
+ nextUntil: function( elem, i, until ) {
2985
+ return jQuery.dir( elem, "nextSibling", until );
2986
+ },
2987
+ prevUntil: function( elem, i, until ) {
2988
+ return jQuery.dir( elem, "previousSibling", until );
2989
+ },
2990
+ siblings: function( elem ) {
2991
+ return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2992
+ },
2993
+ children: function( elem ) {
2994
+ return jQuery.sibling( elem.firstChild );
2995
+ },
2996
+ contents: function( elem ) {
2997
+ return jQuery.nodeName( elem, "iframe" ) ?
2998
+ elem.contentDocument || elem.contentWindow.document :
2999
+ jQuery.merge( [], elem.childNodes );
3000
+ }
3001
+ }, function( name, fn ) {
3002
+ jQuery.fn[ name ] = function( until, selector ) {
3003
+ var ret = jQuery.map( this, fn, until );
3004
+
3005
+ if ( name.slice( -5 ) !== "Until" ) {
3006
+ selector = until;
3007
+ }
3008
+
3009
+ if ( selector && typeof selector === "string" ) {
3010
+ ret = jQuery.filter( selector, ret );
3011
+ }
3012
+
3013
+ if ( this.length > 1 ) {
3014
+ // Remove duplicates
3015
+ if ( !guaranteedUnique[ name ] ) {
3016
+ ret = jQuery.unique( ret );
3017
+ }
3018
+
3019
+ // Reverse order for parents* and prev-derivatives
3020
+ if ( rparentsprev.test( name ) ) {
3021
+ ret = ret.reverse();
3022
+ }
3023
+ }
3024
+
3025
+ return this.pushStack( ret );
3026
+ };
3027
+ });
3028
+ var rnotwhite = (/\S+/g);
3029
+
3030
+
3031
+
3032
+ // String to Object options format cache
3033
+ var optionsCache = {};
3034
+
3035
+ // Convert String-formatted options into Object-formatted ones and store in cache
3036
+ function createOptions( options ) {
3037
+ var object = optionsCache[ options ] = {};
3038
+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3039
+ object[ flag ] = true;
3040
+ });
3041
+ return object;
3042
+ }
3043
+
3044
+ /*
3045
+ * Create a callback list using the following parameters:
3046
+ *
3047
+ * options: an optional list of space-separated options that will change how
3048
+ * the callback list behaves or a more traditional option object
3049
+ *
3050
+ * By default a callback list will act like an event callback list and can be
3051
+ * "fired" multiple times.
3052
+ *
3053
+ * Possible options:
3054
+ *
3055
+ * once: will ensure the callback list can only be fired once (like a Deferred)
3056
+ *
3057
+ * memory: will keep track of previous values and will call any callback added
3058
+ * after the list has been fired right away with the latest "memorized"
3059
+ * values (like a Deferred)
3060
+ *
3061
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
3062
+ *
3063
+ * stopOnFalse: interrupt callings when a callback returns false
3064
+ *
3065
+ */
3066
+ jQuery.Callbacks = function( options ) {
3067
+
3068
+ // Convert options from String-formatted to Object-formatted if needed
3069
+ // (we check in cache first)
3070
+ options = typeof options === "string" ?
3071
+ ( optionsCache[ options ] || createOptions( options ) ) :
3072
+ jQuery.extend( {}, options );
3073
+
3074
+ var // Flag to know if list is currently firing
3075
+ firing,
3076
+ // Last fire value (for non-forgettable lists)
3077
+ memory,
3078
+ // Flag to know if list was already fired
3079
+ fired,
3080
+ // End of the loop when firing
3081
+ firingLength,
3082
+ // Index of currently firing callback (modified by remove if needed)
3083
+ firingIndex,
3084
+ // First callback to fire (used internally by add and fireWith)
3085
+ firingStart,
3086
+ // Actual callback list
3087
+ list = [],
3088
+ // Stack of fire calls for repeatable lists
3089
+ stack = !options.once && [],
3090
+ // Fire callbacks
3091
+ fire = function( data ) {
3092
+ memory = options.memory && data;
3093
+ fired = true;
3094
+ firingIndex = firingStart || 0;
3095
+ firingStart = 0;
3096
+ firingLength = list.length;
3097
+ firing = true;
3098
+ for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3099
+ if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3100
+ memory = false; // To prevent further calls using add
3101
+ break;
3102
+ }
3103
+ }
3104
+ firing = false;
3105
+ if ( list ) {
3106
+ if ( stack ) {
3107
+ if ( stack.length ) {
3108
+ fire( stack.shift() );
3109
+ }
3110
+ } else if ( memory ) {
3111
+ list = [];
3112
+ } else {
3113
+ self.disable();
3114
+ }
3115
+ }
3116
+ },
3117
+ // Actual Callbacks object
3118
+ self = {
3119
+ // Add a callback or a collection of callbacks to the list
3120
+ add: function() {
3121
+ if ( list ) {
3122
+ // First, we save the current length
3123
+ var start = list.length;
3124
+ (function add( args ) {
3125
+ jQuery.each( args, function( _, arg ) {
3126
+ var type = jQuery.type( arg );
3127
+ if ( type === "function" ) {
3128
+ if ( !options.unique || !self.has( arg ) ) {
3129
+ list.push( arg );
3130
+ }
3131
+ } else if ( arg && arg.length && type !== "string" ) {
3132
+ // Inspect recursively
3133
+ add( arg );
3134
+ }
3135
+ });
3136
+ })( arguments );
3137
+ // Do we need to add the callbacks to the
3138
+ // current firing batch?
3139
+ if ( firing ) {
3140
+ firingLength = list.length;
3141
+ // With memory, if we're not firing then
3142
+ // we should call right away
3143
+ } else if ( memory ) {
3144
+ firingStart = start;
3145
+ fire( memory );
3146
+ }
3147
+ }
3148
+ return this;
3149
+ },
3150
+ // Remove a callback from the list
3151
+ remove: function() {
3152
+ if ( list ) {
3153
+ jQuery.each( arguments, function( _, arg ) {
3154
+ var index;
3155
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3156
+ list.splice( index, 1 );
3157
+ // Handle firing indexes
3158
+ if ( firing ) {
3159
+ if ( index <= firingLength ) {
3160
+ firingLength--;
3161
+ }
3162
+ if ( index <= firingIndex ) {
3163
+ firingIndex--;
3164
+ }
3165
+ }
3166
+ }
3167
+ });
3168
+ }
3169
+ return this;
3170
+ },
3171
+ // Check if a given callback is in the list.
3172
+ // If no argument is given, return whether or not list has callbacks attached.
3173
+ has: function( fn ) {
3174
+ return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3175
+ },
3176
+ // Remove all callbacks from the list
3177
+ empty: function() {
3178
+ list = [];
3179
+ firingLength = 0;
3180
+ return this;
3181
+ },
3182
+ // Have the list do nothing anymore
3183
+ disable: function() {
3184
+ list = stack = memory = undefined;
3185
+ return this;
3186
+ },
3187
+ // Is it disabled?
3188
+ disabled: function() {
3189
+ return !list;
3190
+ },
3191
+ // Lock the list in its current state
3192
+ lock: function() {
3193
+ stack = undefined;
3194
+ if ( !memory ) {
3195
+ self.disable();
3196
+ }
3197
+ return this;
3198
+ },
3199
+ // Is it locked?
3200
+ locked: function() {
3201
+ return !stack;
3202
+ },
3203
+ // Call all callbacks with the given context and arguments
3204
+ fireWith: function( context, args ) {
3205
+ if ( list && ( !fired || stack ) ) {
3206
+ args = args || [];
3207
+ args = [ context, args.slice ? args.slice() : args ];
3208
+ if ( firing ) {
3209
+ stack.push( args );
3210
+ } else {
3211
+ fire( args );
3212
+ }
3213
+ }
3214
+ return this;
3215
+ },
3216
+ // Call all the callbacks with the given arguments
3217
+ fire: function() {
3218
+ self.fireWith( this, arguments );
3219
+ return this;
3220
+ },
3221
+ // To know if the callbacks have already been called at least once
3222
+ fired: function() {
3223
+ return !!fired;
3224
+ }
3225
+ };
3226
+
3227
+ return self;
3228
+ };
3229
+
3230
+
3231
+ jQuery.extend({
3232
+
3233
+ Deferred: function( func ) {
3234
+ var tuples = [
3235
+ // action, add listener, listener list, final state
3236
+ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3237
+ [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3238
+ [ "notify", "progress", jQuery.Callbacks("memory") ]
3239
+ ],
3240
+ state = "pending",
3241
+ promise = {
3242
+ state: function() {
3243
+ return state;
3244
+ },
3245
+ always: function() {
3246
+ deferred.done( arguments ).fail( arguments );
3247
+ return this;
3248
+ },
3249
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
3250
+ var fns = arguments;
3251
+ return jQuery.Deferred(function( newDefer ) {
3252
+ jQuery.each( tuples, function( i, tuple ) {
3253
+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3254
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
3255
+ deferred[ tuple[1] ](function() {
3256
+ var returned = fn && fn.apply( this, arguments );
3257
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
3258
+ returned.promise()
3259
+ .done( newDefer.resolve )
3260
+ .fail( newDefer.reject )
3261
+ .progress( newDefer.notify );
3262
+ } else {
3263
+ newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3264
+ }
3265
+ });
3266
+ });
3267
+ fns = null;
3268
+ }).promise();
3269
+ },
3270
+ // Get a promise for this deferred
3271
+ // If obj is provided, the promise aspect is added to the object
3272
+ promise: function( obj ) {
3273
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
3274
+ }
3275
+ },
3276
+ deferred = {};
3277
+
3278
+ // Keep pipe for back-compat
3279
+ promise.pipe = promise.then;
3280
+
3281
+ // Add list-specific methods
3282
+ jQuery.each( tuples, function( i, tuple ) {
3283
+ var list = tuple[ 2 ],
3284
+ stateString = tuple[ 3 ];
3285
+
3286
+ // promise[ done | fail | progress ] = list.add
3287
+ promise[ tuple[1] ] = list.add;
3288
+
3289
+ // Handle state
3290
+ if ( stateString ) {
3291
+ list.add(function() {
3292
+ // state = [ resolved | rejected ]
3293
+ state = stateString;
3294
+
3295
+ // [ reject_list | resolve_list ].disable; progress_list.lock
3296
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3297
+ }
3298
+
3299
+ // deferred[ resolve | reject | notify ]
3300
+ deferred[ tuple[0] ] = function() {
3301
+ deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3302
+ return this;
3303
+ };
3304
+ deferred[ tuple[0] + "With" ] = list.fireWith;
3305
+ });
3306
+
3307
+ // Make the deferred a promise
3308
+ promise.promise( deferred );
3309
+
3310
+ // Call given func if any
3311
+ if ( func ) {
3312
+ func.call( deferred, deferred );
3313
+ }
3314
+
3315
+ // All done!
3316
+ return deferred;
3317
+ },
3318
+
3319
+ // Deferred helper
3320
+ when: function( subordinate /* , ..., subordinateN */ ) {
3321
+ var i = 0,
3322
+ resolveValues = slice.call( arguments ),
3323
+ length = resolveValues.length,
3324
+
3325
+ // the count of uncompleted subordinates
3326
+ remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3327
+
3328
+ // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3329
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3330
+
3331
+ // Update function for both resolve and progress values
3332
+ updateFunc = function( i, contexts, values ) {
3333
+ return function( value ) {
3334
+ contexts[ i ] = this;
3335
+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3336
+ if ( values === progressValues ) {
3337
+ deferred.notifyWith( contexts, values );
3338
+
3339
+ } else if ( !(--remaining) ) {
3340
+ deferred.resolveWith( contexts, values );
3341
+ }
3342
+ };
3343
+ },
3344
+
3345
+ progressValues, progressContexts, resolveContexts;
3346
+
3347
+ // add listeners to Deferred subordinates; treat others as resolved
3348
+ if ( length > 1 ) {
3349
+ progressValues = new Array( length );
3350
+ progressContexts = new Array( length );
3351
+ resolveContexts = new Array( length );
3352
+ for ( ; i < length; i++ ) {
3353
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3354
+ resolveValues[ i ].promise()
3355
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
3356
+ .fail( deferred.reject )
3357
+ .progress( updateFunc( i, progressContexts, progressValues ) );
3358
+ } else {
3359
+ --remaining;
3360
+ }
3361
+ }
3362
+ }
3363
+
3364
+ // if we're not waiting on anything, resolve the master
3365
+ if ( !remaining ) {
3366
+ deferred.resolveWith( resolveContexts, resolveValues );
3367
+ }
3368
+
3369
+ return deferred.promise();
3370
+ }
3371
+ });
3372
+
3373
+
3374
+ // The deferred used on DOM ready
3375
+ var readyList;
3376
+
3377
+ jQuery.fn.ready = function( fn ) {
3378
+ // Add the callback
3379
+ jQuery.ready.promise().done( fn );
3380
+
3381
+ return this;
3382
+ };
3383
+
3384
+ jQuery.extend({
3385
+ // Is the DOM ready to be used? Set to true once it occurs.
3386
+ isReady: false,
3387
+
3388
+ // A counter to track how many items to wait for before
3389
+ // the ready event fires. See #6781
3390
+ readyWait: 1,
3391
+
3392
+ // Hold (or release) the ready event
3393
+ holdReady: function( hold ) {
3394
+ if ( hold ) {
3395
+ jQuery.readyWait++;
3396
+ } else {
3397
+ jQuery.ready( true );
3398
+ }
3399
+ },
3400
+
3401
+ // Handle when the DOM is ready
3402
+ ready: function( wait ) {
3403
+
3404
+ // Abort if there are pending holds or we're already ready
3405
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3406
+ return;
3407
+ }
3408
+
3409
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
3410
+ if ( !document.body ) {
3411
+ return setTimeout( jQuery.ready );
3412
+ }
3413
+
3414
+ // Remember that the DOM is ready
3415
+ jQuery.isReady = true;
3416
+
3417
+ // If a normal DOM Ready event fired, decrement, and wait if need be
3418
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
3419
+ return;
3420
+ }
3421
+
3422
+ // If there are functions bound, to execute
3423
+ readyList.resolveWith( document, [ jQuery ] );
3424
+
3425
+ // Trigger any bound ready events
3426
+ if ( jQuery.fn.trigger ) {
3427
+ jQuery( document ).trigger("ready").off("ready");
3428
+ }
3429
+ }
3430
+ });
3431
+
3432
+ /**
3433
+ * Clean-up method for dom ready events
3434
+ */
3435
+ function detach() {
3436
+ if ( document.addEventListener ) {
3437
+ document.removeEventListener( "DOMContentLoaded", completed, false );
3438
+ window.removeEventListener( "load", completed, false );
3439
+
3440
+ } else {
3441
+ document.detachEvent( "onreadystatechange", completed );
3442
+ window.detachEvent( "onload", completed );
3443
+ }
3444
+ }
3445
+
3446
+ /**
3447
+ * The ready event handler and self cleanup method
3448
+ */
3449
+ function completed() {
3450
+ // readyState === "complete" is good enough for us to call the dom ready in oldIE
3451
+ if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
3452
+ detach();
3453
+ jQuery.ready();
3454
+ }
3455
+ }
3456
+
3457
+ jQuery.ready.promise = function( obj ) {
3458
+ if ( !readyList ) {
3459
+
3460
+ readyList = jQuery.Deferred();
3461
+
3462
+ // Catch cases where $(document).ready() is called after the browser event has already occurred.
3463
+ // we once tried to use readyState "interactive" here, but it caused issues like the one
3464
+ // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3465
+ if ( document.readyState === "complete" ) {
3466
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
3467
+ setTimeout( jQuery.ready );
3468
+
3469
+ // Standards-based browsers support DOMContentLoaded
3470
+ } else if ( document.addEventListener ) {
3471
+ // Use the handy event callback
3472
+ document.addEventListener( "DOMContentLoaded", completed, false );
3473
+
3474
+ // A fallback to window.onload, that will always work
3475
+ window.addEventListener( "load", completed, false );
3476
+
3477
+ // If IE event model is used
3478
+ } else {
3479
+ // Ensure firing before onload, maybe late but safe also for iframes
3480
+ document.attachEvent( "onreadystatechange", completed );
3481
+
3482
+ // A fallback to window.onload, that will always work
3483
+ window.attachEvent( "onload", completed );
3484
+
3485
+ // If IE and not a frame
3486
+ // continually check to see if the document is ready
3487
+ var top = false;
3488
+
3489
+ try {
3490
+ top = window.frameElement == null && document.documentElement;
3491
+ } catch(e) {}
3492
+
3493
+ if ( top && top.doScroll ) {
3494
+ (function doScrollCheck() {
3495
+ if ( !jQuery.isReady ) {
3496
+
3497
+ try {
3498
+ // Use the trick by Diego Perini
3499
+ // http://javascript.nwbox.com/IEContentLoaded/
3500
+ top.doScroll("left");
3501
+ } catch(e) {
3502
+ return setTimeout( doScrollCheck, 50 );
3503
+ }
3504
+
3505
+ // detach all dom ready events
3506
+ detach();
3507
+
3508
+ // and execute any waiting functions
3509
+ jQuery.ready();
3510
+ }
3511
+ })();
3512
+ }
3513
+ }
3514
+ }
3515
+ return readyList.promise( obj );
3516
+ };
3517
+
3518
+
3519
+ var strundefined = typeof undefined;
3520
+
3521
+
3522
+
3523
+ // Support: IE<9
3524
+ // Iteration over object's inherited properties before its own
3525
+ var i;
3526
+ for ( i in jQuery( support ) ) {
3527
+ break;
3528
+ }
3529
+ support.ownLast = i !== "0";
3530
+
3531
+ // Note: most support tests are defined in their respective modules.
3532
+ // false until the test is run
3533
+ support.inlineBlockNeedsLayout = false;
3534
+
3535
+ jQuery(function() {
3536
+ // We need to execute this one support test ASAP because we need to know
3537
+ // if body.style.zoom needs to be set.
3538
+
3539
+ var container, div,
3540
+ body = document.getElementsByTagName("body")[0];
3541
+
3542
+ if ( !body ) {
3543
+ // Return for frameset docs that don't have a body
3544
+ return;
3545
+ }
3546
+
3547
+ // Setup
3548
+ container = document.createElement( "div" );
3549
+ container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
3550
+
3551
+ div = document.createElement( "div" );
3552
+ body.appendChild( container ).appendChild( div );
3553
+
3554
+ if ( typeof div.style.zoom !== strundefined ) {
3555
+ // Support: IE<8
3556
+ // Check if natively block-level elements act like inline-block
3557
+ // elements when setting their display to 'inline' and giving
3558
+ // them layout
3559
+ div.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1";
3560
+
3561
+ if ( (support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 )) ) {
3562
+ // Prevent IE 6 from affecting layout for positioned elements #11048
3563
+ // Prevent IE from shrinking the body in IE 7 mode #12869
3564
+ // Support: IE<8
3565
+ body.style.zoom = 1;
3566
+ }
3567
+ }
3568
+
3569
+ body.removeChild( container );
3570
+
3571
+ // Null elements to avoid leaks in IE
3572
+ container = div = null;
3573
+ });
3574
+
3575
+
3576
+
3577
+
3578
+ (function() {
3579
+ var div = document.createElement( "div" );
3580
+
3581
+ // Execute the test only if not already executed in another module.
3582
+ if (support.deleteExpando == null) {
3583
+ // Support: IE<9
3584
+ support.deleteExpando = true;
3585
+ try {
3586
+ delete div.test;
3587
+ } catch( e ) {
3588
+ support.deleteExpando = false;
3589
+ }
3590
+ }
3591
+
3592
+ // Null elements to avoid leaks in IE.
3593
+ div = null;
3594
+ })();
3595
+
3596
+
3597
+ /**
3598
+ * Determines whether an object can have data
3599
+ */
3600
+ jQuery.acceptData = function( elem ) {
3601
+ var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
3602
+ nodeType = +elem.nodeType || 1;
3603
+
3604
+ // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3605
+ return nodeType !== 1 && nodeType !== 9 ?
3606
+ false :
3607
+
3608
+ // Nodes accept data unless otherwise specified; rejection can be conditional
3609
+ !noData || noData !== true && elem.getAttribute("classid") === noData;
3610
+ };
3611
+
3612
+
3613
+ var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3614
+ rmultiDash = /([A-Z])/g;
3615
+
3616
+ function dataAttr( elem, key, data ) {
3617
+ // If nothing was found internally, try to fetch any
3618
+ // data from the HTML5 data-* attribute
3619
+ if ( data === undefined && elem.nodeType === 1 ) {
3620
+
3621
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3622
+
3623
+ data = elem.getAttribute( name );
3624
+
3625
+ if ( typeof data === "string" ) {
3626
+ try {
3627
+ data = data === "true" ? true :
3628
+ data === "false" ? false :
3629
+ data === "null" ? null :
3630
+ // Only convert to a number if it doesn't change the string
3631
+ +data + "" === data ? +data :
3632
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
3633
+ data;
3634
+ } catch( e ) {}
3635
+
3636
+ // Make sure we set the data so it isn't changed later
3637
+ jQuery.data( elem, key, data );
3638
+
3639
+ } else {
3640
+ data = undefined;
3641
+ }
3642
+ }
3643
+
3644
+ return data;
3645
+ }
3646
+
3647
+ // checks a cache object for emptiness
3648
+ function isEmptyDataObject( obj ) {
3649
+ var name;
3650
+ for ( name in obj ) {
3651
+
3652
+ // if the public data object is empty, the private is still empty
3653
+ if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
3654
+ continue;
3655
+ }
3656
+ if ( name !== "toJSON" ) {
3657
+ return false;
3658
+ }
3659
+ }
3660
+
3661
+ return true;
3662
+ }
3663
+
3664
+ function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3665
+ if ( !jQuery.acceptData( elem ) ) {
3666
+ return;
3667
+ }
3668
+
3669
+ var ret, thisCache,
3670
+ internalKey = jQuery.expando,
3671
+
3672
+ // We have to handle DOM nodes and JS objects differently because IE6-7
3673
+ // can't GC object references properly across the DOM-JS boundary
3674
+ isNode = elem.nodeType,
3675
+
3676
+ // Only DOM nodes need the global jQuery cache; JS object data is
3677
+ // attached directly to the object so GC can occur automatically
3678
+ cache = isNode ? jQuery.cache : elem,
3679
+
3680
+ // Only defining an ID for JS objects if its cache already exists allows
3681
+ // the code to shortcut on the same path as a DOM node with no cache
3682
+ id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3683
+
3684
+ // Avoid doing any more work than we need to when trying to get data on an
3685
+ // object that has no data at all
3686
+ if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
3687
+ return;
3688
+ }
3689
+
3690
+ if ( !id ) {
3691
+ // Only DOM nodes need a new unique ID for each element since their data
3692
+ // ends up in the global cache
3693
+ if ( isNode ) {
3694
+ id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3695
+ } else {
3696
+ id = internalKey;
3697
+ }
3698
+ }
3699
+
3700
+ if ( !cache[ id ] ) {
3701
+ // Avoid exposing jQuery metadata on plain JS objects when the object
3702
+ // is serialized using JSON.stringify
3703
+ cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3704
+ }
3705
+
3706
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
3707
+ // shallow copied over onto the existing cache
3708
+ if ( typeof name === "object" || typeof name === "function" ) {
3709
+ if ( pvt ) {
3710
+ cache[ id ] = jQuery.extend( cache[ id ], name );
3711
+ } else {
3712
+ cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3713
+ }
3714
+ }
3715
+
3716
+ thisCache = cache[ id ];
3717
+
3718
+ // jQuery data() is stored in a separate object inside the object's internal data
3719
+ // cache in order to avoid key collisions between internal data and user-defined
3720
+ // data.
3721
+ if ( !pvt ) {
3722
+ if ( !thisCache.data ) {
3723
+ thisCache.data = {};
3724
+ }
3725
+
3726
+ thisCache = thisCache.data;
3727
+ }
3728
+
3729
+ if ( data !== undefined ) {
3730
+ thisCache[ jQuery.camelCase( name ) ] = data;
3731
+ }
3732
+
3733
+ // Check for both converted-to-camel and non-converted data property names
3734
+ // If a data property was specified
3735
+ if ( typeof name === "string" ) {
3736
+
3737
+ // First Try to find as-is property data
3738
+ ret = thisCache[ name ];
3739
+
3740
+ // Test for null|undefined property data
3741
+ if ( ret == null ) {
3742
+
3743
+ // Try to find the camelCased property
3744
+ ret = thisCache[ jQuery.camelCase( name ) ];
3745
+ }
3746
+ } else {
3747
+ ret = thisCache;
3748
+ }
3749
+
3750
+ return ret;
3751
+ }
3752
+
3753
+ function internalRemoveData( elem, name, pvt ) {
3754
+ if ( !jQuery.acceptData( elem ) ) {
3755
+ return;
3756
+ }
3757
+
3758
+ var thisCache, i,
3759
+ isNode = elem.nodeType,
3760
+
3761
+ // See jQuery.data for more information
3762
+ cache = isNode ? jQuery.cache : elem,
3763
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3764
+
3765
+ // If there is already no cache entry for this object, there is no
3766
+ // purpose in continuing
3767
+ if ( !cache[ id ] ) {
3768
+ return;
3769
+ }
3770
+
3771
+ if ( name ) {
3772
+
3773
+ thisCache = pvt ? cache[ id ] : cache[ id ].data;
3774
+
3775
+ if ( thisCache ) {
3776
+
3777
+ // Support array or space separated string names for data keys
3778
+ if ( !jQuery.isArray( name ) ) {
3779
+
3780
+ // try the string as a key before any manipulation
3781
+ if ( name in thisCache ) {
3782
+ name = [ name ];
3783
+ } else {
3784
+
3785
+ // split the camel cased version by spaces unless a key with the spaces exists
3786
+ name = jQuery.camelCase( name );
3787
+ if ( name in thisCache ) {
3788
+ name = [ name ];
3789
+ } else {
3790
+ name = name.split(" ");
3791
+ }
3792
+ }
3793
+ } else {
3794
+ // If "name" is an array of keys...
3795
+ // When data is initially created, via ("key", "val") signature,
3796
+ // keys will be converted to camelCase.
3797
+ // Since there is no way to tell _how_ a key was added, remove
3798
+ // both plain key and camelCase key. #12786
3799
+ // This will only penalize the array argument path.
3800
+ name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3801
+ }
3802
+
3803
+ i = name.length;
3804
+ while ( i-- ) {
3805
+ delete thisCache[ name[i] ];
3806
+ }
3807
+
3808
+ // If there is no data left in the cache, we want to continue
3809
+ // and let the cache object itself get destroyed
3810
+ if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
3811
+ return;
3812
+ }
3813
+ }
3814
+ }
3815
+
3816
+ // See jQuery.data for more information
3817
+ if ( !pvt ) {
3818
+ delete cache[ id ].data;
3819
+
3820
+ // Don't destroy the parent cache unless the internal data object
3821
+ // had been the only thing left in it
3822
+ if ( !isEmptyDataObject( cache[ id ] ) ) {
3823
+ return;
3824
+ }
3825
+ }
3826
+
3827
+ // Destroy the cache
3828
+ if ( isNode ) {
3829
+ jQuery.cleanData( [ elem ], true );
3830
+
3831
+ // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
3832
+ /* jshint eqeqeq: false */
3833
+ } else if ( support.deleteExpando || cache != cache.window ) {
3834
+ /* jshint eqeqeq: true */
3835
+ delete cache[ id ];
3836
+
3837
+ // When all else fails, null
3838
+ } else {
3839
+ cache[ id ] = null;
3840
+ }
3841
+ }
3842
+
3843
+ jQuery.extend({
3844
+ cache: {},
3845
+
3846
+ // The following elements (space-suffixed to avoid Object.prototype collisions)
3847
+ // throw uncatchable exceptions if you attempt to set expando properties
3848
+ noData: {
3849
+ "applet ": true,
3850
+ "embed ": true,
3851
+ // ...but Flash objects (which have this classid) *can* handle expandos
3852
+ "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
3853
+ },
3854
+
3855
+ hasData: function( elem ) {
3856
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
3857
+ return !!elem && !isEmptyDataObject( elem );
3858
+ },
3859
+
3860
+ data: function( elem, name, data ) {
3861
+ return internalData( elem, name, data );
3862
+ },
3863
+
3864
+ removeData: function( elem, name ) {
3865
+ return internalRemoveData( elem, name );
3866
+ },
3867
+
3868
+ // For internal use only.
3869
+ _data: function( elem, name, data ) {
3870
+ return internalData( elem, name, data, true );
3871
+ },
3872
+
3873
+ _removeData: function( elem, name ) {
3874
+ return internalRemoveData( elem, name, true );
3875
+ }
3876
+ });
3877
+
3878
+ jQuery.fn.extend({
3879
+ data: function( key, value ) {
3880
+ var i, name, data,
3881
+ elem = this[0],
3882
+ attrs = elem && elem.attributes;
3883
+
3884
+ // Special expections of .data basically thwart jQuery.access,
3885
+ // so implement the relevant behavior ourselves
3886
+
3887
+ // Gets all values
3888
+ if ( key === undefined ) {
3889
+ if ( this.length ) {
3890
+ data = jQuery.data( elem );
3891
+
3892
+ if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
3893
+ i = attrs.length;
3894
+ while ( i-- ) {
3895
+ name = attrs[i].name;
3896
+
3897
+ if ( name.indexOf("data-") === 0 ) {
3898
+ name = jQuery.camelCase( name.slice(5) );
3899
+
3900
+ dataAttr( elem, name, data[ name ] );
3901
+ }
3902
+ }
3903
+ jQuery._data( elem, "parsedAttrs", true );
3904
+ }
3905
+ }
3906
+
3907
+ return data;
3908
+ }
3909
+
3910
+ // Sets multiple values
3911
+ if ( typeof key === "object" ) {
3912
+ return this.each(function() {
3913
+ jQuery.data( this, key );
3914
+ });
3915
+ }
3916
+
3917
+ return arguments.length > 1 ?
3918
+
3919
+ // Sets one value
3920
+ this.each(function() {
3921
+ jQuery.data( this, key, value );
3922
+ }) :
3923
+
3924
+ // Gets one value
3925
+ // Try to fetch any internally stored data first
3926
+ elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
3927
+ },
3928
+
3929
+ removeData: function( key ) {
3930
+ return this.each(function() {
3931
+ jQuery.removeData( this, key );
3932
+ });
3933
+ }
3934
+ });
3935
+
3936
+
3937
+ jQuery.extend({
3938
+ queue: function( elem, type, data ) {
3939
+ var queue;
3940
+
3941
+ if ( elem ) {
3942
+ type = ( type || "fx" ) + "queue";
3943
+ queue = jQuery._data( elem, type );
3944
+
3945
+ // Speed up dequeue by getting out quickly if this is just a lookup
3946
+ if ( data ) {
3947
+ if ( !queue || jQuery.isArray(data) ) {
3948
+ queue = jQuery._data( elem, type, jQuery.makeArray(data) );
3949
+ } else {
3950
+ queue.push( data );
3951
+ }
3952
+ }
3953
+ return queue || [];
3954
+ }
3955
+ },
3956
+
3957
+ dequeue: function( elem, type ) {
3958
+ type = type || "fx";
3959
+
3960
+ var queue = jQuery.queue( elem, type ),
3961
+ startLength = queue.length,
3962
+ fn = queue.shift(),
3963
+ hooks = jQuery._queueHooks( elem, type ),
3964
+ next = function() {
3965
+ jQuery.dequeue( elem, type );
3966
+ };
3967
+
3968
+ // If the fx queue is dequeued, always remove the progress sentinel
3969
+ if ( fn === "inprogress" ) {
3970
+ fn = queue.shift();
3971
+ startLength--;
3972
+ }
3973
+
3974
+ if ( fn ) {
3975
+
3976
+ // Add a progress sentinel to prevent the fx queue from being
3977
+ // automatically dequeued
3978
+ if ( type === "fx" ) {
3979
+ queue.unshift( "inprogress" );
3980
+ }
3981
+
3982
+ // clear up the last queue stop function
3983
+ delete hooks.stop;
3984
+ fn.call( elem, next, hooks );
3985
+ }
3986
+
3987
+ if ( !startLength && hooks ) {
3988
+ hooks.empty.fire();
3989
+ }
3990
+ },
3991
+
3992
+ // not intended for public consumption - generates a queueHooks object, or returns the current one
3993
+ _queueHooks: function( elem, type ) {
3994
+ var key = type + "queueHooks";
3995
+ return jQuery._data( elem, key ) || jQuery._data( elem, key, {
3996
+ empty: jQuery.Callbacks("once memory").add(function() {
3997
+ jQuery._removeData( elem, type + "queue" );
3998
+ jQuery._removeData( elem, key );
3999
+ })
4000
+ });
4001
+ }
4002
+ });
4003
+
4004
+ jQuery.fn.extend({
4005
+ queue: function( type, data ) {
4006
+ var setter = 2;
4007
+
4008
+ if ( typeof type !== "string" ) {
4009
+ data = type;
4010
+ type = "fx";
4011
+ setter--;
4012
+ }
4013
+
4014
+ if ( arguments.length < setter ) {
4015
+ return jQuery.queue( this[0], type );
4016
+ }
4017
+
4018
+ return data === undefined ?
4019
+ this :
4020
+ this.each(function() {
4021
+ var queue = jQuery.queue( this, type, data );
4022
+
4023
+ // ensure a hooks for this queue
4024
+ jQuery._queueHooks( this, type );
4025
+
4026
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
4027
+ jQuery.dequeue( this, type );
4028
+ }
4029
+ });
4030
+ },
4031
+ dequeue: function( type ) {
4032
+ return this.each(function() {
4033
+ jQuery.dequeue( this, type );
4034
+ });
4035
+ },
4036
+ clearQueue: function( type ) {
4037
+ return this.queue( type || "fx", [] );
4038
+ },
4039
+ // Get a promise resolved when queues of a certain type
4040
+ // are emptied (fx is the type by default)
4041
+ promise: function( type, obj ) {
4042
+ var tmp,
4043
+ count = 1,
4044
+ defer = jQuery.Deferred(),
4045
+ elements = this,
4046
+ i = this.length,
4047
+ resolve = function() {
4048
+ if ( !( --count ) ) {
4049
+ defer.resolveWith( elements, [ elements ] );
4050
+ }
4051
+ };
4052
+
4053
+ if ( typeof type !== "string" ) {
4054
+ obj = type;
4055
+ type = undefined;
4056
+ }
4057
+ type = type || "fx";
4058
+
4059
+ while ( i-- ) {
4060
+ tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4061
+ if ( tmp && tmp.empty ) {
4062
+ count++;
4063
+ tmp.empty.add( resolve );
4064
+ }
4065
+ }
4066
+ resolve();
4067
+ return defer.promise( obj );
4068
+ }
4069
+ });
4070
+ var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4071
+
4072
+ var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4073
+
4074
+ var isHidden = function( elem, el ) {
4075
+ // isHidden might be called from jQuery#filter function;
4076
+ // in that case, element will be second argument
4077
+ elem = el || elem;
4078
+ return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4079
+ };
4080
+
4081
+
4082
+
4083
+ // Multifunctional method to get and set values of a collection
4084
+ // The value/s can optionally be executed if it's a function
4085
+ var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4086
+ var i = 0,
4087
+ length = elems.length,
4088
+ bulk = key == null;
4089
+
4090
+ // Sets many values
4091
+ if ( jQuery.type( key ) === "object" ) {
4092
+ chainable = true;
4093
+ for ( i in key ) {
4094
+ jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
4095
+ }
4096
+
4097
+ // Sets one value
4098
+ } else if ( value !== undefined ) {
4099
+ chainable = true;
4100
+
4101
+ if ( !jQuery.isFunction( value ) ) {
4102
+ raw = true;
4103
+ }
4104
+
4105
+ if ( bulk ) {
4106
+ // Bulk operations run against the entire set
4107
+ if ( raw ) {
4108
+ fn.call( elems, value );
4109
+ fn = null;
4110
+
4111
+ // ...except when executing function values
4112
+ } else {
4113
+ bulk = fn;
4114
+ fn = function( elem, key, value ) {
4115
+ return bulk.call( jQuery( elem ), value );
4116
+ };
4117
+ }
4118
+ }
4119
+
4120
+ if ( fn ) {
4121
+ for ( ; i < length; i++ ) {
4122
+ fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
4123
+ }
4124
+ }
4125
+ }
4126
+
4127
+ return chainable ?
4128
+ elems :
4129
+
4130
+ // Gets
4131
+ bulk ?
4132
+ fn.call( elems ) :
4133
+ length ? fn( elems[0], key ) : emptyGet;
4134
+ };
4135
+ var rcheckableType = (/^(?:checkbox|radio)$/i);
4136
+
4137
+
4138
+
4139
+ (function() {
4140
+ var fragment = document.createDocumentFragment(),
4141
+ div = document.createElement("div"),
4142
+ input = document.createElement("input");
4143
+
4144
+ // Setup
4145
+ div.setAttribute( "className", "t" );
4146
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a>";
4147
+
4148
+ // IE strips leading whitespace when .innerHTML is used
4149
+ support.leadingWhitespace = div.firstChild.nodeType === 3;
4150
+
4151
+ // Make sure that tbody elements aren't automatically inserted
4152
+ // IE will insert them into empty tables
4153
+ support.tbody = !div.getElementsByTagName( "tbody" ).length;
4154
+
4155
+ // Make sure that link elements get serialized correctly by innerHTML
4156
+ // This requires a wrapper element in IE
4157
+ support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4158
+
4159
+ // Makes sure cloning an html5 element does not cause problems
4160
+ // Where outerHTML is undefined, this still works
4161
+ support.html5Clone =
4162
+ document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4163
+
4164
+ // Check if a disconnected checkbox will retain its checked
4165
+ // value of true after appended to the DOM (IE6/7)
4166
+ input.type = "checkbox";
4167
+ input.checked = true;
4168
+ fragment.appendChild( input );
4169
+ support.appendChecked = input.checked;
4170
+
4171
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
4172
+ // Support: IE6-IE11+
4173
+ div.innerHTML = "<textarea>x</textarea>";
4174
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4175
+
4176
+ // #11217 - WebKit loses check when the name is after the checked attribute
4177
+ fragment.appendChild( div );
4178
+ div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
4179
+
4180
+ // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4181
+ // old WebKit doesn't clone checked state correctly in fragments
4182
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4183
+
4184
+ // Support: IE<9
4185
+ // Opera does not clone events (and typeof div.attachEvent === undefined).
4186
+ // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
4187
+ support.noCloneEvent = true;
4188
+ if ( div.attachEvent ) {
4189
+ div.attachEvent( "onclick", function() {
4190
+ support.noCloneEvent = false;
4191
+ });
4192
+
4193
+ div.cloneNode( true ).click();
4194
+ }
4195
+
4196
+ // Execute the test only if not already executed in another module.
4197
+ if (support.deleteExpando == null) {
4198
+ // Support: IE<9
4199
+ support.deleteExpando = true;
4200
+ try {
4201
+ delete div.test;
4202
+ } catch( e ) {
4203
+ support.deleteExpando = false;
4204
+ }
4205
+ }
4206
+
4207
+ // Null elements to avoid leaks in IE.
4208
+ fragment = div = input = null;
4209
+ })();
4210
+
4211
+
4212
+ (function() {
4213
+ var i, eventName,
4214
+ div = document.createElement( "div" );
4215
+
4216
+ // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
4217
+ for ( i in { submit: true, change: true, focusin: true }) {
4218
+ eventName = "on" + i;
4219
+
4220
+ if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
4221
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4222
+ div.setAttribute( eventName, "t" );
4223
+ support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
4224
+ }
4225
+ }
4226
+
4227
+ // Null elements to avoid leaks in IE.
4228
+ div = null;
4229
+ })();
4230
+
4231
+
4232
+ var rformElems = /^(?:input|select|textarea)$/i,
4233
+ rkeyEvent = /^key/,
4234
+ rmouseEvent = /^(?:mouse|contextmenu)|click/,
4235
+ rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4236
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4237
+
4238
+ function returnTrue() {
4239
+ return true;
4240
+ }
4241
+
4242
+ function returnFalse() {
4243
+ return false;
4244
+ }
4245
+
4246
+ function safeActiveElement() {
4247
+ try {
4248
+ return document.activeElement;
4249
+ } catch ( err ) { }
4250
+ }
4251
+
4252
+ /*
4253
+ * Helper functions for managing events -- not part of the public interface.
4254
+ * Props to Dean Edwards' addEvent library for many of the ideas.
4255
+ */
4256
+ jQuery.event = {
4257
+
4258
+ global: {},
4259
+
4260
+ add: function( elem, types, handler, data, selector ) {
4261
+ var tmp, events, t, handleObjIn,
4262
+ special, eventHandle, handleObj,
4263
+ handlers, type, namespaces, origType,
4264
+ elemData = jQuery._data( elem );
4265
+
4266
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
4267
+ if ( !elemData ) {
4268
+ return;
4269
+ }
4270
+
4271
+ // Caller can pass in an object of custom data in lieu of the handler
4272
+ if ( handler.handler ) {
4273
+ handleObjIn = handler;
4274
+ handler = handleObjIn.handler;
4275
+ selector = handleObjIn.selector;
4276
+ }
4277
+
4278
+ // Make sure that the handler has a unique ID, used to find/remove it later
4279
+ if ( !handler.guid ) {
4280
+ handler.guid = jQuery.guid++;
4281
+ }
4282
+
4283
+ // Init the element's event structure and main handler, if this is the first
4284
+ if ( !(events = elemData.events) ) {
4285
+ events = elemData.events = {};
4286
+ }
4287
+ if ( !(eventHandle = elemData.handle) ) {
4288
+ eventHandle = elemData.handle = function( e ) {
4289
+ // Discard the second event of a jQuery.event.trigger() and
4290
+ // when an event is called after a page has unloaded
4291
+ return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
4292
+ jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4293
+ undefined;
4294
+ };
4295
+ // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
4296
+ eventHandle.elem = elem;
4297
+ }
4298
+
4299
+ // Handle multiple events separated by a space
4300
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
4301
+ t = types.length;
4302
+ while ( t-- ) {
4303
+ tmp = rtypenamespace.exec( types[t] ) || [];
4304
+ type = origType = tmp[1];
4305
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
4306
+
4307
+ // There *must* be a type, no attaching namespace-only handlers
4308
+ if ( !type ) {
4309
+ continue;
4310
+ }
4311
+
4312
+ // If event changes its type, use the special event handlers for the changed type
4313
+ special = jQuery.event.special[ type ] || {};
4314
+
4315
+ // If selector defined, determine special event api type, otherwise given type
4316
+ type = ( selector ? special.delegateType : special.bindType ) || type;
4317
+
4318
+ // Update special based on newly reset type
4319
+ special = jQuery.event.special[ type ] || {};
4320
+
4321
+ // handleObj is passed to all event handlers
4322
+ handleObj = jQuery.extend({
4323
+ type: type,
4324
+ origType: origType,
4325
+ data: data,
4326
+ handler: handler,
4327
+ guid: handler.guid,
4328
+ selector: selector,
4329
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4330
+ namespace: namespaces.join(".")
4331
+ }, handleObjIn );
4332
+
4333
+ // Init the event handler queue if we're the first
4334
+ if ( !(handlers = events[ type ]) ) {
4335
+ handlers = events[ type ] = [];
4336
+ handlers.delegateCount = 0;
4337
+
4338
+ // Only use addEventListener/attachEvent if the special events handler returns false
4339
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4340
+ // Bind the global event handler to the element
4341
+ if ( elem.addEventListener ) {
4342
+ elem.addEventListener( type, eventHandle, false );
4343
+
4344
+ } else if ( elem.attachEvent ) {
4345
+ elem.attachEvent( "on" + type, eventHandle );
4346
+ }
4347
+ }
4348
+ }
4349
+
4350
+ if ( special.add ) {
4351
+ special.add.call( elem, handleObj );
4352
+
4353
+ if ( !handleObj.handler.guid ) {
4354
+ handleObj.handler.guid = handler.guid;
4355
+ }
4356
+ }
4357
+
4358
+ // Add to the element's handler list, delegates in front
4359
+ if ( selector ) {
4360
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
4361
+ } else {
4362
+ handlers.push( handleObj );
4363
+ }
4364
+
4365
+ // Keep track of which events have ever been used, for event optimization
4366
+ jQuery.event.global[ type ] = true;
4367
+ }
4368
+
4369
+ // Nullify elem to prevent memory leaks in IE
4370
+ elem = null;
4371
+ },
4372
+
4373
+ // Detach an event or set of events from an element
4374
+ remove: function( elem, types, handler, selector, mappedTypes ) {
4375
+ var j, handleObj, tmp,
4376
+ origCount, t, events,
4377
+ special, handlers, type,
4378
+ namespaces, origType,
4379
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4380
+
4381
+ if ( !elemData || !(events = elemData.events) ) {
4382
+ return;
4383
+ }
4384
+
4385
+ // Once for each type.namespace in types; type may be omitted
4386
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
4387
+ t = types.length;
4388
+ while ( t-- ) {
4389
+ tmp = rtypenamespace.exec( types[t] ) || [];
4390
+ type = origType = tmp[1];
4391
+ namespaces = ( tmp[2] || "" ).split( "." ).sort();
4392
+
4393
+ // Unbind all events (on this namespace, if provided) for the element
4394
+ if ( !type ) {
4395
+ for ( type in events ) {
4396
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4397
+ }
4398
+ continue;
4399
+ }
4400
+
4401
+ special = jQuery.event.special[ type ] || {};
4402
+ type = ( selector ? special.delegateType : special.bindType ) || type;
4403
+ handlers = events[ type ] || [];
4404
+ tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4405
+
4406
+ // Remove matching events
4407
+ origCount = j = handlers.length;
4408
+ while ( j-- ) {
4409
+ handleObj = handlers[ j ];
4410
+
4411
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
4412
+ ( !handler || handler.guid === handleObj.guid ) &&
4413
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
4414
+ ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4415
+ handlers.splice( j, 1 );
4416
+
4417
+ if ( handleObj.selector ) {
4418
+ handlers.delegateCount--;
4419
+ }
4420
+ if ( special.remove ) {
4421
+ special.remove.call( elem, handleObj );
4422
+ }
4423
+ }
4424
+ }
4425
+
4426
+ // Remove generic event handler if we removed something and no more handlers exist
4427
+ // (avoids potential for endless recursion during removal of special event handlers)
4428
+ if ( origCount && !handlers.length ) {
4429
+ if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4430
+ jQuery.removeEvent( elem, type, elemData.handle );
4431
+ }
4432
+
4433
+ delete events[ type ];
4434
+ }
4435
+ }
4436
+
4437
+ // Remove the expando if it's no longer used
4438
+ if ( jQuery.isEmptyObject( events ) ) {
4439
+ delete elemData.handle;
4440
+
4441
+ // removeData also checks for emptiness and clears the expando if empty
4442
+ // so use it instead of delete
4443
+ jQuery._removeData( elem, "events" );
4444
+ }
4445
+ },
4446
+
4447
+ trigger: function( event, data, elem, onlyHandlers ) {
4448
+ var handle, ontype, cur,
4449
+ bubbleType, special, tmp, i,
4450
+ eventPath = [ elem || document ],
4451
+ type = hasOwn.call( event, "type" ) ? event.type : event,
4452
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4453
+
4454
+ cur = tmp = elem = elem || document;
4455
+
4456
+ // Don't do events on text and comment nodes
4457
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4458
+ return;
4459
+ }
4460
+
4461
+ // focus/blur morphs to focusin/out; ensure we're not firing them right now
4462
+ if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4463
+ return;
4464
+ }
4465
+
4466
+ if ( type.indexOf(".") >= 0 ) {
4467
+ // Namespaced trigger; create a regexp to match event type in handle()
4468
+ namespaces = type.split(".");
4469
+ type = namespaces.shift();
4470
+ namespaces.sort();
4471
+ }
4472
+ ontype = type.indexOf(":") < 0 && "on" + type;
4473
+
4474
+ // Caller can pass in a jQuery.Event object, Object, or just an event type string
4475
+ event = event[ jQuery.expando ] ?
4476
+ event :
4477
+ new jQuery.Event( type, typeof event === "object" && event );
4478
+
4479
+ // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4480
+ event.isTrigger = onlyHandlers ? 2 : 3;
4481
+ event.namespace = namespaces.join(".");
4482
+ event.namespace_re = event.namespace ?
4483
+ new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4484
+ null;
4485
+
4486
+ // Clean up the event in case it is being reused
4487
+ event.result = undefined;
4488
+ if ( !event.target ) {
4489
+ event.target = elem;
4490
+ }
4491
+
4492
+ // Clone any incoming data and prepend the event, creating the handler arg list
4493
+ data = data == null ?
4494
+ [ event ] :
4495
+ jQuery.makeArray( data, [ event ] );
4496
+
4497
+ // Allow special events to draw outside the lines
4498
+ special = jQuery.event.special[ type ] || {};
4499
+ if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4500
+ return;
4501
+ }
4502
+
4503
+ // Determine event propagation path in advance, per W3C events spec (#9951)
4504
+ // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4505
+ if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4506
+
4507
+ bubbleType = special.delegateType || type;
4508
+ if ( !rfocusMorph.test( bubbleType + type ) ) {
4509
+ cur = cur.parentNode;
4510
+ }
4511
+ for ( ; cur; cur = cur.parentNode ) {
4512
+ eventPath.push( cur );
4513
+ tmp = cur;
4514
+ }
4515
+
4516
+ // Only add window if we got to document (e.g., not plain obj or detached DOM)
4517
+ if ( tmp === (elem.ownerDocument || document) ) {
4518
+ eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4519
+ }
4520
+ }
4521
+
4522
+ // Fire handlers on the event path
4523
+ i = 0;
4524
+ while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4525
+
4526
+ event.type = i > 1 ?
4527
+ bubbleType :
4528
+ special.bindType || type;
4529
+
4530
+ // jQuery handler
4531
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
4532
+ if ( handle ) {
4533
+ handle.apply( cur, data );
4534
+ }
4535
+
4536
+ // Native handler
4537
+ handle = ontype && cur[ ontype ];
4538
+ if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4539
+ event.result = handle.apply( cur, data );
4540
+ if ( event.result === false ) {
4541
+ event.preventDefault();
4542
+ }
4543
+ }
4544
+ }
4545
+ event.type = type;
4546
+
4547
+ // If nobody prevented the default action, do it now
4548
+ if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4549
+
4550
+ if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4551
+ jQuery.acceptData( elem ) ) {
4552
+
4553
+ // Call a native DOM method on the target with the same name name as the event.
4554
+ // Can't use an .isFunction() check here because IE6/7 fails that test.
4555
+ // Don't do default actions on window, that's where global variables be (#6170)
4556
+ if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
4557
+
4558
+ // Don't re-trigger an onFOO event when we call its FOO() method
4559
+ tmp = elem[ ontype ];
4560
+
4561
+ if ( tmp ) {
4562
+ elem[ ontype ] = null;
4563
+ }
4564
+
4565
+ // Prevent re-triggering of the same event, since we already bubbled it above
4566
+ jQuery.event.triggered = type;
4567
+ try {
4568
+ elem[ type ]();
4569
+ } catch ( e ) {
4570
+ // IE<9 dies on focus/blur to hidden element (#1486,#12518)
4571
+ // only reproducible on winXP IE8 native, not IE9 in IE8 mode
4572
+ }
4573
+ jQuery.event.triggered = undefined;
4574
+
4575
+ if ( tmp ) {
4576
+ elem[ ontype ] = tmp;
4577
+ }
4578
+ }
4579
+ }
4580
+ }
4581
+
4582
+ return event.result;
4583
+ },
4584
+
4585
+ dispatch: function( event ) {
4586
+
4587
+ // Make a writable jQuery.Event from the native event object
4588
+ event = jQuery.event.fix( event );
4589
+
4590
+ var i, ret, handleObj, matched, j,
4591
+ handlerQueue = [],
4592
+ args = slice.call( arguments ),
4593
+ handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
4594
+ special = jQuery.event.special[ event.type ] || {};
4595
+
4596
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
4597
+ args[0] = event;
4598
+ event.delegateTarget = this;
4599
+
4600
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
4601
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4602
+ return;
4603
+ }
4604
+
4605
+ // Determine handlers
4606
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4607
+
4608
+ // Run delegates first; they may want to stop propagation beneath us
4609
+ i = 0;
4610
+ while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4611
+ event.currentTarget = matched.elem;
4612
+
4613
+ j = 0;
4614
+ while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4615
+
4616
+ // Triggered event must either 1) have no namespace, or
4617
+ // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4618
+ if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4619
+
4620
+ event.handleObj = handleObj;
4621
+ event.data = handleObj.data;
4622
+
4623
+ ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4624
+ .apply( matched.elem, args );
4625
+
4626
+ if ( ret !== undefined ) {
4627
+ if ( (event.result = ret) === false ) {
4628
+ event.preventDefault();
4629
+ event.stopPropagation();
4630
+ }
4631
+ }
4632
+ }
4633
+ }
4634
+ }
4635
+
4636
+ // Call the postDispatch hook for the mapped type
4637
+ if ( special.postDispatch ) {
4638
+ special.postDispatch.call( this, event );
4639
+ }
4640
+
4641
+ return event.result;
4642
+ },
4643
+
4644
+ handlers: function( event, handlers ) {
4645
+ var sel, handleObj, matches, i,
4646
+ handlerQueue = [],
4647
+ delegateCount = handlers.delegateCount,
4648
+ cur = event.target;
4649
+
4650
+ // Find delegate handlers
4651
+ // Black-hole SVG <use> instance trees (#13180)
4652
+ // Avoid non-left-click bubbling in Firefox (#3861)
4653
+ if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4654
+
4655
+ /* jshint eqeqeq: false */
4656
+ for ( ; cur != this; cur = cur.parentNode || this ) {
4657
+ /* jshint eqeqeq: true */
4658
+
4659
+ // Don't check non-elements (#13208)
4660
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4661
+ if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
4662
+ matches = [];
4663
+ for ( i = 0; i < delegateCount; i++ ) {
4664
+ handleObj = handlers[ i ];
4665
+
4666
+ // Don't conflict with Object.prototype properties (#13203)
4667
+ sel = handleObj.selector + " ";
4668
+
4669
+ if ( matches[ sel ] === undefined ) {
4670
+ matches[ sel ] = handleObj.needsContext ?
4671
+ jQuery( sel, this ).index( cur ) >= 0 :
4672
+ jQuery.find( sel, this, null, [ cur ] ).length;
4673
+ }
4674
+ if ( matches[ sel ] ) {
4675
+ matches.push( handleObj );
4676
+ }
4677
+ }
4678
+ if ( matches.length ) {
4679
+ handlerQueue.push({ elem: cur, handlers: matches });
4680
+ }
4681
+ }
4682
+ }
4683
+ }
4684
+
4685
+ // Add the remaining (directly-bound) handlers
4686
+ if ( delegateCount < handlers.length ) {
4687
+ handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4688
+ }
4689
+
4690
+ return handlerQueue;
4691
+ },
4692
+
4693
+ fix: function( event ) {
4694
+ if ( event[ jQuery.expando ] ) {
4695
+ return event;
4696
+ }
4697
+
4698
+ // Create a writable copy of the event object and normalize some properties
4699
+ var i, prop, copy,
4700
+ type = event.type,
4701
+ originalEvent = event,
4702
+ fixHook = this.fixHooks[ type ];
4703
+
4704
+ if ( !fixHook ) {
4705
+ this.fixHooks[ type ] = fixHook =
4706
+ rmouseEvent.test( type ) ? this.mouseHooks :
4707
+ rkeyEvent.test( type ) ? this.keyHooks :
4708
+ {};
4709
+ }
4710
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4711
+
4712
+ event = new jQuery.Event( originalEvent );
4713
+
4714
+ i = copy.length;
4715
+ while ( i-- ) {
4716
+ prop = copy[ i ];
4717
+ event[ prop ] = originalEvent[ prop ];
4718
+ }
4719
+
4720
+ // Support: IE<9
4721
+ // Fix target property (#1925)
4722
+ if ( !event.target ) {
4723
+ event.target = originalEvent.srcElement || document;
4724
+ }
4725
+
4726
+ // Support: Chrome 23+, Safari?
4727
+ // Target should not be a text node (#504, #13143)
4728
+ if ( event.target.nodeType === 3 ) {
4729
+ event.target = event.target.parentNode;
4730
+ }
4731
+
4732
+ // Support: IE<9
4733
+ // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
4734
+ event.metaKey = !!event.metaKey;
4735
+
4736
+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4737
+ },
4738
+
4739
+ // Includes some event props shared by KeyEvent and MouseEvent
4740
+ props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4741
+
4742
+ fixHooks: {},
4743
+
4744
+ keyHooks: {
4745
+ props: "char charCode key keyCode".split(" "),
4746
+ filter: function( event, original ) {
4747
+
4748
+ // Add which for key events
4749
+ if ( event.which == null ) {
4750
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
4751
+ }
4752
+
4753
+ return event;
4754
+ }
4755
+ },
4756
+
4757
+ mouseHooks: {
4758
+ props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4759
+ filter: function( event, original ) {
4760
+ var body, eventDoc, doc,
4761
+ button = original.button,
4762
+ fromElement = original.fromElement;
4763
+
4764
+ // Calculate pageX/Y if missing and clientX/Y available
4765
+ if ( event.pageX == null && original.clientX != null ) {
4766
+ eventDoc = event.target.ownerDocument || document;
4767
+ doc = eventDoc.documentElement;
4768
+ body = eventDoc.body;
4769
+
4770
+ event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4771
+ event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
4772
+ }
4773
+
4774
+ // Add relatedTarget, if necessary
4775
+ if ( !event.relatedTarget && fromElement ) {
4776
+ event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
4777
+ }
4778
+
4779
+ // Add which for click: 1 === left; 2 === middle; 3 === right
4780
+ // Note: button is not normalized, so don't use it
4781
+ if ( !event.which && button !== undefined ) {
4782
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4783
+ }
4784
+
4785
+ return event;
4786
+ }
4787
+ },
4788
+
4789
+ special: {
4790
+ load: {
4791
+ // Prevent triggered image.load events from bubbling to window.load
4792
+ noBubble: true
4793
+ },
4794
+ focus: {
4795
+ // Fire native event if possible so blur/focus sequence is correct
4796
+ trigger: function() {
4797
+ if ( this !== safeActiveElement() && this.focus ) {
4798
+ try {
4799
+ this.focus();
4800
+ return false;
4801
+ } catch ( e ) {
4802
+ // Support: IE<9
4803
+ // If we error on focus to hidden element (#1486, #12518),
4804
+ // let .trigger() run the handlers
4805
+ }
4806
+ }
4807
+ },
4808
+ delegateType: "focusin"
4809
+ },
4810
+ blur: {
4811
+ trigger: function() {
4812
+ if ( this === safeActiveElement() && this.blur ) {
4813
+ this.blur();
4814
+ return false;
4815
+ }
4816
+ },
4817
+ delegateType: "focusout"
4818
+ },
4819
+ click: {
4820
+ // For checkbox, fire native event so checked state will be right
4821
+ trigger: function() {
4822
+ if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
4823
+ this.click();
4824
+ return false;
4825
+ }
4826
+ },
4827
+
4828
+ // For cross-browser consistency, don't fire native .click() on links
4829
+ _default: function( event ) {
4830
+ return jQuery.nodeName( event.target, "a" );
4831
+ }
4832
+ },
4833
+
4834
+ beforeunload: {
4835
+ postDispatch: function( event ) {
4836
+
4837
+ // Even when returnValue equals to undefined Firefox will still show alert
4838
+ if ( event.result !== undefined ) {
4839
+ event.originalEvent.returnValue = event.result;
4840
+ }
4841
+ }
4842
+ }
4843
+ },
4844
+
4845
+ simulate: function( type, elem, event, bubble ) {
4846
+ // Piggyback on a donor event to simulate a different one.
4847
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
4848
+ // simulated event prevents default then we do the same on the donor.
4849
+ var e = jQuery.extend(
4850
+ new jQuery.Event(),
4851
+ event,
4852
+ {
4853
+ type: type,
4854
+ isSimulated: true,
4855
+ originalEvent: {}
4856
+ }
4857
+ );
4858
+ if ( bubble ) {
4859
+ jQuery.event.trigger( e, null, elem );
4860
+ } else {
4861
+ jQuery.event.dispatch.call( elem, e );
4862
+ }
4863
+ if ( e.isDefaultPrevented() ) {
4864
+ event.preventDefault();
4865
+ }
4866
+ }
4867
+ };
4868
+
4869
+ jQuery.removeEvent = document.removeEventListener ?
4870
+ function( elem, type, handle ) {
4871
+ if ( elem.removeEventListener ) {
4872
+ elem.removeEventListener( type, handle, false );
4873
+ }
4874
+ } :
4875
+ function( elem, type, handle ) {
4876
+ var name = "on" + type;
4877
+
4878
+ if ( elem.detachEvent ) {
4879
+
4880
+ // #8545, #7054, preventing memory leaks for custom events in IE6-8
4881
+ // detachEvent needed property on element, by name of that event, to properly expose it to GC
4882
+ if ( typeof elem[ name ] === strundefined ) {
4883
+ elem[ name ] = null;
4884
+ }
4885
+
4886
+ elem.detachEvent( name, handle );
4887
+ }
4888
+ };
4889
+
4890
+ jQuery.Event = function( src, props ) {
4891
+ // Allow instantiation without the 'new' keyword
4892
+ if ( !(this instanceof jQuery.Event) ) {
4893
+ return new jQuery.Event( src, props );
4894
+ }
4895
+
4896
+ // Event object
4897
+ if ( src && src.type ) {
4898
+ this.originalEvent = src;
4899
+ this.type = src.type;
4900
+
4901
+ // Events bubbling up the document may have been marked as prevented
4902
+ // by a handler lower down the tree; reflect the correct value.
4903
+ this.isDefaultPrevented = src.defaultPrevented ||
4904
+ src.defaultPrevented === undefined && (
4905
+ // Support: IE < 9
4906
+ src.returnValue === false ||
4907
+ // Support: Android < 4.0
4908
+ src.getPreventDefault && src.getPreventDefault() ) ?
4909
+ returnTrue :
4910
+ returnFalse;
4911
+
4912
+ // Event type
4913
+ } else {
4914
+ this.type = src;
4915
+ }
4916
+
4917
+ // Put explicitly provided properties onto the event object
4918
+ if ( props ) {
4919
+ jQuery.extend( this, props );
4920
+ }
4921
+
4922
+ // Create a timestamp if incoming event doesn't have one
4923
+ this.timeStamp = src && src.timeStamp || jQuery.now();
4924
+
4925
+ // Mark it as fixed
4926
+ this[ jQuery.expando ] = true;
4927
+ };
4928
+
4929
+ // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4930
+ // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4931
+ jQuery.Event.prototype = {
4932
+ isDefaultPrevented: returnFalse,
4933
+ isPropagationStopped: returnFalse,
4934
+ isImmediatePropagationStopped: returnFalse,
4935
+
4936
+ preventDefault: function() {
4937
+ var e = this.originalEvent;
4938
+
4939
+ this.isDefaultPrevented = returnTrue;
4940
+ if ( !e ) {
4941
+ return;
4942
+ }
4943
+
4944
+ // If preventDefault exists, run it on the original event
4945
+ if ( e.preventDefault ) {
4946
+ e.preventDefault();
4947
+
4948
+ // Support: IE
4949
+ // Otherwise set the returnValue property of the original event to false
4950
+ } else {
4951
+ e.returnValue = false;
4952
+ }
4953
+ },
4954
+ stopPropagation: function() {
4955
+ var e = this.originalEvent;
4956
+
4957
+ this.isPropagationStopped = returnTrue;
4958
+ if ( !e ) {
4959
+ return;
4960
+ }
4961
+ // If stopPropagation exists, run it on the original event
4962
+ if ( e.stopPropagation ) {
4963
+ e.stopPropagation();
4964
+ }
4965
+
4966
+ // Support: IE
4967
+ // Set the cancelBubble property of the original event to true
4968
+ e.cancelBubble = true;
4969
+ },
4970
+ stopImmediatePropagation: function() {
4971
+ this.isImmediatePropagationStopped = returnTrue;
4972
+ this.stopPropagation();
4973
+ }
4974
+ };
4975
+
4976
+ // Create mouseenter/leave events using mouseover/out and event-time checks
4977
+ jQuery.each({
4978
+ mouseenter: "mouseover",
4979
+ mouseleave: "mouseout"
4980
+ }, function( orig, fix ) {
4981
+ jQuery.event.special[ orig ] = {
4982
+ delegateType: fix,
4983
+ bindType: fix,
4984
+
4985
+ handle: function( event ) {
4986
+ var ret,
4987
+ target = this,
4988
+ related = event.relatedTarget,
4989
+ handleObj = event.handleObj;
4990
+
4991
+ // For mousenter/leave call the handler if related is outside the target.
4992
+ // NB: No relatedTarget if the mouse left/entered the browser window
4993
+ if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4994
+ event.type = handleObj.origType;
4995
+ ret = handleObj.handler.apply( this, arguments );
4996
+ event.type = fix;
4997
+ }
4998
+ return ret;
4999
+ }
5000
+ };
5001
+ });
5002
+
5003
+ // IE submit delegation
5004
+ if ( !support.submitBubbles ) {
5005
+
5006
+ jQuery.event.special.submit = {
5007
+ setup: function() {
5008
+ // Only need this for delegated form submit events
5009
+ if ( jQuery.nodeName( this, "form" ) ) {
5010
+ return false;
5011
+ }
5012
+
5013
+ // Lazy-add a submit handler when a descendant form may potentially be submitted
5014
+ jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5015
+ // Node name check avoids a VML-related crash in IE (#9807)
5016
+ var elem = e.target,
5017
+ form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
5018
+ if ( form && !jQuery._data( form, "submitBubbles" ) ) {
5019
+ jQuery.event.add( form, "submit._submit", function( event ) {
5020
+ event._submit_bubble = true;
5021
+ });
5022
+ jQuery._data( form, "submitBubbles", true );
5023
+ }
5024
+ });
5025
+ // return undefined since we don't need an event listener
5026
+ },
5027
+
5028
+ postDispatch: function( event ) {
5029
+ // If form was submitted by the user, bubble the event up the tree
5030
+ if ( event._submit_bubble ) {
5031
+ delete event._submit_bubble;
5032
+ if ( this.parentNode && !event.isTrigger ) {
5033
+ jQuery.event.simulate( "submit", this.parentNode, event, true );
5034
+ }
5035
+ }
5036
+ },
5037
+
5038
+ teardown: function() {
5039
+ // Only need this for delegated form submit events
5040
+ if ( jQuery.nodeName( this, "form" ) ) {
5041
+ return false;
5042
+ }
5043
+
5044
+ // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5045
+ jQuery.event.remove( this, "._submit" );
5046
+ }
5047
+ };
5048
+ }
5049
+
5050
+ // IE change delegation and checkbox/radio fix
5051
+ if ( !support.changeBubbles ) {
5052
+
5053
+ jQuery.event.special.change = {
5054
+
5055
+ setup: function() {
5056
+
5057
+ if ( rformElems.test( this.nodeName ) ) {
5058
+ // IE doesn't fire change on a check/radio until blur; trigger it on click
5059
+ // after a propertychange. Eat the blur-change in special.change.handle.
5060
+ // This still fires onchange a second time for check/radio after blur.
5061
+ if ( this.type === "checkbox" || this.type === "radio" ) {
5062
+ jQuery.event.add( this, "propertychange._change", function( event ) {
5063
+ if ( event.originalEvent.propertyName === "checked" ) {
5064
+ this._just_changed = true;
5065
+ }
5066
+ });
5067
+ jQuery.event.add( this, "click._change", function( event ) {
5068
+ if ( this._just_changed && !event.isTrigger ) {
5069
+ this._just_changed = false;
5070
+ }
5071
+ // Allow triggered, simulated change events (#11500)
5072
+ jQuery.event.simulate( "change", this, event, true );
5073
+ });
5074
+ }
5075
+ return false;
5076
+ }
5077
+ // Delegated event; lazy-add a change handler on descendant inputs
5078
+ jQuery.event.add( this, "beforeactivate._change", function( e ) {
5079
+ var elem = e.target;
5080
+
5081
+ if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
5082
+ jQuery.event.add( elem, "change._change", function( event ) {
5083
+ if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5084
+ jQuery.event.simulate( "change", this.parentNode, event, true );
5085
+ }
5086
+ });
5087
+ jQuery._data( elem, "changeBubbles", true );
5088
+ }
5089
+ });
5090
+ },
5091
+
5092
+ handle: function( event ) {
5093
+ var elem = event.target;
5094
+
5095
+ // Swallow native change events from checkbox/radio, we already triggered them above
5096
+ if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
5097
+ return event.handleObj.handler.apply( this, arguments );
5098
+ }
5099
+ },
5100
+
5101
+ teardown: function() {
5102
+ jQuery.event.remove( this, "._change" );
5103
+
5104
+ return !rformElems.test( this.nodeName );
5105
+ }
5106
+ };
5107
+ }
5108
+
5109
+ // Create "bubbling" focus and blur events
5110
+ if ( !support.focusinBubbles ) {
5111
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5112
+
5113
+ // Attach a single capturing handler on the document while someone wants focusin/focusout
5114
+ var handler = function( event ) {
5115
+ jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
5116
+ };
5117
+
5118
+ jQuery.event.special[ fix ] = {
5119
+ setup: function() {
5120
+ var doc = this.ownerDocument || this,
5121
+ attaches = jQuery._data( doc, fix );
5122
+
5123
+ if ( !attaches ) {
5124
+ doc.addEventListener( orig, handler, true );
5125
+ }
5126
+ jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5127
+ },
5128
+ teardown: function() {
5129
+ var doc = this.ownerDocument || this,
5130
+ attaches = jQuery._data( doc, fix ) - 1;
5131
+
5132
+ if ( !attaches ) {
5133
+ doc.removeEventListener( orig, handler, true );
5134
+ jQuery._removeData( doc, fix );
5135
+ } else {
5136
+ jQuery._data( doc, fix, attaches );
5137
+ }
5138
+ }
5139
+ };
5140
+ });
5141
+ }
5142
+
5143
+ jQuery.fn.extend({
5144
+
5145
+ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
5146
+ var type, origFn;
5147
+
5148
+ // Types can be a map of types/handlers
5149
+ if ( typeof types === "object" ) {
5150
+ // ( types-Object, selector, data )
5151
+ if ( typeof selector !== "string" ) {
5152
+ // ( types-Object, data )
5153
+ data = data || selector;
5154
+ selector = undefined;
5155
+ }
5156
+ for ( type in types ) {
5157
+ this.on( type, selector, data, types[ type ], one );
5158
+ }
5159
+ return this;
5160
+ }
5161
+
5162
+ if ( data == null && fn == null ) {
5163
+ // ( types, fn )
5164
+ fn = selector;
5165
+ data = selector = undefined;
5166
+ } else if ( fn == null ) {
5167
+ if ( typeof selector === "string" ) {
5168
+ // ( types, selector, fn )
5169
+ fn = data;
5170
+ data = undefined;
5171
+ } else {
5172
+ // ( types, data, fn )
5173
+ fn = data;
5174
+ data = selector;
5175
+ selector = undefined;
5176
+ }
5177
+ }
5178
+ if ( fn === false ) {
5179
+ fn = returnFalse;
5180
+ } else if ( !fn ) {
5181
+ return this;
5182
+ }
5183
+
5184
+ if ( one === 1 ) {
5185
+ origFn = fn;
5186
+ fn = function( event ) {
5187
+ // Can use an empty set, since event contains the info
5188
+ jQuery().off( event );
5189
+ return origFn.apply( this, arguments );
5190
+ };
5191
+ // Use same guid so caller can remove using origFn
5192
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5193
+ }
5194
+ return this.each( function() {
5195
+ jQuery.event.add( this, types, fn, data, selector );
5196
+ });
5197
+ },
5198
+ one: function( types, selector, data, fn ) {
5199
+ return this.on( types, selector, data, fn, 1 );
5200
+ },
5201
+ off: function( types, selector, fn ) {
5202
+ var handleObj, type;
5203
+ if ( types && types.preventDefault && types.handleObj ) {
5204
+ // ( event ) dispatched jQuery.Event
5205
+ handleObj = types.handleObj;
5206
+ jQuery( types.delegateTarget ).off(
5207
+ handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
5208
+ handleObj.selector,
5209
+ handleObj.handler
5210
+ );
5211
+ return this;
5212
+ }
5213
+ if ( typeof types === "object" ) {
5214
+ // ( types-object [, selector] )
5215
+ for ( type in types ) {
5216
+ this.off( type, selector, types[ type ] );
5217
+ }
5218
+ return this;
5219
+ }
5220
+ if ( selector === false || typeof selector === "function" ) {
5221
+ // ( types [, fn] )
5222
+ fn = selector;
5223
+ selector = undefined;
5224
+ }
5225
+ if ( fn === false ) {
5226
+ fn = returnFalse;
5227
+ }
5228
+ return this.each(function() {
5229
+ jQuery.event.remove( this, types, fn, selector );
5230
+ });
5231
+ },
5232
+
5233
+ trigger: function( type, data ) {
5234
+ return this.each(function() {
5235
+ jQuery.event.trigger( type, data, this );
5236
+ });
5237
+ },
5238
+ triggerHandler: function( type, data ) {
5239
+ var elem = this[0];
5240
+ if ( elem ) {
5241
+ return jQuery.event.trigger( type, data, elem, true );
5242
+ }
5243
+ }
5244
+ });
5245
+
5246
+
5247
+ function createSafeFragment( document ) {
5248
+ var list = nodeNames.split( "|" ),
5249
+ safeFrag = document.createDocumentFragment();
5250
+
5251
+ if ( safeFrag.createElement ) {
5252
+ while ( list.length ) {
5253
+ safeFrag.createElement(
5254
+ list.pop()
5255
+ );
5256
+ }
5257
+ }
5258
+ return safeFrag;
5259
+ }
5260
+
5261
+ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
5262
+ "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
5263
+ rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5264
+ rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5265
+ rleadingWhitespace = /^\s+/,
5266
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5267
+ rtagName = /<([\w:]+)/,
5268
+ rtbody = /<tbody/i,
5269
+ rhtml = /<|&#?\w+;/,
5270
+ rnoInnerhtml = /<(?:script|style|link)/i,
5271
+ // checked="checked" or checked
5272
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5273
+ rscriptType = /^$|\/(?:java|ecma)script/i,
5274
+ rscriptTypeMasked = /^true\/(.*)/,
5275
+ rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5276
+
5277
+ // We have to close these tags to support XHTML (#13200)
5278
+ wrapMap = {
5279
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
5280
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
5281
+ area: [ 1, "<map>", "</map>" ],
5282
+ param: [ 1, "<object>", "</object>" ],
5283
+ thead: [ 1, "<table>", "</table>" ],
5284
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5285
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5286
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5287
+
5288
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
5289
+ // unless wrapped in a div with non-breaking characters in front of it.
5290
+ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
5291
+ },
5292
+ safeFragment = createSafeFragment( document ),
5293
+ fragmentDiv = safeFragment.appendChild( document.createElement("div") );
5294
+
5295
+ wrapMap.optgroup = wrapMap.option;
5296
+ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5297
+ wrapMap.th = wrapMap.td;
5298
+
5299
+ function getAll( context, tag ) {
5300
+ var elems, elem,
5301
+ i = 0,
5302
+ found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
5303
+ typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
5304
+ undefined;
5305
+
5306
+ if ( !found ) {
5307
+ for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
5308
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
5309
+ found.push( elem );
5310
+ } else {
5311
+ jQuery.merge( found, getAll( elem, tag ) );
5312
+ }
5313
+ }
5314
+ }
5315
+
5316
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5317
+ jQuery.merge( [ context ], found ) :
5318
+ found;
5319
+ }
5320
+
5321
+ // Used in buildFragment, fixes the defaultChecked property
5322
+ function fixDefaultChecked( elem ) {
5323
+ if ( rcheckableType.test( elem.type ) ) {
5324
+ elem.defaultChecked = elem.checked;
5325
+ }
5326
+ }
5327
+
5328
+ // Support: IE<8
5329
+ // Manipulating tables requires a tbody
5330
+ function manipulationTarget( elem, content ) {
5331
+ return jQuery.nodeName( elem, "table" ) &&
5332
+ jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5333
+
5334
+ elem.getElementsByTagName("tbody")[0] ||
5335
+ elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
5336
+ elem;
5337
+ }
5338
+
5339
+ // Replace/restore the type attribute of script elements for safe DOM manipulation
5340
+ function disableScript( elem ) {
5341
+ elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
5342
+ return elem;
5343
+ }
5344
+ function restoreScript( elem ) {
5345
+ var match = rscriptTypeMasked.exec( elem.type );
5346
+ if ( match ) {
5347
+ elem.type = match[1];
5348
+ } else {
5349
+ elem.removeAttribute("type");
5350
+ }
5351
+ return elem;
5352
+ }
5353
+
5354
+ // Mark scripts as having already been evaluated
5355
+ function setGlobalEval( elems, refElements ) {
5356
+ var elem,
5357
+ i = 0;
5358
+ for ( ; (elem = elems[i]) != null; i++ ) {
5359
+ jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
5360
+ }
5361
+ }
5362
+
5363
+ function cloneCopyEvent( src, dest ) {
5364
+
5365
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5366
+ return;
5367
+ }
5368
+
5369
+ var type, i, l,
5370
+ oldData = jQuery._data( src ),
5371
+ curData = jQuery._data( dest, oldData ),
5372
+ events = oldData.events;
5373
+
5374
+ if ( events ) {
5375
+ delete curData.handle;
5376
+ curData.events = {};
5377
+
5378
+ for ( type in events ) {
5379
+ for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5380
+ jQuery.event.add( dest, type, events[ type ][ i ] );
5381
+ }
5382
+ }
5383
+ }
5384
+
5385
+ // make the cloned public data object a copy from the original
5386
+ if ( curData.data ) {
5387
+ curData.data = jQuery.extend( {}, curData.data );
5388
+ }
5389
+ }
5390
+
5391
+ function fixCloneNodeIssues( src, dest ) {
5392
+ var nodeName, e, data;
5393
+
5394
+ // We do not need to do anything for non-Elements
5395
+ if ( dest.nodeType !== 1 ) {
5396
+ return;
5397
+ }
5398
+
5399
+ nodeName = dest.nodeName.toLowerCase();
5400
+
5401
+ // IE6-8 copies events bound via attachEvent when using cloneNode.
5402
+ if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5403
+ data = jQuery._data( dest );
5404
+
5405
+ for ( e in data.events ) {
5406
+ jQuery.removeEvent( dest, e, data.handle );
5407
+ }
5408
+
5409
+ // Event data gets referenced instead of copied if the expando gets copied too
5410
+ dest.removeAttribute( jQuery.expando );
5411
+ }
5412
+
5413
+ // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5414
+ if ( nodeName === "script" && dest.text !== src.text ) {
5415
+ disableScript( dest ).text = src.text;
5416
+ restoreScript( dest );
5417
+
5418
+ // IE6-10 improperly clones children of object elements using classid.
5419
+ // IE10 throws NoModificationAllowedError if parent is null, #12132.
5420
+ } else if ( nodeName === "object" ) {
5421
+ if ( dest.parentNode ) {
5422
+ dest.outerHTML = src.outerHTML;
5423
+ }
5424
+
5425
+ // This path appears unavoidable for IE9. When cloning an object
5426
+ // element in IE9, the outerHTML strategy above is not sufficient.
5427
+ // If the src has innerHTML and the destination does not,
5428
+ // copy the src.innerHTML into the dest.innerHTML. #10324
5429
+ if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
5430
+ dest.innerHTML = src.innerHTML;
5431
+ }
5432
+
5433
+ } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5434
+ // IE6-8 fails to persist the checked state of a cloned checkbox
5435
+ // or radio button. Worse, IE6-7 fail to give the cloned element
5436
+ // a checked appearance if the defaultChecked value isn't also set
5437
+
5438
+ dest.defaultChecked = dest.checked = src.checked;
5439
+
5440
+ // IE6-7 get confused and end up setting the value of a cloned
5441
+ // checkbox/radio button to an empty string instead of "on"
5442
+ if ( dest.value !== src.value ) {
5443
+ dest.value = src.value;
5444
+ }
5445
+
5446
+ // IE6-8 fails to return the selected option to the default selected
5447
+ // state when cloning options
5448
+ } else if ( nodeName === "option" ) {
5449
+ dest.defaultSelected = dest.selected = src.defaultSelected;
5450
+
5451
+ // IE6-8 fails to set the defaultValue to the correct value when
5452
+ // cloning other types of input fields
5453
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
5454
+ dest.defaultValue = src.defaultValue;
5455
+ }
5456
+ }
5457
+
5458
+ jQuery.extend({
5459
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5460
+ var destElements, node, clone, i, srcElements,
5461
+ inPage = jQuery.contains( elem.ownerDocument, elem );
5462
+
5463
+ if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
5464
+ clone = elem.cloneNode( true );
5465
+
5466
+ // IE<=8 does not properly clone detached, unknown element nodes
5467
+ } else {
5468
+ fragmentDiv.innerHTML = elem.outerHTML;
5469
+ fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
5470
+ }
5471
+
5472
+ if ( (!support.noCloneEvent || !support.noCloneChecked) &&
5473
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
5474
+
5475
+ // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5476
+ destElements = getAll( clone );
5477
+ srcElements = getAll( elem );
5478
+
5479
+ // Fix all IE cloning issues
5480
+ for ( i = 0; (node = srcElements[i]) != null; ++i ) {
5481
+ // Ensure that the destination node is not null; Fixes #9587
5482
+ if ( destElements[i] ) {
5483
+ fixCloneNodeIssues( node, destElements[i] );
5484
+ }
5485
+ }
5486
+ }
5487
+
5488
+ // Copy the events from the original to the clone
5489
+ if ( dataAndEvents ) {
5490
+ if ( deepDataAndEvents ) {
5491
+ srcElements = srcElements || getAll( elem );
5492
+ destElements = destElements || getAll( clone );
5493
+
5494
+ for ( i = 0; (node = srcElements[i]) != null; i++ ) {
5495
+ cloneCopyEvent( node, destElements[i] );
5496
+ }
5497
+ } else {
5498
+ cloneCopyEvent( elem, clone );
5499
+ }
5500
+ }
5501
+
5502
+ // Preserve script evaluation history
5503
+ destElements = getAll( clone, "script" );
5504
+ if ( destElements.length > 0 ) {
5505
+ setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5506
+ }
5507
+
5508
+ destElements = srcElements = node = null;
5509
+
5510
+ // Return the cloned set
5511
+ return clone;
5512
+ },
5513
+
5514
+ buildFragment: function( elems, context, scripts, selection ) {
5515
+ var j, elem, contains,
5516
+ tmp, tag, tbody, wrap,
5517
+ l = elems.length,
5518
+
5519
+ // Ensure a safe fragment
5520
+ safe = createSafeFragment( context ),
5521
+
5522
+ nodes = [],
5523
+ i = 0;
5524
+
5525
+ for ( ; i < l; i++ ) {
5526
+ elem = elems[ i ];
5527
+
5528
+ if ( elem || elem === 0 ) {
5529
+
5530
+ // Add nodes directly
5531
+ if ( jQuery.type( elem ) === "object" ) {
5532
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5533
+
5534
+ // Convert non-html into a text node
5535
+ } else if ( !rhtml.test( elem ) ) {
5536
+ nodes.push( context.createTextNode( elem ) );
5537
+
5538
+ // Convert html into DOM nodes
5539
+ } else {
5540
+ tmp = tmp || safe.appendChild( context.createElement("div") );
5541
+
5542
+ // Deserialize a standard representation
5543
+ tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
5544
+ wrap = wrapMap[ tag ] || wrapMap._default;
5545
+
5546
+ tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
5547
+
5548
+ // Descend through wrappers to the right content
5549
+ j = wrap[0];
5550
+ while ( j-- ) {
5551
+ tmp = tmp.lastChild;
5552
+ }
5553
+
5554
+ // Manually add leading whitespace removed by IE
5555
+ if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5556
+ nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
5557
+ }
5558
+
5559
+ // Remove IE's autoinserted <tbody> from table fragments
5560
+ if ( !support.tbody ) {
5561
+
5562
+ // String was a <table>, *may* have spurious <tbody>
5563
+ elem = tag === "table" && !rtbody.test( elem ) ?
5564
+ tmp.firstChild :
5565
+
5566
+ // String was a bare <thead> or <tfoot>
5567
+ wrap[1] === "<table>" && !rtbody.test( elem ) ?
5568
+ tmp :
5569
+ 0;
5570
+
5571
+ j = elem && elem.childNodes.length;
5572
+ while ( j-- ) {
5573
+ if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
5574
+ elem.removeChild( tbody );
5575
+ }
5576
+ }
5577
+ }
5578
+
5579
+ jQuery.merge( nodes, tmp.childNodes );
5580
+
5581
+ // Fix #12392 for WebKit and IE > 9
5582
+ tmp.textContent = "";
5583
+
5584
+ // Fix #12392 for oldIE
5585
+ while ( tmp.firstChild ) {
5586
+ tmp.removeChild( tmp.firstChild );
5587
+ }
5588
+
5589
+ // Remember the top-level container for proper cleanup
5590
+ tmp = safe.lastChild;
5591
+ }
5592
+ }
5593
+ }
5594
+
5595
+ // Fix #11356: Clear elements from fragment
5596
+ if ( tmp ) {
5597
+ safe.removeChild( tmp );
5598
+ }
5599
+
5600
+ // Reset defaultChecked for any radios and checkboxes
5601
+ // about to be appended to the DOM in IE 6/7 (#8060)
5602
+ if ( !support.appendChecked ) {
5603
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
5604
+ }
5605
+
5606
+ i = 0;
5607
+ while ( (elem = nodes[ i++ ]) ) {
5608
+
5609
+ // #4087 - If origin and destination elements are the same, and this is
5610
+ // that element, do not do anything
5611
+ if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5612
+ continue;
5613
+ }
5614
+
5615
+ contains = jQuery.contains( elem.ownerDocument, elem );
5616
+
5617
+ // Append to fragment
5618
+ tmp = getAll( safe.appendChild( elem ), "script" );
5619
+
5620
+ // Preserve script evaluation history
5621
+ if ( contains ) {
5622
+ setGlobalEval( tmp );
5623
+ }
5624
+
5625
+ // Capture executables
5626
+ if ( scripts ) {
5627
+ j = 0;
5628
+ while ( (elem = tmp[ j++ ]) ) {
5629
+ if ( rscriptType.test( elem.type || "" ) ) {
5630
+ scripts.push( elem );
5631
+ }
5632
+ }
5633
+ }
5634
+ }
5635
+
5636
+ tmp = null;
5637
+
5638
+ return safe;
5639
+ },
5640
+
5641
+ cleanData: function( elems, /* internal */ acceptData ) {
5642
+ var elem, type, id, data,
5643
+ i = 0,
5644
+ internalKey = jQuery.expando,
5645
+ cache = jQuery.cache,
5646
+ deleteExpando = support.deleteExpando,
5647
+ special = jQuery.event.special;
5648
+
5649
+ for ( ; (elem = elems[i]) != null; i++ ) {
5650
+ if ( acceptData || jQuery.acceptData( elem ) ) {
5651
+
5652
+ id = elem[ internalKey ];
5653
+ data = id && cache[ id ];
5654
+
5655
+ if ( data ) {
5656
+ if ( data.events ) {
5657
+ for ( type in data.events ) {
5658
+ if ( special[ type ] ) {
5659
+ jQuery.event.remove( elem, type );
5660
+
5661
+ // This is a shortcut to avoid jQuery.event.remove's overhead
5662
+ } else {
5663
+ jQuery.removeEvent( elem, type, data.handle );
5664
+ }
5665
+ }
5666
+ }
5667
+
5668
+ // Remove cache only if it was not already removed by jQuery.event.remove
5669
+ if ( cache[ id ] ) {
5670
+
5671
+ delete cache[ id ];
5672
+
5673
+ // IE does not allow us to delete expando properties from nodes,
5674
+ // nor does it have a removeAttribute function on Document nodes;
5675
+ // we must handle all of these cases
5676
+ if ( deleteExpando ) {
5677
+ delete elem[ internalKey ];
5678
+
5679
+ } else if ( typeof elem.removeAttribute !== strundefined ) {
5680
+ elem.removeAttribute( internalKey );
5681
+
5682
+ } else {
5683
+ elem[ internalKey ] = null;
5684
+ }
5685
+
5686
+ deletedIds.push( id );
5687
+ }
5688
+ }
5689
+ }
5690
+ }
5691
+ }
5692
+ });
5693
+
5694
+ jQuery.fn.extend({
5695
+ text: function( value ) {
5696
+ return access( this, function( value ) {
5697
+ return value === undefined ?
5698
+ jQuery.text( this ) :
5699
+ this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
5700
+ }, null, value, arguments.length );
5701
+ },
5702
+
5703
+ append: function() {
5704
+ return this.domManip( arguments, function( elem ) {
5705
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5706
+ var target = manipulationTarget( this, elem );
5707
+ target.appendChild( elem );
5708
+ }
5709
+ });
5710
+ },
5711
+
5712
+ prepend: function() {
5713
+ return this.domManip( arguments, function( elem ) {
5714
+ if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5715
+ var target = manipulationTarget( this, elem );
5716
+ target.insertBefore( elem, target.firstChild );
5717
+ }
5718
+ });
5719
+ },
5720
+
5721
+ before: function() {
5722
+ return this.domManip( arguments, function( elem ) {
5723
+ if ( this.parentNode ) {
5724
+ this.parentNode.insertBefore( elem, this );
5725
+ }
5726
+ });
5727
+ },
5728
+
5729
+ after: function() {
5730
+ return this.domManip( arguments, function( elem ) {
5731
+ if ( this.parentNode ) {
5732
+ this.parentNode.insertBefore( elem, this.nextSibling );
5733
+ }
5734
+ });
5735
+ },
5736
+
5737
+ remove: function( selector, keepData /* Internal Use Only */ ) {
5738
+ var elem,
5739
+ elems = selector ? jQuery.filter( selector, this ) : this,
5740
+ i = 0;
5741
+
5742
+ for ( ; (elem = elems[i]) != null; i++ ) {
5743
+
5744
+ if ( !keepData && elem.nodeType === 1 ) {
5745
+ jQuery.cleanData( getAll( elem ) );
5746
+ }
5747
+
5748
+ if ( elem.parentNode ) {
5749
+ if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5750
+ setGlobalEval( getAll( elem, "script" ) );
5751
+ }
5752
+ elem.parentNode.removeChild( elem );
5753
+ }
5754
+ }
5755
+
5756
+ return this;
5757
+ },
5758
+
5759
+ empty: function() {
5760
+ var elem,
5761
+ i = 0;
5762
+
5763
+ for ( ; (elem = this[i]) != null; i++ ) {
5764
+ // Remove element nodes and prevent memory leaks
5765
+ if ( elem.nodeType === 1 ) {
5766
+ jQuery.cleanData( getAll( elem, false ) );
5767
+ }
5768
+
5769
+ // Remove any remaining nodes
5770
+ while ( elem.firstChild ) {
5771
+ elem.removeChild( elem.firstChild );
5772
+ }
5773
+
5774
+ // If this is a select, ensure that it displays empty (#12336)
5775
+ // Support: IE<9
5776
+ if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
5777
+ elem.options.length = 0;
5778
+ }
5779
+ }
5780
+
5781
+ return this;
5782
+ },
5783
+
5784
+ clone: function( dataAndEvents, deepDataAndEvents ) {
5785
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5786
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5787
+
5788
+ return this.map(function() {
5789
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5790
+ });
5791
+ },
5792
+
5793
+ html: function( value ) {
5794
+ return access( this, function( value ) {
5795
+ var elem = this[ 0 ] || {},
5796
+ i = 0,
5797
+ l = this.length;
5798
+
5799
+ if ( value === undefined ) {
5800
+ return elem.nodeType === 1 ?
5801
+ elem.innerHTML.replace( rinlinejQuery, "" ) :
5802
+ undefined;
5803
+ }
5804
+
5805
+ // See if we can take a shortcut and just use innerHTML
5806
+ if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5807
+ ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
5808
+ ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
5809
+ !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
5810
+
5811
+ value = value.replace( rxhtmlTag, "<$1></$2>" );
5812
+
5813
+ try {
5814
+ for (; i < l; i++ ) {
5815
+ // Remove element nodes and prevent memory leaks
5816
+ elem = this[i] || {};
5817
+ if ( elem.nodeType === 1 ) {
5818
+ jQuery.cleanData( getAll( elem, false ) );
5819
+ elem.innerHTML = value;
5820
+ }
5821
+ }
5822
+
5823
+ elem = 0;
5824
+
5825
+ // If using innerHTML throws an exception, use the fallback method
5826
+ } catch(e) {}
5827
+ }
5828
+
5829
+ if ( elem ) {
5830
+ this.empty().append( value );
5831
+ }
5832
+ }, null, value, arguments.length );
5833
+ },
5834
+
5835
+ replaceWith: function() {
5836
+ var arg = arguments[ 0 ];
5837
+
5838
+ // Make the changes, replacing each context element with the new content
5839
+ this.domManip( arguments, function( elem ) {
5840
+ arg = this.parentNode;
5841
+
5842
+ jQuery.cleanData( getAll( this ) );
5843
+
5844
+ if ( arg ) {
5845
+ arg.replaceChild( elem, this );
5846
+ }
5847
+ });
5848
+
5849
+ // Force removal if there was no new content (e.g., from empty arguments)
5850
+ return arg && (arg.length || arg.nodeType) ? this : this.remove();
5851
+ },
5852
+
5853
+ detach: function( selector ) {
5854
+ return this.remove( selector, true );
5855
+ },
5856
+
5857
+ domManip: function( args, callback ) {
5858
+
5859
+ // Flatten any nested arrays
5860
+ args = concat.apply( [], args );
5861
+
5862
+ var first, node, hasScripts,
5863
+ scripts, doc, fragment,
5864
+ i = 0,
5865
+ l = this.length,
5866
+ set = this,
5867
+ iNoClone = l - 1,
5868
+ value = args[0],
5869
+ isFunction = jQuery.isFunction( value );
5870
+
5871
+ // We can't cloneNode fragments that contain checked, in WebKit
5872
+ if ( isFunction ||
5873
+ ( l > 1 && typeof value === "string" &&
5874
+ !support.checkClone && rchecked.test( value ) ) ) {
5875
+ return this.each(function( index ) {
5876
+ var self = set.eq( index );
5877
+ if ( isFunction ) {
5878
+ args[0] = value.call( this, index, self.html() );
5879
+ }
5880
+ self.domManip( args, callback );
5881
+ });
5882
+ }
5883
+
5884
+ if ( l ) {
5885
+ fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5886
+ first = fragment.firstChild;
5887
+
5888
+ if ( fragment.childNodes.length === 1 ) {
5889
+ fragment = first;
5890
+ }
5891
+
5892
+ if ( first ) {
5893
+ scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5894
+ hasScripts = scripts.length;
5895
+
5896
+ // Use the original fragment for the last item instead of the first because it can end up
5897
+ // being emptied incorrectly in certain situations (#8070).
5898
+ for ( ; i < l; i++ ) {
5899
+ node = fragment;
5900
+
5901
+ if ( i !== iNoClone ) {
5902
+ node = jQuery.clone( node, true, true );
5903
+
5904
+ // Keep references to cloned scripts for later restoration
5905
+ if ( hasScripts ) {
5906
+ jQuery.merge( scripts, getAll( node, "script" ) );
5907
+ }
5908
+ }
5909
+
5910
+ callback.call( this[i], node, i );
5911
+ }
5912
+
5913
+ if ( hasScripts ) {
5914
+ doc = scripts[ scripts.length - 1 ].ownerDocument;
5915
+
5916
+ // Reenable scripts
5917
+ jQuery.map( scripts, restoreScript );
5918
+
5919
+ // Evaluate executable scripts on first document insertion
5920
+ for ( i = 0; i < hasScripts; i++ ) {
5921
+ node = scripts[ i ];
5922
+ if ( rscriptType.test( node.type || "" ) &&
5923
+ !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5924
+
5925
+ if ( node.src ) {
5926
+ // Optional AJAX dependency, but won't run scripts if not present
5927
+ if ( jQuery._evalUrl ) {
5928
+ jQuery._evalUrl( node.src );
5929
+ }
5930
+ } else {
5931
+ jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
5932
+ }
5933
+ }
5934
+ }
5935
+ }
5936
+
5937
+ // Fix #11809: Avoid leaking memory
5938
+ fragment = first = null;
5939
+ }
5940
+ }
5941
+
5942
+ return this;
5943
+ }
5944
+ });
5945
+
5946
+ jQuery.each({
5947
+ appendTo: "append",
5948
+ prependTo: "prepend",
5949
+ insertBefore: "before",
5950
+ insertAfter: "after",
5951
+ replaceAll: "replaceWith"
5952
+ }, function( name, original ) {
5953
+ jQuery.fn[ name ] = function( selector ) {
5954
+ var elems,
5955
+ i = 0,
5956
+ ret = [],
5957
+ insert = jQuery( selector ),
5958
+ last = insert.length - 1;
5959
+
5960
+ for ( ; i <= last; i++ ) {
5961
+ elems = i === last ? this : this.clone(true);
5962
+ jQuery( insert[i] )[ original ]( elems );
5963
+
5964
+ // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
5965
+ push.apply( ret, elems.get() );
5966
+ }
5967
+
5968
+ return this.pushStack( ret );
5969
+ };
5970
+ });
5971
+
5972
+
5973
+ var iframe,
5974
+ elemdisplay = {};
5975
+
5976
+ /**
5977
+ * Retrieve the actual display of a element
5978
+ * @param {String} name nodeName of the element
5979
+ * @param {Object} doc Document object
5980
+ */
5981
+ // Called only from within defaultDisplay
5982
+ function actualDisplay( name, doc ) {
5983
+ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5984
+
5985
+ // getDefaultComputedStyle might be reliably used only on attached element
5986
+ display = window.getDefaultComputedStyle ?
5987
+
5988
+ // Use of this method is a temporary fix (more like optmization) until something better comes along,
5989
+ // since it was removed from specification and supported only in FF
5990
+ window.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], "display" );
5991
+
5992
+ // We don't have any data stored on the element,
5993
+ // so use "detach" method as fast way to get rid of the element
5994
+ elem.detach();
5995
+
5996
+ return display;
5997
+ }
5998
+
5999
+ /**
6000
+ * Try to determine the default display value of an element
6001
+ * @param {String} nodeName
6002
+ */
6003
+ function defaultDisplay( nodeName ) {
6004
+ var doc = document,
6005
+ display = elemdisplay[ nodeName ];
6006
+
6007
+ if ( !display ) {
6008
+ display = actualDisplay( nodeName, doc );
6009
+
6010
+ // If the simple way fails, read from inside an iframe
6011
+ if ( display === "none" || !display ) {
6012
+
6013
+ // Use the already-created iframe if possible
6014
+ iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
6015
+
6016
+ // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6017
+ doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6018
+
6019
+ // Support: IE
6020
+ doc.write();
6021
+ doc.close();
6022
+
6023
+ display = actualDisplay( nodeName, doc );
6024
+ iframe.detach();
6025
+ }
6026
+
6027
+ // Store the correct default display
6028
+ elemdisplay[ nodeName ] = display;
6029
+ }
6030
+
6031
+ return display;
6032
+ }
6033
+
6034
+
6035
+ (function() {
6036
+ var a, shrinkWrapBlocksVal,
6037
+ div = document.createElement( "div" ),
6038
+ divReset =
6039
+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;" +
6040
+ "display:block;padding:0;margin:0;border:0";
6041
+
6042
+ // Setup
6043
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6044
+ a = div.getElementsByTagName( "a" )[ 0 ];
6045
+
6046
+ a.style.cssText = "float:left;opacity:.5";
6047
+
6048
+ // Make sure that element opacity exists
6049
+ // (IE uses filter instead)
6050
+ // Use a regex to work around a WebKit issue. See #5145
6051
+ support.opacity = /^0.5/.test( a.style.opacity );
6052
+
6053
+ // Verify style float existence
6054
+ // (IE uses styleFloat instead of cssFloat)
6055
+ support.cssFloat = !!a.style.cssFloat;
6056
+
6057
+ div.style.backgroundClip = "content-box";
6058
+ div.cloneNode( true ).style.backgroundClip = "";
6059
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
6060
+
6061
+ // Null elements to avoid leaks in IE.
6062
+ a = div = null;
6063
+
6064
+ support.shrinkWrapBlocks = function() {
6065
+ var body, container, div, containerStyles;
6066
+
6067
+ if ( shrinkWrapBlocksVal == null ) {
6068
+ body = document.getElementsByTagName( "body" )[ 0 ];
6069
+ if ( !body ) {
6070
+ // Test fired too early or in an unsupported environment, exit.
6071
+ return;
6072
+ }
6073
+
6074
+ containerStyles = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px";
6075
+ container = document.createElement( "div" );
6076
+ div = document.createElement( "div" );
6077
+
6078
+ body.appendChild( container ).appendChild( div );
6079
+
6080
+ // Will be changed later if needed.
6081
+ shrinkWrapBlocksVal = false;
6082
+
6083
+ if ( typeof div.style.zoom !== strundefined ) {
6084
+ // Support: IE6
6085
+ // Check if elements with layout shrink-wrap their children
6086
+ div.style.cssText = divReset + ";width:1px;padding:1px;zoom:1";
6087
+ div.innerHTML = "<div></div>";
6088
+ div.firstChild.style.width = "5px";
6089
+ shrinkWrapBlocksVal = div.offsetWidth !== 3;
6090
+ }
6091
+
6092
+ body.removeChild( container );
6093
+
6094
+ // Null elements to avoid leaks in IE.
6095
+ body = container = div = null;
6096
+ }
6097
+
6098
+ return shrinkWrapBlocksVal;
6099
+ };
6100
+
6101
+ })();
6102
+ var rmargin = (/^margin/);
6103
+
6104
+ var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6105
+
6106
+
6107
+
6108
+ var getStyles, curCSS,
6109
+ rposition = /^(top|right|bottom|left)$/;
6110
+
6111
+ if ( window.getComputedStyle ) {
6112
+ getStyles = function( elem ) {
6113
+ return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
6114
+ };
6115
+
6116
+ curCSS = function( elem, name, computed ) {
6117
+ var width, minWidth, maxWidth, ret,
6118
+ style = elem.style;
6119
+
6120
+ computed = computed || getStyles( elem );
6121
+
6122
+ // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6123
+ ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6124
+
6125
+ if ( computed ) {
6126
+
6127
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6128
+ ret = jQuery.style( elem, name );
6129
+ }
6130
+
6131
+ // A tribute to the "awesome hack by Dean Edwards"
6132
+ // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
6133
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6134
+ // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6135
+ if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6136
+
6137
+ // Remember the original values
6138
+ width = style.width;
6139
+ minWidth = style.minWidth;
6140
+ maxWidth = style.maxWidth;
6141
+
6142
+ // Put in the new values to get a computed value out
6143
+ style.minWidth = style.maxWidth = style.width = ret;
6144
+ ret = computed.width;
6145
+
6146
+ // Revert the changed values
6147
+ style.width = width;
6148
+ style.minWidth = minWidth;
6149
+ style.maxWidth = maxWidth;
6150
+ }
6151
+ }
6152
+
6153
+ // Support: IE
6154
+ // IE returns zIndex value as an integer.
6155
+ return ret === undefined ?
6156
+ ret :
6157
+ ret + "";
6158
+ };
6159
+ } else if ( document.documentElement.currentStyle ) {
6160
+ getStyles = function( elem ) {
6161
+ return elem.currentStyle;
6162
+ };
6163
+
6164
+ curCSS = function( elem, name, computed ) {
6165
+ var left, rs, rsLeft, ret,
6166
+ style = elem.style;
6167
+
6168
+ computed = computed || getStyles( elem );
6169
+ ret = computed ? computed[ name ] : undefined;
6170
+
6171
+ // Avoid setting ret to empty string here
6172
+ // so we don't default to auto
6173
+ if ( ret == null && style && style[ name ] ) {
6174
+ ret = style[ name ];
6175
+ }
6176
+
6177
+ // From the awesome hack by Dean Edwards
6178
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6179
+
6180
+ // If we're not dealing with a regular pixel number
6181
+ // but a number that has a weird ending, we need to convert it to pixels
6182
+ // but not position css attributes, as those are proportional to the parent element instead
6183
+ // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
6184
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6185
+
6186
+ // Remember the original values
6187
+ left = style.left;
6188
+ rs = elem.runtimeStyle;
6189
+ rsLeft = rs && rs.left;
6190
+
6191
+ // Put in the new values to get a computed value out
6192
+ if ( rsLeft ) {
6193
+ rs.left = elem.currentStyle.left;
6194
+ }
6195
+ style.left = name === "fontSize" ? "1em" : ret;
6196
+ ret = style.pixelLeft + "px";
6197
+
6198
+ // Revert the changed values
6199
+ style.left = left;
6200
+ if ( rsLeft ) {
6201
+ rs.left = rsLeft;
6202
+ }
6203
+ }
6204
+
6205
+ // Support: IE
6206
+ // IE returns zIndex value as an integer.
6207
+ return ret === undefined ?
6208
+ ret :
6209
+ ret + "" || "auto";
6210
+ };
6211
+ }
6212
+
6213
+
6214
+
6215
+
6216
+ function addGetHookIf( conditionFn, hookFn ) {
6217
+ // Define the hook, we'll check on the first run if it's really needed.
6218
+ return {
6219
+ get: function() {
6220
+ var condition = conditionFn();
6221
+
6222
+ if ( condition == null ) {
6223
+ // The test was not ready at this point; screw the hook this time
6224
+ // but check again when needed next time.
6225
+ return;
6226
+ }
6227
+
6228
+ if ( condition ) {
6229
+ // Hook not needed (or it's not possible to use it due to missing dependency),
6230
+ // remove it.
6231
+ // Since there are no other hooks for marginRight, remove the whole object.
6232
+ delete this.get;
6233
+ return;
6234
+ }
6235
+
6236
+ // Hook needed; redefine it so that the support test is not executed again.
6237
+
6238
+ return (this.get = hookFn).apply( this, arguments );
6239
+ }
6240
+ };
6241
+ }
6242
+
6243
+
6244
+ (function() {
6245
+ var a, reliableHiddenOffsetsVal, boxSizingVal, boxSizingReliableVal,
6246
+ pixelPositionVal, reliableMarginRightVal,
6247
+ div = document.createElement( "div" ),
6248
+ containerStyles = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px",
6249
+ divReset =
6250
+ "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;" +
6251
+ "display:block;padding:0;margin:0;border:0";
6252
+
6253
+ // Setup
6254
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6255
+ a = div.getElementsByTagName( "a" )[ 0 ];
6256
+
6257
+ a.style.cssText = "float:left;opacity:.5";
6258
+
6259
+ // Make sure that element opacity exists
6260
+ // (IE uses filter instead)
6261
+ // Use a regex to work around a WebKit issue. See #5145
6262
+ support.opacity = /^0.5/.test( a.style.opacity );
6263
+
6264
+ // Verify style float existence
6265
+ // (IE uses styleFloat instead of cssFloat)
6266
+ support.cssFloat = !!a.style.cssFloat;
6267
+
6268
+ div.style.backgroundClip = "content-box";
6269
+ div.cloneNode( true ).style.backgroundClip = "";
6270
+ support.clearCloneStyle = div.style.backgroundClip === "content-box";
6271
+
6272
+ // Null elements to avoid leaks in IE.
6273
+ a = div = null;
6274
+
6275
+ jQuery.extend(support, {
6276
+ reliableHiddenOffsets: function() {
6277
+ if ( reliableHiddenOffsetsVal != null ) {
6278
+ return reliableHiddenOffsetsVal;
6279
+ }
6280
+
6281
+ var container, tds, isSupported,
6282
+ div = document.createElement( "div" ),
6283
+ body = document.getElementsByTagName( "body" )[ 0 ];
6284
+
6285
+ if ( !body ) {
6286
+ // Return for frameset docs that don't have a body
6287
+ return;
6288
+ }
6289
+
6290
+ // Setup
6291
+ div.setAttribute( "className", "t" );
6292
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
6293
+
6294
+ container = document.createElement( "div" );
6295
+ container.style.cssText = containerStyles;
6296
+
6297
+ body.appendChild( container ).appendChild( div );
6298
+
6299
+ // Support: IE8
6300
+ // Check if table cells still have offsetWidth/Height when they are set
6301
+ // to display:none and there are still other visible table cells in a
6302
+ // table row; if so, offsetWidth/Height are not reliable for use when
6303
+ // determining if an element has been hidden directly using
6304
+ // display:none (it is still safe to use offsets if a parent element is
6305
+ // hidden; don safety goggles and see bug #4512 for more information).
6306
+ div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6307
+ tds = div.getElementsByTagName( "td" );
6308
+ tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
6309
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
6310
+
6311
+ tds[ 0 ].style.display = "";
6312
+ tds[ 1 ].style.display = "none";
6313
+
6314
+ // Support: IE8
6315
+ // Check if empty table cells still have offsetWidth/Height
6316
+ reliableHiddenOffsetsVal = isSupported && ( tds[ 0 ].offsetHeight === 0 );
6317
+
6318
+ body.removeChild( container );
6319
+
6320
+ // Null elements to avoid leaks in IE.
6321
+ div = body = null;
6322
+
6323
+ return reliableHiddenOffsetsVal;
6324
+ },
6325
+
6326
+ boxSizing: function() {
6327
+ if ( boxSizingVal == null ) {
6328
+ computeStyleTests();
6329
+ }
6330
+ return boxSizingVal;
6331
+ },
6332
+
6333
+ boxSizingReliable: function() {
6334
+ if ( boxSizingReliableVal == null ) {
6335
+ computeStyleTests();
6336
+ }
6337
+ return boxSizingReliableVal;
6338
+ },
6339
+
6340
+ pixelPosition: function() {
6341
+ if ( pixelPositionVal == null ) {
6342
+ computeStyleTests();
6343
+ }
6344
+ return pixelPositionVal;
6345
+ },
6346
+
6347
+ reliableMarginRight: function() {
6348
+ var body, container, div, marginDiv;
6349
+
6350
+ // Use window.getComputedStyle because jsdom on node.js will break without it.
6351
+ if ( reliableMarginRightVal == null && window.getComputedStyle ) {
6352
+ body = document.getElementsByTagName( "body" )[ 0 ];
6353
+ if ( !body ) {
6354
+ // Test fired too early or in an unsupported environment, exit.
6355
+ return;
6356
+ }
6357
+
6358
+ container = document.createElement( "div" );
6359
+ div = document.createElement( "div" );
6360
+ container.style.cssText = containerStyles;
6361
+
6362
+ body.appendChild( container ).appendChild( div );
6363
+
6364
+ // Check if div with explicit width and no margin-right incorrectly
6365
+ // gets computed margin-right based on width of container. (#3333)
6366
+ // Fails in WebKit before Feb 2011 nightlies
6367
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6368
+ marginDiv = div.appendChild( document.createElement( "div" ) );
6369
+ marginDiv.style.cssText = div.style.cssText = divReset;
6370
+ marginDiv.style.marginRight = marginDiv.style.width = "0";
6371
+ div.style.width = "1px";
6372
+
6373
+ reliableMarginRightVal =
6374
+ !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
6375
+
6376
+ body.removeChild( container );
6377
+ }
6378
+
6379
+ return reliableMarginRightVal;
6380
+ }
6381
+ });
6382
+
6383
+ function computeStyleTests() {
6384
+ var container, div,
6385
+ body = document.getElementsByTagName( "body" )[ 0 ];
6386
+
6387
+ if ( !body ) {
6388
+ // Test fired too early or in an unsupported environment, exit.
6389
+ return;
6390
+ }
6391
+
6392
+ container = document.createElement( "div" );
6393
+ div = document.createElement( "div" );
6394
+ container.style.cssText = containerStyles;
6395
+
6396
+ body.appendChild( container ).appendChild( div );
6397
+
6398
+ div.style.cssText =
6399
+ "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
6400
+ "position:absolute;display:block;padding:1px;border:1px;width:4px;" +
6401
+ "margin-top:1%;top:1%";
6402
+
6403
+ // Workaround failing boxSizing test due to offsetWidth returning wrong value
6404
+ // with some non-1 values of body zoom, ticket #13543
6405
+ jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
6406
+ boxSizingVal = div.offsetWidth === 4;
6407
+ });
6408
+
6409
+ // Will be changed later if needed.
6410
+ boxSizingReliableVal = true;
6411
+ pixelPositionVal = false;
6412
+ reliableMarginRightVal = true;
6413
+
6414
+ // Use window.getComputedStyle because jsdom on node.js will break without it.
6415
+ if ( window.getComputedStyle ) {
6416
+ pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
6417
+ boxSizingReliableVal =
6418
+ ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
6419
+ }
6420
+
6421
+ body.removeChild( container );
6422
+
6423
+ // Null elements to avoid leaks in IE.
6424
+ div = body = null;
6425
+ }
6426
+
6427
+ })();
6428
+
6429
+
6430
+ // A method for quickly swapping in/out CSS properties to get correct calculations.
6431
+ jQuery.swap = function( elem, options, callback, args ) {
6432
+ var ret, name,
6433
+ old = {};
6434
+
6435
+ // Remember the old values, and insert the new ones
6436
+ for ( name in options ) {
6437
+ old[ name ] = elem.style[ name ];
6438
+ elem.style[ name ] = options[ name ];
6439
+ }
6440
+
6441
+ ret = callback.apply( elem, args || [] );
6442
+
6443
+ // Revert the old values
6444
+ for ( name in options ) {
6445
+ elem.style[ name ] = old[ name ];
6446
+ }
6447
+
6448
+ return ret;
6449
+ };
6450
+
6451
+
6452
+ var
6453
+ ralpha = /alpha\([^)]*\)/i,
6454
+ ropacity = /opacity\s*=\s*([^)]*)/,
6455
+
6456
+ // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6457
+ // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6458
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6459
+ rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6460
+ rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
6461
+
6462
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6463
+ cssNormalTransform = {
6464
+ letterSpacing: 0,
6465
+ fontWeight: 400
6466
+ },
6467
+
6468
+ cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
6469
+
6470
+
6471
+ // return a css property mapped to a potentially vendor prefixed property
6472
+ function vendorPropName( style, name ) {
6473
+
6474
+ // shortcut for names that are not vendor prefixed
6475
+ if ( name in style ) {
6476
+ return name;
6477
+ }
6478
+
6479
+ // check for vendor prefixed names
6480
+ var capName = name.charAt(0).toUpperCase() + name.slice(1),
6481
+ origName = name,
6482
+ i = cssPrefixes.length;
6483
+
6484
+ while ( i-- ) {
6485
+ name = cssPrefixes[ i ] + capName;
6486
+ if ( name in style ) {
6487
+ return name;
6488
+ }
6489
+ }
6490
+
6491
+ return origName;
6492
+ }
6493
+
6494
+ function showHide( elements, show ) {
6495
+ var display, elem, hidden,
6496
+ values = [],
6497
+ index = 0,
6498
+ length = elements.length;
6499
+
6500
+ for ( ; index < length; index++ ) {
6501
+ elem = elements[ index ];
6502
+ if ( !elem.style ) {
6503
+ continue;
6504
+ }
6505
+
6506
+ values[ index ] = jQuery._data( elem, "olddisplay" );
6507
+ display = elem.style.display;
6508
+ if ( show ) {
6509
+ // Reset the inline display of this element to learn if it is
6510
+ // being hidden by cascaded rules or not
6511
+ if ( !values[ index ] && display === "none" ) {
6512
+ elem.style.display = "";
6513
+ }
6514
+
6515
+ // Set elements which have been overridden with display: none
6516
+ // in a stylesheet to whatever the default browser style is
6517
+ // for such an element
6518
+ if ( elem.style.display === "" && isHidden( elem ) ) {
6519
+ values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
6520
+ }
6521
+ } else {
6522
+
6523
+ if ( !values[ index ] ) {
6524
+ hidden = isHidden( elem );
6525
+
6526
+ if ( display && display !== "none" || !hidden ) {
6527
+ jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
6528
+ }
6529
+ }
6530
+ }
6531
+ }
6532
+
6533
+ // Set the display of most of the elements in a second loop
6534
+ // to avoid the constant reflow
6535
+ for ( index = 0; index < length; index++ ) {
6536
+ elem = elements[ index ];
6537
+ if ( !elem.style ) {
6538
+ continue;
6539
+ }
6540
+ if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6541
+ elem.style.display = show ? values[ index ] || "" : "none";
6542
+ }
6543
+ }
6544
+
6545
+ return elements;
6546
+ }
6547
+
6548
+ function setPositiveNumber( elem, value, subtract ) {
6549
+ var matches = rnumsplit.exec( value );
6550
+ return matches ?
6551
+ // Guard against undefined "subtract", e.g., when used as in cssHooks
6552
+ Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6553
+ value;
6554
+ }
6555
+
6556
+ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6557
+ var i = extra === ( isBorderBox ? "border" : "content" ) ?
6558
+ // If we already have the right measurement, avoid augmentation
6559
+ 4 :
6560
+ // Otherwise initialize for horizontal or vertical properties
6561
+ name === "width" ? 1 : 0,
6562
+
6563
+ val = 0;
6564
+
6565
+ for ( ; i < 4; i += 2 ) {
6566
+ // both box models exclude margin, so add it if we want it
6567
+ if ( extra === "margin" ) {
6568
+ val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6569
+ }
6570
+
6571
+ if ( isBorderBox ) {
6572
+ // border-box includes padding, so remove it if we want content
6573
+ if ( extra === "content" ) {
6574
+ val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6575
+ }
6576
+
6577
+ // at this point, extra isn't border nor margin, so remove border
6578
+ if ( extra !== "margin" ) {
6579
+ val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6580
+ }
6581
+ } else {
6582
+ // at this point, extra isn't content, so add padding
6583
+ val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6584
+
6585
+ // at this point, extra isn't content nor padding, so add border
6586
+ if ( extra !== "padding" ) {
6587
+ val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6588
+ }
6589
+ }
6590
+ }
6591
+
6592
+ return val;
6593
+ }
6594
+
6595
+ function getWidthOrHeight( elem, name, extra ) {
6596
+
6597
+ // Start with offset property, which is equivalent to the border-box value
6598
+ var valueIsBorderBox = true,
6599
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6600
+ styles = getStyles( elem ),
6601
+ isBorderBox = support.boxSizing() && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6602
+
6603
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
6604
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6605
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6606
+ if ( val <= 0 || val == null ) {
6607
+ // Fall back to computed then uncomputed css if necessary
6608
+ val = curCSS( elem, name, styles );
6609
+ if ( val < 0 || val == null ) {
6610
+ val = elem.style[ name ];
6611
+ }
6612
+
6613
+ // Computed unit is not pixels. Stop here and return.
6614
+ if ( rnumnonpx.test(val) ) {
6615
+ return val;
6616
+ }
6617
+
6618
+ // we need the check for style in case a browser which returns unreliable values
6619
+ // for getComputedStyle silently falls back to the reliable elem.style
6620
+ valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
6621
+
6622
+ // Normalize "", auto, and prepare for extra
6623
+ val = parseFloat( val ) || 0;
6624
+ }
6625
+
6626
+ // use the active box-sizing model to add/subtract irrelevant styles
6627
+ return ( val +
6628
+ augmentWidthOrHeight(
6629
+ elem,
6630
+ name,
6631
+ extra || ( isBorderBox ? "border" : "content" ),
6632
+ valueIsBorderBox,
6633
+ styles
6634
+ )
6635
+ ) + "px";
6636
+ }
6637
+
6638
+ jQuery.extend({
6639
+ // Add in style property hooks for overriding the default
6640
+ // behavior of getting and setting a style property
6641
+ cssHooks: {
6642
+ opacity: {
6643
+ get: function( elem, computed ) {
6644
+ if ( computed ) {
6645
+ // We should always get a number back from opacity
6646
+ var ret = curCSS( elem, "opacity" );
6647
+ return ret === "" ? "1" : ret;
6648
+ }
6649
+ }
6650
+ }
6651
+ },
6652
+
6653
+ // Don't automatically add "px" to these possibly-unitless properties
6654
+ cssNumber: {
6655
+ "columnCount": true,
6656
+ "fillOpacity": true,
6657
+ "fontWeight": true,
6658
+ "lineHeight": true,
6659
+ "opacity": true,
6660
+ "order": true,
6661
+ "orphans": true,
6662
+ "widows": true,
6663
+ "zIndex": true,
6664
+ "zoom": true
6665
+ },
6666
+
6667
+ // Add in properties whose names you wish to fix before
6668
+ // setting or getting the value
6669
+ cssProps: {
6670
+ // normalize float css property
6671
+ "float": support.cssFloat ? "cssFloat" : "styleFloat"
6672
+ },
6673
+
6674
+ // Get and set the style property on a DOM Node
6675
+ style: function( elem, name, value, extra ) {
6676
+ // Don't set styles on text and comment nodes
6677
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6678
+ return;
6679
+ }
6680
+
6681
+ // Make sure that we're working with the right name
6682
+ var ret, type, hooks,
6683
+ origName = jQuery.camelCase( name ),
6684
+ style = elem.style;
6685
+
6686
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6687
+
6688
+ // gets hook for the prefixed version
6689
+ // followed by the unprefixed version
6690
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6691
+
6692
+ // Check if we're setting a value
6693
+ if ( value !== undefined ) {
6694
+ type = typeof value;
6695
+
6696
+ // convert relative number strings (+= or -=) to relative numbers. #7345
6697
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6698
+ value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6699
+ // Fixes bug #9237
6700
+ type = "number";
6701
+ }
6702
+
6703
+ // Make sure that null and NaN values aren't set. See: #7116
6704
+ if ( value == null || value !== value ) {
6705
+ return;
6706
+ }
6707
+
6708
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
6709
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6710
+ value += "px";
6711
+ }
6712
+
6713
+ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
6714
+ // but it would mean to define eight (for every problematic property) identical functions
6715
+ if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
6716
+ style[ name ] = "inherit";
6717
+ }
6718
+
6719
+ // If a hook was provided, use that value, otherwise just set the specified value
6720
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6721
+
6722
+ // Support: IE
6723
+ // Swallow errors from 'invalid' CSS values (#5509)
6724
+ try {
6725
+ // Support: Chrome, Safari
6726
+ // Setting style to blank string required to delete "style: x !important;"
6727
+ style[ name ] = "";
6728
+ style[ name ] = value;
6729
+ } catch(e) {}
6730
+ }
6731
+
6732
+ } else {
6733
+ // If a hook was provided get the non-computed value from there
6734
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6735
+ return ret;
6736
+ }
6737
+
6738
+ // Otherwise just get the value from the style object
6739
+ return style[ name ];
6740
+ }
6741
+ },
6742
+
6743
+ css: function( elem, name, extra, styles ) {
6744
+ var num, val, hooks,
6745
+ origName = jQuery.camelCase( name );
6746
+
6747
+ // Make sure that we're working with the right name
6748
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6749
+
6750
+ // gets hook for the prefixed version
6751
+ // followed by the unprefixed version
6752
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6753
+
6754
+ // If a hook was provided get the computed value from there
6755
+ if ( hooks && "get" in hooks ) {
6756
+ val = hooks.get( elem, true, extra );
6757
+ }
6758
+
6759
+ // Otherwise, if a way to get the computed value exists, use that
6760
+ if ( val === undefined ) {
6761
+ val = curCSS( elem, name, styles );
6762
+ }
6763
+
6764
+ //convert "normal" to computed value
6765
+ if ( val === "normal" && name in cssNormalTransform ) {
6766
+ val = cssNormalTransform[ name ];
6767
+ }
6768
+
6769
+ // Return, converting to number if forced or a qualifier was provided and val looks numeric
6770
+ if ( extra === "" || extra ) {
6771
+ num = parseFloat( val );
6772
+ return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6773
+ }
6774
+ return val;
6775
+ }
6776
+ });
6777
+
6778
+ jQuery.each([ "height", "width" ], function( i, name ) {
6779
+ jQuery.cssHooks[ name ] = {
6780
+ get: function( elem, computed, extra ) {
6781
+ if ( computed ) {
6782
+ // certain elements can have dimension info if we invisibly show them
6783
+ // however, it must have a current display style that would benefit from this
6784
+ return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
6785
+ jQuery.swap( elem, cssShow, function() {
6786
+ return getWidthOrHeight( elem, name, extra );
6787
+ }) :
6788
+ getWidthOrHeight( elem, name, extra );
6789
+ }
6790
+ },
6791
+
6792
+ set: function( elem, value, extra ) {
6793
+ var styles = extra && getStyles( elem );
6794
+ return setPositiveNumber( elem, value, extra ?
6795
+ augmentWidthOrHeight(
6796
+ elem,
6797
+ name,
6798
+ extra,
6799
+ support.boxSizing() && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6800
+ styles
6801
+ ) : 0
6802
+ );
6803
+ }
6804
+ };
6805
+ });
6806
+
6807
+ if ( !support.opacity ) {
6808
+ jQuery.cssHooks.opacity = {
6809
+ get: function( elem, computed ) {
6810
+ // IE uses filters for opacity
6811
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6812
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
6813
+ computed ? "1" : "";
6814
+ },
6815
+
6816
+ set: function( elem, value ) {
6817
+ var style = elem.style,
6818
+ currentStyle = elem.currentStyle,
6819
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
6820
+ filter = currentStyle && currentStyle.filter || style.filter || "";
6821
+
6822
+ // IE has trouble with opacity if it does not have layout
6823
+ // Force it by setting the zoom level
6824
+ style.zoom = 1;
6825
+
6826
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6827
+ // if value === "", then remove inline opacity #12685
6828
+ if ( ( value >= 1 || value === "" ) &&
6829
+ jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
6830
+ style.removeAttribute ) {
6831
+
6832
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6833
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
6834
+ // style.removeAttribute is IE Only, but so apparently is this code path...
6835
+ style.removeAttribute( "filter" );
6836
+
6837
+ // if there is no filter style applied in a css rule or unset inline opacity, we are done
6838
+ if ( value === "" || currentStyle && !currentStyle.filter ) {
6839
+ return;
6840
+ }
6841
+ }
6842
+
6843
+ // otherwise, set new filter values
6844
+ style.filter = ralpha.test( filter ) ?
6845
+ filter.replace( ralpha, opacity ) :
6846
+ filter + " " + opacity;
6847
+ }
6848
+ };
6849
+ }
6850
+
6851
+ jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6852
+ function( elem, computed ) {
6853
+ if ( computed ) {
6854
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6855
+ // Work around by temporarily setting element display to inline-block
6856
+ return jQuery.swap( elem, { "display": "inline-block" },
6857
+ curCSS, [ elem, "marginRight" ] );
6858
+ }
6859
+ }
6860
+ );
6861
+
6862
+ // These hooks are used by animate to expand properties
6863
+ jQuery.each({
6864
+ margin: "",
6865
+ padding: "",
6866
+ border: "Width"
6867
+ }, function( prefix, suffix ) {
6868
+ jQuery.cssHooks[ prefix + suffix ] = {
6869
+ expand: function( value ) {
6870
+ var i = 0,
6871
+ expanded = {},
6872
+
6873
+ // assumes a single number if not a string
6874
+ parts = typeof value === "string" ? value.split(" ") : [ value ];
6875
+
6876
+ for ( ; i < 4; i++ ) {
6877
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
6878
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6879
+ }
6880
+
6881
+ return expanded;
6882
+ }
6883
+ };
6884
+
6885
+ if ( !rmargin.test( prefix ) ) {
6886
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6887
+ }
6888
+ });
6889
+
6890
+ jQuery.fn.extend({
6891
+ css: function( name, value ) {
6892
+ return access( this, function( elem, name, value ) {
6893
+ var styles, len,
6894
+ map = {},
6895
+ i = 0;
6896
+
6897
+ if ( jQuery.isArray( name ) ) {
6898
+ styles = getStyles( elem );
6899
+ len = name.length;
6900
+
6901
+ for ( ; i < len; i++ ) {
6902
+ map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6903
+ }
6904
+
6905
+ return map;
6906
+ }
6907
+
6908
+ return value !== undefined ?
6909
+ jQuery.style( elem, name, value ) :
6910
+ jQuery.css( elem, name );
6911
+ }, name, value, arguments.length > 1 );
6912
+ },
6913
+ show: function() {
6914
+ return showHide( this, true );
6915
+ },
6916
+ hide: function() {
6917
+ return showHide( this );
6918
+ },
6919
+ toggle: function( state ) {
6920
+ if ( typeof state === "boolean" ) {
6921
+ return state ? this.show() : this.hide();
6922
+ }
6923
+
6924
+ return this.each(function() {
6925
+ if ( isHidden( this ) ) {
6926
+ jQuery( this ).show();
6927
+ } else {
6928
+ jQuery( this ).hide();
6929
+ }
6930
+ });
6931
+ }
6932
+ });
6933
+
6934
+
6935
+ function Tween( elem, options, prop, end, easing ) {
6936
+ return new Tween.prototype.init( elem, options, prop, end, easing );
6937
+ }
6938
+ jQuery.Tween = Tween;
6939
+
6940
+ Tween.prototype = {
6941
+ constructor: Tween,
6942
+ init: function( elem, options, prop, end, easing, unit ) {
6943
+ this.elem = elem;
6944
+ this.prop = prop;
6945
+ this.easing = easing || "swing";
6946
+ this.options = options;
6947
+ this.start = this.now = this.cur();
6948
+ this.end = end;
6949
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6950
+ },
6951
+ cur: function() {
6952
+ var hooks = Tween.propHooks[ this.prop ];
6953
+
6954
+ return hooks && hooks.get ?
6955
+ hooks.get( this ) :
6956
+ Tween.propHooks._default.get( this );
6957
+ },
6958
+ run: function( percent ) {
6959
+ var eased,
6960
+ hooks = Tween.propHooks[ this.prop ];
6961
+
6962
+ if ( this.options.duration ) {
6963
+ this.pos = eased = jQuery.easing[ this.easing ](
6964
+ percent, this.options.duration * percent, 0, 1, this.options.duration
6965
+ );
6966
+ } else {
6967
+ this.pos = eased = percent;
6968
+ }
6969
+ this.now = ( this.end - this.start ) * eased + this.start;
6970
+
6971
+ if ( this.options.step ) {
6972
+ this.options.step.call( this.elem, this.now, this );
6973
+ }
6974
+
6975
+ if ( hooks && hooks.set ) {
6976
+ hooks.set( this );
6977
+ } else {
6978
+ Tween.propHooks._default.set( this );
6979
+ }
6980
+ return this;
6981
+ }
6982
+ };
6983
+
6984
+ Tween.prototype.init.prototype = Tween.prototype;
6985
+
6986
+ Tween.propHooks = {
6987
+ _default: {
6988
+ get: function( tween ) {
6989
+ var result;
6990
+
6991
+ if ( tween.elem[ tween.prop ] != null &&
6992
+ (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6993
+ return tween.elem[ tween.prop ];
6994
+ }
6995
+
6996
+ // passing an empty string as a 3rd parameter to .css will automatically
6997
+ // attempt a parseFloat and fallback to a string if the parse fails
6998
+ // so, simple values such as "10px" are parsed to Float.
6999
+ // complex values such as "rotate(1rad)" are returned as is.
7000
+ result = jQuery.css( tween.elem, tween.prop, "" );
7001
+ // Empty strings, null, undefined and "auto" are converted to 0.
7002
+ return !result || result === "auto" ? 0 : result;
7003
+ },
7004
+ set: function( tween ) {
7005
+ // use step hook for back compat - use cssHook if its there - use .style if its
7006
+ // available and use plain properties where available
7007
+ if ( jQuery.fx.step[ tween.prop ] ) {
7008
+ jQuery.fx.step[ tween.prop ]( tween );
7009
+ } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
7010
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7011
+ } else {
7012
+ tween.elem[ tween.prop ] = tween.now;
7013
+ }
7014
+ }
7015
+ }
7016
+ };
7017
+
7018
+ // Support: IE <=9
7019
+ // Panic based approach to setting things on disconnected nodes
7020
+
7021
+ Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7022
+ set: function( tween ) {
7023
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
7024
+ tween.elem[ tween.prop ] = tween.now;
7025
+ }
7026
+ }
7027
+ };
7028
+
7029
+ jQuery.easing = {
7030
+ linear: function( p ) {
7031
+ return p;
7032
+ },
7033
+ swing: function( p ) {
7034
+ return 0.5 - Math.cos( p * Math.PI ) / 2;
7035
+ }
7036
+ };
7037
+
7038
+ jQuery.fx = Tween.prototype.init;
7039
+
7040
+ // Back Compat <1.8 extension point
7041
+ jQuery.fx.step = {};
7042
+
7043
+
7044
+
7045
+
7046
+ var
7047
+ fxNow, timerId,
7048
+ rfxtypes = /^(?:toggle|show|hide)$/,
7049
+ rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
7050
+ rrun = /queueHooks$/,
7051
+ animationPrefilters = [ defaultPrefilter ],
7052
+ tweeners = {
7053
+ "*": [ function( prop, value ) {
7054
+ var tween = this.createTween( prop, value ),
7055
+ target = tween.cur(),
7056
+ parts = rfxnum.exec( value ),
7057
+ unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
7058
+
7059
+ // Starting value computation is required for potential unit mismatches
7060
+ start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
7061
+ rfxnum.exec( jQuery.css( tween.elem, prop ) ),
7062
+ scale = 1,
7063
+ maxIterations = 20;
7064
+
7065
+ if ( start && start[ 3 ] !== unit ) {
7066
+ // Trust units reported by jQuery.css
7067
+ unit = unit || start[ 3 ];
7068
+
7069
+ // Make sure we update the tween properties later on
7070
+ parts = parts || [];
7071
+
7072
+ // Iteratively approximate from a nonzero starting point
7073
+ start = +target || 1;
7074
+
7075
+ do {
7076
+ // If previous iteration zeroed out, double until we get *something*
7077
+ // Use a string for doubling factor so we don't accidentally see scale as unchanged below
7078
+ scale = scale || ".5";
7079
+
7080
+ // Adjust and apply
7081
+ start = start / scale;
7082
+ jQuery.style( tween.elem, prop, start + unit );
7083
+
7084
+ // Update scale, tolerating zero or NaN from tween.cur()
7085
+ // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
7086
+ } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
7087
+ }
7088
+
7089
+ // Update tween properties
7090
+ if ( parts ) {
7091
+ start = tween.start = +start || +target || 0;
7092
+ tween.unit = unit;
7093
+ // If a +=/-= token was provided, we're doing a relative animation
7094
+ tween.end = parts[ 1 ] ?
7095
+ start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
7096
+ +parts[ 2 ];
7097
+ }
7098
+
7099
+ return tween;
7100
+ } ]
7101
+ };
7102
+
7103
+ // Animations created synchronously will run synchronously
7104
+ function createFxNow() {
7105
+ setTimeout(function() {
7106
+ fxNow = undefined;
7107
+ });
7108
+ return ( fxNow = jQuery.now() );
7109
+ }
7110
+
7111
+ // Generate parameters to create a standard animation
7112
+ function genFx( type, includeWidth ) {
7113
+ var which,
7114
+ attrs = { height: type },
7115
+ i = 0;
7116
+
7117
+ // if we include width, step value is 1 to do all cssExpand values,
7118
+ // if we don't include width, step value is 2 to skip over Left and Right
7119
+ includeWidth = includeWidth ? 1 : 0;
7120
+ for ( ; i < 4 ; i += 2 - includeWidth ) {
7121
+ which = cssExpand[ i ];
7122
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7123
+ }
7124
+
7125
+ if ( includeWidth ) {
7126
+ attrs.opacity = attrs.width = type;
7127
+ }
7128
+
7129
+ return attrs;
7130
+ }
7131
+
7132
+ function createTween( value, prop, animation ) {
7133
+ var tween,
7134
+ collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
7135
+ index = 0,
7136
+ length = collection.length;
7137
+ for ( ; index < length; index++ ) {
7138
+ if ( (tween = collection[ index ].call( animation, prop, value )) ) {
7139
+
7140
+ // we're done with this property
7141
+ return tween;
7142
+ }
7143
+ }
7144
+ }
7145
+
7146
+ function defaultPrefilter( elem, props, opts ) {
7147
+ /* jshint validthis: true */
7148
+ var prop, value, toggle, tween, hooks, oldfire, display, dDisplay,
7149
+ anim = this,
7150
+ orig = {},
7151
+ style = elem.style,
7152
+ hidden = elem.nodeType && isHidden( elem ),
7153
+ dataShow = jQuery._data( elem, "fxshow" );
7154
+
7155
+ // handle queue: false promises
7156
+ if ( !opts.queue ) {
7157
+ hooks = jQuery._queueHooks( elem, "fx" );
7158
+ if ( hooks.unqueued == null ) {
7159
+ hooks.unqueued = 0;
7160
+ oldfire = hooks.empty.fire;
7161
+ hooks.empty.fire = function() {
7162
+ if ( !hooks.unqueued ) {
7163
+ oldfire();
7164
+ }
7165
+ };
7166
+ }
7167
+ hooks.unqueued++;
7168
+
7169
+ anim.always(function() {
7170
+ // doing this makes sure that the complete handler will be called
7171
+ // before this completes
7172
+ anim.always(function() {
7173
+ hooks.unqueued--;
7174
+ if ( !jQuery.queue( elem, "fx" ).length ) {
7175
+ hooks.empty.fire();
7176
+ }
7177
+ });
7178
+ });
7179
+ }
7180
+
7181
+ // height/width overflow pass
7182
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7183
+ // Make sure that nothing sneaks out
7184
+ // Record all 3 overflow attributes because IE does not
7185
+ // change the overflow attribute when overflowX and
7186
+ // overflowY are set to the same value
7187
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7188
+
7189
+ // Set display property to inline-block for height/width
7190
+ // animations on inline elements that are having width/height animated
7191
+ display = jQuery.css( elem, "display" );
7192
+ dDisplay = defaultDisplay( elem.nodeName );
7193
+ if ( display === "none" ) {
7194
+ display = dDisplay;
7195
+ }
7196
+ if ( display === "inline" &&
7197
+ jQuery.css( elem, "float" ) === "none" ) {
7198
+
7199
+ // inline-level elements accept inline-block;
7200
+ // block-level elements need to be inline with layout
7201
+ if ( !support.inlineBlockNeedsLayout || dDisplay === "inline" ) {
7202
+ style.display = "inline-block";
7203
+ } else {
7204
+ style.zoom = 1;
7205
+ }
7206
+ }
7207
+ }
7208
+
7209
+ if ( opts.overflow ) {
7210
+ style.overflow = "hidden";
7211
+ if ( !support.shrinkWrapBlocks() ) {
7212
+ anim.always(function() {
7213
+ style.overflow = opts.overflow[ 0 ];
7214
+ style.overflowX = opts.overflow[ 1 ];
7215
+ style.overflowY = opts.overflow[ 2 ];
7216
+ });
7217
+ }
7218
+ }
7219
+
7220
+ // show/hide pass
7221
+ for ( prop in props ) {
7222
+ value = props[ prop ];
7223
+ if ( rfxtypes.exec( value ) ) {
7224
+ delete props[ prop ];
7225
+ toggle = toggle || value === "toggle";
7226
+ if ( value === ( hidden ? "hide" : "show" ) ) {
7227
+
7228
+ // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
7229
+ if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7230
+ hidden = true;
7231
+ } else {
7232
+ continue;
7233
+ }
7234
+ }
7235
+ orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7236
+ }
7237
+ }
7238
+
7239
+ if ( !jQuery.isEmptyObject( orig ) ) {
7240
+ if ( dataShow ) {
7241
+ if ( "hidden" in dataShow ) {
7242
+ hidden = dataShow.hidden;
7243
+ }
7244
+ } else {
7245
+ dataShow = jQuery._data( elem, "fxshow", {} );
7246
+ }
7247
+
7248
+ // store state if its toggle - enables .stop().toggle() to "reverse"
7249
+ if ( toggle ) {
7250
+ dataShow.hidden = !hidden;
7251
+ }
7252
+ if ( hidden ) {
7253
+ jQuery( elem ).show();
7254
+ } else {
7255
+ anim.done(function() {
7256
+ jQuery( elem ).hide();
7257
+ });
7258
+ }
7259
+ anim.done(function() {
7260
+ var prop;
7261
+ jQuery._removeData( elem, "fxshow" );
7262
+ for ( prop in orig ) {
7263
+ jQuery.style( elem, prop, orig[ prop ] );
7264
+ }
7265
+ });
7266
+ for ( prop in orig ) {
7267
+ tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7268
+
7269
+ if ( !( prop in dataShow ) ) {
7270
+ dataShow[ prop ] = tween.start;
7271
+ if ( hidden ) {
7272
+ tween.end = tween.start;
7273
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
7274
+ }
7275
+ }
7276
+ }
7277
+ }
7278
+ }
7279
+
7280
+ function propFilter( props, specialEasing ) {
7281
+ var index, name, easing, value, hooks;
7282
+
7283
+ // camelCase, specialEasing and expand cssHook pass
7284
+ for ( index in props ) {
7285
+ name = jQuery.camelCase( index );
7286
+ easing = specialEasing[ name ];
7287
+ value = props[ index ];
7288
+ if ( jQuery.isArray( value ) ) {
7289
+ easing = value[ 1 ];
7290
+ value = props[ index ] = value[ 0 ];
7291
+ }
7292
+
7293
+ if ( index !== name ) {
7294
+ props[ name ] = value;
7295
+ delete props[ index ];
7296
+ }
7297
+
7298
+ hooks = jQuery.cssHooks[ name ];
7299
+ if ( hooks && "expand" in hooks ) {
7300
+ value = hooks.expand( value );
7301
+ delete props[ name ];
7302
+
7303
+ // not quite $.extend, this wont overwrite keys already present.
7304
+ // also - reusing 'index' from above because we have the correct "name"
7305
+ for ( index in value ) {
7306
+ if ( !( index in props ) ) {
7307
+ props[ index ] = value[ index ];
7308
+ specialEasing[ index ] = easing;
7309
+ }
7310
+ }
7311
+ } else {
7312
+ specialEasing[ name ] = easing;
7313
+ }
7314
+ }
7315
+ }
7316
+
7317
+ function Animation( elem, properties, options ) {
7318
+ var result,
7319
+ stopped,
7320
+ index = 0,
7321
+ length = animationPrefilters.length,
7322
+ deferred = jQuery.Deferred().always( function() {
7323
+ // don't match elem in the :animated selector
7324
+ delete tick.elem;
7325
+ }),
7326
+ tick = function() {
7327
+ if ( stopped ) {
7328
+ return false;
7329
+ }
7330
+ var currentTime = fxNow || createFxNow(),
7331
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7332
+ // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
7333
+ temp = remaining / animation.duration || 0,
7334
+ percent = 1 - temp,
7335
+ index = 0,
7336
+ length = animation.tweens.length;
7337
+
7338
+ for ( ; index < length ; index++ ) {
7339
+ animation.tweens[ index ].run( percent );
7340
+ }
7341
+
7342
+ deferred.notifyWith( elem, [ animation, percent, remaining ]);
7343
+
7344
+ if ( percent < 1 && length ) {
7345
+ return remaining;
7346
+ } else {
7347
+ deferred.resolveWith( elem, [ animation ] );
7348
+ return false;
7349
+ }
7350
+ },
7351
+ animation = deferred.promise({
7352
+ elem: elem,
7353
+ props: jQuery.extend( {}, properties ),
7354
+ opts: jQuery.extend( true, { specialEasing: {} }, options ),
7355
+ originalProperties: properties,
7356
+ originalOptions: options,
7357
+ startTime: fxNow || createFxNow(),
7358
+ duration: options.duration,
7359
+ tweens: [],
7360
+ createTween: function( prop, end ) {
7361
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
7362
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
7363
+ animation.tweens.push( tween );
7364
+ return tween;
7365
+ },
7366
+ stop: function( gotoEnd ) {
7367
+ var index = 0,
7368
+ // if we are going to the end, we want to run all the tweens
7369
+ // otherwise we skip this part
7370
+ length = gotoEnd ? animation.tweens.length : 0;
7371
+ if ( stopped ) {
7372
+ return this;
7373
+ }
7374
+ stopped = true;
7375
+ for ( ; index < length ; index++ ) {
7376
+ animation.tweens[ index ].run( 1 );
7377
+ }
7378
+
7379
+ // resolve when we played the last frame
7380
+ // otherwise, reject
7381
+ if ( gotoEnd ) {
7382
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
7383
+ } else {
7384
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
7385
+ }
7386
+ return this;
7387
+ }
7388
+ }),
7389
+ props = animation.props;
7390
+
7391
+ propFilter( props, animation.opts.specialEasing );
7392
+
7393
+ for ( ; index < length ; index++ ) {
7394
+ result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
7395
+ if ( result ) {
7396
+ return result;
7397
+ }
7398
+ }
7399
+
7400
+ jQuery.map( props, createTween, animation );
7401
+
7402
+ if ( jQuery.isFunction( animation.opts.start ) ) {
7403
+ animation.opts.start.call( elem, animation );
7404
+ }
7405
+
7406
+ jQuery.fx.timer(
7407
+ jQuery.extend( tick, {
7408
+ elem: elem,
7409
+ anim: animation,
7410
+ queue: animation.opts.queue
7411
+ })
7412
+ );
7413
+
7414
+ // attach callbacks from options
7415
+ return animation.progress( animation.opts.progress )
7416
+ .done( animation.opts.done, animation.opts.complete )
7417
+ .fail( animation.opts.fail )
7418
+ .always( animation.opts.always );
7419
+ }
7420
+
7421
+ jQuery.Animation = jQuery.extend( Animation, {
7422
+ tweener: function( props, callback ) {
7423
+ if ( jQuery.isFunction( props ) ) {
7424
+ callback = props;
7425
+ props = [ "*" ];
7426
+ } else {
7427
+ props = props.split(" ");
7428
+ }
7429
+
7430
+ var prop,
7431
+ index = 0,
7432
+ length = props.length;
7433
+
7434
+ for ( ; index < length ; index++ ) {
7435
+ prop = props[ index ];
7436
+ tweeners[ prop ] = tweeners[ prop ] || [];
7437
+ tweeners[ prop ].unshift( callback );
7438
+ }
7439
+ },
7440
+
7441
+ prefilter: function( callback, prepend ) {
7442
+ if ( prepend ) {
7443
+ animationPrefilters.unshift( callback );
7444
+ } else {
7445
+ animationPrefilters.push( callback );
7446
+ }
7447
+ }
7448
+ });
7449
+
7450
+ jQuery.speed = function( speed, easing, fn ) {
7451
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7452
+ complete: fn || !fn && easing ||
7453
+ jQuery.isFunction( speed ) && speed,
7454
+ duration: speed,
7455
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7456
+ };
7457
+
7458
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7459
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7460
+
7461
+ // normalize opt.queue - true/undefined/null -> "fx"
7462
+ if ( opt.queue == null || opt.queue === true ) {
7463
+ opt.queue = "fx";
7464
+ }
7465
+
7466
+ // Queueing
7467
+ opt.old = opt.complete;
7468
+
7469
+ opt.complete = function() {
7470
+ if ( jQuery.isFunction( opt.old ) ) {
7471
+ opt.old.call( this );
7472
+ }
7473
+
7474
+ if ( opt.queue ) {
7475
+ jQuery.dequeue( this, opt.queue );
7476
+ }
7477
+ };
7478
+
7479
+ return opt;
7480
+ };
7481
+
7482
+ jQuery.fn.extend({
7483
+ fadeTo: function( speed, to, easing, callback ) {
7484
+
7485
+ // show any hidden elements after setting opacity to 0
7486
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
7487
+
7488
+ // animate to the value specified
7489
+ .end().animate({ opacity: to }, speed, easing, callback );
7490
+ },
7491
+ animate: function( prop, speed, easing, callback ) {
7492
+ var empty = jQuery.isEmptyObject( prop ),
7493
+ optall = jQuery.speed( speed, easing, callback ),
7494
+ doAnimation = function() {
7495
+ // Operate on a copy of prop so per-property easing won't be lost
7496
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7497
+
7498
+ // Empty animations, or finishing resolves immediately
7499
+ if ( empty || jQuery._data( this, "finish" ) ) {
7500
+ anim.stop( true );
7501
+ }
7502
+ };
7503
+ doAnimation.finish = doAnimation;
7504
+
7505
+ return empty || optall.queue === false ?
7506
+ this.each( doAnimation ) :
7507
+ this.queue( optall.queue, doAnimation );
7508
+ },
7509
+ stop: function( type, clearQueue, gotoEnd ) {
7510
+ var stopQueue = function( hooks ) {
7511
+ var stop = hooks.stop;
7512
+ delete hooks.stop;
7513
+ stop( gotoEnd );
7514
+ };
7515
+
7516
+ if ( typeof type !== "string" ) {
7517
+ gotoEnd = clearQueue;
7518
+ clearQueue = type;
7519
+ type = undefined;
7520
+ }
7521
+ if ( clearQueue && type !== false ) {
7522
+ this.queue( type || "fx", [] );
7523
+ }
7524
+
7525
+ return this.each(function() {
7526
+ var dequeue = true,
7527
+ index = type != null && type + "queueHooks",
7528
+ timers = jQuery.timers,
7529
+ data = jQuery._data( this );
7530
+
7531
+ if ( index ) {
7532
+ if ( data[ index ] && data[ index ].stop ) {
7533
+ stopQueue( data[ index ] );
7534
+ }
7535
+ } else {
7536
+ for ( index in data ) {
7537
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7538
+ stopQueue( data[ index ] );
7539
+ }
7540
+ }
7541
+ }
7542
+
7543
+ for ( index = timers.length; index--; ) {
7544
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
7545
+ timers[ index ].anim.stop( gotoEnd );
7546
+ dequeue = false;
7547
+ timers.splice( index, 1 );
7548
+ }
7549
+ }
7550
+
7551
+ // start the next in the queue if the last step wasn't forced
7552
+ // timers currently will call their complete callbacks, which will dequeue
7553
+ // but only if they were gotoEnd
7554
+ if ( dequeue || !gotoEnd ) {
7555
+ jQuery.dequeue( this, type );
7556
+ }
7557
+ });
7558
+ },
7559
+ finish: function( type ) {
7560
+ if ( type !== false ) {
7561
+ type = type || "fx";
7562
+ }
7563
+ return this.each(function() {
7564
+ var index,
7565
+ data = jQuery._data( this ),
7566
+ queue = data[ type + "queue" ],
7567
+ hooks = data[ type + "queueHooks" ],
7568
+ timers = jQuery.timers,
7569
+ length = queue ? queue.length : 0;
7570
+
7571
+ // enable finishing flag on private data
7572
+ data.finish = true;
7573
+
7574
+ // empty the queue first
7575
+ jQuery.queue( this, type, [] );
7576
+
7577
+ if ( hooks && hooks.stop ) {
7578
+ hooks.stop.call( this, true );
7579
+ }
7580
+
7581
+ // look for any active animations, and finish them
7582
+ for ( index = timers.length; index--; ) {
7583
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7584
+ timers[ index ].anim.stop( true );
7585
+ timers.splice( index, 1 );
7586
+ }
7587
+ }
7588
+
7589
+ // look for any animations in the old queue and finish them
7590
+ for ( index = 0; index < length; index++ ) {
7591
+ if ( queue[ index ] && queue[ index ].finish ) {
7592
+ queue[ index ].finish.call( this );
7593
+ }
7594
+ }
7595
+
7596
+ // turn off finishing flag
7597
+ delete data.finish;
7598
+ });
7599
+ }
7600
+ });
7601
+
7602
+ jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
7603
+ var cssFn = jQuery.fn[ name ];
7604
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
7605
+ return speed == null || typeof speed === "boolean" ?
7606
+ cssFn.apply( this, arguments ) :
7607
+ this.animate( genFx( name, true ), speed, easing, callback );
7608
+ };
7609
+ });
7610
+
7611
+ // Generate shortcuts for custom animations
7612
+ jQuery.each({
7613
+ slideDown: genFx("show"),
7614
+ slideUp: genFx("hide"),
7615
+ slideToggle: genFx("toggle"),
7616
+ fadeIn: { opacity: "show" },
7617
+ fadeOut: { opacity: "hide" },
7618
+ fadeToggle: { opacity: "toggle" }
7619
+ }, function( name, props ) {
7620
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
7621
+ return this.animate( props, speed, easing, callback );
7622
+ };
7623
+ });
7624
+
7625
+ jQuery.timers = [];
7626
+ jQuery.fx.tick = function() {
7627
+ var timer,
7628
+ timers = jQuery.timers,
7629
+ i = 0;
7630
+
7631
+ fxNow = jQuery.now();
7632
+
7633
+ for ( ; i < timers.length; i++ ) {
7634
+ timer = timers[ i ];
7635
+ // Checks the timer has not already been removed
7636
+ if ( !timer() && timers[ i ] === timer ) {
7637
+ timers.splice( i--, 1 );
7638
+ }
7639
+ }
7640
+
7641
+ if ( !timers.length ) {
7642
+ jQuery.fx.stop();
7643
+ }
7644
+ fxNow = undefined;
7645
+ };
7646
+
7647
+ jQuery.fx.timer = function( timer ) {
7648
+ jQuery.timers.push( timer );
7649
+ if ( timer() ) {
7650
+ jQuery.fx.start();
7651
+ } else {
7652
+ jQuery.timers.pop();
7653
+ }
7654
+ };
7655
+
7656
+ jQuery.fx.interval = 13;
7657
+
7658
+ jQuery.fx.start = function() {
7659
+ if ( !timerId ) {
7660
+ timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
7661
+ }
7662
+ };
7663
+
7664
+ jQuery.fx.stop = function() {
7665
+ clearInterval( timerId );
7666
+ timerId = null;
7667
+ };
7668
+
7669
+ jQuery.fx.speeds = {
7670
+ slow: 600,
7671
+ fast: 200,
7672
+ // Default speed
7673
+ _default: 400
7674
+ };
7675
+
7676
+
7677
+ // Based off of the plugin by Clint Helfers, with permission.
7678
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
7679
+ jQuery.fn.delay = function( time, type ) {
7680
+ time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7681
+ type = type || "fx";
7682
+
7683
+ return this.queue( type, function( next, hooks ) {
7684
+ var timeout = setTimeout( next, time );
7685
+ hooks.stop = function() {
7686
+ clearTimeout( timeout );
7687
+ };
7688
+ });
7689
+ };
7690
+
7691
+
7692
+ (function() {
7693
+ var a, input, select, opt,
7694
+ div = document.createElement("div" );
7695
+
7696
+ // Setup
7697
+ div.setAttribute( "className", "t" );
7698
+ div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
7699
+ a = div.getElementsByTagName("a")[ 0 ];
7700
+
7701
+ // First batch of tests.
7702
+ select = document.createElement("select");
7703
+ opt = select.appendChild( document.createElement("option") );
7704
+ input = div.getElementsByTagName("input")[ 0 ];
7705
+
7706
+ a.style.cssText = "top:1px";
7707
+
7708
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
7709
+ support.getSetAttribute = div.className !== "t";
7710
+
7711
+ // Get the style information from getAttribute
7712
+ // (IE uses .cssText instead)
7713
+ support.style = /top/.test( a.getAttribute("style") );
7714
+
7715
+ // Make sure that URLs aren't manipulated
7716
+ // (IE normalizes it by default)
7717
+ support.hrefNormalized = a.getAttribute("href") === "/a";
7718
+
7719
+ // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
7720
+ support.checkOn = !!input.value;
7721
+
7722
+ // Make sure that a selected-by-default option has a working selected property.
7723
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
7724
+ support.optSelected = opt.selected;
7725
+
7726
+ // Tests for enctype support on a form (#6743)
7727
+ support.enctype = !!document.createElement("form").enctype;
7728
+
7729
+ // Make sure that the options inside disabled selects aren't marked as disabled
7730
+ // (WebKit marks them as disabled)
7731
+ select.disabled = true;
7732
+ support.optDisabled = !opt.disabled;
7733
+
7734
+ // Support: IE8 only
7735
+ // Check if we can trust getAttribute("value")
7736
+ input = document.createElement( "input" );
7737
+ input.setAttribute( "value", "" );
7738
+ support.input = input.getAttribute( "value" ) === "";
7739
+
7740
+ // Check if an input maintains its value after becoming a radio
7741
+ input.value = "t";
7742
+ input.setAttribute( "type", "radio" );
7743
+ support.radioValue = input.value === "t";
7744
+
7745
+ // Null elements to avoid leaks in IE.
7746
+ a = input = select = opt = div = null;
7747
+ })();
7748
+
7749
+
7750
+ var rreturn = /\r/g;
7751
+
7752
+ jQuery.fn.extend({
7753
+ val: function( value ) {
7754
+ var hooks, ret, isFunction,
7755
+ elem = this[0];
7756
+
7757
+ if ( !arguments.length ) {
7758
+ if ( elem ) {
7759
+ hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7760
+
7761
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7762
+ return ret;
7763
+ }
7764
+
7765
+ ret = elem.value;
7766
+
7767
+ return typeof ret === "string" ?
7768
+ // handle most common string cases
7769
+ ret.replace(rreturn, "") :
7770
+ // handle cases where value is null/undef or number
7771
+ ret == null ? "" : ret;
7772
+ }
7773
+
7774
+ return;
7775
+ }
7776
+
7777
+ isFunction = jQuery.isFunction( value );
7778
+
7779
+ return this.each(function( i ) {
7780
+ var val;
7781
+
7782
+ if ( this.nodeType !== 1 ) {
7783
+ return;
7784
+ }
7785
+
7786
+ if ( isFunction ) {
7787
+ val = value.call( this, i, jQuery( this ).val() );
7788
+ } else {
7789
+ val = value;
7790
+ }
7791
+
7792
+ // Treat null/undefined as ""; convert numbers to string
7793
+ if ( val == null ) {
7794
+ val = "";
7795
+ } else if ( typeof val === "number" ) {
7796
+ val += "";
7797
+ } else if ( jQuery.isArray( val ) ) {
7798
+ val = jQuery.map( val, function( value ) {
7799
+ return value == null ? "" : value + "";
7800
+ });
7801
+ }
7802
+
7803
+ hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7804
+
7805
+ // If set returns undefined, fall back to normal setting
7806
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7807
+ this.value = val;
7808
+ }
7809
+ });
7810
+ }
7811
+ });
7812
+
7813
+ jQuery.extend({
7814
+ valHooks: {
7815
+ option: {
7816
+ get: function( elem ) {
7817
+ var val = jQuery.find.attr( elem, "value" );
7818
+ return val != null ?
7819
+ val :
7820
+ jQuery.text( elem );
7821
+ }
7822
+ },
7823
+ select: {
7824
+ get: function( elem ) {
7825
+ var value, option,
7826
+ options = elem.options,
7827
+ index = elem.selectedIndex,
7828
+ one = elem.type === "select-one" || index < 0,
7829
+ values = one ? null : [],
7830
+ max = one ? index + 1 : options.length,
7831
+ i = index < 0 ?
7832
+ max :
7833
+ one ? index : 0;
7834
+
7835
+ // Loop through all the selected options
7836
+ for ( ; i < max; i++ ) {
7837
+ option = options[ i ];
7838
+
7839
+ // oldIE doesn't update selected after form reset (#2551)
7840
+ if ( ( option.selected || i === index ) &&
7841
+ // Don't return options that are disabled or in a disabled optgroup
7842
+ ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
7843
+ ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7844
+
7845
+ // Get the specific value for the option
7846
+ value = jQuery( option ).val();
7847
+
7848
+ // We don't need an array for one selects
7849
+ if ( one ) {
7850
+ return value;
7851
+ }
7852
+
7853
+ // Multi-Selects return an array
7854
+ values.push( value );
7855
+ }
7856
+ }
7857
+
7858
+ return values;
7859
+ },
7860
+
7861
+ set: function( elem, value ) {
7862
+ var optionSet, option,
7863
+ options = elem.options,
7864
+ values = jQuery.makeArray( value ),
7865
+ i = options.length;
7866
+
7867
+ while ( i-- ) {
7868
+ option = options[ i ];
7869
+
7870
+ if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
7871
+
7872
+ // Support: IE6
7873
+ // When new option element is added to select box we need to
7874
+ // force reflow of newly added node in order to workaround delay
7875
+ // of initialization properties
7876
+ try {
7877
+ option.selected = optionSet = true;
7878
+
7879
+ } catch ( _ ) {
7880
+
7881
+ // Will be executed only in IE6
7882
+ option.scrollHeight;
7883
+ }
7884
+
7885
+ } else {
7886
+ option.selected = false;
7887
+ }
7888
+ }
7889
+
7890
+ // Force browsers to behave consistently when non-matching value is set
7891
+ if ( !optionSet ) {
7892
+ elem.selectedIndex = -1;
7893
+ }
7894
+
7895
+ return options;
7896
+ }
7897
+ }
7898
+ }
7899
+ });
7900
+
7901
+ // Radios and checkboxes getter/setter
7902
+ jQuery.each([ "radio", "checkbox" ], function() {
7903
+ jQuery.valHooks[ this ] = {
7904
+ set: function( elem, value ) {
7905
+ if ( jQuery.isArray( value ) ) {
7906
+ return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7907
+ }
7908
+ }
7909
+ };
7910
+ if ( !support.checkOn ) {
7911
+ jQuery.valHooks[ this ].get = function( elem ) {
7912
+ // Support: Webkit
7913
+ // "" is returned instead of "on" if a value isn't specified
7914
+ return elem.getAttribute("value") === null ? "on" : elem.value;
7915
+ };
7916
+ }
7917
+ });
7918
+
7919
+
7920
+
7921
+
7922
+ var nodeHook, boolHook,
7923
+ attrHandle = jQuery.expr.attrHandle,
7924
+ ruseDefault = /^(?:checked|selected)$/i,
7925
+ getSetAttribute = support.getSetAttribute,
7926
+ getSetInput = support.input;
7927
+
7928
+ jQuery.fn.extend({
7929
+ attr: function( name, value ) {
7930
+ return access( this, jQuery.attr, name, value, arguments.length > 1 );
7931
+ },
7932
+
7933
+ removeAttr: function( name ) {
7934
+ return this.each(function() {
7935
+ jQuery.removeAttr( this, name );
7936
+ });
7937
+ }
7938
+ });
7939
+
7940
+ jQuery.extend({
7941
+ attr: function( elem, name, value ) {
7942
+ var hooks, ret,
7943
+ nType = elem.nodeType;
7944
+
7945
+ // don't get/set attributes on text, comment and attribute nodes
7946
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7947
+ return;
7948
+ }
7949
+
7950
+ // Fallback to prop when attributes are not supported
7951
+ if ( typeof elem.getAttribute === strundefined ) {
7952
+ return jQuery.prop( elem, name, value );
7953
+ }
7954
+
7955
+ // All attributes are lowercase
7956
+ // Grab necessary hook if one is defined
7957
+ if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7958
+ name = name.toLowerCase();
7959
+ hooks = jQuery.attrHooks[ name ] ||
7960
+ ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
7961
+ }
7962
+
7963
+ if ( value !== undefined ) {
7964
+
7965
+ if ( value === null ) {
7966
+ jQuery.removeAttr( elem, name );
7967
+
7968
+ } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
7969
+ return ret;
7970
+
7971
+ } else {
7972
+ elem.setAttribute( name, value + "" );
7973
+ return value;
7974
+ }
7975
+
7976
+ } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
7977
+ return ret;
7978
+
7979
+ } else {
7980
+ ret = jQuery.find.attr( elem, name );
7981
+
7982
+ // Non-existent attributes return null, we normalize to undefined
7983
+ return ret == null ?
7984
+ undefined :
7985
+ ret;
7986
+ }
7987
+ },
7988
+
7989
+ removeAttr: function( elem, value ) {
7990
+ var name, propName,
7991
+ i = 0,
7992
+ attrNames = value && value.match( rnotwhite );
7993
+
7994
+ if ( attrNames && elem.nodeType === 1 ) {
7995
+ while ( (name = attrNames[i++]) ) {
7996
+ propName = jQuery.propFix[ name ] || name;
7997
+
7998
+ // Boolean attributes get special treatment (#10870)
7999
+ if ( jQuery.expr.match.bool.test( name ) ) {
8000
+ // Set corresponding property to false
8001
+ if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8002
+ elem[ propName ] = false;
8003
+ // Support: IE<9
8004
+ // Also clear defaultChecked/defaultSelected (if appropriate)
8005
+ } else {
8006
+ elem[ jQuery.camelCase( "default-" + name ) ] =
8007
+ elem[ propName ] = false;
8008
+ }
8009
+
8010
+ // See #9699 for explanation of this approach (setting first, then removal)
8011
+ } else {
8012
+ jQuery.attr( elem, name, "" );
8013
+ }
8014
+
8015
+ elem.removeAttribute( getSetAttribute ? name : propName );
8016
+ }
8017
+ }
8018
+ },
8019
+
8020
+ attrHooks: {
8021
+ type: {
8022
+ set: function( elem, value ) {
8023
+ if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
8024
+ // Setting the type on a radio button after the value resets the value in IE6-9
8025
+ // Reset value to default in case type is set after value during creation
8026
+ var val = elem.value;
8027
+ elem.setAttribute( "type", value );
8028
+ if ( val ) {
8029
+ elem.value = val;
8030
+ }
8031
+ return value;
8032
+ }
8033
+ }
8034
+ }
8035
+ }
8036
+ });
8037
+
8038
+ // Hook for boolean attributes
8039
+ boolHook = {
8040
+ set: function( elem, value, name ) {
8041
+ if ( value === false ) {
8042
+ // Remove boolean attributes when set to false
8043
+ jQuery.removeAttr( elem, name );
8044
+ } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8045
+ // IE<8 needs the *property* name
8046
+ elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8047
+
8048
+ // Use defaultChecked and defaultSelected for oldIE
8049
+ } else {
8050
+ elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8051
+ }
8052
+
8053
+ return name;
8054
+ }
8055
+ };
8056
+
8057
+ // Retrieve booleans specially
8058
+ jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8059
+
8060
+ var getter = attrHandle[ name ] || jQuery.find.attr;
8061
+
8062
+ attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
8063
+ function( elem, name, isXML ) {
8064
+ var ret, handle;
8065
+ if ( !isXML ) {
8066
+ // Avoid an infinite loop by temporarily removing this function from the getter
8067
+ handle = attrHandle[ name ];
8068
+ attrHandle[ name ] = ret;
8069
+ ret = getter( elem, name, isXML ) != null ?
8070
+ name.toLowerCase() :
8071
+ null;
8072
+ attrHandle[ name ] = handle;
8073
+ }
8074
+ return ret;
8075
+ } :
8076
+ function( elem, name, isXML ) {
8077
+ if ( !isXML ) {
8078
+ return elem[ jQuery.camelCase( "default-" + name ) ] ?
8079
+ name.toLowerCase() :
8080
+ null;
8081
+ }
8082
+ };
8083
+ });
8084
+
8085
+ // fix oldIE attroperties
8086
+ if ( !getSetInput || !getSetAttribute ) {
8087
+ jQuery.attrHooks.value = {
8088
+ set: function( elem, value, name ) {
8089
+ if ( jQuery.nodeName( elem, "input" ) ) {
8090
+ // Does not return so that setAttribute is also used
8091
+ elem.defaultValue = value;
8092
+ } else {
8093
+ // Use nodeHook if defined (#1954); otherwise setAttribute is fine
8094
+ return nodeHook && nodeHook.set( elem, value, name );
8095
+ }
8096
+ }
8097
+ };
8098
+ }
8099
+
8100
+ // IE6/7 do not support getting/setting some attributes with get/setAttribute
8101
+ if ( !getSetAttribute ) {
8102
+
8103
+ // Use this for any attribute in IE6/7
8104
+ // This fixes almost every IE6/7 issue
8105
+ nodeHook = {
8106
+ set: function( elem, value, name ) {
8107
+ // Set the existing or create a new attribute node
8108
+ var ret = elem.getAttributeNode( name );
8109
+ if ( !ret ) {
8110
+ elem.setAttributeNode(
8111
+ (ret = elem.ownerDocument.createAttribute( name ))
8112
+ );
8113
+ }
8114
+
8115
+ ret.value = value += "";
8116
+
8117
+ // Break association with cloned elements by also using setAttribute (#9646)
8118
+ if ( name === "value" || value === elem.getAttribute( name ) ) {
8119
+ return value;
8120
+ }
8121
+ }
8122
+ };
8123
+
8124
+ // Some attributes are constructed with empty-string values when not defined
8125
+ attrHandle.id = attrHandle.name = attrHandle.coords =
8126
+ function( elem, name, isXML ) {
8127
+ var ret;
8128
+ if ( !isXML ) {
8129
+ return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
8130
+ ret.value :
8131
+ null;
8132
+ }
8133
+ };
8134
+
8135
+ // Fixing value retrieval on a button requires this module
8136
+ jQuery.valHooks.button = {
8137
+ get: function( elem, name ) {
8138
+ var ret = elem.getAttributeNode( name );
8139
+ if ( ret && ret.specified ) {
8140
+ return ret.value;
8141
+ }
8142
+ },
8143
+ set: nodeHook.set
8144
+ };
8145
+
8146
+ // Set contenteditable to false on removals(#10429)
8147
+ // Setting to empty string throws an error as an invalid value
8148
+ jQuery.attrHooks.contenteditable = {
8149
+ set: function( elem, value, name ) {
8150
+ nodeHook.set( elem, value === "" ? false : value, name );
8151
+ }
8152
+ };
8153
+
8154
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
8155
+ // This is for removals
8156
+ jQuery.each([ "width", "height" ], function( i, name ) {
8157
+ jQuery.attrHooks[ name ] = {
8158
+ set: function( elem, value ) {
8159
+ if ( value === "" ) {
8160
+ elem.setAttribute( name, "auto" );
8161
+ return value;
8162
+ }
8163
+ }
8164
+ };
8165
+ });
8166
+ }
8167
+
8168
+ if ( !support.style ) {
8169
+ jQuery.attrHooks.style = {
8170
+ get: function( elem ) {
8171
+ // Return undefined in the case of empty string
8172
+ // Note: IE uppercases css property names, but if we were to .toLowerCase()
8173
+ // .cssText, that would destroy case senstitivity in URL's, like in "background"
8174
+ return elem.style.cssText || undefined;
8175
+ },
8176
+ set: function( elem, value ) {
8177
+ return ( elem.style.cssText = value + "" );
8178
+ }
8179
+ };
8180
+ }
8181
+
8182
+
8183
+
8184
+
8185
+ var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8186
+ rclickable = /^(?:a|area)$/i;
8187
+
8188
+ jQuery.fn.extend({
8189
+ prop: function( name, value ) {
8190
+ return access( this, jQuery.prop, name, value, arguments.length > 1 );
8191
+ },
8192
+
8193
+ removeProp: function( name ) {
8194
+ name = jQuery.propFix[ name ] || name;
8195
+ return this.each(function() {
8196
+ // try/catch handles cases where IE balks (such as removing a property on window)
8197
+ try {
8198
+ this[ name ] = undefined;
8199
+ delete this[ name ];
8200
+ } catch( e ) {}
8201
+ });
8202
+ }
8203
+ });
8204
+
8205
+ jQuery.extend({
8206
+ propFix: {
8207
+ "for": "htmlFor",
8208
+ "class": "className"
8209
+ },
8210
+
8211
+ prop: function( elem, name, value ) {
8212
+ var ret, hooks, notxml,
8213
+ nType = elem.nodeType;
8214
+
8215
+ // don't get/set properties on text, comment and attribute nodes
8216
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
8217
+ return;
8218
+ }
8219
+
8220
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
8221
+
8222
+ if ( notxml ) {
8223
+ // Fix name and attach hooks
8224
+ name = jQuery.propFix[ name ] || name;
8225
+ hooks = jQuery.propHooks[ name ];
8226
+ }
8227
+
8228
+ if ( value !== undefined ) {
8229
+ return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
8230
+ ret :
8231
+ ( elem[ name ] = value );
8232
+
8233
+ } else {
8234
+ return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
8235
+ ret :
8236
+ elem[ name ];
8237
+ }
8238
+ },
8239
+
8240
+ propHooks: {
8241
+ tabIndex: {
8242
+ get: function( elem ) {
8243
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
8244
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8245
+ // Use proper attribute retrieval(#12072)
8246
+ var tabindex = jQuery.find.attr( elem, "tabindex" );
8247
+
8248
+ return tabindex ?
8249
+ parseInt( tabindex, 10 ) :
8250
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
8251
+ 0 :
8252
+ -1;
8253
+ }
8254
+ }
8255
+ }
8256
+ });
8257
+
8258
+ // Some attributes require a special call on IE
8259
+ // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8260
+ if ( !support.hrefNormalized ) {
8261
+ // href/src property should get the full normalized URL (#10299/#12915)
8262
+ jQuery.each([ "href", "src" ], function( i, name ) {
8263
+ jQuery.propHooks[ name ] = {
8264
+ get: function( elem ) {
8265
+ return elem.getAttribute( name, 4 );
8266
+ }
8267
+ };
8268
+ });
8269
+ }
8270
+
8271
+ // Support: Safari, IE9+
8272
+ // mis-reports the default selected property of an option
8273
+ // Accessing the parent's selectedIndex property fixes it
8274
+ if ( !support.optSelected ) {
8275
+ jQuery.propHooks.selected = {
8276
+ get: function( elem ) {
8277
+ var parent = elem.parentNode;
8278
+
8279
+ if ( parent ) {
8280
+ parent.selectedIndex;
8281
+
8282
+ // Make sure that it also works with optgroups, see #5701
8283
+ if ( parent.parentNode ) {
8284
+ parent.parentNode.selectedIndex;
8285
+ }
8286
+ }
8287
+ return null;
8288
+ }
8289
+ };
8290
+ }
8291
+
8292
+ jQuery.each([
8293
+ "tabIndex",
8294
+ "readOnly",
8295
+ "maxLength",
8296
+ "cellSpacing",
8297
+ "cellPadding",
8298
+ "rowSpan",
8299
+ "colSpan",
8300
+ "useMap",
8301
+ "frameBorder",
8302
+ "contentEditable"
8303
+ ], function() {
8304
+ jQuery.propFix[ this.toLowerCase() ] = this;
8305
+ });
8306
+
8307
+ // IE6/7 call enctype encoding
8308
+ if ( !support.enctype ) {
8309
+ jQuery.propFix.enctype = "encoding";
8310
+ }
8311
+
8312
+
8313
+
8314
+
8315
+ var rclass = /[\t\r\n\f]/g;
8316
+
8317
+ jQuery.fn.extend({
8318
+ addClass: function( value ) {
8319
+ var classes, elem, cur, clazz, j, finalValue,
8320
+ i = 0,
8321
+ len = this.length,
8322
+ proceed = typeof value === "string" && value;
8323
+
8324
+ if ( jQuery.isFunction( value ) ) {
8325
+ return this.each(function( j ) {
8326
+ jQuery( this ).addClass( value.call( this, j, this.className ) );
8327
+ });
8328
+ }
8329
+
8330
+ if ( proceed ) {
8331
+ // The disjunction here is for better compressibility (see removeClass)
8332
+ classes = ( value || "" ).match( rnotwhite ) || [];
8333
+
8334
+ for ( ; i < len; i++ ) {
8335
+ elem = this[ i ];
8336
+ cur = elem.nodeType === 1 && ( elem.className ?
8337
+ ( " " + elem.className + " " ).replace( rclass, " " ) :
8338
+ " "
8339
+ );
8340
+
8341
+ if ( cur ) {
8342
+ j = 0;
8343
+ while ( (clazz = classes[j++]) ) {
8344
+ if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8345
+ cur += clazz + " ";
8346
+ }
8347
+ }
8348
+
8349
+ // only assign if different to avoid unneeded rendering.
8350
+ finalValue = jQuery.trim( cur );
8351
+ if ( elem.className !== finalValue ) {
8352
+ elem.className = finalValue;
8353
+ }
8354
+ }
8355
+ }
8356
+ }
8357
+
8358
+ return this;
8359
+ },
8360
+
8361
+ removeClass: function( value ) {
8362
+ var classes, elem, cur, clazz, j, finalValue,
8363
+ i = 0,
8364
+ len = this.length,
8365
+ proceed = arguments.length === 0 || typeof value === "string" && value;
8366
+
8367
+ if ( jQuery.isFunction( value ) ) {
8368
+ return this.each(function( j ) {
8369
+ jQuery( this ).removeClass( value.call( this, j, this.className ) );
8370
+ });
8371
+ }
8372
+ if ( proceed ) {
8373
+ classes = ( value || "" ).match( rnotwhite ) || [];
8374
+
8375
+ for ( ; i < len; i++ ) {
8376
+ elem = this[ i ];
8377
+ // This expression is here for better compressibility (see addClass)
8378
+ cur = elem.nodeType === 1 && ( elem.className ?
8379
+ ( " " + elem.className + " " ).replace( rclass, " " ) :
8380
+ ""
8381
+ );
8382
+
8383
+ if ( cur ) {
8384
+ j = 0;
8385
+ while ( (clazz = classes[j++]) ) {
8386
+ // Remove *all* instances
8387
+ while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
8388
+ cur = cur.replace( " " + clazz + " ", " " );
8389
+ }
8390
+ }
8391
+
8392
+ // only assign if different to avoid unneeded rendering.
8393
+ finalValue = value ? jQuery.trim( cur ) : "";
8394
+ if ( elem.className !== finalValue ) {
8395
+ elem.className = finalValue;
8396
+ }
8397
+ }
8398
+ }
8399
+ }
8400
+
8401
+ return this;
8402
+ },
8403
+
8404
+ toggleClass: function( value, stateVal ) {
8405
+ var type = typeof value;
8406
+
8407
+ if ( typeof stateVal === "boolean" && type === "string" ) {
8408
+ return stateVal ? this.addClass( value ) : this.removeClass( value );
8409
+ }
8410
+
8411
+ if ( jQuery.isFunction( value ) ) {
8412
+ return this.each(function( i ) {
8413
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
8414
+ });
8415
+ }
8416
+
8417
+ return this.each(function() {
8418
+ if ( type === "string" ) {
8419
+ // toggle individual class names
8420
+ var className,
8421
+ i = 0,
8422
+ self = jQuery( this ),
8423
+ classNames = value.match( rnotwhite ) || [];
8424
+
8425
+ while ( (className = classNames[ i++ ]) ) {
8426
+ // check each className given, space separated list
8427
+ if ( self.hasClass( className ) ) {
8428
+ self.removeClass( className );
8429
+ } else {
8430
+ self.addClass( className );
8431
+ }
8432
+ }
8433
+
8434
+ // Toggle whole class name
8435
+ } else if ( type === strundefined || type === "boolean" ) {
8436
+ if ( this.className ) {
8437
+ // store className if set
8438
+ jQuery._data( this, "__className__", this.className );
8439
+ }
8440
+
8441
+ // If the element has a class name or if we're passed "false",
8442
+ // then remove the whole classname (if there was one, the above saved it).
8443
+ // Otherwise bring back whatever was previously saved (if anything),
8444
+ // falling back to the empty string if nothing was stored.
8445
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
8446
+ }
8447
+ });
8448
+ },
8449
+
8450
+ hasClass: function( selector ) {
8451
+ var className = " " + selector + " ",
8452
+ i = 0,
8453
+ l = this.length;
8454
+ for ( ; i < l; i++ ) {
8455
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
8456
+ return true;
8457
+ }
8458
+ }
8459
+
8460
+ return false;
8461
+ }
8462
+ });
8463
+
8464
+
8465
+
8466
+
8467
+ // Return jQuery for attributes-only inclusion
8468
+
8469
+
8470
+ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
8471
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8472
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
8473
+
8474
+ // Handle event binding
8475
+ jQuery.fn[ name ] = function( data, fn ) {
8476
+ return arguments.length > 0 ?
8477
+ this.on( name, null, data, fn ) :
8478
+ this.trigger( name );
8479
+ };
8480
+ });
8481
+
8482
+ jQuery.fn.extend({
8483
+ hover: function( fnOver, fnOut ) {
8484
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8485
+ },
8486
+
8487
+ bind: function( types, data, fn ) {
8488
+ return this.on( types, null, data, fn );
8489
+ },
8490
+ unbind: function( types, fn ) {
8491
+ return this.off( types, null, fn );
8492
+ },
8493
+
8494
+ delegate: function( selector, types, data, fn ) {
8495
+ return this.on( types, selector, data, fn );
8496
+ },
8497
+ undelegate: function( selector, types, fn ) {
8498
+ // ( namespace ) or ( selector, types [, fn] )
8499
+ return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
8500
+ }
8501
+ });
8502
+
8503
+
8504
+ var nonce = jQuery.now();
8505
+
8506
+ var rquery = (/\?/);
8507
+
8508
+
8509
+
8510
+ var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
8511
+
8512
+ jQuery.parseJSON = function( data ) {
8513
+ // Attempt to parse using the native JSON parser first
8514
+ if ( window.JSON && window.JSON.parse ) {
8515
+ // Support: Android 2.3
8516
+ // Workaround failure to string-cast null input
8517
+ return window.JSON.parse( data + "" );
8518
+ }
8519
+
8520
+ var requireNonComma,
8521
+ depth = null,
8522
+ str = jQuery.trim( data + "" );
8523
+
8524
+ // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
8525
+ // after removing valid tokens
8526
+ return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
8527
+
8528
+ // Force termination if we see a misplaced comma
8529
+ if ( requireNonComma && comma ) {
8530
+ depth = 0;
8531
+ }
8532
+
8533
+ // Perform no more replacements after returning to outermost depth
8534
+ if ( depth === 0 ) {
8535
+ return token;
8536
+ }
8537
+
8538
+ // Commas must not follow "[", "{", or ","
8539
+ requireNonComma = open || comma;
8540
+
8541
+ // Determine new depth
8542
+ // array/object open ("[" or "{"): depth += true - false (increment)
8543
+ // array/object close ("]" or "}"): depth += false - true (decrement)
8544
+ // other cases ("," or primitive): depth += true - true (numeric cast)
8545
+ depth += !close - !open;
8546
+
8547
+ // Remove this token
8548
+ return "";
8549
+ }) ) ?
8550
+ ( Function( "return " + str ) )() :
8551
+ jQuery.error( "Invalid JSON: " + data );
8552
+ };
8553
+
8554
+
8555
+ // Cross-browser xml parsing
8556
+ jQuery.parseXML = function( data ) {
8557
+ var xml, tmp;
8558
+ if ( !data || typeof data !== "string" ) {
8559
+ return null;
8560
+ }
8561
+ try {
8562
+ if ( window.DOMParser ) { // Standard
8563
+ tmp = new DOMParser();
8564
+ xml = tmp.parseFromString( data, "text/xml" );
8565
+ } else { // IE
8566
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
8567
+ xml.async = "false";
8568
+ xml.loadXML( data );
8569
+ }
8570
+ } catch( e ) {
8571
+ xml = undefined;
8572
+ }
8573
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
8574
+ jQuery.error( "Invalid XML: " + data );
8575
+ }
8576
+ return xml;
8577
+ };
8578
+
8579
+
8580
+ var
8581
+ // Document location
8582
+ ajaxLocParts,
8583
+ ajaxLocation,
8584
+
8585
+ rhash = /#.*$/,
8586
+ rts = /([?&])_=[^&]*/,
8587
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
8588
+ // #7653, #8125, #8152: local protocol detection
8589
+ rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8590
+ rnoContent = /^(?:GET|HEAD)$/,
8591
+ rprotocol = /^\/\//,
8592
+ rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
8593
+
8594
+ /* Prefilters
8595
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8596
+ * 2) These are called:
8597
+ * - BEFORE asking for a transport
8598
+ * - AFTER param serialization (s.data is a string if s.processData is true)
8599
+ * 3) key is the dataType
8600
+ * 4) the catchall symbol "*" can be used
8601
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8602
+ */
8603
+ prefilters = {},
8604
+
8605
+ /* Transports bindings
8606
+ * 1) key is the dataType
8607
+ * 2) the catchall symbol "*" can be used
8608
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
8609
+ */
8610
+ transports = {},
8611
+
8612
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8613
+ allTypes = "*/".concat("*");
8614
+
8615
+ // #8138, IE may throw an exception when accessing
8616
+ // a field from window.location if document.domain has been set
8617
+ try {
8618
+ ajaxLocation = location.href;
8619
+ } catch( e ) {
8620
+ // Use the href attribute of an A element
8621
+ // since IE will modify it given document.location
8622
+ ajaxLocation = document.createElement( "a" );
8623
+ ajaxLocation.href = "";
8624
+ ajaxLocation = ajaxLocation.href;
8625
+ }
8626
+
8627
+ // Segment location into parts
8628
+ ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
8629
+
8630
+ // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8631
+ function addToPrefiltersOrTransports( structure ) {
8632
+
8633
+ // dataTypeExpression is optional and defaults to "*"
8634
+ return function( dataTypeExpression, func ) {
8635
+
8636
+ if ( typeof dataTypeExpression !== "string" ) {
8637
+ func = dataTypeExpression;
8638
+ dataTypeExpression = "*";
8639
+ }
8640
+
8641
+ var dataType,
8642
+ i = 0,
8643
+ dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8644
+
8645
+ if ( jQuery.isFunction( func ) ) {
8646
+ // For each dataType in the dataTypeExpression
8647
+ while ( (dataType = dataTypes[i++]) ) {
8648
+ // Prepend if requested
8649
+ if ( dataType.charAt( 0 ) === "+" ) {
8650
+ dataType = dataType.slice( 1 ) || "*";
8651
+ (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
8652
+
8653
+ // Otherwise append
8654
+ } else {
8655
+ (structure[ dataType ] = structure[ dataType ] || []).push( func );
8656
+ }
8657
+ }
8658
+ }
8659
+ };
8660
+ }
8661
+
8662
+ // Base inspection function for prefilters and transports
8663
+ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8664
+
8665
+ var inspected = {},
8666
+ seekingTransport = ( structure === transports );
8667
+
8668
+ function inspect( dataType ) {
8669
+ var selected;
8670
+ inspected[ dataType ] = true;
8671
+ jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8672
+ var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8673
+ if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8674
+ options.dataTypes.unshift( dataTypeOrTransport );
8675
+ inspect( dataTypeOrTransport );
8676
+ return false;
8677
+ } else if ( seekingTransport ) {
8678
+ return !( selected = dataTypeOrTransport );
8679
+ }
8680
+ });
8681
+ return selected;
8682
+ }
8683
+
8684
+ return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8685
+ }
8686
+
8687
+ // A special extend for ajax options
8688
+ // that takes "flat" options (not to be deep extended)
8689
+ // Fixes #9887
8690
+ function ajaxExtend( target, src ) {
8691
+ var deep, key,
8692
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
8693
+
8694
+ for ( key in src ) {
8695
+ if ( src[ key ] !== undefined ) {
8696
+ ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
8697
+ }
8698
+ }
8699
+ if ( deep ) {
8700
+ jQuery.extend( true, target, deep );
8701
+ }
8702
+
8703
+ return target;
8704
+ }
8705
+
8706
+ /* Handles responses to an ajax request:
8707
+ * - finds the right dataType (mediates between content-type and expected dataType)
8708
+ * - returns the corresponding response
8709
+ */
8710
+ function ajaxHandleResponses( s, jqXHR, responses ) {
8711
+ var firstDataType, ct, finalDataType, type,
8712
+ contents = s.contents,
8713
+ dataTypes = s.dataTypes;
8714
+
8715
+ // Remove auto dataType and get content-type in the process
8716
+ while ( dataTypes[ 0 ] === "*" ) {
8717
+ dataTypes.shift();
8718
+ if ( ct === undefined ) {
8719
+ ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8720
+ }
8721
+ }
8722
+
8723
+ // Check if we're dealing with a known content-type
8724
+ if ( ct ) {
8725
+ for ( type in contents ) {
8726
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
8727
+ dataTypes.unshift( type );
8728
+ break;
8729
+ }
8730
+ }
8731
+ }
8732
+
8733
+ // Check to see if we have a response for the expected dataType
8734
+ if ( dataTypes[ 0 ] in responses ) {
8735
+ finalDataType = dataTypes[ 0 ];
8736
+ } else {
8737
+ // Try convertible dataTypes
8738
+ for ( type in responses ) {
8739
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8740
+ finalDataType = type;
8741
+ break;
8742
+ }
8743
+ if ( !firstDataType ) {
8744
+ firstDataType = type;
8745
+ }
8746
+ }
8747
+ // Or just use first one
8748
+ finalDataType = finalDataType || firstDataType;
8749
+ }
8750
+
8751
+ // If we found a dataType
8752
+ // We add the dataType to the list if needed
8753
+ // and return the corresponding response
8754
+ if ( finalDataType ) {
8755
+ if ( finalDataType !== dataTypes[ 0 ] ) {
8756
+ dataTypes.unshift( finalDataType );
8757
+ }
8758
+ return responses[ finalDataType ];
8759
+ }
8760
+ }
8761
+
8762
+ /* Chain conversions given the request and the original response
8763
+ * Also sets the responseXXX fields on the jqXHR instance
8764
+ */
8765
+ function ajaxConvert( s, response, jqXHR, isSuccess ) {
8766
+ var conv2, current, conv, tmp, prev,
8767
+ converters = {},
8768
+ // Work with a copy of dataTypes in case we need to modify it for conversion
8769
+ dataTypes = s.dataTypes.slice();
8770
+
8771
+ // Create converters map with lowercased keys
8772
+ if ( dataTypes[ 1 ] ) {
8773
+ for ( conv in s.converters ) {
8774
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
8775
+ }
8776
+ }
8777
+
8778
+ current = dataTypes.shift();
8779
+
8780
+ // Convert to each sequential dataType
8781
+ while ( current ) {
8782
+
8783
+ if ( s.responseFields[ current ] ) {
8784
+ jqXHR[ s.responseFields[ current ] ] = response;
8785
+ }
8786
+
8787
+ // Apply the dataFilter if provided
8788
+ if ( !prev && isSuccess && s.dataFilter ) {
8789
+ response = s.dataFilter( response, s.dataType );
8790
+ }
8791
+
8792
+ prev = current;
8793
+ current = dataTypes.shift();
8794
+
8795
+ if ( current ) {
8796
+
8797
+ // There's only work to do if current dataType is non-auto
8798
+ if ( current === "*" ) {
8799
+
8800
+ current = prev;
8801
+
8802
+ // Convert response if prev dataType is non-auto and differs from current
8803
+ } else if ( prev !== "*" && prev !== current ) {
8804
+
8805
+ // Seek a direct converter
8806
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8807
+
8808
+ // If none found, seek a pair
8809
+ if ( !conv ) {
8810
+ for ( conv2 in converters ) {
8811
+
8812
+ // If conv2 outputs current
8813
+ tmp = conv2.split( " " );
8814
+ if ( tmp[ 1 ] === current ) {
8815
+
8816
+ // If prev can be converted to accepted input
8817
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
8818
+ converters[ "* " + tmp[ 0 ] ];
8819
+ if ( conv ) {
8820
+ // Condense equivalence converters
8821
+ if ( conv === true ) {
8822
+ conv = converters[ conv2 ];
8823
+
8824
+ // Otherwise, insert the intermediate dataType
8825
+ } else if ( converters[ conv2 ] !== true ) {
8826
+ current = tmp[ 0 ];
8827
+ dataTypes.unshift( tmp[ 1 ] );
8828
+ }
8829
+ break;
8830
+ }
8831
+ }
8832
+ }
8833
+ }
8834
+
8835
+ // Apply converter (if not an equivalence)
8836
+ if ( conv !== true ) {
8837
+
8838
+ // Unless errors are allowed to bubble, catch and return them
8839
+ if ( conv && s[ "throws" ] ) {
8840
+ response = conv( response );
8841
+ } else {
8842
+ try {
8843
+ response = conv( response );
8844
+ } catch ( e ) {
8845
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
8846
+ }
8847
+ }
8848
+ }
8849
+ }
8850
+ }
8851
+ }
8852
+
8853
+ return { state: "success", data: response };
8854
+ }
8855
+
8856
+ jQuery.extend({
8857
+
8858
+ // Counter for holding the number of active queries
8859
+ active: 0,
8860
+
8861
+ // Last-Modified header cache for next request
8862
+ lastModified: {},
8863
+ etag: {},
8864
+
8865
+ ajaxSettings: {
8866
+ url: ajaxLocation,
8867
+ type: "GET",
8868
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
8869
+ global: true,
8870
+ processData: true,
8871
+ async: true,
8872
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8873
+ /*
8874
+ timeout: 0,
8875
+ data: null,
8876
+ dataType: null,
8877
+ username: null,
8878
+ password: null,
8879
+ cache: null,
8880
+ throws: false,
8881
+ traditional: false,
8882
+ headers: {},
8883
+ */
8884
+
8885
+ accepts: {
8886
+ "*": allTypes,
8887
+ text: "text/plain",
8888
+ html: "text/html",
8889
+ xml: "application/xml, text/xml",
8890
+ json: "application/json, text/javascript"
8891
+ },
8892
+
8893
+ contents: {
8894
+ xml: /xml/,
8895
+ html: /html/,
8896
+ json: /json/
8897
+ },
8898
+
8899
+ responseFields: {
8900
+ xml: "responseXML",
8901
+ text: "responseText",
8902
+ json: "responseJSON"
8903
+ },
8904
+
8905
+ // Data converters
8906
+ // Keys separate source (or catchall "*") and destination types with a single space
8907
+ converters: {
8908
+
8909
+ // Convert anything to text
8910
+ "* text": String,
8911
+
8912
+ // Text to html (true = no transformation)
8913
+ "text html": true,
8914
+
8915
+ // Evaluate text as a json expression
8916
+ "text json": jQuery.parseJSON,
8917
+
8918
+ // Parse text as xml
8919
+ "text xml": jQuery.parseXML
8920
+ },
8921
+
8922
+ // For options that shouldn't be deep extended:
8923
+ // you can add your own custom options here if
8924
+ // and when you create one that shouldn't be
8925
+ // deep extended (see ajaxExtend)
8926
+ flatOptions: {
8927
+ url: true,
8928
+ context: true
8929
+ }
8930
+ },
8931
+
8932
+ // Creates a full fledged settings object into target
8933
+ // with both ajaxSettings and settings fields.
8934
+ // If target is omitted, writes into ajaxSettings.
8935
+ ajaxSetup: function( target, settings ) {
8936
+ return settings ?
8937
+
8938
+ // Building a settings object
8939
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8940
+
8941
+ // Extending ajaxSettings
8942
+ ajaxExtend( jQuery.ajaxSettings, target );
8943
+ },
8944
+
8945
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8946
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
8947
+
8948
+ // Main method
8949
+ ajax: function( url, options ) {
8950
+
8951
+ // If url is an object, simulate pre-1.5 signature
8952
+ if ( typeof url === "object" ) {
8953
+ options = url;
8954
+ url = undefined;
8955
+ }
8956
+
8957
+ // Force options to be an object
8958
+ options = options || {};
8959
+
8960
+ var // Cross-domain detection vars
8961
+ parts,
8962
+ // Loop variable
8963
+ i,
8964
+ // URL without anti-cache param
8965
+ cacheURL,
8966
+ // Response headers as string
8967
+ responseHeadersString,
8968
+ // timeout handle
8969
+ timeoutTimer,
8970
+
8971
+ // To know if global events are to be dispatched
8972
+ fireGlobals,
8973
+
8974
+ transport,
8975
+ // Response headers
8976
+ responseHeaders,
8977
+ // Create the final options object
8978
+ s = jQuery.ajaxSetup( {}, options ),
8979
+ // Callbacks context
8980
+ callbackContext = s.context || s,
8981
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
8982
+ globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
8983
+ jQuery( callbackContext ) :
8984
+ jQuery.event,
8985
+ // Deferreds
8986
+ deferred = jQuery.Deferred(),
8987
+ completeDeferred = jQuery.Callbacks("once memory"),
8988
+ // Status-dependent callbacks
8989
+ statusCode = s.statusCode || {},
8990
+ // Headers (they are sent all at once)
8991
+ requestHeaders = {},
8992
+ requestHeadersNames = {},
8993
+ // The jqXHR state
8994
+ state = 0,
8995
+ // Default abort message
8996
+ strAbort = "canceled",
8997
+ // Fake xhr
8998
+ jqXHR = {
8999
+ readyState: 0,
9000
+
9001
+ // Builds headers hashtable if needed
9002
+ getResponseHeader: function( key ) {
9003
+ var match;
9004
+ if ( state === 2 ) {
9005
+ if ( !responseHeaders ) {
9006
+ responseHeaders = {};
9007
+ while ( (match = rheaders.exec( responseHeadersString )) ) {
9008
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
9009
+ }
9010
+ }
9011
+ match = responseHeaders[ key.toLowerCase() ];
9012
+ }
9013
+ return match == null ? null : match;
9014
+ },
9015
+
9016
+ // Raw string
9017
+ getAllResponseHeaders: function() {
9018
+ return state === 2 ? responseHeadersString : null;
9019
+ },
9020
+
9021
+ // Caches the header
9022
+ setRequestHeader: function( name, value ) {
9023
+ var lname = name.toLowerCase();
9024
+ if ( !state ) {
9025
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9026
+ requestHeaders[ name ] = value;
9027
+ }
9028
+ return this;
9029
+ },
9030
+
9031
+ // Overrides response content-type header
9032
+ overrideMimeType: function( type ) {
9033
+ if ( !state ) {
9034
+ s.mimeType = type;
9035
+ }
9036
+ return this;
9037
+ },
9038
+
9039
+ // Status-dependent callbacks
9040
+ statusCode: function( map ) {
9041
+ var code;
9042
+ if ( map ) {
9043
+ if ( state < 2 ) {
9044
+ for ( code in map ) {
9045
+ // Lazy-add the new callback in a way that preserves old ones
9046
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9047
+ }
9048
+ } else {
9049
+ // Execute the appropriate callbacks
9050
+ jqXHR.always( map[ jqXHR.status ] );
9051
+ }
9052
+ }
9053
+ return this;
9054
+ },
9055
+
9056
+ // Cancel the request
9057
+ abort: function( statusText ) {
9058
+ var finalText = statusText || strAbort;
9059
+ if ( transport ) {
9060
+ transport.abort( finalText );
9061
+ }
9062
+ done( 0, finalText );
9063
+ return this;
9064
+ }
9065
+ };
9066
+
9067
+ // Attach deferreds
9068
+ deferred.promise( jqXHR ).complete = completeDeferred.add;
9069
+ jqXHR.success = jqXHR.done;
9070
+ jqXHR.error = jqXHR.fail;
9071
+
9072
+ // Remove hash character (#7531: and string promotion)
9073
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9074
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
9075
+ // We also use the url parameter if available
9076
+ s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9077
+
9078
+ // Alias method option to type as per ticket #12004
9079
+ s.type = options.method || options.type || s.method || s.type;
9080
+
9081
+ // Extract dataTypes list
9082
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9083
+
9084
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
9085
+ if ( s.crossDomain == null ) {
9086
+ parts = rurl.exec( s.url.toLowerCase() );
9087
+ s.crossDomain = !!( parts &&
9088
+ ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9089
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9090
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9091
+ );
9092
+ }
9093
+
9094
+ // Convert data if not already a string
9095
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
9096
+ s.data = jQuery.param( s.data, s.traditional );
9097
+ }
9098
+
9099
+ // Apply prefilters
9100
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9101
+
9102
+ // If request was aborted inside a prefilter, stop there
9103
+ if ( state === 2 ) {
9104
+ return jqXHR;
9105
+ }
9106
+
9107
+ // We can fire global events as of now if asked to
9108
+ fireGlobals = s.global;
9109
+
9110
+ // Watch for a new set of requests
9111
+ if ( fireGlobals && jQuery.active++ === 0 ) {
9112
+ jQuery.event.trigger("ajaxStart");
9113
+ }
9114
+
9115
+ // Uppercase the type
9116
+ s.type = s.type.toUpperCase();
9117
+
9118
+ // Determine if request has content
9119
+ s.hasContent = !rnoContent.test( s.type );
9120
+
9121
+ // Save the URL in case we're toying with the If-Modified-Since
9122
+ // and/or If-None-Match header later on
9123
+ cacheURL = s.url;
9124
+
9125
+ // More options handling for requests with no content
9126
+ if ( !s.hasContent ) {
9127
+
9128
+ // If data is available, append data to url
9129
+ if ( s.data ) {
9130
+ cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9131
+ // #9682: remove data so that it's not used in an eventual retry
9132
+ delete s.data;
9133
+ }
9134
+
9135
+ // Add anti-cache in url if needed
9136
+ if ( s.cache === false ) {
9137
+ s.url = rts.test( cacheURL ) ?
9138
+
9139
+ // If there is already a '_' parameter, set its value
9140
+ cacheURL.replace( rts, "$1_=" + nonce++ ) :
9141
+
9142
+ // Otherwise add one to the end
9143
+ cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9144
+ }
9145
+ }
9146
+
9147
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9148
+ if ( s.ifModified ) {
9149
+ if ( jQuery.lastModified[ cacheURL ] ) {
9150
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9151
+ }
9152
+ if ( jQuery.etag[ cacheURL ] ) {
9153
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9154
+ }
9155
+ }
9156
+
9157
+ // Set the correct header, if data is being sent
9158
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9159
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
9160
+ }
9161
+
9162
+ // Set the Accepts header for the server, depending on the dataType
9163
+ jqXHR.setRequestHeader(
9164
+ "Accept",
9165
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
9166
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9167
+ s.accepts[ "*" ]
9168
+ );
9169
+
9170
+ // Check for headers option
9171
+ for ( i in s.headers ) {
9172
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
9173
+ }
9174
+
9175
+ // Allow custom headers/mimetypes and early abort
9176
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9177
+ // Abort if not done already and return
9178
+ return jqXHR.abort();
9179
+ }
9180
+
9181
+ // aborting is no longer a cancellation
9182
+ strAbort = "abort";
9183
+
9184
+ // Install callbacks on deferreds
9185
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
9186
+ jqXHR[ i ]( s[ i ] );
9187
+ }
9188
+
9189
+ // Get transport
9190
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9191
+
9192
+ // If no transport, we auto-abort
9193
+ if ( !transport ) {
9194
+ done( -1, "No Transport" );
9195
+ } else {
9196
+ jqXHR.readyState = 1;
9197
+
9198
+ // Send global event
9199
+ if ( fireGlobals ) {
9200
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9201
+ }
9202
+ // Timeout
9203
+ if ( s.async && s.timeout > 0 ) {
9204
+ timeoutTimer = setTimeout(function() {
9205
+ jqXHR.abort("timeout");
9206
+ }, s.timeout );
9207
+ }
9208
+
9209
+ try {
9210
+ state = 1;
9211
+ transport.send( requestHeaders, done );
9212
+ } catch ( e ) {
9213
+ // Propagate exception as error if not done
9214
+ if ( state < 2 ) {
9215
+ done( -1, e );
9216
+ // Simply rethrow otherwise
9217
+ } else {
9218
+ throw e;
9219
+ }
9220
+ }
9221
+ }
9222
+
9223
+ // Callback for when everything is done
9224
+ function done( status, nativeStatusText, responses, headers ) {
9225
+ var isSuccess, success, error, response, modified,
9226
+ statusText = nativeStatusText;
9227
+
9228
+ // Called once
9229
+ if ( state === 2 ) {
9230
+ return;
9231
+ }
9232
+
9233
+ // State is "done" now
9234
+ state = 2;
9235
+
9236
+ // Clear timeout if it exists
9237
+ if ( timeoutTimer ) {
9238
+ clearTimeout( timeoutTimer );
9239
+ }
9240
+
9241
+ // Dereference transport for early garbage collection
9242
+ // (no matter how long the jqXHR object will be used)
9243
+ transport = undefined;
9244
+
9245
+ // Cache response headers
9246
+ responseHeadersString = headers || "";
9247
+
9248
+ // Set readyState
9249
+ jqXHR.readyState = status > 0 ? 4 : 0;
9250
+
9251
+ // Determine if successful
9252
+ isSuccess = status >= 200 && status < 300 || status === 304;
9253
+
9254
+ // Get response data
9255
+ if ( responses ) {
9256
+ response = ajaxHandleResponses( s, jqXHR, responses );
9257
+ }
9258
+
9259
+ // Convert no matter what (that way responseXXX fields are always set)
9260
+ response = ajaxConvert( s, response, jqXHR, isSuccess );
9261
+
9262
+ // If successful, handle type chaining
9263
+ if ( isSuccess ) {
9264
+
9265
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9266
+ if ( s.ifModified ) {
9267
+ modified = jqXHR.getResponseHeader("Last-Modified");
9268
+ if ( modified ) {
9269
+ jQuery.lastModified[ cacheURL ] = modified;
9270
+ }
9271
+ modified = jqXHR.getResponseHeader("etag");
9272
+ if ( modified ) {
9273
+ jQuery.etag[ cacheURL ] = modified;
9274
+ }
9275
+ }
9276
+
9277
+ // if no content
9278
+ if ( status === 204 || s.type === "HEAD" ) {
9279
+ statusText = "nocontent";
9280
+
9281
+ // if not modified
9282
+ } else if ( status === 304 ) {
9283
+ statusText = "notmodified";
9284
+
9285
+ // If we have data, let's convert it
9286
+ } else {
9287
+ statusText = response.state;
9288
+ success = response.data;
9289
+ error = response.error;
9290
+ isSuccess = !error;
9291
+ }
9292
+ } else {
9293
+ // We extract error from statusText
9294
+ // then normalize statusText and status for non-aborts
9295
+ error = statusText;
9296
+ if ( status || !statusText ) {
9297
+ statusText = "error";
9298
+ if ( status < 0 ) {
9299
+ status = 0;
9300
+ }
9301
+ }
9302
+ }
9303
+
9304
+ // Set data for the fake xhr object
9305
+ jqXHR.status = status;
9306
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9307
+
9308
+ // Success/Error
9309
+ if ( isSuccess ) {
9310
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9311
+ } else {
9312
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9313
+ }
9314
+
9315
+ // Status-dependent callbacks
9316
+ jqXHR.statusCode( statusCode );
9317
+ statusCode = undefined;
9318
+
9319
+ if ( fireGlobals ) {
9320
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9321
+ [ jqXHR, s, isSuccess ? success : error ] );
9322
+ }
9323
+
9324
+ // Complete
9325
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9326
+
9327
+ if ( fireGlobals ) {
9328
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9329
+ // Handle the global AJAX counter
9330
+ if ( !( --jQuery.active ) ) {
9331
+ jQuery.event.trigger("ajaxStop");
9332
+ }
9333
+ }
9334
+ }
9335
+
9336
+ return jqXHR;
9337
+ },
9338
+
9339
+ getJSON: function( url, data, callback ) {
9340
+ return jQuery.get( url, data, callback, "json" );
9341
+ },
9342
+
9343
+ getScript: function( url, callback ) {
9344
+ return jQuery.get( url, undefined, callback, "script" );
9345
+ }
9346
+ });
9347
+
9348
+ jQuery.each( [ "get", "post" ], function( i, method ) {
9349
+ jQuery[ method ] = function( url, data, callback, type ) {
9350
+ // shift arguments if data argument was omitted
9351
+ if ( jQuery.isFunction( data ) ) {
9352
+ type = type || callback;
9353
+ callback = data;
9354
+ data = undefined;
9355
+ }
9356
+
9357
+ return jQuery.ajax({
9358
+ url: url,
9359
+ type: method,
9360
+ dataType: type,
9361
+ data: data,
9362
+ success: callback
9363
+ });
9364
+ };
9365
+ });
9366
+
9367
+ // Attach a bunch of functions for handling common AJAX events
9368
+ jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
9369
+ jQuery.fn[ type ] = function( fn ) {
9370
+ return this.on( type, fn );
9371
+ };
9372
+ });
9373
+
9374
+
9375
+ jQuery._evalUrl = function( url ) {
9376
+ return jQuery.ajax({
9377
+ url: url,
9378
+ type: "GET",
9379
+ dataType: "script",
9380
+ async: false,
9381
+ global: false,
9382
+ "throws": true
9383
+ });
9384
+ };
9385
+
9386
+
9387
+ jQuery.fn.extend({
9388
+ wrapAll: function( html ) {
9389
+ if ( jQuery.isFunction( html ) ) {
9390
+ return this.each(function(i) {
9391
+ jQuery(this).wrapAll( html.call(this, i) );
9392
+ });
9393
+ }
9394
+
9395
+ if ( this[0] ) {
9396
+ // The elements to wrap the target around
9397
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
9398
+
9399
+ if ( this[0].parentNode ) {
9400
+ wrap.insertBefore( this[0] );
9401
+ }
9402
+
9403
+ wrap.map(function() {
9404
+ var elem = this;
9405
+
9406
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9407
+ elem = elem.firstChild;
9408
+ }
9409
+
9410
+ return elem;
9411
+ }).append( this );
9412
+ }
9413
+
9414
+ return this;
9415
+ },
9416
+
9417
+ wrapInner: function( html ) {
9418
+ if ( jQuery.isFunction( html ) ) {
9419
+ return this.each(function(i) {
9420
+ jQuery(this).wrapInner( html.call(this, i) );
9421
+ });
9422
+ }
9423
+
9424
+ return this.each(function() {
9425
+ var self = jQuery( this ),
9426
+ contents = self.contents();
9427
+
9428
+ if ( contents.length ) {
9429
+ contents.wrapAll( html );
9430
+
9431
+ } else {
9432
+ self.append( html );
9433
+ }
9434
+ });
9435
+ },
9436
+
9437
+ wrap: function( html ) {
9438
+ var isFunction = jQuery.isFunction( html );
9439
+
9440
+ return this.each(function(i) {
9441
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
9442
+ });
9443
+ },
9444
+
9445
+ unwrap: function() {
9446
+ return this.parent().each(function() {
9447
+ if ( !jQuery.nodeName( this, "body" ) ) {
9448
+ jQuery( this ).replaceWith( this.childNodes );
9449
+ }
9450
+ }).end();
9451
+ }
9452
+ });
9453
+
9454
+
9455
+ jQuery.expr.filters.hidden = function( elem ) {
9456
+ // Support: Opera <= 12.12
9457
+ // Opera reports offsetWidths and offsetHeights less than zero on some elements
9458
+ return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
9459
+ (!support.reliableHiddenOffsets() &&
9460
+ ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
9461
+ };
9462
+
9463
+ jQuery.expr.filters.visible = function( elem ) {
9464
+ return !jQuery.expr.filters.hidden( elem );
9465
+ };
9466
+
9467
+
9468
+
9469
+
9470
+ var r20 = /%20/g,
9471
+ rbracket = /\[\]$/,
9472
+ rCRLF = /\r?\n/g,
9473
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9474
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
9475
+
9476
+ function buildParams( prefix, obj, traditional, add ) {
9477
+ var name;
9478
+
9479
+ if ( jQuery.isArray( obj ) ) {
9480
+ // Serialize array item.
9481
+ jQuery.each( obj, function( i, v ) {
9482
+ if ( traditional || rbracket.test( prefix ) ) {
9483
+ // Treat each array item as a scalar.
9484
+ add( prefix, v );
9485
+
9486
+ } else {
9487
+ // Item is non-scalar (array or object), encode its numeric index.
9488
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
9489
+ }
9490
+ });
9491
+
9492
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
9493
+ // Serialize object item.
9494
+ for ( name in obj ) {
9495
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9496
+ }
9497
+
9498
+ } else {
9499
+ // Serialize scalar item.
9500
+ add( prefix, obj );
9501
+ }
9502
+ }
9503
+
9504
+ // Serialize an array of form elements or a set of
9505
+ // key/values into a query string
9506
+ jQuery.param = function( a, traditional ) {
9507
+ var prefix,
9508
+ s = [],
9509
+ add = function( key, value ) {
9510
+ // If value is a function, invoke it and return its value
9511
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
9512
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
9513
+ };
9514
+
9515
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
9516
+ if ( traditional === undefined ) {
9517
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
9518
+ }
9519
+
9520
+ // If an array was passed in, assume that it is an array of form elements.
9521
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9522
+ // Serialize the form elements
9523
+ jQuery.each( a, function() {
9524
+ add( this.name, this.value );
9525
+ });
9526
+
9527
+ } else {
9528
+ // If traditional, encode the "old" way (the way 1.3.2 or older
9529
+ // did it), otherwise encode params recursively.
9530
+ for ( prefix in a ) {
9531
+ buildParams( prefix, a[ prefix ], traditional, add );
9532
+ }
9533
+ }
9534
+
9535
+ // Return the resulting serialization
9536
+ return s.join( "&" ).replace( r20, "+" );
9537
+ };
9538
+
9539
+ jQuery.fn.extend({
9540
+ serialize: function() {
9541
+ return jQuery.param( this.serializeArray() );
9542
+ },
9543
+ serializeArray: function() {
9544
+ return this.map(function() {
9545
+ // Can add propHook for "elements" to filter or add form elements
9546
+ var elements = jQuery.prop( this, "elements" );
9547
+ return elements ? jQuery.makeArray( elements ) : this;
9548
+ })
9549
+ .filter(function() {
9550
+ var type = this.type;
9551
+ // Use .is(":disabled") so that fieldset[disabled] works
9552
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
9553
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9554
+ ( this.checked || !rcheckableType.test( type ) );
9555
+ })
9556
+ .map(function( i, elem ) {
9557
+ var val = jQuery( this ).val();
9558
+
9559
+ return val == null ?
9560
+ null :
9561
+ jQuery.isArray( val ) ?
9562
+ jQuery.map( val, function( val ) {
9563
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9564
+ }) :
9565
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9566
+ }).get();
9567
+ }
9568
+ });
9569
+
9570
+
9571
+ // Create the request object
9572
+ // (This is still attached to ajaxSettings for backward compatibility)
9573
+ jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
9574
+ // Support: IE6+
9575
+ function() {
9576
+
9577
+ // XHR cannot access local files, always use ActiveX for that case
9578
+ return !this.isLocal &&
9579
+
9580
+ // Support: IE7-8
9581
+ // oldIE XHR does not support non-RFC2616 methods (#13240)
9582
+ // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
9583
+ // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
9584
+ // Although this check for six methods instead of eight
9585
+ // since IE also does not support "trace" and "connect"
9586
+ /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
9587
+
9588
+ createStandardXHR() || createActiveXHR();
9589
+ } :
9590
+ // For all other browsers, use the standard XMLHttpRequest object
9591
+ createStandardXHR;
9592
+
9593
+ var xhrId = 0,
9594
+ xhrCallbacks = {},
9595
+ xhrSupported = jQuery.ajaxSettings.xhr();
9596
+
9597
+ // Support: IE<10
9598
+ // Open requests must be manually aborted on unload (#5280)
9599
+ if ( window.ActiveXObject ) {
9600
+ jQuery( window ).on( "unload", function() {
9601
+ for ( var key in xhrCallbacks ) {
9602
+ xhrCallbacks[ key ]( undefined, true );
9603
+ }
9604
+ });
9605
+ }
9606
+
9607
+ // Determine support properties
9608
+ support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9609
+ xhrSupported = support.ajax = !!xhrSupported;
9610
+
9611
+ // Create transport if the browser can provide an xhr
9612
+ if ( xhrSupported ) {
9613
+
9614
+ jQuery.ajaxTransport(function( options ) {
9615
+ // Cross domain only allowed if supported through XMLHttpRequest
9616
+ if ( !options.crossDomain || support.cors ) {
9617
+
9618
+ var callback;
9619
+
9620
+ return {
9621
+ send: function( headers, complete ) {
9622
+ var i,
9623
+ xhr = options.xhr(),
9624
+ id = ++xhrId;
9625
+
9626
+ // Open the socket
9627
+ xhr.open( options.type, options.url, options.async, options.username, options.password );
9628
+
9629
+ // Apply custom fields if provided
9630
+ if ( options.xhrFields ) {
9631
+ for ( i in options.xhrFields ) {
9632
+ xhr[ i ] = options.xhrFields[ i ];
9633
+ }
9634
+ }
9635
+
9636
+ // Override mime type if needed
9637
+ if ( options.mimeType && xhr.overrideMimeType ) {
9638
+ xhr.overrideMimeType( options.mimeType );
9639
+ }
9640
+
9641
+ // X-Requested-With header
9642
+ // For cross-domain requests, seeing as conditions for a preflight are
9643
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
9644
+ // (it can always be set on a per-request basis or even using ajaxSetup)
9645
+ // For same-domain requests, won't change header if already provided.
9646
+ if ( !options.crossDomain && !headers["X-Requested-With"] ) {
9647
+ headers["X-Requested-With"] = "XMLHttpRequest";
9648
+ }
9649
+
9650
+ // Set headers
9651
+ for ( i in headers ) {
9652
+ // Support: IE<9
9653
+ // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
9654
+ // request header to a null-value.
9655
+ //
9656
+ // To keep consistent with other XHR implementations, cast the value
9657
+ // to string and ignore `undefined`.
9658
+ if ( headers[ i ] !== undefined ) {
9659
+ xhr.setRequestHeader( i, headers[ i ] + "" );
9660
+ }
9661
+ }
9662
+
9663
+ // Do send the request
9664
+ // This may raise an exception which is actually
9665
+ // handled in jQuery.ajax (so no try/catch here)
9666
+ xhr.send( ( options.hasContent && options.data ) || null );
9667
+
9668
+ // Listener
9669
+ callback = function( _, isAbort ) {
9670
+ var status, statusText, responses;
9671
+
9672
+ // Was never called and is aborted or complete
9673
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
9674
+ // Clean up
9675
+ delete xhrCallbacks[ id ];
9676
+ callback = undefined;
9677
+ xhr.onreadystatechange = jQuery.noop;
9678
+
9679
+ // Abort manually if needed
9680
+ if ( isAbort ) {
9681
+ if ( xhr.readyState !== 4 ) {
9682
+ xhr.abort();
9683
+ }
9684
+ } else {
9685
+ responses = {};
9686
+ status = xhr.status;
9687
+
9688
+ // Support: IE<10
9689
+ // Accessing binary-data responseText throws an exception
9690
+ // (#11426)
9691
+ if ( typeof xhr.responseText === "string" ) {
9692
+ responses.text = xhr.responseText;
9693
+ }
9694
+
9695
+ // Firefox throws an exception when accessing
9696
+ // statusText for faulty cross-domain requests
9697
+ try {
9698
+ statusText = xhr.statusText;
9699
+ } catch( e ) {
9700
+ // We normalize with Webkit giving an empty statusText
9701
+ statusText = "";
9702
+ }
9703
+
9704
+ // Filter status for non standard behaviors
9705
+
9706
+ // If the request is local and we have data: assume a success
9707
+ // (success with no data won't get notified, that's the best we
9708
+ // can do given current implementations)
9709
+ if ( !status && options.isLocal && !options.crossDomain ) {
9710
+ status = responses.text ? 200 : 404;
9711
+ // IE - #1450: sometimes returns 1223 when it should be 204
9712
+ } else if ( status === 1223 ) {
9713
+ status = 204;
9714
+ }
9715
+ }
9716
+ }
9717
+
9718
+ // Call complete if needed
9719
+ if ( responses ) {
9720
+ complete( status, statusText, responses, xhr.getAllResponseHeaders() );
9721
+ }
9722
+ };
9723
+
9724
+ if ( !options.async ) {
9725
+ // if we're in sync mode we fire the callback
9726
+ callback();
9727
+ } else if ( xhr.readyState === 4 ) {
9728
+ // (IE6 & IE7) if it's in cache and has been
9729
+ // retrieved directly we need to fire the callback
9730
+ setTimeout( callback );
9731
+ } else {
9732
+ // Add to the list of active xhr callbacks
9733
+ xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
9734
+ }
9735
+ },
9736
+
9737
+ abort: function() {
9738
+ if ( callback ) {
9739
+ callback( undefined, true );
9740
+ }
9741
+ }
9742
+ };
9743
+ }
9744
+ });
9745
+ }
9746
+
9747
+ // Functions to create xhrs
9748
+ function createStandardXHR() {
9749
+ try {
9750
+ return new window.XMLHttpRequest();
9751
+ } catch( e ) {}
9752
+ }
9753
+
9754
+ function createActiveXHR() {
9755
+ try {
9756
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
9757
+ } catch( e ) {}
9758
+ }
9759
+
9760
+
9761
+
9762
+
9763
+ // Install script dataType
9764
+ jQuery.ajaxSetup({
9765
+ accepts: {
9766
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
9767
+ },
9768
+ contents: {
9769
+ script: /(?:java|ecma)script/
9770
+ },
9771
+ converters: {
9772
+ "text script": function( text ) {
9773
+ jQuery.globalEval( text );
9774
+ return text;
9775
+ }
9776
+ }
9777
+ });
9778
+
9779
+ // Handle cache's special case and global
9780
+ jQuery.ajaxPrefilter( "script", function( s ) {
9781
+ if ( s.cache === undefined ) {
9782
+ s.cache = false;
9783
+ }
9784
+ if ( s.crossDomain ) {
9785
+ s.type = "GET";
9786
+ s.global = false;
9787
+ }
9788
+ });
9789
+
9790
+ // Bind script tag hack transport
9791
+ jQuery.ajaxTransport( "script", function(s) {
9792
+
9793
+ // This transport only deals with cross domain requests
9794
+ if ( s.crossDomain ) {
9795
+
9796
+ var script,
9797
+ head = document.head || jQuery("head")[0] || document.documentElement;
9798
+
9799
+ return {
9800
+
9801
+ send: function( _, callback ) {
9802
+
9803
+ script = document.createElement("script");
9804
+
9805
+ script.async = true;
9806
+
9807
+ if ( s.scriptCharset ) {
9808
+ script.charset = s.scriptCharset;
9809
+ }
9810
+
9811
+ script.src = s.url;
9812
+
9813
+ // Attach handlers for all browsers
9814
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
9815
+
9816
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
9817
+
9818
+ // Handle memory leak in IE
9819
+ script.onload = script.onreadystatechange = null;
9820
+
9821
+ // Remove the script
9822
+ if ( script.parentNode ) {
9823
+ script.parentNode.removeChild( script );
9824
+ }
9825
+
9826
+ // Dereference the script
9827
+ script = null;
9828
+
9829
+ // Callback if not abort
9830
+ if ( !isAbort ) {
9831
+ callback( 200, "success" );
9832
+ }
9833
+ }
9834
+ };
9835
+
9836
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
9837
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
9838
+ head.insertBefore( script, head.firstChild );
9839
+ },
9840
+
9841
+ abort: function() {
9842
+ if ( script ) {
9843
+ script.onload( undefined, true );
9844
+ }
9845
+ }
9846
+ };
9847
+ }
9848
+ });
9849
+
9850
+
9851
+
9852
+
9853
+ var oldCallbacks = [],
9854
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
9855
+
9856
+ // Default jsonp settings
9857
+ jQuery.ajaxSetup({
9858
+ jsonp: "callback",
9859
+ jsonpCallback: function() {
9860
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9861
+ this[ callback ] = true;
9862
+ return callback;
9863
+ }
9864
+ });
9865
+
9866
+ // Detect, normalize options and install callbacks for jsonp requests
9867
+ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9868
+
9869
+ var callbackName, overwritten, responseContainer,
9870
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9871
+ "url" :
9872
+ typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
9873
+ );
9874
+
9875
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
9876
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9877
+
9878
+ // Get callback name, remembering preexisting value associated with it
9879
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9880
+ s.jsonpCallback() :
9881
+ s.jsonpCallback;
9882
+
9883
+ // Insert callback into url or form data
9884
+ if ( jsonProp ) {
9885
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9886
+ } else if ( s.jsonp !== false ) {
9887
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9888
+ }
9889
+
9890
+ // Use data converter to retrieve json after script execution
9891
+ s.converters["script json"] = function() {
9892
+ if ( !responseContainer ) {
9893
+ jQuery.error( callbackName + " was not called" );
9894
+ }
9895
+ return responseContainer[ 0 ];
9896
+ };
9897
+
9898
+ // force json dataType
9899
+ s.dataTypes[ 0 ] = "json";
9900
+
9901
+ // Install callback
9902
+ overwritten = window[ callbackName ];
9903
+ window[ callbackName ] = function() {
9904
+ responseContainer = arguments;
9905
+ };
9906
+
9907
+ // Clean-up function (fires after converters)
9908
+ jqXHR.always(function() {
9909
+ // Restore preexisting value
9910
+ window[ callbackName ] = overwritten;
9911
+
9912
+ // Save back as free
9913
+ if ( s[ callbackName ] ) {
9914
+ // make sure that re-using the options doesn't screw things around
9915
+ s.jsonpCallback = originalSettings.jsonpCallback;
9916
+
9917
+ // save the callback name for future use
9918
+ oldCallbacks.push( callbackName );
9919
+ }
9920
+
9921
+ // Call if it was a function and we have a response
9922
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9923
+ overwritten( responseContainer[ 0 ] );
9924
+ }
9925
+
9926
+ responseContainer = overwritten = undefined;
9927
+ });
9928
+
9929
+ // Delegate to script
9930
+ return "script";
9931
+ }
9932
+ });
9933
+
9934
+
9935
+
9936
+
9937
+ // data: string of html
9938
+ // context (optional): If specified, the fragment will be created in this context, defaults to document
9939
+ // keepScripts (optional): If true, will include scripts passed in the html string
9940
+ jQuery.parseHTML = function( data, context, keepScripts ) {
9941
+ if ( !data || typeof data !== "string" ) {
9942
+ return null;
9943
+ }
9944
+ if ( typeof context === "boolean" ) {
9945
+ keepScripts = context;
9946
+ context = false;
9947
+ }
9948
+ context = context || document;
9949
+
9950
+ var parsed = rsingleTag.exec( data ),
9951
+ scripts = !keepScripts && [];
9952
+
9953
+ // Single tag
9954
+ if ( parsed ) {
9955
+ return [ context.createElement( parsed[1] ) ];
9956
+ }
9957
+
9958
+ parsed = jQuery.buildFragment( [ data ], context, scripts );
9959
+
9960
+ if ( scripts && scripts.length ) {
9961
+ jQuery( scripts ).remove();
9962
+ }
9963
+
9964
+ return jQuery.merge( [], parsed.childNodes );
9965
+ };
9966
+
9967
+
9968
+ // Keep a copy of the old load method
9969
+ var _load = jQuery.fn.load;
9970
+
9971
+ /**
9972
+ * Load a url into a page
9973
+ */
9974
+ jQuery.fn.load = function( url, params, callback ) {
9975
+ if ( typeof url !== "string" && _load ) {
9976
+ return _load.apply( this, arguments );
9977
+ }
9978
+
9979
+ var selector, response, type,
9980
+ self = this,
9981
+ off = url.indexOf(" ");
9982
+
9983
+ if ( off >= 0 ) {
9984
+ selector = url.slice( off, url.length );
9985
+ url = url.slice( 0, off );
9986
+ }
9987
+
9988
+ // If it's a function
9989
+ if ( jQuery.isFunction( params ) ) {
9990
+
9991
+ // We assume that it's the callback
9992
+ callback = params;
9993
+ params = undefined;
9994
+
9995
+ // Otherwise, build a param string
9996
+ } else if ( params && typeof params === "object" ) {
9997
+ type = "POST";
9998
+ }
9999
+
10000
+ // If we have elements to modify, make the request
10001
+ if ( self.length > 0 ) {
10002
+ jQuery.ajax({
10003
+ url: url,
10004
+
10005
+ // if "type" variable is undefined, then "GET" method will be used
10006
+ type: type,
10007
+ dataType: "html",
10008
+ data: params
10009
+ }).done(function( responseText ) {
10010
+
10011
+ // Save response for use in complete callback
10012
+ response = arguments;
10013
+
10014
+ self.html( selector ?
10015
+
10016
+ // If a selector was specified, locate the right elements in a dummy div
10017
+ // Exclude scripts to avoid IE 'Permission Denied' errors
10018
+ jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
10019
+
10020
+ // Otherwise use the full result
10021
+ responseText );
10022
+
10023
+ }).complete( callback && function( jqXHR, status ) {
10024
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
10025
+ });
10026
+ }
10027
+
10028
+ return this;
10029
+ };
10030
+
10031
+
10032
+
10033
+
10034
+ jQuery.expr.filters.animated = function( elem ) {
10035
+ return jQuery.grep(jQuery.timers, function( fn ) {
10036
+ return elem === fn.elem;
10037
+ }).length;
10038
+ };
10039
+
10040
+
10041
+
10042
+
10043
+
10044
+ var docElem = window.document.documentElement;
10045
+
10046
+ /**
10047
+ * Gets a window from an element
10048
+ */
10049
+ function getWindow( elem ) {
10050
+ return jQuery.isWindow( elem ) ?
10051
+ elem :
10052
+ elem.nodeType === 9 ?
10053
+ elem.defaultView || elem.parentWindow :
10054
+ false;
10055
+ }
10056
+
10057
+ jQuery.offset = {
10058
+ setOffset: function( elem, options, i ) {
10059
+ var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10060
+ position = jQuery.css( elem, "position" ),
10061
+ curElem = jQuery( elem ),
10062
+ props = {};
10063
+
10064
+ // set position first, in-case top/left are set even on static elem
10065
+ if ( position === "static" ) {
10066
+ elem.style.position = "relative";
10067
+ }
10068
+
10069
+ curOffset = curElem.offset();
10070
+ curCSSTop = jQuery.css( elem, "top" );
10071
+ curCSSLeft = jQuery.css( elem, "left" );
10072
+ calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10073
+ jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
10074
+
10075
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
10076
+ if ( calculatePosition ) {
10077
+ curPosition = curElem.position();
10078
+ curTop = curPosition.top;
10079
+ curLeft = curPosition.left;
10080
+ } else {
10081
+ curTop = parseFloat( curCSSTop ) || 0;
10082
+ curLeft = parseFloat( curCSSLeft ) || 0;
10083
+ }
10084
+
10085
+ if ( jQuery.isFunction( options ) ) {
10086
+ options = options.call( elem, i, curOffset );
10087
+ }
10088
+
10089
+ if ( options.top != null ) {
10090
+ props.top = ( options.top - curOffset.top ) + curTop;
10091
+ }
10092
+ if ( options.left != null ) {
10093
+ props.left = ( options.left - curOffset.left ) + curLeft;
10094
+ }
10095
+
10096
+ if ( "using" in options ) {
10097
+ options.using.call( elem, props );
10098
+ } else {
10099
+ curElem.css( props );
10100
+ }
10101
+ }
10102
+ };
10103
+
10104
+ jQuery.fn.extend({
10105
+ offset: function( options ) {
10106
+ if ( arguments.length ) {
10107
+ return options === undefined ?
10108
+ this :
10109
+ this.each(function( i ) {
10110
+ jQuery.offset.setOffset( this, options, i );
10111
+ });
10112
+ }
10113
+
10114
+ var docElem, win,
10115
+ box = { top: 0, left: 0 },
10116
+ elem = this[ 0 ],
10117
+ doc = elem && elem.ownerDocument;
10118
+
10119
+ if ( !doc ) {
10120
+ return;
10121
+ }
10122
+
10123
+ docElem = doc.documentElement;
10124
+
10125
+ // Make sure it's not a disconnected DOM node
10126
+ if ( !jQuery.contains( docElem, elem ) ) {
10127
+ return box;
10128
+ }
10129
+
10130
+ // If we don't have gBCR, just use 0,0 rather than error
10131
+ // BlackBerry 5, iOS 3 (original iPhone)
10132
+ if ( typeof elem.getBoundingClientRect !== strundefined ) {
10133
+ box = elem.getBoundingClientRect();
10134
+ }
10135
+ win = getWindow( doc );
10136
+ return {
10137
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
10138
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10139
+ };
10140
+ },
10141
+
10142
+ position: function() {
10143
+ if ( !this[ 0 ] ) {
10144
+ return;
10145
+ }
10146
+
10147
+ var offsetParent, offset,
10148
+ parentOffset = { top: 0, left: 0 },
10149
+ elem = this[ 0 ];
10150
+
10151
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
10152
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
10153
+ // we assume that getBoundingClientRect is available when computed position is fixed
10154
+ offset = elem.getBoundingClientRect();
10155
+ } else {
10156
+ // Get *real* offsetParent
10157
+ offsetParent = this.offsetParent();
10158
+
10159
+ // Get correct offsets
10160
+ offset = this.offset();
10161
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10162
+ parentOffset = offsetParent.offset();
10163
+ }
10164
+
10165
+ // Add offsetParent borders
10166
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10167
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10168
+ }
10169
+
10170
+ // Subtract parent offsets and element margins
10171
+ // note: when an element has margin: auto the offsetLeft and marginLeft
10172
+ // are the same in Safari causing offset.left to incorrectly be 0
10173
+ return {
10174
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10175
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
10176
+ };
10177
+ },
10178
+
10179
+ offsetParent: function() {
10180
+ return this.map(function() {
10181
+ var offsetParent = this.offsetParent || docElem;
10182
+
10183
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
10184
+ offsetParent = offsetParent.offsetParent;
10185
+ }
10186
+ return offsetParent || docElem;
10187
+ });
10188
+ }
10189
+ });
10190
+
10191
+ // Create scrollLeft and scrollTop methods
10192
+ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10193
+ var top = /Y/.test( prop );
10194
+
10195
+ jQuery.fn[ method ] = function( val ) {
10196
+ return access( this, function( elem, method, val ) {
10197
+ var win = getWindow( elem );
10198
+
10199
+ if ( val === undefined ) {
10200
+ return win ? (prop in win) ? win[ prop ] :
10201
+ win.document.documentElement[ method ] :
10202
+ elem[ method ];
10203
+ }
10204
+
10205
+ if ( win ) {
10206
+ win.scrollTo(
10207
+ !top ? val : jQuery( win ).scrollLeft(),
10208
+ top ? val : jQuery( win ).scrollTop()
10209
+ );
10210
+
10211
+ } else {
10212
+ elem[ method ] = val;
10213
+ }
10214
+ }, method, val, arguments.length, null );
10215
+ };
10216
+ });
10217
+
10218
+ // Add the top/left cssHooks using jQuery.fn.position
10219
+ // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10220
+ // getComputedStyle returns percent when specified for top/left/bottom/right
10221
+ // rather than make the css module depend on the offset module, we just check for it here
10222
+ jQuery.each( [ "top", "left" ], function( i, prop ) {
10223
+ jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10224
+ function( elem, computed ) {
10225
+ if ( computed ) {
10226
+ computed = curCSS( elem, prop );
10227
+ // if curCSS returns percentage, fallback to offset
10228
+ return rnumnonpx.test( computed ) ?
10229
+ jQuery( elem ).position()[ prop ] + "px" :
10230
+ computed;
10231
+ }
10232
+ }
10233
+ );
10234
+ });
10235
+
10236
+
10237
+ // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10238
+ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10239
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
10240
+ // margin is only for outerHeight, outerWidth
10241
+ jQuery.fn[ funcName ] = function( margin, value ) {
10242
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10243
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10244
+
10245
+ return access( this, function( elem, type, value ) {
10246
+ var doc;
10247
+
10248
+ if ( jQuery.isWindow( elem ) ) {
10249
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10250
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
10251
+ // https://github.com/jquery/jquery/pull/764
10252
+ return elem.document.documentElement[ "client" + name ];
10253
+ }
10254
+
10255
+ // Get document width or height
10256
+ if ( elem.nodeType === 9 ) {
10257
+ doc = elem.documentElement;
10258
+
10259
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
10260
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
10261
+ return Math.max(
10262
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10263
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
10264
+ doc[ "client" + name ]
10265
+ );
10266
+ }
10267
+
10268
+ return value === undefined ?
10269
+ // Get width or height on the element, requesting but not forcing parseFloat
10270
+ jQuery.css( elem, type, extra ) :
10271
+
10272
+ // Set width or height on the element
10273
+ jQuery.style( elem, type, value, extra );
10274
+ }, type, chainable ? margin : undefined, chainable, null );
10275
+ };
10276
+ });
10277
+ });
10278
+
10279
+
10280
+ // The number of elements contained in the matched element set
10281
+ jQuery.fn.size = function() {
10282
+ return this.length;
10283
+ };
10284
+
10285
+ jQuery.fn.andSelf = jQuery.fn.addBack;
10286
+
10287
+
10288
+
10289
+
10290
+ // Register as a named AMD module, since jQuery can be concatenated with other
10291
+ // files that may use define, but not via a proper concatenation script that
10292
+ // understands anonymous AMD modules. A named AMD is safest and most robust
10293
+ // way to register. Lowercase jquery is used because AMD module names are
10294
+ // derived from file names, and jQuery is normally delivered in a lowercase
10295
+ // file name. Do this after creating the global so that if an AMD module wants
10296
+ // to call noConflict to hide this version of jQuery, it will work.
10297
+ if ( typeof define === "function" && define.amd ) {
10298
+ define( "jquery", [], function() {
10299
+ return jQuery;
10300
+ });
10301
+ }
10302
+
10303
+
10304
+
10305
+
10306
+ var
10307
+ // Map over jQuery in case of overwrite
10308
+ _jQuery = window.jQuery,
10309
+
10310
+ // Map over the $ in case of overwrite
10311
+ _$ = window.$;
10312
+
10313
+ jQuery.noConflict = function( deep ) {
10314
+ if ( window.$ === jQuery ) {
10315
+ window.$ = _$;
10316
+ }
10317
+
10318
+ if ( deep && window.jQuery === jQuery ) {
10319
+ window.jQuery = _jQuery;
10320
+ }
10321
+
10322
+ return jQuery;
10323
+ };
10324
+
10325
+ // Expose jQuery and $ identifiers, even in
10326
+ // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10327
+ // and CommonJS for browser emulators (#13566)
10328
+ if ( typeof noGlobal === strundefined ) {
10329
+ window.jQuery = window.$ = jQuery;
10330
+ }
10331
+
10332
+
10333
+
10334
+
10335
+ return jQuery;
10336
+
10337
+ }));
skin/frontend/default/default/ship/js/jquery.autoSuggest.js CHANGED
@@ -1,440 +1,440 @@
1
- /*
2
- * AutoSuggest
3
- * Copyright 2009-2010 Drew Wilson
4
- * www.drewwilson.com
5
- * code.drewwilson.com/entry/autosuggest-jquery-plugin
6
- *
7
- * Forked by Wu Yuntao
8
- * github.com/wuyuntao/jquery-autosuggest
9
- *
10
- * Version 1.6.2
11
- *
12
- * This Plug-In will auto-complete or auto-suggest completed search queries
13
- * for you as you type. You can add multiple selections and remove them on
14
- * the fly. It supports keybord navigation (UP + DOWN + RETURN), as well
15
- * as multiple AutoSuggest fields on the same page.
16
- *
17
- * Inspired by the Autocomplete plugin by: Joern Zaefferer
18
- * and the Facelist plugin by: Ian Tearle (iantearle.com)
19
- *
20
- * This AutoSuggest jQuery plug-in is dual licensed under the MIT and GPL licenses:
21
- * http://www.opensource.org/licenses/mit-license.php
22
- * http://www.gnu.org/licenses/gpl.html
23
- */
24
-
25
- (function($){
26
- $.fn.autoSuggest = function(data, options) {
27
- var defaults = {
28
- asHtmlID: false,
29
- startText: "Enter Suburb / Postcode Here",
30
- usePlaceholder: false,
31
- emptyText: "No Results Found",
32
- preFill: {},
33
- limitText: "No More Selections Are Allowed",
34
- selectedItemProp: "value", //name of object property
35
- selectedValuesProp: "value", //name of object property
36
- searchObjProps: "value", //comma separated list of object property names
37
- queryParam: "q",
38
- retrieveLimit: false, //number for 'limit' param on ajax request
39
- extraParams: "",
40
- matchCase: false,
41
- minChars: 1,
42
- keyDelay: 400,
43
- resultsHighlight: true,
44
- neverSubmit: false,
45
- selectionLimit: false,
46
- showResultList: true,
47
- showResultListWhenNoMatch: false,
48
- canGenerateNewSelections: true,
49
- start: function(){},
50
- selectionClick: function(elem){},
51
- selectionAdded: function(elem){},
52
- selectionRemoved: function(elem){ elem.remove(); },
53
- formatList: false, //callback function
54
- beforeRetrieve: function(string){ return string; },
55
- retrieveComplete: function(data){ return data; },
56
- resultClick: function(data){},
57
- resultsComplete: function(){}
58
- };
59
- var opts = $.extend(defaults, options);
60
-
61
- function countValidItems(data) { var n = 0; for (k in data) if (data.hasOwnProperty(k)) n++; return n; }
62
-
63
- function getExtraParams() {
64
- var params = opts.extraParams;
65
- if($.isFunction(params)) {
66
- return params();
67
- }
68
- return params;
69
- }
70
-
71
- var d_fetcher;
72
- var request = null;
73
- if(typeof data == "function") {
74
- d_fetcher = data;
75
- } else if(typeof data == "string") {
76
- d_fetcher = function(query, next) {
77
- var limit = "";
78
- if(opts.retrieveLimit){
79
- limit = "&limit="+encodeURIComponent(opts.retrieveLimit);
80
- }
81
- request = $.getJSON(data+"?"+opts.queryParam+"="+encodeURIComponent(query)+limit+getExtraParams(), function(data){
82
- var new_data = opts.retrieveComplete.call(this, data);
83
- next(new_data, query);
84
- });
85
- };
86
- } else if(typeof data == "object" && countValidItems(data) > 0) {
87
- d_fetcher = function(query, next) { next(data, query); };
88
- }
89
-
90
- if(d_fetcher) {
91
- return this.each(function(x){
92
- if(!opts.asHtmlID){
93
- x = x+""+Math.floor(Math.random()*100); //this ensures there will be unique IDs on the page if autoSuggest() is called multiple times
94
- var x_id = "as-input-"+x;
95
- } else {
96
- x = opts.asHtmlID;
97
- var x_id = x;
98
- }
99
- opts.start.call(this, {
100
- add: function(data) {
101
- add_selected_item(data, 'u' + $('li', selections_holder).length).addClass('blur');
102
- },
103
- remove: function(value) {
104
- values_input.val(values_input.val().replace(","+value+",",","));
105
- selections_holder.find('li[data-value = "' + value + '"]').remove();
106
- }
107
- });
108
- var input = $(this);
109
- input.attr("autocomplete","off").addClass("as-input").attr("id",x_id);
110
- if (opts.usePlaceholder) {
111
- input.attr('placeholder', opts.startText);
112
- } else {
113
- input.val(opts.startText);
114
- }
115
- var input_focus = false;
116
-
117
- // Setup basic elements and render them to the DOM
118
- input.wrap('<ul class="as-selections" id="as-selections-'+x+'"></ul>').wrap('<li class="as-original" id="as-original-'+x+'"></li>');
119
- var selections_holder = $("#as-selections-"+x);
120
- var org_li = $("#as-original-"+x);
121
- var results_holder = $('<div class="as-results" id="as-results-'+x+'"></div>').hide();
122
- var results_ul = $('<ul class="as-list"></ul>');
123
- var values_input = $('<input type="hidden" class="as-values" name="as_values_'+x+'" id="as-values-'+x+'" />');
124
- var prefill_value = "";
125
- if(typeof opts.preFill == "string"){
126
- var vals = opts.preFill.split(",");
127
- for(var i=0; i < vals.length; i++){
128
- var v_data = {};
129
- v_data[opts.selectedValuesProp] = vals[i];
130
- if(vals[i] != ""){
131
- add_selected_item(v_data, "000"+i);
132
- }
133
- }
134
- prefill_value = opts.preFill;
135
- } else {
136
- prefill_value = "";
137
- var prefill_count = 0;
138
- for (k in opts.preFill) if (opts.preFill.hasOwnProperty(k)) prefill_count++;
139
- if(prefill_count > 0){
140
- for(var i=0; i < prefill_count; i++){
141
- var new_v = opts.preFill[i][opts.selectedValuesProp];
142
- if(new_v == undefined){ new_v = ""; }
143
- prefill_value = prefill_value+new_v+",";
144
- if(new_v != ""){
145
- add_selected_item(opts.preFill[i], "000"+i);
146
- }
147
- }
148
- }
149
- }
150
- if(prefill_value != ""){
151
- input.val("");
152
- var lastChar = prefill_value.substring(prefill_value.length-1);
153
- if(lastChar != ","){ prefill_value = prefill_value+","; }
154
- values_input.val(","+prefill_value);
155
- $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
156
- }
157
- input.after(values_input);
158
- selections_holder.click(function(){
159
- input_focus = true;
160
- input.focus();
161
- }).mousedown(function(){ input_focus = false; }).after(results_holder);
162
-
163
- var interval = null;
164
- var timeout = null;
165
- var prev = "";
166
- var totalSelections = 0;
167
- var tab_press = false;
168
- var lastKeyPressCode = null;
169
-
170
- // Handle input field events
171
- input.focus(function(){
172
- if(!opts.usePlaceholder && $(this).val() == opts.startText && values_input.val() == ""){
173
- $(this).val("");
174
- } else if(input_focus){
175
- $("li.as-selection-item", selections_holder).removeClass("blur");
176
- if($(this).val() != ""){
177
- results_ul.css("width",selections_holder.outerWidth());
178
- results_holder.show();
179
- }
180
- }
181
- if (interval) clearInterval(interval);
182
- interval = setInterval(function() {
183
- if(opts.showResultList){
184
- if(opts.selectionLimit && $("li.as-selection-item", selections_holder).length >= opts.selectionLimit){
185
- results_ul.html('<li class="as-message">'+opts.limitText+'</li>');
186
- //results_holder.show(); // Nayan Code Added
187
- } else {
188
- keyChange();
189
- }
190
- }
191
- }, opts.keyDelay);
192
- input_focus = true;
193
- if (opts.minChars == 0){
194
- processRequest($(this).val());
195
- }
196
- return true;
197
- }).blur(function(){
198
- if (!opts.usePlaceholder && $(this).val() == "" && values_input.val() == "" && prefill_value == "" && opts.minChars > 0) {
199
- $(this).val(opts.startText);
200
- } else if(input_focus){
201
- $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
202
- results_holder.hide();
203
- }
204
- if (interval) clearInterval(interval);
205
- }).keydown(function(e) {
206
- // track last key pressed
207
- lastKeyPressCode = e.keyCode;
208
- first_focus = false;
209
- switch(e.keyCode) {
210
- case 38: // up
211
- e.preventDefault();
212
- moveSelection("up");
213
- break;
214
- case 40: // down
215
- e.preventDefault();
216
- moveSelection("down");
217
- break;
218
- case 8: // delete
219
- if(input.val() == ""){
220
- var last = values_input.val().split(",");
221
- last = last[last.length - 2];
222
- selections_holder.children().not(org_li.prev()).removeClass("selected");
223
- if(org_li.prev().hasClass("selected")){
224
- values_input.val(values_input.val().replace(","+last+",",","));
225
- opts.selectionRemoved.call(this, org_li.prev());
226
-
227
- $("li.as-original input").removeAttr("disabled"); //Nayan Code Added
228
-
229
- } else {
230
- opts.selectionClick.call(this, org_li.prev());
231
- org_li.prev().addClass("selected");
232
- }
233
- }
234
- if(input.val().length == 1){
235
- results_holder.hide();
236
- prev = "";
237
- abortRequest();
238
- }
239
- if($(":visible",results_holder).length > 0){
240
- if (timeout){ clearTimeout(timeout); }
241
- timeout = setTimeout(function(){ keyChange(); }, opts.keyDelay);
242
- }
243
- break;
244
- case 9: case 188: // tab or comm
245
- if(opts.canGenerateNewSelections){
246
- tab_press = true;
247
- var i_input = input.val().replace(/(,)/g, "");
248
- var active = $("li.active:first", results_holder);
249
- // Generate a new bubble with text when no suggestion selected
250
- if(i_input !== "" && values_input.val().search(","+i_input+",") < 0 && i_input.length >= opts.minChars && active.length === 0){
251
- e.preventDefault();
252
- var n_data = {};
253
- n_data[opts.selectedItemProp] = i_input;
254
- n_data[opts.selectedValuesProp] = i_input;
255
- var lis = $("li", selections_holder).length;
256
- add_selected_item(n_data, "00"+(lis+1));
257
- input.val("");
258
- // Cancel previous request when new tag is added
259
- abortRequest();
260
- break;
261
- }
262
- }
263
- case 13: // return
264
- tab_press = false;
265
- var active = $("li.active:first", results_holder);
266
- if(active.length > 0){
267
- active.click();
268
- results_holder.hide();
269
- }
270
- if(opts.neverSubmit || active.length > 0){
271
- e.preventDefault();
272
- }
273
- break;
274
- // ignore if the following keys are pressed: [escape] [shift] [capslock]
275
- case 27: // escape
276
- case 16: // shift
277
- case 20: // capslock
278
- abortRequest();
279
- results_holder.hide();
280
- break;
281
- }
282
- });
283
-
284
- function keyChange() {
285
- // Since most IME does not trigger any key events, if we press [del]
286
- // and type some chinese character, `lastKeyPressCode` will still be [del].
287
- // This might cause problem so we move the line to key events section;
288
- // ignore if the following keys are pressed: [del] [shift] [capslock]
289
- // if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ){ return results_holder.hide(); }
290
- var string = input.val().replace(/[\\]+|[\/]+/g,"");
291
- if (string == prev) return;
292
- prev = string;
293
- if (string.length >= opts.minChars) {
294
- selections_holder.addClass("loading");
295
- processRequest(string);
296
- } else {
297
- selections_holder.removeClass("loading");
298
- results_holder.hide();
299
- }
300
- }
301
- function processRequest(string){
302
- if(opts.beforeRetrieve){
303
- string = opts.beforeRetrieve.call(this, string);
304
- }
305
- abortRequest();
306
- d_fetcher(string, processData);
307
- }
308
- var num_count = 0;
309
- function processData(data, query){
310
- if (!opts.matchCase){ query = query.toLowerCase(); }
311
- query = query.replace("(", "\\(", "g").replace(")", "\\)", "g");
312
- var matchCount = 0;
313
- results_holder.html(results_ul.html("")).hide();
314
- var d_count = countValidItems(data);
315
- for(var i=0;i<d_count;i++){
316
- var num = i;
317
- num_count++;
318
- var forward = false;
319
- if(opts.searchObjProps == "value") {
320
- var str = data[num].value;
321
- } else {
322
- var str = "";
323
- var names = opts.searchObjProps.split(",");
324
- for(var y=0;y<names.length;y++){
325
- var name = $.trim(names[y]);
326
- str = str+data[num][name]+" ";
327
- }
328
- }
329
- if(str){
330
- if (!opts.matchCase){ str = str.toLowerCase(); }
331
- if(str.search(query) != -1 && values_input.val().search(","+data[num][opts.selectedValuesProp]+",") == -1){
332
- forward = true;
333
- }
334
- }
335
- if(forward){
336
- var formatted = $('<li class="as-result-item" id="as-result-item-'+num+'"></li>').click(function(){
337
- var raw_data = $(this).data("data");
338
- var number = raw_data.num;
339
- if($("#as-selection-"+number, selections_holder).length <= 0 && !tab_press){
340
- var data = raw_data.attributes;
341
- input.val("").focus();
342
- prev = "";
343
- add_selected_item(data, number);
344
- opts.resultClick.call(this, raw_data);
345
- results_holder.hide();
346
- }
347
- tab_press = false;
348
- }).mousedown(function(){ input_focus = false; }).mouseover(function(){
349
- $("li", results_ul).removeClass("active");
350
- $(this).addClass("active");
351
- }).data("data",{attributes: data[num], num: num_count});
352
- var this_data = $.extend({},data[num]);
353
- if (!opts.matchCase){
354
- var regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi");
355
- } else {
356
- var regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "g");
357
- }
358
-
359
- if(opts.resultsHighlight && query.length > 0){
360
- this_data[opts.selectedItemProp] = this_data[opts.selectedItemProp].replace(regx,"<em>$1</em>");
361
- }
362
- if(!opts.formatList){
363
- formatted = formatted.html(this_data[opts.selectedItemProp]);
364
- } else {
365
- formatted = opts.formatList.call(this, this_data, formatted);
366
- }
367
- results_ul.append(formatted);
368
- delete this_data;
369
- matchCount++;
370
- if(opts.retrieveLimit && opts.retrieveLimit == matchCount ){ break; }
371
- }
372
- }
373
- selections_holder.removeClass("loading");
374
- if(matchCount <= 0){
375
- results_ul.html('<li class="as-message">'+opts.emptyText+'</li>');
376
- }
377
- results_ul.css("width", selections_holder.outerWidth());
378
- if (matchCount > 0 || !opts.showResultListWhenNoMatch) {
379
- results_holder.show();
380
- }
381
- opts.resultsComplete.call(this);
382
- }
383
-
384
- function add_selected_item(data, num){
385
- values_input.val((values_input.val()||",")+data[opts.selectedValuesProp]+",");
386
- var item = $('<li class="as-selection-item" id="as-selection-'+num+'" data-value="' + data[opts.selectedValuesProp] + '"></li>').click(function(){
387
- opts.selectionClick.call(this, $(this));
388
- selections_holder.children().removeClass("selected");
389
- $(this).addClass("selected");
390
- }).mousedown(function(){ input_focus = false; });
391
- var close = $('<a class="as-close">&times;</a>').click(function(){
392
- values_input.val(values_input.val().replace(","+data[opts.selectedValuesProp]+",",","));
393
- opts.selectionRemoved.call(this, item);
394
- $("li.as-original input").removeAttr("disabled"); //Nayan Code Added
395
- $("ul.as-selections li.as-original").css("display","block");
396
- $(".postcode_suburb #suburb").removeAttr("value");
397
- $(".postcode_suburb #postcode").removeAttr("value");
398
- input_focus = true;
399
- input.focus();
400
- return false;
401
- });
402
- org_li.before(item.html(data[opts.selectedItemProp]).prepend(close));
403
- opts.selectionAdded.call(this, org_li.prev(), data[opts.selectedValuesProp]);
404
- $("li.as-original input").attr("disabled",true); //Nayan Code Added
405
- $("ul.as-selections li.as-original").css("display","none");
406
- return org_li.prev();
407
- }
408
-
409
- function moveSelection(direction){
410
- if($(":visible",results_holder).length > 0){
411
- var lis = $("li", results_holder);
412
- if(direction == "down"){
413
- var start = lis.eq(0);
414
- } else {
415
- var start = lis.filter(":last");
416
- }
417
- var active = $("li.active:first", results_holder);
418
- if(active.length > 0){
419
- if(direction == "down"){
420
- start = active.next();
421
- } else {
422
- start = active.prev();
423
- }
424
- }
425
- lis.removeClass("active");
426
- start.addClass("active");
427
- }
428
- }
429
-
430
- function abortRequest() {
431
- if (request) {
432
- request.abort();
433
- request = null;
434
- }
435
- }
436
-
437
- });
438
- }
439
- };
440
- })(jQuery);
1
+ /*
2
+ * AutoSuggest
3
+ * Copyright 2009-2010 Drew Wilson
4
+ * www.drewwilson.com
5
+ * code.drewwilson.com/entry/autosuggest-jquery-plugin
6
+ *
7
+ * Forked by Wu Yuntao
8
+ * github.com/wuyuntao/jquery-autosuggest
9
+ *
10
+ * Version 1.6.2
11
+ *
12
+ * This Plug-In will auto-complete or auto-suggest completed search queries
13
+ * for you as you type. You can add multiple selections and remove them on
14
+ * the fly. It supports keybord navigation (UP + DOWN + RETURN), as well
15
+ * as multiple AutoSuggest fields on the same page.
16
+ *
17
+ * Inspired by the Autocomplete plugin by: Joern Zaefferer
18
+ * and the Facelist plugin by: Ian Tearle (iantearle.com)
19
+ *
20
+ * This AutoSuggest jQuery plug-in is dual licensed under the MIT and GPL licenses:
21
+ * http://www.opensource.org/licenses/mit-license.php
22
+ * http://www.gnu.org/licenses/gpl.html
23
+ */
24
+
25
+ (function($){
26
+ $.fn.autoSuggest = function(data, options) {
27
+ var defaults = {
28
+ asHtmlID: false,
29
+ startText: "Enter Suburb / Postcode Here",
30
+ usePlaceholder: false,
31
+ emptyText: "No Results Found",
32
+ preFill: {},
33
+ limitText: "No More Selections Are Allowed",
34
+ selectedItemProp: "value", //name of object property
35
+ selectedValuesProp: "value", //name of object property
36
+ searchObjProps: "value", //comma separated list of object property names
37
+ queryParam: "q",
38
+ retrieveLimit: false, //number for 'limit' param on ajax request
39
+ extraParams: "",
40
+ matchCase: false,
41
+ minChars: 1,
42
+ keyDelay: 400,
43
+ resultsHighlight: true,
44
+ neverSubmit: false,
45
+ selectionLimit: false,
46
+ showResultList: true,
47
+ showResultListWhenNoMatch: false,
48
+ canGenerateNewSelections: true,
49
+ start: function(){},
50
+ selectionClick: function(elem){},
51
+ selectionAdded: function(elem){},
52
+ selectionRemoved: function(elem){ elem.remove(); },
53
+ formatList: false, //callback function
54
+ beforeRetrieve: function(string){ return string; },
55
+ retrieveComplete: function(data){ return data; },
56
+ resultClick: function(data){},
57
+ resultsComplete: function(){}
58
+ };
59
+ var opts = $.extend(defaults, options);
60
+
61
+ function countValidItems(data) { var n = 0; for (k in data) if (data.hasOwnProperty(k)) n++; return n; }
62
+
63
+ function getExtraParams() {
64
+ var params = opts.extraParams;
65
+ if($.isFunction(params)) {
66
+ return params();
67
+ }
68
+ return params;
69
+ }
70
+
71
+ var d_fetcher;
72
+ var request = null;
73
+ if(typeof data == "function") {
74
+ d_fetcher = data;
75
+ } else if(typeof data == "string") {
76
+ d_fetcher = function(query, next) {
77
+ var limit = "";
78
+ if(opts.retrieveLimit){
79
+ limit = "&limit="+encodeURIComponent(opts.retrieveLimit);
80
+ }
81
+ request = $.getJSON(data+"?"+opts.queryParam+"="+encodeURIComponent(query)+limit+getExtraParams(), function(data){
82
+ var new_data = opts.retrieveComplete.call(this, data);
83
+ next(new_data, query);
84
+ });
85
+ };
86
+ } else if(typeof data == "object" && countValidItems(data) > 0) {
87
+ d_fetcher = function(query, next) { next(data, query); };
88
+ }
89
+
90
+ if(d_fetcher) {
91
+ return this.each(function(x){
92
+ if(!opts.asHtmlID){
93
+ x = x+""+Math.floor(Math.random()*100); //this ensures there will be unique IDs on the page if autoSuggest() is called multiple times
94
+ var x_id = "as-input-"+x;
95
+ } else {
96
+ x = opts.asHtmlID;
97
+ var x_id = x;
98
+ }
99
+ opts.start.call(this, {
100
+ add: function(data) {
101
+ add_selected_item(data, 'u' + $('li', selections_holder).length).addClass('blur');
102
+ },
103
+ remove: function(value) {
104
+ values_input.val(values_input.val().replace(","+value+",",","));
105
+ selections_holder.find('li[data-value = "' + value + '"]').remove();
106
+ }
107
+ });
108
+ var input = $(this);
109
+ input.attr("autocomplete","off").addClass("as-input").attr("id",x_id);
110
+ if (opts.usePlaceholder) {
111
+ input.attr('placeholder', opts.startText);
112
+ } else {
113
+ input.val(opts.startText);
114
+ }
115
+ var input_focus = false;
116
+
117
+ // Setup basic elements and render them to the DOM
118
+ input.wrap('<ul class="as-selections" id="as-selections-'+x+'"></ul>').wrap('<li class="as-original" id="as-original-'+x+'"></li>');
119
+ var selections_holder = $("#as-selections-"+x);
120
+ var org_li = $("#as-original-"+x);
121
+ var results_holder = $('<div class="as-results" id="as-results-'+x+'"></div>').hide();
122
+ var results_ul = $('<ul class="as-list"></ul>');
123
+ var values_input = $('<input type="hidden" class="as-values" name="as_values_'+x+'" id="as-values-'+x+'" />');
124
+ var prefill_value = "";
125
+ if(typeof opts.preFill == "string"){
126
+ var vals = opts.preFill.split(",");
127
+ for(var i=0; i < vals.length; i++){
128
+ var v_data = {};
129
+ v_data[opts.selectedValuesProp] = vals[i];
130
+ if(vals[i] != ""){
131
+ add_selected_item(v_data, "000"+i);
132
+ }
133
+ }
134
+ prefill_value = opts.preFill;
135
+ } else {
136
+ prefill_value = "";
137
+ var prefill_count = 0;
138
+ for (k in opts.preFill) if (opts.preFill.hasOwnProperty(k)) prefill_count++;
139
+ if(prefill_count > 0){
140
+ for(var i=0; i < prefill_count; i++){
141
+ var new_v = opts.preFill[i][opts.selectedValuesProp];
142
+ if(new_v == undefined){ new_v = ""; }
143
+ prefill_value = prefill_value+new_v+",";
144
+ if(new_v != ""){
145
+ add_selected_item(opts.preFill[i], "000"+i);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ if(prefill_value != ""){
151
+ input.val("");
152
+ var lastChar = prefill_value.substring(prefill_value.length-1);
153
+ if(lastChar != ","){ prefill_value = prefill_value+","; }
154
+ values_input.val(","+prefill_value);
155
+ $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
156
+ }
157
+ input.after(values_input);
158
+ selections_holder.click(function(){
159
+ input_focus = true;
160
+ input.focus();
161
+ }).mousedown(function(){ input_focus = false; }).after(results_holder);
162
+
163
+ var interval = null;
164
+ var timeout = null;
165
+ var prev = "";
166
+ var totalSelections = 0;
167
+ var tab_press = false;
168
+ var lastKeyPressCode = null;
169
+
170
+ // Handle input field events
171
+ input.focus(function(){
172
+ if(!opts.usePlaceholder && $(this).val() == opts.startText && values_input.val() == ""){
173
+ $(this).val("");
174
+ } else if(input_focus){
175
+ $("li.as-selection-item", selections_holder).removeClass("blur");
176
+ if($(this).val() != ""){
177
+ results_ul.css("width",selections_holder.outerWidth());
178
+ results_holder.show();
179
+ }
180
+ }
181
+ if (interval) clearInterval(interval);
182
+ interval = setInterval(function() {
183
+ if(opts.showResultList){
184
+ if(opts.selectionLimit && $("li.as-selection-item", selections_holder).length >= opts.selectionLimit){
185
+ results_ul.html('<li class="as-message">'+opts.limitText+'</li>');
186
+ //results_holder.show(); // Nayan Code Added
187
+ } else {
188
+ keyChange();
189
+ }
190
+ }
191
+ }, opts.keyDelay);
192
+ input_focus = true;
193
+ if (opts.minChars == 0){
194
+ processRequest($(this).val());
195
+ }
196
+ return true;
197
+ }).blur(function(){
198
+ if (!opts.usePlaceholder && $(this).val() == "" && values_input.val() == "" && prefill_value == "" && opts.minChars > 0) {
199
+ $(this).val(opts.startText);
200
+ } else if(input_focus){
201
+ $("li.as-selection-item", selections_holder).addClass("blur").removeClass("selected");
202
+ results_holder.hide();
203
+ }
204
+ if (interval) clearInterval(interval);
205
+ }).keydown(function(e) {
206
+ // track last key pressed
207
+ lastKeyPressCode = e.keyCode;
208
+ first_focus = false;
209
+ switch(e.keyCode) {
210
+ case 38: // up
211
+ e.preventDefault();
212
+ moveSelection("up");
213
+ break;
214
+ case 40: // down
215
+ e.preventDefault();
216
+ moveSelection("down");
217
+ break;
218
+ case 8: // delete
219
+ if(input.val() == ""){
220
+ var last = values_input.val().split(",");
221
+ last = last[last.length - 2];
222
+ selections_holder.children().not(org_li.prev()).removeClass("selected");
223
+ if(org_li.prev().hasClass("selected")){
224
+ values_input.val(values_input.val().replace(","+last+",",","));
225
+ opts.selectionRemoved.call(this, org_li.prev());
226
+
227
+ $("li.as-original input").removeAttr("disabled"); //Nayan Code Added
228
+
229
+ } else {
230
+ opts.selectionClick.call(this, org_li.prev());
231
+ org_li.prev().addClass("selected");
232
+ }
233
+ }
234
+ if(input.val().length == 1){
235
+ results_holder.hide();
236
+ prev = "";
237
+ abortRequest();
238
+ }
239
+ if($(":visible",results_holder).length > 0){
240
+ if (timeout){ clearTimeout(timeout); }
241
+ timeout = setTimeout(function(){ keyChange(); }, opts.keyDelay);
242
+ }
243
+ break;
244
+ case 9: case 188: // tab or comm
245
+ if(opts.canGenerateNewSelections){
246
+ tab_press = true;
247
+ var i_input = input.val().replace(/(,)/g, "");
248
+ var active = $("li.active:first", results_holder);
249
+ // Generate a new bubble with text when no suggestion selected
250
+ if(i_input !== "" && values_input.val().search(","+i_input+",") < 0 && i_input.length >= opts.minChars && active.length === 0){
251
+ e.preventDefault();
252
+ var n_data = {};
253
+ n_data[opts.selectedItemProp] = i_input;
254
+ n_data[opts.selectedValuesProp] = i_input;
255
+ var lis = $("li", selections_holder).length;
256
+ add_selected_item(n_data, "00"+(lis+1));
257
+ input.val("");
258
+ // Cancel previous request when new tag is added
259
+ abortRequest();
260
+ break;
261
+ }
262
+ }
263
+ case 13: // return
264
+ tab_press = false;
265
+ var active = $("li.active:first", results_holder);
266
+ if(active.length > 0){
267
+ active.click();
268
+ results_holder.hide();
269
+ }
270
+ if(opts.neverSubmit || active.length > 0){
271
+ e.preventDefault();
272
+ }
273
+ break;
274
+ // ignore if the following keys are pressed: [escape] [shift] [capslock]
275
+ case 27: // escape
276
+ case 16: // shift
277
+ case 20: // capslock
278
+ abortRequest();
279
+ results_holder.hide();
280
+ break;
281
+ }
282
+ });
283
+
284
+ function keyChange() {
285
+ // Since most IME does not trigger any key events, if we press [del]
286
+ // and type some chinese character, `lastKeyPressCode` will still be [del].
287
+ // This might cause problem so we move the line to key events section;
288
+ // ignore if the following keys are pressed: [del] [shift] [capslock]
289
+ // if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ){ return results_holder.hide(); }
290
+ var string = input.val().replace(/[\\]+|[\/]+/g,"");
291
+ if (string == prev) return;
292
+ prev = string;
293
+ if (string.length >= opts.minChars) {
294
+ selections_holder.addClass("loading");
295
+ processRequest(string);
296
+ } else {
297
+ selections_holder.removeClass("loading");
298
+ results_holder.hide();
299
+ }
300
+ }
301
+ function processRequest(string){
302
+ if(opts.beforeRetrieve){
303
+ string = opts.beforeRetrieve.call(this, string);
304
+ }
305
+ abortRequest();
306
+ d_fetcher(string, processData);
307
+ }
308
+ var num_count = 0;
309
+ function processData(data, query){
310
+ if (!opts.matchCase){ query = query.toLowerCase(); }
311
+ query = query.replace("(", "\\(", "g").replace(")", "\\)", "g");
312
+ var matchCount = 0;
313
+ results_holder.html(results_ul.html("")).hide();
314
+ var d_count = countValidItems(data);
315
+ for(var i=0;i<d_count;i++){
316
+ var num = i;
317
+ num_count++;
318
+ var forward = false;
319
+ if(opts.searchObjProps == "value") {
320
+ var str = data[num].value;
321
+ } else {
322
+ var str = "";
323
+ var names = opts.searchObjProps.split(",");
324
+ for(var y=0;y<names.length;y++){
325
+ var name = $.trim(names[y]);
326
+ str = str+data[num][name]+" ";
327
+ }
328
+ }
329
+ if(str){
330
+ if (!opts.matchCase){ str = str.toLowerCase(); }
331
+ if(str.search(query) != -1 && values_input.val().search(","+data[num][opts.selectedValuesProp]+",") == -1){
332
+ forward = true;
333
+ }
334
+ }
335
+ if(forward){
336
+ var formatted = $('<li class="as-result-item" id="as-result-item-'+num+'"></li>').click(function(){
337
+ var raw_data = $(this).data("data");
338
+ var number = raw_data.num;
339
+ if($("#as-selection-"+number, selections_holder).length <= 0 && !tab_press){
340
+ var data = raw_data.attributes;
341
+ input.val("").focus();
342
+ prev = "";
343
+ add_selected_item(data, number);
344
+ opts.resultClick.call(this, raw_data);
345
+ results_holder.hide();
346
+ }
347
+ tab_press = false;
348
+ }).mousedown(function(){ input_focus = false; }).mouseover(function(){
349
+ $("li", results_ul).removeClass("active");
350
+ $(this).addClass("active");
351
+ }).data("data",{attributes: data[num], num: num_count});
352
+ var this_data = $.extend({},data[num]);
353
+ if (!opts.matchCase){
354
+ var regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi");
355
+ } else {
356
+ var regx = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "g");
357
+ }
358
+
359
+ if(opts.resultsHighlight && query.length > 0){
360
+ this_data[opts.selectedItemProp] = this_data[opts.selectedItemProp].replace(regx,"<em>$1</em>");
361
+ }
362
+ if(!opts.formatList){
363
+ formatted = formatted.html(this_data[opts.selectedItemProp]);
364
+ } else {
365
+ formatted = opts.formatList.call(this, this_data, formatted);
366
+ }
367
+ results_ul.append(formatted);
368
+ delete this_data;
369
+ matchCount++;
370
+ if(opts.retrieveLimit && opts.retrieveLimit == matchCount ){ break; }
371
+ }
372
+ }
373
+ selections_holder.removeClass("loading");
374
+ if(matchCount <= 0){
375
+ results_ul.html('<li class="as-message">'+opts.emptyText+'</li>');
376
+ }
377
+ results_ul.css("width", selections_holder.outerWidth());
378
+ if (matchCount > 0 || !opts.showResultListWhenNoMatch) {
379
+ results_holder.show();
380
+ }
381
+ opts.resultsComplete.call(this);
382
+ }
383
+
384
+ function add_selected_item(data, num){
385
+ values_input.val((values_input.val()||",")+data[opts.selectedValuesProp]+",");
386
+ var item = $('<li class="as-selection-item" id="as-selection-'+num+'" data-value="' + data[opts.selectedValuesProp] + '"></li>').click(function(){
387
+ opts.selectionClick.call(this, $(this));
388
+ selections_holder.children().removeClass("selected");
389
+ $(this).addClass("selected");
390
+ }).mousedown(function(){ input_focus = false; });
391
+ var close = $('<a class="as-close">&times;</a>').click(function(){
392
+ values_input.val(values_input.val().replace(","+data[opts.selectedValuesProp]+",",","));
393
+ opts.selectionRemoved.call(this, item);
394
+ $("li.as-original input").removeAttr("disabled"); //Nayan Code Added
395
+ $("ul.as-selections li.as-original").css("display","block");
396
+ $(".postcode_suburb #suburb").removeAttr("value");
397
+ $(".postcode_suburb #postcode").removeAttr("value");
398
+ input_focus = true;
399
+ input.focus();
400
+ return false;
401
+ });
402
+ org_li.before(item.html(data[opts.selectedItemProp]).prepend(close));
403
+ opts.selectionAdded.call(this, org_li.prev(), data[opts.selectedValuesProp]);
404
+ $("li.as-original input").attr("disabled",true); //Nayan Code Added
405
+ $("ul.as-selections li.as-original").css("display","none");
406
+ return org_li.prev();
407
+ }
408
+
409
+ function moveSelection(direction){
410
+ if($(":visible",results_holder).length > 0){
411
+ var lis = $("li", results_holder);
412
+ if(direction == "down"){
413
+ var start = lis.eq(0);
414
+ } else {
415
+ var start = lis.filter(":last");
416
+ }
417
+ var active = $("li.active:first", results_holder);
418
+ if(active.length > 0){
419
+ if(direction == "down"){
420
+ start = active.next();
421
+ } else {
422
+ start = active.prev();
423
+ }
424
+ }
425
+ lis.removeClass("active");
426
+ start.addClass("active");
427
+ }
428
+ }
429
+
430
+ function abortRequest() {
431
+ if (request) {
432
+ request.abort();
433
+ request = null;
434
+ }
435
+ }
436
+
437
+ });
438
+ }
439
+ };
440
+ })(jQuery);
skin/frontend/{default/default/ship/css/bkp_4-7-2014----jquery.autoSuggest.css → rwd/default/ship/css/jquery.autoSuggest.css} RENAMED
@@ -1,253 +1,257 @@
1
- /* AutoSuggest CSS - Version 1.2 */
2
-
3
- ul.as-selections {
4
- list-style-type: none;
5
- border-top: 1px solid #888;
6
- border-bottom: 1px solid #b6b6b6;
7
- border-left: 1px solid #aaa;
8
- border-right: 1px solid #aaa;
9
- padding: 4px 0 4px 4px;
10
- margin: 0;
11
- overflow: auto;
12
- background-color: #fff;
13
- box-shadow:inset 0 1px 2px #888;
14
- -webkit-box-shadow:inset 0 1px 2px #888;
15
- -moz-box-shadow:inset 0 1px 2px #888;
16
- }
17
-
18
- ul.as-selections.loading {
19
- background-color: #eee;
20
- }
21
-
22
- ul.as-selections li {
23
- float: left;
24
- margin: 1px 4px 1px 0;
25
- width:90%;
26
- }
27
-
28
- ul.as-selections li.as-selection-item {
29
- color: #2b3840;
30
- font-size: 13px;
31
- font-family: "Lucida Grande", arial, sans-serif;
32
- text-shadow: 0 1px 1px #fff;
33
- background-color: #ddeefe;
34
- background-image: -moz-linear-gradient(top, #ddeefe, #bfe0f1);
35
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddeefe), to(#bfe0f1));
36
- border: 1px solid #acc3ec;
37
- border-top-color: #c0d9e9;
38
- padding: 2px 7px 2px 10px;
39
- border-radius: 12px;
40
- -webkit-border-radius: 12px;
41
- -moz-border-radius: 12px;
42
- box-shadow: 0 1px 1px #e4edf2;
43
- -webkit-box-shadow: 0 1px 1px #e4edf2;
44
- -moz-box-shadow: 0 1px 1px #e4edf2;
45
- }
46
-
47
- ul.as-selections li.as-selection-item:last-child {
48
- margin-left: 30px;
49
- }
50
-
51
- ul.as-selections li.as-selection-item a.as-close {
52
- float: right;
53
- margin: 1px 0 0 7px;
54
- padding: 0 2px;
55
- cursor: pointer;
56
- color: #5491be;
57
- font-family: "Helvetica", helvetica, arial, sans-serif;
58
- font-size: 14px;
59
- font-weight: bold;
60
- text-shadow: 0 1px 1px #fff;
61
- -webkit-transition: color .1s ease-in;
62
- }
63
-
64
- ul.as-selections li.as-selection-item.blur {
65
- color: #666666;
66
- background-color: #f4f4f4;
67
- background-image: -moz-linear-gradient(top, #f4f4f4, #d5d5d5);
68
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f4f4f4), to(#d5d5d5));
69
- border-color: #bbb;
70
- border-top-color: #ccc;
71
- box-shadow: 0 1px 1px #e9e9e9;
72
- -webkit-box-shadow: 0 1px 1px #e9e9e9;
73
- -moz-box-shadow: 0 1px 1px #e9e9e9;
74
- }
75
-
76
- ul.as-selections li.as-selection-item.blur a.as-close {
77
- color: #999;
78
- }
79
-
80
- ul.as-selections li:hover.as-selection-item {
81
- color: #2b3840;
82
- background-color: #bbd4f1;
83
- background-image: -moz-linear-gradient(top, #bbd4f1, #a3c2e5);
84
- background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbd4f1), to(#a3c2e5));
85
- border-color: #6da0e0;
86
- border-top-color: #8bb7ed;
87
- }
88
-
89
- ul.as-selections li:hover.as-selection-item a.as-close {
90
- color: #4d70b0;
91
- }
92
-
93
- ul.as-selections li.as-selection-item.selected {
94
- border-color: #1f30e4;
95
- }
96
-
97
- ul.as-selections li.as-selection-item a:hover.as-close {
98
- color: #1b3c65;
99
- }
100
-
101
- ul.as-selections li.as-selection-item a:active.as-close {
102
- color: #4d70b0;
103
- }
104
-
105
- ul.as-selections li.as-original {
106
- margin-left: 0;
107
- }
108
-
109
- ul.as-selections li.as-original input {
110
- border: none;
111
- outline: none;
112
- font-size: 13px;
113
- width: 120px;
114
- height: 18px;
115
- padding-top: 3px;
116
- width:100%;
117
- }
118
- .catalog-product-view ul.as-selections li.as-original input {font-size:11px;}
119
- ul.as-selections li.as-original input[type=text]:disabled { background: none; }
120
-
121
- ul.as-list {
122
- position: absolute;
123
- list-style-type: none;
124
- margin: 2px 0 0 0;
125
- padding: 0;
126
- font-size: 14px;
127
- color: #000;
128
- font-family: "Lucida Grande", arial, sans-serif;
129
- background-color: #fff;
130
- background-color: rgba(255,255,255,0.95);
131
- z-index: 2;
132
- box-shadow: 0 2px 12px #222;
133
- -webkit-box-shadow: 0 2px 12px #222;
134
- -moz-box-shadow: 0 2px 12px #222;
135
- border-radius: 5px;
136
- -webkit-border-radius: 5px;
137
- -moz-border-radius: 5px;
138
- max-height:290px;
139
- min-height:33px;
140
- overflow-y: auto;
141
- }
142
-
143
- li.as-result-item, li.as-message {
144
- margin: 0 0 0 0;
145
- padding: 5px 12px;
146
- background-color: transparent;
147
- border: 1px solid #fff;
148
- border-bottom: 1px solid #ddd;
149
- cursor: pointer;
150
- border-radius: 5px;
151
- -webkit-border-radius: 5px;
152
- -moz-border-radius: 5px;
153
- }
154
-
155
- li:first-child.as-result-item {
156
- margin: 0;
157
- }
158
-
159
- li.as-message {
160
- margin: 0;
161
- cursor: default;
162
- }
163
-
164
- li.as-result-item.active {
165
- background-color: #ddeefe;
166
- background-image: -moz-linear-gradient(top, #ddeefe, #ddeefe);
167
- background-image: -webkit-gradient(linear, 0% 0%, 0% 64%, from(rgb(110, 129, 245)), to(rgb(62, 82, 242)));
168
- border-color: #ddeefe;
169
- color: #000;
170
- text-shadow:none;
171
- }
172
-
173
- li.as-result-item em {
174
- font-style: normal;
175
- /*background: #444;
176
- color: #fff;*/
177
- background: none;
178
- color: #000;
179
- padding: 0px;
180
- }
181
-
182
- li.as-result-item.active em {
183
- /*background: #253f7a;
184
- color: #fff;*/
185
- background: none;
186
- color: #000;
187
- }
188
-
189
- /* Webkit Hacks */
190
- @media screen and (-webkit-min-device-pixel-ratio:0) {
191
- ul.as-selections {
192
- border-top-width: 2px;
193
- }
194
- ul.as-selections li.as-selection-item {
195
- padding-top: 3px;
196
- padding-bottom: 3px;
197
- }
198
- ul.as-selections li.as-selection-item a.as-close {
199
- margin-top: -1px;
200
- }
201
- ul.as-selections li.as-original input {
202
- height: 19px;
203
- }
204
- }
205
-
206
- /* Opera Hacks */
207
- @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
208
- ul.as-list {
209
- border: 1px solid #888;
210
- }
211
- ul.as-selections li.as-selection-item a.as-close {
212
- margin-left: 4px;
213
- margin-top: 0;
214
- }
215
- }
216
-
217
- /* IE Hacks */
218
- ul.as-list {
219
- border: 1px solid #888\9;
220
- }
221
- ul.as-selections li.as-selection-item a.as-close {
222
- margin-left: 4px\9;
223
- margin-top: 0\9;
224
- }
225
-
226
- /* Firefox 3.0 Hacks */
227
- ul.as-list, x:-moz-any-link, x:default {
228
- border: 1px solid #888;
229
- }
230
- BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */
231
- border: none;
232
- }
233
-
234
- .previous-selection {
235
- float: left;
236
- margin-top: 10px;
237
- width: 100%;
238
- }
239
- .previous-selection .text {
240
- float: left;
241
- font-size: 13px;
242
- font-weight: bold;
243
- }
244
- .previous-selection .post {
245
- float: left;
246
- width: 100%;
247
- font-weight: bold;
248
- }
249
- .previous-selection .locality {
250
- float: left;
251
- width: 100%;
252
- font-weight: bold;
 
 
 
 
253
  }
1
+ /* AutoSuggest CSS - Version 1.2 */
2
+
3
+ ul.as-selections {
4
+ list-style-type: none;
5
+ border-top: 1px solid #888;
6
+ border-bottom: 1px solid #b6b6b6;
7
+ border-left: 1px solid #aaa;
8
+ border-right: 1px solid #aaa;
9
+ padding: 0 0 0 4px;
10
+ margin: 0;
11
+ overflow: auto;
12
+ background-color: #fff;
13
+ /*box-shadow:inset 0 1px 2px #888;
14
+ -webkit-box-shadow:inset 0 1px 2px #888;
15
+ -moz-box-shadow:inset 0 1px 2px #888;*/
16
+ }
17
+
18
+ ul.as-selections.loading {
19
+ background-color: #eee;
20
+ }
21
+
22
+ ul.as-selections li {
23
+ float: left;
24
+ margin: 0px 4px 0px 0;
25
+ /*width:90%;*/
26
+ width:91%;
27
+ }
28
+
29
+ ul.as-selections li.as-selection-item {
30
+ color: #2b3840;
31
+ font-size: 12px;
32
+ font-family: "Lucida Grande", arial, sans-serif;
33
+ text-shadow: 0 1px 1px #fff;
34
+ padding: 2px 5px 0;
35
+ /*border: 1px solid #747474;
36
+ border-top-color: #747474;
37
+ background-color: #ddeefe;
38
+ background-image: -moz-linear-gradient(top, #ddeefe, #bfe0f1);
39
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ddeefe), to(#bfe0f1));
40
+ border-radius: 12px;
41
+ -webkit-border-radius: 12px;
42
+ -moz-border-radius: 12px;
43
+ box-shadow: 0 1px 1px #e4edf2;
44
+ -webkit-box-shadow: 0 1px 1px #e4edf2;
45
+ -moz-box-shadow: 0 1px 1px #e4edf2;*/
46
+ }
47
+
48
+ ul.as-selections li.as-selection-item:last-child {
49
+ margin-left: 30px;
50
+ }
51
+
52
+ ul.as-selections li.as-selection-item a.as-close {
53
+ float: right;
54
+ margin: -4px 0 -2px 7px;
55
+ padding: 0 2px;
56
+ cursor: pointer;
57
+ color: #747474;
58
+ font-family: "Helvetica", helvetica, arial, sans-serif;
59
+ font-size: 17px;
60
+ text-decoration:none;
61
+ font-weight: bold;
62
+ text-shadow: 0 1px 1px #fff;
63
+ -webkit-transition: color .1s ease-in;
64
+ }
65
+
66
+ ul.as-selections li.as-selection-item.blur {
67
+ color: #666666;
68
+ background-color: #f4f4f4;
69
+ background-image: -moz-linear-gradient(top, #f4f4f4, #d5d5d5);
70
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f4f4f4), to(#d5d5d5));
71
+ border-color: #bbb;
72
+ border-top-color: #ccc;
73
+ box-shadow: 0 1px 1px #e9e9e9;
74
+ -webkit-box-shadow: 0 1px 1px #e9e9e9;
75
+ -moz-box-shadow: 0 1px 1px #e9e9e9;
76
+ }
77
+
78
+ ul.as-selections li.as-selection-item.blur a.as-close {
79
+ color: #999;
80
+ }
81
+
82
+ ul.as-selections li:hover.as-selection-item {
83
+ /*color: #2b3840;
84
+ background-color: #bbd4f1;
85
+ background-image: -moz-linear-gradient(top, #bbd4f1, #a3c2e5);
86
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bbd4f1), to(#a3c2e5));
87
+ border-color: #6da0e0;
88
+ border-top-color: #8bb7ed;*/
89
+ }
90
+
91
+ ul.as-selections li:hover.as-selection-item a.as-close {
92
+ color: #4d70b0;
93
+ }
94
+
95
+ ul.as-selections li.as-selection-item.selected {
96
+ /*border-color: #1f30e4;*/
97
+ }
98
+
99
+ ul.as-selections li.as-selection-item a:hover.as-close {
100
+ color: #1b3c65;
101
+ }
102
+
103
+ ul.as-selections li.as-selection-item a:active.as-close {
104
+ color: #4d70b0;
105
+ }
106
+
107
+ ul.as-selections li.as-original {
108
+ margin-left: 0;
109
+ }
110
+
111
+ ul.as-selections li.as-original input {
112
+ border: none;
113
+ outline: none;
114
+ font-size: 12px;
115
+ width: 120px;
116
+ height: 18px;
117
+ /*padding-top: 3px;*/
118
+ width:100%;
119
+ }
120
+ .catalog-product-view ul.as-selections li.as-original input {font-size:11px;}
121
+ ul.as-selections li.as-original input[type=text]:disabled { background: none; }
122
+
123
+ ul.as-list {
124
+ position: absolute;
125
+ list-style-type: none;
126
+ margin: 2px 0 0 0;
127
+ padding: 0;
128
+ font-size: 12px;
129
+ color: #000;
130
+ font-family: "Lucida Grande", arial, sans-serif;
131
+ background-color: #fff;
132
+ background-color: rgba(255,255,255,0.95);
133
+ z-index: 2;
134
+ box-shadow: 0 2px 12px #222;
135
+ -webkit-box-shadow: 0 2px 12px #222;
136
+ -moz-box-shadow: 0 2px 12px #222;
137
+ border-radius: 5px;
138
+ -webkit-border-radius: 5px;
139
+ -moz-border-radius: 5px;
140
+ max-height:290px;
141
+ min-height:33px;
142
+ overflow-y: auto;
143
+ }
144
+
145
+ li.as-result-item, li.as-message {
146
+ margin: 0 0 0 0;
147
+ padding: 5px 12px;
148
+ background-color: transparent;
149
+ border: 1px solid #fff;
150
+ border-bottom: 1px solid #ddd;
151
+ cursor: pointer;
152
+ border-radius: 5px;
153
+ -webkit-border-radius: 5px;
154
+ -moz-border-radius: 5px;
155
+ }
156
+
157
+ li:first-child.as-result-item {
158
+ margin: 0;
159
+ }
160
+
161
+ li.as-message {
162
+ margin: 0;
163
+ cursor: default;
164
+ }
165
+
166
+ li.as-result-item.active {
167
+ background-color: #ddeefe;
168
+ background-image: -moz-linear-gradient(top, #ddeefe, #ddeefe);
169
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 64%, from(rgb(110, 129, 245)), to(rgb(62, 82, 242)));
170
+ border-color: #ddeefe;
171
+ color: #000;
172
+ text-shadow:none;
173
+ }
174
+
175
+ li.as-result-item em {
176
+ font-style: normal;
177
+ /*background: #444;
178
+ color: #fff;*/
179
+ background: none;
180
+ color: #000;
181
+ padding: 0px;
182
+ }
183
+
184
+ li.as-result-item.active em {
185
+ /*background: #253f7a;
186
+ color: #fff;*/
187
+ background: none;
188
+ color: #000;
189
+ }
190
+
191
+ /* Webkit Hacks */
192
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
193
+ ul.as-selections {
194
+ border-top-width: 2px;
195
+ }
196
+ ul.as-selections li.as-selection-item {
197
+ padding-top: 3px;
198
+ padding-bottom: 3px;
199
+ }
200
+ ul.as-selections li.as-selection-item a.as-close {
201
+ margin-top: -1px;
202
+ }
203
+ ul.as-selections li.as-original input {
204
+ height: 19px;
205
+ }
206
+ }
207
+
208
+ /* Opera Hacks */
209
+ @media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
210
+ ul.as-list {
211
+ border: 1px solid #888;
212
+ }
213
+ ul.as-selections li.as-selection-item a.as-close {
214
+ margin-left: 4px;
215
+ margin-top: 0;
216
+ }
217
+ }
218
+
219
+ /* IE Hacks */
220
+ ul.as-list {
221
+ border: 1px solid #888\9;
222
+ }
223
+ ul.as-selections li.as-selection-item a.as-close {
224
+ margin-left: 4px\9;
225
+ margin-top: 0\9;
226
+ }
227
+
228
+ /* Firefox 3.0 Hacks */
229
+ ul.as-list, x:-moz-any-link, x:default {
230
+ border: 1px solid #888;
231
+ }
232
+ BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */
233
+ border: none;
234
+ }
235
+
236
+ .as-results .as-message {/* display:none;*/}
237
+
238
+ .previous-selection {
239
+ float: left;
240
+ margin-top: 10px;
241
+ width: 100%;
242
+ }
243
+ .previous-selection .text {
244
+ float: left;
245
+ font-size: 13px;
246
+ font-weight: bold;
247
+ }
248
+ .previous-selection .post {
249
+ float: left;
250
+ width: 100%;
251
+ font-weight: bold;
252
+ }
253
+ .previous-selection .locality {
254
+ float: left;
255
+ width: 100%;
256
+ font-weight: bold;
257
  }
skin/frontend/rwd/default/ship/js/jquery-1.11.0.js ADDED
@@ -0,0 +1,10337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * jQuery JavaScript Library v1.11.0
3
+ * http://jquery.com/
4
+ *
5
+ * Includes Sizzle.js
6
+ * http://sizzlejs.com/
7
+ *
8
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
9
+ * Released under the MIT license
10
+ * http://jquery.org/license
11
+ *
12
+ * Date: 2014-01-23T21:02Z
13
+ */
14
+
15
+ (function( global, factory ) {
16
+
17
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
18
+ // For CommonJS and CommonJS-like environments where a proper window is present,
19
+ // execute the factory and get jQuery
20
+ // For environments that do not inherently posses a window with a document
21
+ // (such as Node.js), expose a jQuery-making factory as module.exports
22
+ // This accentuates the need for the creation of a real window
23
+ // e.g. var jQuery = require("jquery")(window);
24
+ // See ticket #14549 for more info
25
+ module.exports = global.document ?
26
+ factory( global, true ) :
27
+ function( w ) {
28
+ if ( !w.document ) {
29
+ throw new Error( "jQuery requires a window with a document" );
30
+ }
31
+ return factory( w );
32
+ };
33
+ } else {
34
+ factory( global );
35
+ }
36
+
37
+ // Pass this if window is not defined yet
38
+ }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
39
+
40
+ // Can't do this because several apps including ASP.NET trace
41
+ // the stack via arguments.caller.callee and Firefox dies if
42
+ // you try to trace through "use strict" call chains. (#13335)
43
+ // Support: Firefox 18+
44
+ //
45
+
46
+ var deletedIds = [];
47
+
48
+ var slice = deletedIds.slice;
49
+
50
+ var concat = deletedIds.concat;
51
+
52
+ var push = deletedIds.push;
53
+
54
+ var indexOf = deletedIds.indexOf;
55
+
56
+ var class2type = {};
57
+
58
+ var toString = class2type.toString;
59
+
60
+ var hasOwn = class2type.hasOwnProperty;
61
+
62
+ var trim = "".trim;
63
+
64
+ var support = {};
65
+
66
+
67
+
68
+ var
69
+ version = "1.11.0",
70
+
71
+ // Define a local copy of jQuery
72
+ jQuery = function( selector, context ) {
73
+ // The jQuery object is actually just the init constructor 'enhanced'
74
+ // Need init if jQuery is called (just allow error to be thrown if not included)
75
+ return new jQuery.fn.init( selector, context );
76
+ },
77
+
78
+ // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
79
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
80
+
81
+ // Matches dashed string for camelizing
82
+ rmsPrefix = /^-ms-/,
83
+ rdashAlpha = /-([\da-z])/gi,
84
+
85
+ // Used by jQuery.camelCase as callback to replace()
86
+ fcamelCase = function( all, letter ) {
87
+ return letter.toUpperCase();
88
+ };
89
+
90
+ jQuery.fn = jQuery.prototype = {
91
+ // The current version of jQuery being used
92
+ jquery: version,
93
+
94
+ constructor: jQuery,
95
+
96
+ // Start with an empty selector
97
+ selector: "",
98
+
99
+ // The default length of a jQuery object is 0
100
+ length: 0,
101
+
102
+ toArray: function() {
103
+ return slice.call( this );
104
+ },
105
+
106
+ // Get the Nth element in the matched element set OR
107
+ // Get the whole matched element set as a clean array
108
+ get: function( num ) {
109
+ return num != null ?
110
+
111
+ // Return a 'clean' array
112
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
113
+
114
+ // Return just the object
115
+ slice.call( this );
116
+ },
117
+
118
+ // Take an array of elements and push it onto the stack
119
+ // (returning the new matched element set)
120
+ pushStack: function( elems ) {
121
+
122
+ // Build a new jQuery matched element set
123
+ var ret = jQuery.merge( this.constructor(), elems );
124
+
125
+ // Add the old object onto the stack (as a reference)
126
+ ret.prevObject = this;
127
+ ret.context = this.context;
128
+
129
+ // Return the newly-formed element set
130
+ return ret;
131
+ },
132
+
133
+ // Execute a callback for every element in the matched set.
134
+ // (You can seed the arguments with an array of args, but this is
135
+ // only used internally.)
136
+ each: function( callback, args ) {
137
+ return jQuery.each( this, callback, args );
138
+ },
139
+
140
+ map: function( callback ) {
141
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
142
+ return callback.call( elem, i, elem );
143
+ }));
144
+ },
145
+
146
+ slice: function() {
147
+ return this.pushStack( slice.apply( this, arguments ) );
148
+ },
149
+
150
+ first: function() {
151
+ return this.eq( 0 );
152
+ },
153
+
154
+ last: function() {
155
+ return this.eq( -1 );
156
+ },
157
+
158
+ eq: function( i ) {
159
+ var len = this.length,
160
+ j = +i + ( i < 0 ? len : 0 );
161
+ return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
162
+ },
163
+
164
+ end: function() {
165
+ return this.prevObject || this.constructor(null);
166
+ },
167
+
168
+ // For internal use only.
169
+ // Behaves like an Array's method, not like a jQuery method.
170
+ push: push,
171
+ sort: deletedIds.sort,
172
+ splice: deletedIds.splice
173
+ };
174
+
175
+ jQuery.extend = jQuery.fn.extend = function() {
176
+ var src, copyIsArray, copy, name, options, clone,
177
+ target = arguments[0] || {},
178
+ i = 1,
179
+ length = arguments.length,
180
+ deep = false;
181
+
182
+ // Handle a deep copy situation
183
+ if ( typeof target === "boolean" ) {
184
+ deep = target;
185
+
186
+ // skip the boolean and the target
187
+ target = arguments[ i ] || {};
188
+ i++;
189
+ }
190
+
191
+ // Handle case when target is a string or something (possible in deep copy)
192
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
193
+ target = {};
194
+ }
195
+
196
+ // extend jQuery itself if only one argument is passed
197
+ if ( i === length ) {
198
+ target = this;
199
+ i--;
200
+ }
201
+
202
+ for ( ; i < length; i++ ) {
203
+ // Only deal with non-null/undefined values
204
+ if ( (options = arguments[ i ]) != null ) {
205
+ // Extend the base object
206
+ for ( name in options ) {
207
+ src = target[ name ];
208
+ copy = options[ name ];
209
+
210
+ // Prevent never-ending loop
211
+ if ( target === copy ) {
212
+ continue;
213
+ }
214
+
215
+ // Recurse if we're merging plain objects or arrays
216
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
217
+ if ( copyIsArray ) {
218
+ copyIsArray = false;
219
+ clone = src && jQuery.isArray(src) ? src : [];
220
+
221
+ } else {
222
+ clone = src && jQuery.isPlainObject(src) ? src : {};
223
+ }
224
+
225
+ // Never move original objects, clone them
226
+ target[ name ] = jQuery.extend( deep, clone, copy );
227
+
228
+ // Don't bring in undefined values
229
+ } else if ( copy !== undefined ) {
230
+ target[ name ] = copy;
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ // Return the modified object
237
+ return target;
238
+ };
239
+
240
+ jQuery.extend({
241
+ // Unique for each copy of jQuery on the page
242
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
243
+
244
+ // Assume jQuery is ready without the ready module
245
+ isReady: true,
246
+
247
+ error: function( msg ) {
248
+ throw new Error( msg );
249
+ },
250
+
251
+ noop: function() {},
252
+
253
+ // See test/unit/core.js for details concerning isFunction.
254
+ // Since version 1.3, DOM methods and functions like alert
255
+ // aren't supported. They return false on IE (#2968).
256
+ isFunction: function( obj ) {
257
+ return jQuery.type(obj) === "function";
258
+ },
259
+
260
+ isArray: Array.isArray || function( obj ) {
261
+ return jQuery.type(obj) === "array";
262
+ },
263
+
264
+ isWindow: function( obj ) {
265
+ /* jshint eqeqeq: false */
266
+ return obj != null && obj == obj.window;
267
+ },
268
+
269
+ isNumeric: function( obj ) {
270
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
271
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
272
+ // subtraction forces infinities to NaN
273
+ return obj - parseFloat( obj ) >= 0;
274
+ },
275
+
276
+ isEmptyObject: function( obj ) {
277
+ var name;
278
+ for ( name in obj ) {
279
+ return false;
280
+ }
281
+ return true;
282
+ },
283
+
284
+ isPlainObject: function( obj ) {
285
+ var key;
286
+
287
+ // Must be an Object.
288
+ // Because of IE, we also have to check the presence of the constructor property.
289
+ // Make sure that DOM nodes and window objects don't pass through, as well
290
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
291
+ return false;
292
+ }
293
+
294
+ try {
295
+ // Not own constructor property must be Object
296
+ if ( obj.constructor &&
297
+ !hasOwn.call(obj, "constructor") &&
298
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
299
+ return false;
300
+ }
301
+ } catch ( e ) {
302
+ // IE8,9 Will throw exceptions on certain host objects #9897
303
+ return false;
304
+ }
305
+
306
+ // Support: IE<9
307
+ // Handle iteration over inherited properties before own properties.
308
+ if ( support.ownLast ) {
309
+ for ( key in obj ) {
310
+ return hasOwn.call( obj, key );
311
+ }
312
+ }
313
+
314
+ // Own properties are enumerated firstly, so to speed up,
315
+ // if last one is own, then all properties are own.
316
+ for ( key in obj ) {}
317
+
318
+ return key === undefined || hasOwn.call( obj, key );
319
+ },
320
+
321
+ type: function( obj ) {
322
+ if ( obj == null ) {
323
+ return obj + "";
324
+ }
325
+ return typeof obj === "object" || typeof obj === "function" ?
326
+ class2type[ toString.call(obj) ] || "object" :
327
+ typeof obj;
328
+ },
329
+
330
+ // Evaluates a script in a global context
331
+ // Workarounds based on findings by Jim Driscoll
332
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
333
+ globalEval: function( data ) {
334
+ if ( data && jQuery.trim( data ) ) {
335
+ // We use execScript on Internet Explorer
336
+ // We use an anonymous function so that context is window
337
+ // rather than jQuery in Firefox
338
+ ( window.execScript || function( data ) {
339
+ window[ "eval" ].call( window, data );
340
+ } )( data );
341
+ }
342
+ },
343
+
344
+ // Convert dashed to camelCase; used by the css and data modules
345
+ // Microsoft forgot to hump their vendor prefix (#9572)
346
+ camelCase: function( string ) {
347
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
348
+ },
349
+
350
+ nodeName: function( elem, name ) {
351
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
352
+ },
353
+
354
+ // args is for internal usage only
355
+ each: function( obj, callback, args ) {
356
+ var value,
357
+ i = 0,
358
+ length = obj.length,
359
+ isArray = isArraylike( obj );
360
+
361
+ if ( args ) {
362
+ if ( isArray ) {
363
+ for ( ; i < length; i++ ) {
364
+ value = callback.apply( obj[ i ], args );
365
+
366
+ if ( value === false ) {
367
+ break;
368
+ }
369
+ }
370
+ } else {
371
+ for ( i in obj ) {
372
+ value = callback.apply( obj[ i ], args );
373
+
374
+ if ( value === false ) {
375
+ break;
376
+ }
377
+ }
378
+ }
379
+
380
+ // A special, fast, case for the most common use of each
381
+ } else {
382
+ if ( isArray ) {
383
+ for ( ; i < length; i++ ) {
384
+ value = callback.call( obj[ i ], i, obj[ i ] );
385
+
386
+ if ( value === false ) {
387
+ break;
388
+ }
389
+ }
390
+ } else {
391
+ for ( i in obj ) {
392
+ value = callback.call( obj[ i ], i, obj[ i ] );
393
+
394
+ if ( value === false ) {
395
+ break;
396
+ }
397
+ }
398
+ }
399
+ }
400
+
401
+ return obj;
402
+ },
403
+
404
+ // Use native String.trim function wherever possible
405
+ trim: trim && !trim.call("\uFEFF\xA0") ?
406
+ function( text ) {
407
+ return text == null ?
408
+ "" :
409
+ trim.call( text );
410
+ } :
411
+
412
+ // Otherwise use our own trimming functionality
413
+ function( text ) {
414
+ return text == null ?
415
+ "" :
416
+ ( text + "" ).replace( rtrim, "" );
417
+ },
418
+
419
+ // results is for internal usage only
420
+ makeArray: function( arr, results ) {
421
+ var ret = results || [];
422
+
423
+ if ( arr != null ) {
424
+ if ( isArraylike( Object(arr) ) ) {
425
+ jQuery.merge( ret,
426
+ typeof arr === "string" ?
427
+ [ arr ] : arr
428
+ );
429
+ } else {
430
+ push.call( ret, arr );
431
+ }
432
+ }
433
+
434
+ return ret;
435
+ },
436
+
437
+ inArray: function( elem, arr, i ) {
438
+ var len;
439
+
440
+ if ( arr ) {
441
+ if ( indexOf ) {
442
+ return indexOf.call( arr, elem, i );
443
+ }
444
+
445
+ len = arr.length;
446
+ i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
447
+
448
+ for ( ; i < len; i++ ) {
449
+ // Skip accessing in sparse arrays
450
+ if ( i in arr && arr[ i ] === elem ) {
451
+ return i;
452
+ }
453
+ }
454
+ }
455
+
456
+ return -1;
457
+ },
458
+
459
+ merge: function( first, second ) {
460
+ var len = +second.length,
461
+ j = 0,
462
+ i = first.length;
463
+
464
+ while ( j < len ) {
465
+ first[ i++ ] = second[ j++ ];
466
+ }
467
+
468
+ // Support: IE<9
469
+ // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
470
+ if ( len !== len ) {
471
+ while ( second[j] !== undefined ) {
472
+ first[ i++ ] = second[ j++ ];
473
+ }
474
+ }
475
+
476
+ first.length = i;
477
+
478
+ return first;
479
+ },
480
+
481
+ grep: function( elems, callback, invert ) {
482
+ var callbackInverse,
483
+ matches = [],
484
+ i = 0,
485
+ length = elems.length,
486
+ callbackExpect = !invert;
487
+
488
+ // Go through the array, only saving the items
489
+ // that pass the validator function
490
+ for ( ; i < length; i++ ) {
491
+ callbackInverse = !callback( elems[ i ], i );
492
+ if ( callbackInverse !== callbackExpect ) {
493
+ matches.push( elems[ i ] );
494
+ }
495
+ }
496
+
497
+ return matches;
498
+ },
499
+
500
+ // arg is for internal usage only
501
+ map: function( elems, callback, arg ) {
502
+ var value,
503
+ i = 0,
504
+ length = elems.length,
505
+ isArray = isArraylike( elems ),
506
+ ret = [];
507
+
508
+ // Go through the array, translating each of the items to their new values
509
+ if ( isArray ) {
510
+ for ( ; i < length; i++ ) {
511
+ value = callback( elems[ i ], i, arg );
512
+
513
+ if ( value != null ) {
514
+ ret.push( value );
515
+ }
516
+ }
517
+
518
+ // Go through every key on the object,
519
+ } else {
520
+ for ( i in elems ) {
521
+ value = callback( elems[ i ], i, arg );
522
+
523
+ if ( value != null ) {
524
+ ret.push( value );
525
+ }
526
+ }
527
+ }
528
+
529
+ // Flatten any nested arrays
530
+ return concat.apply( [], ret );
531
+ },
532
+
533
+ // A global GUID counter for objects
534
+ guid: 1,
535
+
536
+ // Bind a function to a context, optionally partially applying any
537
+ // arguments.
538
+ proxy: function( fn, context ) {
539
+ var args, proxy, tmp;
540
+
541
+ if ( typeof context === "string" ) {
542
+ tmp = fn[ context ];
543
+ context = fn;
544
+ fn = tmp;
545
+ }
546
+
547
+ // Quick check to determine if target is callable, in the spec
548
+ // this throws a TypeError, but we will just return undefined.
549
+ if ( !jQuery.isFunction( fn ) ) {
550
+ return undefined;
551
+ }
552
+
553
+ // Simulated bind
554
+ args = slice.call( arguments, 2 );
555
+ proxy = function() {
556
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
557
+ };
558
+
559
+ // Set the guid of unique handler to the same of original handler, so it can be removed
560
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
561
+
562
+ return proxy;
563
+ },
564
+
565
+ now: function() {
566
+ return +( new Date() );
567
+ },
568
+
569
+ // jQuery.support is not used in Core but other projects attach their
570
+ // properties to it so it needs to exist.
571
+ support: support
572
+ });
573
+
574
+ // Populate the class2type map
575
+ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
576
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
577
+ });
578
+
579
+ function isArraylike( obj ) {
580
+ var length = obj.length,
581
+ type = jQuery.type( obj );
582
+
583
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
584
+ return false;
585
+ }
586
+
587
+ if ( obj.nodeType === 1 && length ) {
588
+ return true;
589
+ }
590
+
591
+ return type === "array" || length === 0 ||
592
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
593
+ }
594
+ var Sizzle =
595
+ /*!
596
+ * Sizzle CSS Selector Engine v1.10.16
597
+ * http://sizzlejs.com/
598
+ *
599
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
600
+ * Released under the MIT license
601
+ * http://jquery.org/license
602
+ *
603
+ * Date: 2014-01-13
604
+ */
605
+ (function( window ) {
606
+
607
+ var i,
608
+ support,
609
+ Expr,
610
+ getText,
611
+ isXML,
612
+ compile,
613
+ outermostContext,
614
+ sortInput,
615
+ hasDuplicate,
616
+
617
+ // Local document vars
618
+ setDocument,
619
+ document,
620
+ docElem,
621
+ documentIsHTML,
622
+ rbuggyQSA,
623
+ rbuggyMatches,
624
+ matches,
625
+ contains,
626
+
627
+ // Instance-specific data
628
+ expando = "sizzle" + -(new Date()),
629
+ preferredDoc = window.document,
630
+ dirruns = 0,
631
+ done = 0,
632
+ classCache = createCache(),
633
+ tokenCache = createCache(),
634
+ compilerCache = createCache(),
635
+ sortOrder = function( a, b ) {
636
+ if ( a === b ) {
637
+ hasDuplicate = true;
638
+ }
639
+ return 0;
640
+ },
641
+
642
+ // General-purpose constants
643
+ strundefined = typeof undefined,
644
+ MAX_NEGATIVE = 1 << 31,
645
+
646
+ // Instance methods
647
+ hasOwn = ({}).hasOwnProperty,
648
+ arr = [],
649
+ pop = arr.pop,
650
+ push_native = arr.push,
651
+ push = arr.push,
652
+ slice = arr.slice,
653
+ // Use a stripped-down indexOf if we can't use a native one
654
+ indexOf = arr.indexOf || function( elem ) {
655
+ var i = 0,
656
+ len = this.length;
657
+ for ( ; i < len; i++ ) {
658
+ if ( this[i] === elem ) {
659
+ return i;
660
+ }
661
+ }
662
+ return -1;
663
+ },
664
+
665
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
666
+
667
+ // Regular expressions
668
+
669
+ // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
670
+ whitespace = "[\\x20\\t\\r\\n\\f]",
671
+ // http://www.w3.org/TR/css3-syntax/#characters
672
+ characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
673
+
674
+ // Loosely modeled on CSS identifier characters
675
+ // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
676
+ // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
677
+ identifier = characterEncoding.replace( "w", "w#" ),
678
+
679
+ // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
680
+ attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
681
+ "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
682
+
683
+ // Prefer arguments quoted,
684
+ // then not containing pseudos/brackets,
685
+ // then attribute selectors/non-parenthetical expressions,
686
+ // then anything else
687
+ // These preferences are here to reduce the number of selectors
688
+ // needing tokenize in the PSEUDO preFilter
689
+ pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
690
+
691
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
692
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
693
+
694
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
695
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
696
+
697
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
698
+
699
+ rpseudo = new RegExp( pseudos ),
700
+ ridentifier = new RegExp( "^" + identifier + "$" ),
701
+
702
+ matchExpr = {
703
+ "ID": new RegExp( "^#(" + characterEncoding + ")" ),
704
+ "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
705
+ "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
706
+ "ATTR": new RegExp( "^" + attributes ),
707
+ "PSEUDO": new RegExp( "^" + pseudos ),
708
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
709
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
710
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
711
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
712
+ // For use in libraries implementing .is()
713
+ // We use this for POS matching in `select`
714
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
715
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
716
+ },
717
+
718
+ rinputs = /^(?:input|select|textarea|button)$/i,
719
+ rheader = /^h\d$/i,
720
+
721
+ rnative = /^[^{]+\{\s*\[native \w/,
722
+
723
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
724
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
725
+
726
+ rsibling = /[+~]/,
727
+ rescape = /'|\\/g,
728
+
729
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
730
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
731
+ funescape = function( _, escaped, escapedWhitespace ) {
732
+ var high = "0x" + escaped - 0x10000;
733
+ // NaN means non-codepoint
734
+ // Support: Firefox
735
+ // Workaround erroneous numeric interpretation of +"0x"
736
+ return high !== high || escapedWhitespace ?
737
+ escaped :
738
+ high < 0 ?
739
+ // BMP codepoint
740
+ String.fromCharCode( high + 0x10000 ) :
741
+ // Supplemental Plane codepoint (surrogate pair)
742
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
743
+ };
744
+
745
+ // Optimize for push.apply( _, NodeList )
746
+ try {
747
+ push.apply(
748
+ (arr = slice.call( preferredDoc.childNodes )),
749
+ preferredDoc.childNodes
750
+ );
751
+ // Support: Android<4.0
752
+ // Detect silently failing push.apply
753
+ arr[ preferredDoc.childNodes.length ].nodeType;
754
+ } catch ( e ) {
755
+ push = { apply: arr.length ?
756
+
757
+ // Leverage slice if possible
758
+ function( target, els ) {
759
+ push_native.apply( target, slice.call(els) );
760
+ } :
761
+
762
+ // Support: IE<9
763
+ // Otherwise append directly
764
+ function( target, els ) {
765
+ var j = target.length,
766
+ i = 0;
767
+ // Can't trust NodeList.length
768
+ while ( (target[j++] = els[i++]) ) {}
769
+ target.length = j - 1;
770
+ }
771
+ };
772
+ }
773
+
774
+ function Sizzle( selector, context, results, seed ) {
775
+ var match, elem, m, nodeType,
776
+ // QSA vars
777
+ i, groups, old, nid, newContext, newSelector;
778
+
779
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
780
+ setDocument( context );
781
+ }
782
+
783
+ context = context || document;
784
+ results = results || [];
785
+
786
+ if ( !selector || typeof selector !== "string" ) {
787
+ return results;
788
+ }
789
+
790
+ if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
791
+ return [];
792
+ }
793
+
794
+ if ( documentIsHTML && !seed ) {
795
+
796
+ // Shortcuts
797
+ if ( (match = rquickExpr.exec( selector )) ) {
798
+ // Speed-up: Sizzle("#ID")
799
+ if ( (m = match[1]) ) {
800
+ if ( nodeType === 9 ) {
801
+ elem = context.getElementById( m );
802
+ // Check parentNode to catch when Blackberry 4.6 returns
803
+ // nodes that are no longer in the document (jQuery #6963)
804
+ if ( elem && elem.parentNode ) {
805
+ // Handle the case where IE, Opera, and Webkit return items
806
+ // by name instead of ID
807
+ if ( elem.id === m ) {
808
+ results.push( elem );
809
+ return results;
810
+ }
811
+ } else {
812
+ return results;
813
+ }
814
+ } else {
815
+ // Context is not a document
816
+ if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
817
+ contains( context, elem ) && elem.id === m ) {
818
+ results.push( elem );
819
+ return results;
820
+ }
821
+ }
822
+
823
+ // Speed-up: Sizzle("TAG")
824
+ } else if ( match[2] ) {
825
+ push.apply( results, context.getElementsByTagName( selector ) );
826
+ return results;
827
+
828
+ // Speed-up: Sizzle(".CLASS")
829
+ } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
830
+ push.apply( results, context.getElementsByClassName( m ) );
831
+ return results;
832
+ }
833
+ }
834
+
835
+ // QSA path
836
+ if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
837
+ nid = old = expando;
838
+ newContext = context;
839
+ newSelector = nodeType === 9 && selector;
840
+
841
+ // qSA works strangely on Element-rooted queries
842
+ // We can work around this by specifying an extra ID on the root
843
+ // and working up from there (Thanks to Andrew Dupont for the technique)
844
+ // IE 8 doesn't work on object elements
845
+ if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
846
+ groups = tokenize( selector );
847
+
848
+ if ( (old = context.getAttribute("id")) ) {
849
+ nid = old.replace( rescape, "\\$&" );
850
+ } else {
851
+ context.setAttribute( "id", nid );
852
+ }
853
+ nid = "[id='" + nid + "'] ";
854
+
855
+ i = groups.length;
856
+ while ( i-- ) {
857
+ groups[i] = nid + toSelector( groups[i] );
858
+ }
859
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
860
+ newSelector = groups.join(",");
861
+ }
862
+
863
+ if ( newSelector ) {
864
+ try {
865
+ push.apply( results,
866
+ newContext.querySelectorAll( newSelector )
867
+ );
868
+ return results;
869
+ } catch(qsaError) {
870
+ } finally {
871
+ if ( !old ) {
872
+ context.removeAttribute("id");
873
+ }
874
+ }
875
+ }
876
+ }
877
+ }
878
+
879
+ // All others
880
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
881
+ }
882
+
883
+ /**
884
+ * Create key-value caches of limited size
885
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
886
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
887
+ * deleting the oldest entry
888
+ */
889
+ function createCache() {
890
+ var keys = [];
891
+
892
+ function cache( key, value ) {
893
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
894
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
895
+ // Only keep the most recent entries
896
+ delete cache[ keys.shift() ];
897
+ }
898
+ return (cache[ key + " " ] = value);
899
+ }
900
+ return cache;
901
+ }
902
+
903
+ /**
904
+ * Mark a function for special use by Sizzle
905
+ * @param {Function} fn The function to mark
906
+ */
907
+ function markFunction( fn ) {
908
+ fn[ expando ] = true;
909
+ return fn;
910
+ }
911
+
912
+ /**
913
+ * Support testing using an element
914
+ * @param {Function} fn Passed the created div and expects a boolean result
915
+ */
916
+ function assert( fn ) {
917
+ var div = document.createElement("div");
918
+
919
+ try {
920
+ return !!fn( div );
921
+ } catch (e) {
922
+ return false;
923
+ } finally {
924
+ // Remove from its parent by default
925
+ if ( div.parentNode ) {
926
+ div.parentNode.removeChild( div );
927
+ }
928
+ // release memory in IE
929
+ div = null;
930
+ }
931
+ }
932
+
933
+ /**
934
+ * Adds the same handler for all of the specified attrs
935
+ * @param {String} attrs Pipe-separated list of attributes
936
+ * @param {Function} handler The method that will be applied
937
+ */
938
+ function addHandle( attrs, handler ) {
939
+ var arr = attrs.split("|"),
940
+ i = attrs.length;
941
+
942
+ while ( i-- ) {
943
+ Expr.attrHandle[ arr[i] ] = handler;
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Checks document order of two siblings
949
+ * @param {Element} a
950
+ * @param {Element} b
951
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
952
+ */
953
+ function siblingCheck( a, b ) {
954
+ var cur = b && a,
955
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
956
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
957
+ ( ~a.sourceIndex || MAX_NEGATIVE );
958
+
959
+ // Use IE sourceIndex if available on both nodes
960
+ if ( diff ) {
961
+ return diff;
962
+ }
963
+
964
+ // Check if b follows a
965
+ if ( cur ) {
966
+ while ( (cur = cur.nextSibling) ) {
967
+ if ( cur === b ) {
968
+ return -1;
969
+ }
970
+ }
971
+ }
972
+
973
+ return a ? 1 : -1;
974
+ }
975
+
976
+ /**
977
+ * Returns a function to use in pseudos for input types
978
+ * @param {String} type
979
+ */
980
+ function createInputPseudo( type ) {
981
+ return function( elem ) {
982
+ var name = elem.nodeName.toLowerCase();
983
+ return name === "input" && elem.type === type;
984
+ };
985
+ }
986
+
987
+ /**
988
+ * Returns a function to use in pseudos for buttons
989
+ * @param {String} type
990
+ */
991
+ function createButtonPseudo( type ) {
992
+ return function( elem ) {
993
+ var name = elem.nodeName.toLowerCase();
994
+ return (name === "input" || name === "button") && elem.type === type;
995
+ };
996
+ }
997
+
998
+ /**
999
+ * Returns a function to use in pseudos for positionals
1000
+ * @param {Function} fn
1001
+ */
1002
+ function createPositionalPseudo( fn ) {
1003
+ return markFunction(function( argument ) {
1004
+ argument = +argument;
1005
+ return markFunction(function( seed, matches ) {
1006
+ var j,
1007
+ matchIndexes = fn( [], seed.length, argument ),
1008
+ i = matchIndexes.length;
1009
+
1010
+ // Match elements found at the specified indexes
1011
+ while ( i-- ) {
1012
+ if ( seed[ (j = matchIndexes[i]) ] ) {
1013
+ seed[j] = !(matches[j] = seed[j]);
1014
+ }
1015
+ }
1016
+ });
1017
+ });
1018
+ }
1019
+
1020
+ /**
1021
+ * Checks a node for validity as a Sizzle context
1022
+ * @param {Element|Object=} context
1023
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1024
+ */
1025
+ function testContext( context ) {
1026
+ return context && typeof context.getElementsByTagName !== strundefined && context;
1027
+ }
1028
+
1029
+ // Expose support vars for convenience
1030
+ support = Sizzle.support = {};
1031
+
1032
+ /**
1033
+ * Detects XML nodes
1034
+ * @param {Element|Object} elem An element or a document
1035
+ * @returns {Boolean} True iff elem is a non-HTML XML node
1036
+ */
1037
+ isXML = Sizzle.isXML = function( elem ) {
1038
+ // documentElement is verified for cases where it doesn't yet exist
1039
+ // (such as loading iframes in IE - #4833)
1040
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1041
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
1042
+ };
1043
+
1044
+ /**
1045
+ * Sets document-related variables once based on the current document
1046
+ * @param {Element|Object} [doc] An element or document object to use to set the document
1047
+ * @returns {Object} Returns the current document
1048
+ */
1049
+ setDocument = Sizzle.setDocument = function( node ) {
1050
+ var hasCompare,
1051
+ doc = node ? node.ownerDocument || node : preferredDoc,
1052
+ parent = doc.defaultView;
1053
+
1054
+ // If no document and documentElement is available, return
1055
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1056
+ return document;
1057
+ }
1058
+
1059
+ // Set our document
1060
+ document = doc;
1061
+ docElem = doc.documentElement;
1062
+
1063
+ // Support tests
1064
+ documentIsHTML = !isXML( doc );
1065
+
1066
+ // Support: IE>8
1067
+ // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1068
+ // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1069
+ // IE6-8 do not support the defaultView property so parent will be undefined
1070
+ if ( parent && parent !== parent.top ) {
1071
+ // IE11 does not have attachEvent, so all must suffer
1072
+ if ( parent.addEventListener ) {
1073
+ parent.addEventListener( "unload", function() {
1074
+ setDocument();
1075
+ }, false );
1076
+ } else if ( parent.attachEvent ) {
1077
+ parent.attachEvent( "onunload", function() {
1078
+ setDocument();
1079
+ });
1080
+ }
1081
+ }
1082
+
1083
+ /* Attributes
1084
+ ---------------------------------------------------------------------- */
1085
+
1086
+ // Support: IE<8
1087
+ // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1088
+ support.attributes = assert(function( div ) {
1089
+ div.className = "i";
1090
+ return !div.getAttribute("className");
1091
+ });
1092
+
1093
+ /* getElement(s)By*
1094
+ ---------------------------------------------------------------------- */
1095
+
1096
+ // Check if getElementsByTagName("*") returns only elements
1097
+ support.getElementsByTagName = assert(function( div ) {
1098
+ div.appendChild( doc.createComment("") );
1099
+ return !div.getElementsByTagName("*").length;
1100
+ });
1101
+
1102
+ // Check if getElementsByClassName can be trusted
1103
+ support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1104
+ div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1105
+
1106
+ // Support: Safari<4
1107
+ // Catch class over-caching
1108
+ div.firstChild.className = "i";
1109
+ // Support: Opera<10
1110
+ // Catch gEBCN failure to find non-leading classes
1111
+ return div.getElementsByClassName("i").length === 2;
1112
+ });
1113
+
1114
+ // Support: IE<10
1115
+ // Check if getElementById returns elements by name
1116
+ // The broken getElementById methods don't pick up programatically-set names,
1117
+ // so use a roundabout getElementsByName test
1118
+ support.getById = assert(function( div ) {
1119
+ docElem.appendChild( div ).id = expando;
1120
+ return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1121
+ });
1122
+
1123
+ // ID find and filter
1124
+ if ( support.getById ) {
1125
+ Expr.find["ID"] = function( id, context ) {
1126
+ if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1127
+ var m = context.getElementById( id );
1128
+ // Check parentNode to catch when Blackberry 4.6 returns
1129
+ // nodes that are no longer in the document #6963
1130
+ return m && m.parentNode ? [m] : [];
1131
+ }
1132
+ };
1133
+ Expr.filter["ID"] = function( id ) {
1134
+ var attrId = id.replace( runescape, funescape );
1135
+ return function( elem ) {
1136
+ return elem.getAttribute("id") === attrId;
1137
+ };
1138
+ };
1139
+ } else {
1140
+ // Support: IE6/7
1141
+ // getElementById is not reliable as a find shortcut
1142
+ delete Expr.find["ID"];
1143
+
1144
+ Expr.filter["ID"] = function( id ) {
1145
+ var attrId = id.replace( runescape, funescape );
1146
+ return function( elem ) {
1147
+ var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1148
+ return node && node.value === attrId;
1149
+ };
1150
+ };
1151
+ }
1152
+
1153
+ // Tag
1154
+ Expr.find["TAG"] = support.getElementsByTagName ?
1155
+ function( tag, context ) {
1156
+ if ( typeof context.getElementsByTagName !== strundefined ) {
1157
+ return context.getElementsByTagName( tag );
1158
+ }
1159
+ } :
1160
+ function( tag, context ) {
1161
+ var elem,
1162
+ tmp = [],
1163
+ i = 0,
1164
+ results = context.getElementsByTagName( tag );
1165
+
1166
+ // Filter out possible comments
1167
+ if ( tag === "*" ) {
1168
+ while ( (elem = results[i++]) ) {
1169
+ if ( elem.nodeType === 1 ) {
1170
+ tmp.push( elem );
1171
+ }
1172
+ }
1173
+
1174
+ return tmp;
1175
+ }
1176
+ return results;
1177
+ };
1178
+
1179
+ // Class
1180
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1181
+ if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1182
+ return context.getElementsByClassName( className );
1183
+ }
1184
+ };
1185
+
1186
+ /* QSA/matchesSelector
1187
+ ---------------------------------------------------------------------- */
1188
+
1189
+ // QSA and matchesSelector support
1190
+
1191
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1192
+ rbuggyMatches = [];
1193
+
1194
+ // qSa(:focus) reports false when true (Chrome 21)
1195
+ // We allow this because of a bug in IE8/9 that throws an error
1196
+ // whenever `document.activeElement` is accessed on an iframe
1197
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
1198
+ // See http://bugs.jquery.com/ticket/13378
1199
+ rbuggyQSA = [];
1200
+
1201
+ if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1202
+ // Build QSA regex
1203
+ // Regex strategy adopted from Diego Perini
1204
+ assert(function( div ) {
1205
+ // Select is set to empty string on purpose
1206
+ // This is to test IE's treatment of not explicitly
1207
+ // setting a boolean content attribute,
1208
+ // since its presence should be enough
1209
+ // http://bugs.jquery.com/ticket/12359
1210
+ div.innerHTML = "<select t=''><option selected=''></option></select>";
1211
+
1212
+ // Support: IE8, Opera 10-12
1213
+ // Nothing should be selected when empty strings follow ^= or $= or *=
1214
+ if ( div.querySelectorAll("[t^='']").length ) {
1215
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1216
+ }
1217
+
1218
+ // Support: IE8
1219
+ // Boolean attributes and "value" are not treated correctly
1220
+ if ( !div.querySelectorAll("[selected]").length ) {
1221
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1222
+ }
1223
+
1224
+ // Webkit/Opera - :checked should return selected option elements
1225
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1226
+ // IE8 throws error here and will not see later tests
1227
+ if ( !div.querySelectorAll(":checked").length ) {
1228
+ rbuggyQSA.push(":checked");
1229
+ }
1230
+ });
1231
+
1232
+ assert(function( div ) {
1233
+ // Support: Windows 8 Native Apps
1234
+ // The type and name attributes are restricted during .innerHTML assignment
1235
+ var input = doc.createElement("input");
1236
+ input.setAttribute( "type", "hidden" );
1237
+ div.appendChild( input ).setAttribute( "name", "D" );
1238
+
1239
+ // Support: IE8
1240
+ // Enforce case-sensitivity of name attribute
1241
+ if ( div.querySelectorAll("[name=d]").length ) {
1242
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1243
+ }
1244
+
1245
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1246
+ // IE8 throws error here and will not see later tests
1247
+ if ( !div.querySelectorAll(":enabled").length ) {
1248
+ rbuggyQSA.push( ":enabled", ":disabled" );
1249
+ }
1250
+
1251
+ // Opera 10-11 does not throw on post-comma invalid pseudos
1252
+ div.querySelectorAll("*,:x");
1253
+ rbuggyQSA.push(",.*:");
1254
+ });
1255
+ }
1256
+
1257
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1258
+ docElem.mozMatchesSelector ||
1259
+ docElem.oMatchesSelector ||
1260
+ docElem.msMatchesSelector) )) ) {
1261
+
1262
+ assert(function( div ) {
1263
+ // Check to see if it's possible to do matchesSelector
1264
+ // on a disconnected node (IE 9)
1265
+ support.disconnectedMatch = matches.call( div, "div" );
1266
+
1267
+ // This should fail with an exception
1268
+ // Gecko does not error, returns false instead
1269
+ matches.call( div, "[s!='']:x" );
1270
+ rbuggyMatches.push( "!=", pseudos );
1271
+ });
1272
+ }
1273
+
1274
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1275
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1276
+
1277
+ /* Contains
1278
+ ---------------------------------------------------------------------- */
1279
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
1280
+
1281
+ // Element contains another
1282
+ // Purposefully does not implement inclusive descendent
1283
+ // As in, an element does not contain itself
1284
+ contains = hasCompare || rnative.test( docElem.contains ) ?
1285
+ function( a, b ) {
1286
+ var adown = a.nodeType === 9 ? a.documentElement : a,
1287
+ bup = b && b.parentNode;
1288
+ return a === bup || !!( bup && bup.nodeType === 1 && (
1289
+ adown.contains ?
1290
+ adown.contains( bup ) :
1291
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1292
+ ));
1293
+ } :
1294
+ function( a, b ) {
1295
+ if ( b ) {
1296
+ while ( (b = b.parentNode) ) {
1297
+ if ( b === a ) {
1298
+ return true;
1299
+ }
1300
+ }
1301
+ }
1302
+ return false;
1303
+ };
1304
+
1305
+ /* Sorting
1306
+ ---------------------------------------------------------------------- */
1307
+
1308
+ // Document order sorting
1309
+ sortOrder = hasCompare ?
1310
+ function( a, b ) {
1311
+
1312
+ // Flag for duplicate removal
1313
+ if ( a === b ) {
1314
+ hasDuplicate = true;
1315
+ return 0;
1316
+ }
1317
+
1318
+ // Sort on method existence if only one input has compareDocumentPosition
1319
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1320
+ if ( compare ) {
1321
+ return compare;
1322
+ }
1323
+
1324
+ // Calculate position if both inputs belong to the same document
1325
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1326
+ a.compareDocumentPosition( b ) :
1327
+
1328
+ // Otherwise we know they are disconnected
1329
+ 1;
1330
+
1331
+ // Disconnected nodes
1332
+ if ( compare & 1 ||
1333
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1334
+
1335
+ // Choose the first element that is related to our preferred document
1336
+ if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1337
+ return -1;
1338
+ }
1339
+ if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1340
+ return 1;
1341
+ }
1342
+
1343
+ // Maintain original order
1344
+ return sortInput ?
1345
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1346
+ 0;
1347
+ }
1348
+
1349
+ return compare & 4 ? -1 : 1;
1350
+ } :
1351
+ function( a, b ) {
1352
+ // Exit early if the nodes are identical
1353
+ if ( a === b ) {
1354
+ hasDuplicate = true;
1355
+ return 0;
1356
+ }
1357
+
1358
+ var cur,
1359
+ i = 0,
1360
+ aup = a.parentNode,
1361
+ bup = b.parentNode,
1362
+ ap = [ a ],
1363
+ bp = [ b ];
1364
+
1365
+ // Parentless nodes are either documents or disconnected
1366
+ if ( !aup || !bup ) {
1367
+ return a === doc ? -1 :
1368
+ b === doc ? 1 :
1369
+ aup ? -1 :
1370
+ bup ? 1 :
1371
+ sortInput ?
1372
+ ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1373
+ 0;
1374
+
1375
+ // If the nodes are siblings, we can do a quick check
1376
+ } else if ( aup === bup ) {
1377
+ return siblingCheck( a, b );
1378
+ }
1379
+
1380
+ // Otherwise we need full lists of their ancestors for comparison
1381
+ cur = a;
1382
+ while ( (cur = cur.parentNode) ) {
1383
+ ap.unshift( cur );
1384
+ }
1385
+ cur = b;
1386
+ while ( (cur = cur.parentNode) ) {
1387
+ bp.unshift( cur );
1388
+ }
1389
+
1390
+ // Walk down the tree looking for a discrepancy
1391
+ while ( ap[i] === bp[i] ) {
1392
+ i++;
1393
+ }
1394
+
1395
+ return i ?
1396
+ // Do a sibling check if the nodes have a common ancestor
1397
+ siblingCheck( ap[i], bp[i] ) :
1398
+
1399
+ // Otherwise nodes in our document sort first
1400
+ ap[i] === preferredDoc ? -1 :
1401
+ bp[i] === preferredDoc ? 1 :
1402
+ 0;
1403
+ };
1404
+
1405
+ return doc;
1406
+ };
1407
+
1408
+ Sizzle.matches = function( expr, elements ) {
1409
+ return Sizzle( expr, null, null, elements );
1410
+ };
1411
+
1412
+ Sizzle.matchesSelector = function( elem, expr ) {
1413
+ // Set document vars if needed
1414
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1415
+ setDocument( elem );
1416
+ }
1417
+
1418
+ // Make sure that attribute selectors are quoted
1419
+ expr = expr.replace( rattributeQuotes, "='$1']" );
1420
+
1421
+ if ( support.matchesSelector && documentIsHTML &&
1422
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1423
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1424
+
1425
+ try {
1426
+ var ret = matches.call( elem, expr );
1427
+
1428
+ // IE 9's matchesSelector returns false on disconnected nodes
1429
+ if ( ret || support.disconnectedMatch ||
1430
+ // As well, disconnected nodes are said to be in a document
1431
+ // fragment in IE 9
1432
+ elem.document && elem.document.nodeType !== 11 ) {
1433
+ return ret;
1434
+ }
1435
+ } catch(e) {}
1436
+ }
1437
+
1438
+ return Sizzle( expr, document, null, [elem] ).length > 0;
1439
+ };
1440
+
1441
+ Sizzle.contains = function( context, elem ) {
1442
+ // Set document vars if needed
1443
+ if ( ( context.ownerDocument || context ) !== document ) {
1444
+ setDocument( context );
1445
+ }
1446
+ return contains( context, elem );
1447
+ };
1448
+
1449
+ Sizzle.attr = function( elem, name ) {
1450
+ // Set document vars if needed
1451
+ if ( ( elem.ownerDocument || elem ) !== document ) {
1452
+ setDocument( elem );
1453
+ }
1454
+
1455
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
1456
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
1457
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1458
+ fn( elem, name, !documentIsHTML ) :
1459
+ undefined;
1460
+
1461
+ return val !== undefined ?
1462
+ val :
1463
+ support.attributes || !documentIsHTML ?
1464
+ elem.getAttribute( name ) :
1465
+ (val = elem.getAttributeNode(name)) && val.specified ?
1466
+ val.value :
1467
+ null;
1468
+ };
1469
+
1470
+ Sizzle.error = function( msg ) {
1471
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
1472
+ };
1473
+
1474
+ /**
1475
+ * Document sorting and removing duplicates
1476
+ * @param {ArrayLike} results
1477
+ */
1478
+ Sizzle.uniqueSort = function( results ) {
1479
+ var elem,
1480
+ duplicates = [],
1481
+ j = 0,
1482
+ i = 0;
1483
+
1484
+ // Unless we *know* we can detect duplicates, assume their presence
1485
+ hasDuplicate = !support.detectDuplicates;
1486
+ sortInput = !support.sortStable && results.slice( 0 );
1487
+ results.sort( sortOrder );
1488
+
1489
+ if ( hasDuplicate ) {
1490
+ while ( (elem = results[i++]) ) {
1491
+ if ( elem === results[ i ] ) {
1492
+ j = duplicates.push( i );
1493
+ }
1494
+ }
1495
+ while ( j-- ) {
1496
+ results.splice( duplicates[ j ], 1 );
1497
+ }
1498
+ }
1499
+
1500
+ // Clear input after sorting to release objects
1501
+ // See https://github.com/jquery/sizzle/pull/225
1502
+ sortInput = null;
1503
+
1504
+ return results;
1505
+ };
1506
+
1507
+ /**
1508
+ * Utility function for retrieving the text value of an array of DOM nodes
1509
+ * @param {Array|Element} elem
1510
+ */
1511
+ getText = Sizzle.getText = function( elem ) {
1512
+ var node,
1513
+ ret = "",
1514
+ i = 0,
1515
+ nodeType = elem.nodeType;
1516
+
1517
+ if ( !nodeType ) {
1518
+ // If no nodeType, this is expected to be an array
1519
+ while ( (node = elem[i++]) ) {
1520
+ // Do not traverse comment nodes
1521
+ ret += getText( node );
1522
+ }
1523
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1524
+ // Use textContent for elements
1525
+ // innerText usage removed for consistency of new lines (jQuery #11153)
1526
+ if ( typeof elem.textContent === "string" ) {
1527
+ return elem.textContent;
1528
+ } else {
1529
+ // Traverse its children
1530
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1531
+ ret += getText( elem );
1532
+ }
1533
+ }
1534
+ } else if ( nodeType === 3 || nodeType === 4 ) {
1535
+ return elem.nodeValue;
1536
+ }
1537
+ // Do not include comment or processing instruction nodes
1538
+
1539
+ return ret;
1540
+ };
1541
+
1542
+ Expr = Sizzle.selectors = {
1543
+
1544
+ // Can be adjusted by the user
1545
+ cacheLength: 50,
1546
+
1547
+ createPseudo: markFunction,
1548
+
1549
+ match: matchExpr,
1550
+
1551
+ attrHandle: {},
1552
+
1553
+ find: {},
1554
+
1555
+ relative: {
1556
+ ">": { dir: "parentNode", first: true },
1557
+ " ": { dir: "parentNode" },
1558
+ "+": { dir: "previousSibling", first: true },
1559
+ "~": { dir: "previousSibling" }
1560
+ },
1561
+
1562
+ preFilter: {
1563
+ "ATTR": function( match ) {
1564
+ match[1] = match[1].replace( runescape, funescape );
1565
+
1566
+ // Move the given value to match[3] whether quoted or unquoted
1567
+ match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1568
+
1569
+ if ( match[2] === "~=" ) {
1570
+ match[3] = " " + match[3] + " ";
1571
+ }
1572
+
1573
+ return match.slice( 0, 4 );
1574
+ },
1575
+
1576
+ "CHILD": function( match ) {
1577
+ /* matches from matchExpr["CHILD"]
1578
+ 1 type (only|nth|...)
1579
+ 2 what (child|of-type)
1580
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1581
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
1582
+ 5 sign of xn-component
1583
+ 6 x of xn-component
1584
+ 7 sign of y-component
1585
+ 8 y of y-component
1586
+ */
1587
+ match[1] = match[1].toLowerCase();
1588
+
1589
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
1590
+ // nth-* requires argument
1591
+ if ( !match[3] ) {
1592
+ Sizzle.error( match[0] );
1593
+ }
1594
+
1595
+ // numeric x and y parameters for Expr.filter.CHILD
1596
+ // remember that false/true cast respectively to 0/1
1597
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1598
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1599
+
1600
+ // other types prohibit arguments
1601
+ } else if ( match[3] ) {
1602
+ Sizzle.error( match[0] );
1603
+ }
1604
+
1605
+ return match;
1606
+ },
1607
+
1608
+ "PSEUDO": function( match ) {
1609
+ var excess,
1610
+ unquoted = !match[5] && match[2];
1611
+
1612
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
1613
+ return null;
1614
+ }
1615
+
1616
+ // Accept quoted arguments as-is
1617
+ if ( match[3] && match[4] !== undefined ) {
1618
+ match[2] = match[4];
1619
+
1620
+ // Strip excess characters from unquoted arguments
1621
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
1622
+ // Get excess from tokenize (recursively)
1623
+ (excess = tokenize( unquoted, true )) &&
1624
+ // advance to the next closing parenthesis
1625
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1626
+
1627
+ // excess is a negative index
1628
+ match[0] = match[0].slice( 0, excess );
1629
+ match[2] = unquoted.slice( 0, excess );
1630
+ }
1631
+
1632
+ // Return only captures needed by the pseudo filter method (type and argument)
1633
+ return match.slice( 0, 3 );
1634
+ }
1635
+ },
1636
+
1637
+ filter: {
1638
+
1639
+ "TAG": function( nodeNameSelector ) {
1640
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1641
+ return nodeNameSelector === "*" ?
1642
+ function() { return true; } :
1643
+ function( elem ) {
1644
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1645
+ };
1646
+ },
1647
+
1648
+ "CLASS": function( className ) {
1649
+ var pattern = classCache[ className + " " ];
1650
+
1651
+ return pattern ||
1652
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1653
+ classCache( className, function( elem ) {
1654
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1655
+ });
1656
+ },
1657
+
1658
+ "ATTR": function( name, operator, check ) {
1659
+ return function( elem ) {
1660
+ var result = Sizzle.attr( elem, name );
1661
+
1662
+ if ( result == null ) {
1663
+ return operator === "!=";
1664
+ }
1665
+ if ( !operator ) {
1666
+ return true;
1667
+ }
1668
+
1669
+ result += "";
1670
+
1671
+ return operator === "=" ? result === check :
1672
+ operator === "!=" ? result !== check :
1673
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
1674
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
1675
+ operator === "$=" ? check && result.slice( -check.length ) === check :
1676
+ operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1677
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1678
+ false;
1679
+ };
1680
+ },
1681
+
1682
+ "CHILD": function( type, what, argument, first, last ) {
1683
+ var simple = type.slice( 0, 3 ) !== "nth",
1684
+ forward = type.slice( -4 ) !== "last",
1685
+ ofType = what === "of-type";
1686
+
1687
+ return first === 1 && last === 0 ?
1688
+
1689
+ // Shortcut for :nth-*(n)
1690
+ function( elem ) {
1691
+ return !!elem.parentNode;
1692
+ } :
1693
+
1694
+ function( elem, context, xml ) {
1695
+ var cache, outerCache, node, diff, nodeIndex, start,
1696
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
1697
+ parent = elem.parentNode,
1698
+ name = ofType && elem.nodeName.toLowerCase(),
1699
+ useCache = !xml && !ofType;
1700
+
1701
+ if ( parent ) {
1702
+
1703
+ // :(first|last|only)-(child|of-type)
1704
+ if ( simple ) {
1705
+ while ( dir ) {
1706
+ node = elem;
1707
+ while ( (node = node[ dir ]) ) {
1708
+ if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1709
+ return false;
1710
+ }
1711
+ }
1712
+ // Reverse direction for :only-* (if we haven't yet done so)
1713
+ start = dir = type === "only" && !start && "nextSibling";
1714
+ }
1715
+ return true;
1716
+ }
1717
+
1718
+ start = [ forward ? parent.firstChild : parent.lastChild ];
1719
+
1720
+ // non-xml :nth-child(...) stores cache data on `parent`
1721
+ if ( forward && useCache ) {
1722
+ // Seek `elem` from a previously-cached index
1723
+ outerCache = parent[ expando ] || (parent[ expando ] = {});
1724
+ cache = outerCache[ type ] || [];
1725
+ nodeIndex = cache[0] === dirruns && cache[1];
1726
+ diff = cache[0] === dirruns && cache[2];
1727
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
1728
+
1729
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1730
+
1731
+ // Fallback to seeking `elem` from the start
1732
+ (diff = nodeIndex = 0) || start.pop()) ) {
1733
+
1734
+ // When found, cache indexes on `parent` and break
1735
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
1736
+ outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1737
+ break;
1738
+ }
1739
+ }
1740
+
1741
+ // Use previously-cached element index if available
1742
+ } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1743
+ diff = cache[1];
1744
+
1745
+ // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1746
+ } else {
1747
+ // Use the same loop as above to seek `elem` from the start
1748
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1749
+ (diff = nodeIndex = 0) || start.pop()) ) {
1750
+
1751
+ if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1752
+ // Cache the index of each encountered element
1753
+ if ( useCache ) {
1754
+ (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1755
+ }
1756
+
1757
+ if ( node === elem ) {
1758
+ break;
1759
+ }
1760
+ }
1761
+ }
1762
+ }
1763
+
1764
+ // Incorporate the offset, then check against cycle size
1765
+ diff -= last;
1766
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
1767
+ }
1768
+ };
1769
+ },
1770
+
1771
+ "PSEUDO": function( pseudo, argument ) {
1772
+ // pseudo-class names are case-insensitive
1773
+ // http://www.w3.org/TR/selectors/#pseudo-classes
1774
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1775
+ // Remember that setFilters inherits from pseudos
1776
+ var args,
1777
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1778
+ Sizzle.error( "unsupported pseudo: " + pseudo );
1779
+
1780
+ // The user may use createPseudo to indicate that
1781
+ // arguments are needed to create the filter function
1782
+ // just as Sizzle does
1783
+ if ( fn[ expando ] ) {
1784
+ return fn( argument );
1785
+ }
1786
+
1787
+ // But maintain support for old signatures
1788
+ if ( fn.length > 1 ) {
1789
+ args = [ pseudo, pseudo, "", argument ];
1790
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1791
+ markFunction(function( seed, matches ) {
1792
+ var idx,
1793
+ matched = fn( seed, argument ),
1794
+ i = matched.length;
1795
+ while ( i-- ) {
1796
+ idx = indexOf.call( seed, matched[i] );
1797
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
1798
+ }
1799
+ }) :
1800
+ function( elem ) {
1801
+ return fn( elem, 0, args );
1802
+ };
1803
+ }
1804
+
1805
+ return fn;
1806
+ }
1807
+ },
1808
+
1809
+ pseudos: {
1810
+ // Potentially complex pseudos
1811
+ "not": markFunction(function( selector ) {
1812
+ // Trim the selector passed to compile
1813
+ // to avoid treating leading and trailing
1814
+ // spaces as combinators
1815
+ var input = [],
1816
+ results = [],
1817
+ matcher = compile( selector.replace( rtrim, "$1" ) );
1818
+
1819
+ return matcher[ expando ] ?
1820
+ markFunction(function( seed, matches, context, xml ) {
1821
+ var elem,
1822
+ unmatched = matcher( seed, null, xml, [] ),
1823
+ i = seed.length;
1824
+
1825
+ // Match elements unmatched by `matcher`
1826
+ while ( i-- ) {
1827
+ if ( (elem = unmatched[i]) ) {
1828
+ seed[i] = !(matches[i] = elem);
1829
+ }
1830
+ }
1831
+ }) :
1832
+ function( elem, context, xml ) {
1833
+ input[0] = elem;
1834
+ matcher( input, null, xml, results );
1835
+ return !results.pop();
1836
+ };
1837
+ }),
1838
+
1839
+ "has": markFunction(function( selector ) {
1840
+ return function( elem ) {
1841
+ return Sizzle( selector, elem ).length > 0;
1842
+ };
1843
+ }),
1844
+
1845
+ "contains": markFunction(function( text ) {
1846
+ return function( elem ) {
1847
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1848
+ };
1849
+ }),
1850
+
1851
+ // "Whether an element is represented by a :lang() selector
1852
+ // is based solely on the element's language value
1853
+ // being equal to the identifier C,
1854
+ // or beginning with the identifier C immediately followed by "-".
1855
+ // The matching of C against the element's language value is performed case-insensitively.
1856
+ // The identifier C does not have to be a valid language name."
1857
+ // http://www.w3.org/TR/selectors/#lang-pseudo
1858
+ "lang": markFunction( function( lang ) {
1859
+ // lang value must be a valid identifier
1860
+ if ( !ridentifier.test(lang || "") ) {
1861
+ Sizzle.error( "unsupported lang: " + lang );
1862
+ }
1863
+ lang = lang.replace( runescape, funescape ).toLowerCase();
1864
+ return function( elem ) {
1865
+ var elemLang;
1866
+ do {
1867
+ if ( (elemLang = documentIsHTML ?
1868
+ elem.lang :
1869
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1870
+
1871
+ elemLang = elemLang.toLowerCase();
1872
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1873
+ }
1874
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1875
+ return false;
1876
+ };
1877
+ }),
1878
+
1879
+ // Miscellaneous
1880
+ "target": function( elem ) {
1881
+ var hash = window.location && window.location.hash;
1882
+ return hash && hash.slice( 1 ) === elem.id;
1883
+ },
1884
+
1885
+ "root": function( elem ) {
1886
+ return elem === docElem;
1887
+ },
1888
+
1889
+ "focus": function( elem ) {
1890
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1891
+ },
1892
+
1893
+ // Boolean properties
1894
+ "enabled": function( elem ) {
1895
+ return elem.disabled === false;
1896
+ },
1897
+
1898
+ "disabled": function( elem ) {
1899
+ return elem.disabled === true;
1900
+ },
1901
+
1902
+ "checked": function( elem ) {
1903
+ // In CSS3, :checked should return both checked and selected elements
1904
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1905
+ var nodeName = elem.nodeName.toLowerCase();
1906
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1907
+ },
1908
+
1909
+ "selected": function( elem ) {
1910
+ // Accessing this property makes selected-by-default
1911
+ // options in Safari work properly
1912
+ if ( elem.parentNode ) {
1913
+ elem.parentNode.selectedIndex;
1914
+ }
1915
+
1916
+ return elem.selected === true;
1917
+ },
1918
+
1919
+ // Contents
1920
+ "empty": function( elem ) {
1921
+ // http://www.w3.org/TR/selectors/#empty-pseudo
1922
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1923
+ // but not by others (comment: 8; processing instruction: 7; etc.)
1924
+ // nodeType < 6 works because attributes (2) do not appear as children
1925
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1926
+ if ( elem.nodeType < 6 ) {
1927
+ return false;
1928
+ }
1929
+ }
1930
+ return true;
1931
+ },
1932
+
1933
+ "parent": function( elem ) {
1934
+ return !Expr.pseudos["empty"]( elem );
1935
+ },
1936
+
1937
+ // Element/input types
1938
+ "header": function( elem ) {
1939
+ return rheader.test( elem.nodeName );
1940
+ },
1941
+
1942
+ "input": function( elem ) {
1943
+ return rinputs.test( elem.nodeName );
1944
+ },
1945
+
1946
+ "button": function( elem ) {
1947
+ var name = elem.nodeName.toLowerCase();
1948
+ return name === "input" && elem.type === "button" || name === "button";
1949
+ },
1950
+
1951
+ "text": function( elem ) {
1952
+ var attr;
1953
+ return elem.nodeName.toLowerCase() === "input" &&
1954
+ elem.type === "text" &&
1955
+
1956
+ // Support: IE<8
1957
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1958
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1959
+ },
1960
+
1961
+ // Position-in-collection
1962
+ "first": createPositionalPseudo(function() {
1963
+ return [ 0 ];
1964
+ }),
1965
+
1966
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
1967
+ return [ length - 1 ];
1968
+ }),
1969
+
1970
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1971
+ return [ argument < 0 ? argument + length : argument ];
1972
+ }),
1973
+
1974
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
1975
+ var i = 0;
1976
+ for ( ; i < length; i += 2 ) {
1977
+ matchIndexes.push( i );
1978
+ }
1979
+ return matchIndexes;
1980
+ }),
1981
+
1982
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
1983
+ var i = 1;
1984
+ for ( ; i < length; i += 2 ) {
1985
+ matchIndexes.push( i );
1986
+ }
1987
+ retu