webspeaks_notifycustomer - Version 0.0.1

Version Notes

Notifycustomer for Magento released

Download this release

Release Info

Developer Arvind Bhardwaj
Extension webspeaks_notifycustomer
Version 0.0.1
Comparing to
See all releases


Version 0.0.1

Files changed (39) hide show
  1. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification.php +42 -0
  2. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit.php +87 -0
  3. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Form.php +52 -0
  4. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Tab/Form.php +146 -0
  5. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Tabs.php +74 -0
  6. app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Grid.php +253 -0
  7. app/code/local/Webspeaks/NotifyCustomer/Block/Notification/Link.php +38 -0
  8. app/code/local/Webspeaks/NotifyCustomer/Block/Notification/List.php +75 -0
  9. app/code/local/Webspeaks/NotifyCustomer/Block/Notification/View.php +37 -0
  10. app/code/local/Webspeaks/NotifyCustomer/Controller/Adminhtml/NotifyCustomer.php +60 -0
  11. app/code/local/Webspeaks/NotifyCustomer/Helper/Data.php +120 -0
  12. app/code/local/Webspeaks/NotifyCustomer/Helper/Notification.php +53 -0
  13. app/code/local/Webspeaks/NotifyCustomer/Model/Notification.php +172 -0
  14. app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Notification.php +37 -0
  15. app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Notification/Collection.php +105 -0
  16. app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Setup.php +26 -0
  17. app/code/local/Webspeaks/NotifyCustomer/controllers/Adminhtml/Notifycustomer/NotificationController.php +403 -0
  18. app/code/local/Webspeaks/NotifyCustomer/controllers/NotificationController.php +253 -0
  19. app/code/local/Webspeaks/NotifyCustomer/etc/adminhtml.xml +58 -0
  20. app/code/local/Webspeaks/NotifyCustomer/etc/config.xml +124 -0
  21. app/code/local/Webspeaks/NotifyCustomer/etc/system.xml +60 -0
  22. app/code/local/Webspeaks/NotifyCustomer/sql/webspeaks_notifycustomer_setup/install-0.0.1.php +85 -0
  23. app/design/adminhtml/default/default/layout/webspeaks_notifycustomer.xml +60 -0
  24. app/design/frontend/base/default/layout/webspeaks_notifycustomer.xml +69 -0
  25. app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/link.phtml +27 -0
  26. app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/list.phtml +66 -0
  27. app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/pop-message-item.phtml +30 -0
  28. app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/view.phtml +34 -0
  29. app/etc/modules/Webspeaks_NotifyCustomer.xml +29 -0
  30. app/locale/en_US/template/email/ws_notify_customer.html +5 -0
  31. js/webspeaks/notifycustomer/adminhtml/notify.js +30 -0
  32. js/webspeaks/notifycustomer/jquery-1.10.2.min.js +6 -0
  33. js/webspeaks/notifycustomer/noconflict.js +27 -0
  34. js/webspeaks/notifycustomer/notifycustomer.js +77 -0
  35. package.xml +22 -0
  36. skin/frontend/base/default/webspeaks/notifycustomer/css/notifycustomer.css +119 -0
  37. skin/frontend/base/default/webspeaks/notifycustomer/img/button-close.png +0 -0
  38. skin/frontend/base/default/webspeaks/notifycustomer/img/email-icon.png +0 -0
  39. skin/frontend/base/default/webspeaks/notifycustomer/img/opc-ajax-loader.gif +0 -0
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification admin block
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification extends Mage_Adminhtml_Block_Widget_Grid_Container
25
+ {
26
+ /**
27
+ * constructor
28
+ *
29
+ * @access public
30
+ * @return void
31
+ * @author Ultimate Module Creator
32
+ */
33
+ public function __construct()
34
+ {
35
+ $this->_controller = 'adminhtml_notification';
36
+ $this->_blockGroup = 'webspeaks_notifycustomer';
37
+ parent::__construct();
38
+ $this->_headerText = Mage::helper('webspeaks_notifycustomer')->__('Notification');
39
+ $this->_updateButton('add', 'label', Mage::helper('webspeaks_notifycustomer')->__('New Notification'));
40
+
41
+ }
42
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification admin edit form
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Webspeaks
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
25
+ {
26
+ /**
27
+ * constructor
28
+ *
29
+ * @access public
30
+ * @return void
31
+ * @author Webspeaks
32
+ */
33
+ public function __construct()
34
+ {
35
+ parent::__construct();
36
+ $this->_blockGroup = 'webspeaks_notifycustomer';
37
+ $this->_controller = 'adminhtml_notification';
38
+ $this->_updateButton(
39
+ 'save',
40
+ 'label',
41
+ Mage::helper('webspeaks_notifycustomer')->__('Send Notification')
42
+ );
43
+ $this->_updateButton(
44
+ 'delete',
45
+ 'label',
46
+ Mage::helper('webspeaks_notifycustomer')->__('Delete Notification')
47
+ );
48
+ /*$this->_addButton(
49
+ 'saveandcontinue',
50
+ array(
51
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Save And Continue Edit'),
52
+ 'onclick' => 'saveAndContinueEdit()',
53
+ 'class' => 'save',
54
+ ),
55
+ -100
56
+ );
57
+ $this->_formScripts[] = "
58
+ function saveAndContinueEdit() {
59
+ editForm.submit($('edit_form').action+'back/edit/');
60
+ }
61
+ ";*/
62
+
63
+ if ($this->getRequest()->getParam('id')) {
64
+ $this->_removeButton('save');
65
+ $this->_removeButton('reset');
66
+ }
67
+ }
68
+
69
+ /**
70
+ * get the edit form header
71
+ *
72
+ * @access public
73
+ * @return string
74
+ * @author Ultimate Module Creator
75
+ */
76
+ public function getHeaderText()
77
+ {
78
+ if (Mage::registry('current_notification') && Mage::registry('current_notification')->getId()) {
79
+ return Mage::helper('webspeaks_notifycustomer')->__(
80
+ "View Notification '%s'",
81
+ $this->escapeHtml(Mage::registry('current_notification')->getTitle())
82
+ );
83
+ } else {
84
+ return Mage::helper('webspeaks_notifycustomer')->__('Send Notification');
85
+ }
86
+ }
87
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Form.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification edit form
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
25
+ {
26
+ /**
27
+ * prepare form
28
+ *
29
+ * @access protected
30
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Form
31
+ * @author Ultimate Module Creator
32
+ */
33
+ protected function _prepareForm()
34
+ {
35
+ $form = new Varien_Data_Form(
36
+ array(
37
+ 'id' => 'edit_form',
38
+ 'action' => $this->getUrl(
39
+ '*/*/save',
40
+ array(
41
+ 'id' => $this->getRequest()->getParam('id')
42
+ )
43
+ ),
44
+ 'method' => 'post',
45
+ 'enctype' => 'multipart/form-data'
46
+ )
47
+ );
48
+ $form->setUseContainer(true);
49
+ $this->setForm($form);
50
+ return parent::_prepareForm();
51
+ }
52
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Tab/Form.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification edit form tab
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
25
+ {
26
+ /**
27
+ * prepare the form
28
+ *
29
+ * @access protected
30
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Tab_Form
31
+ * @author Ultimate Module Creator
32
+ */
33
+ protected function _prepareForm()
34
+ {
35
+ $form = new Varien_Data_Form();
36
+ $form->setHtmlIdPrefix('notification_');
37
+ $form->setFieldNameSuffix('notification');
38
+ $this->setForm($form);
39
+
40
+ $formValues = Mage::registry('current_notification')->getDefaultValues();
41
+ if (!is_array($formValues)) {
42
+ $formValues = array();
43
+ }
44
+ if (Mage::getSingleton('adminhtml/session')->getNotificationData()) {
45
+ $formValues = array_merge($formValues, Mage::getSingleton('adminhtml/session')->getNotificationData());
46
+ Mage::getSingleton('adminhtml/session')->setNotificationData(null);
47
+ } elseif (Mage::registry('current_notification')) {
48
+ $formValues = array_merge($formValues, Mage::registry('current_notification')->getData());
49
+ }
50
+
51
+ $fieldset = $form->addFieldset(
52
+ 'notification_form',
53
+ array('legend' => Mage::helper('webspeaks_notifycustomer')->__('Notification'))
54
+ );
55
+ $wysiwygConfig = Mage::getSingleton('cms/wysiwyg_config')->getConfig();
56
+
57
+ $fieldset->addField(
58
+ 'title',
59
+ 'text',
60
+ array(
61
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Title'),
62
+ 'name' => 'title',
63
+ 'required' => true,
64
+ 'class' => 'required-entry',
65
+
66
+ )
67
+ );
68
+
69
+ $fieldset->addField(
70
+ 'message',
71
+ 'editor',
72
+ array(
73
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Message'),
74
+ 'name' => 'message',
75
+ 'config' => $wysiwygConfig,
76
+ 'required' => true,
77
+ 'class' => 'required-entry',
78
+
79
+ )
80
+ );
81
+
82
+ if (!$this->getRequest()->getParam('id')) {
83
+ $fieldset->addField(
84
+ 'customer_email',
85
+ 'text',
86
+ array(
87
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Customer Email'),
88
+ 'name' => 'customer_email',
89
+ 'required' => true,
90
+ 'class' => 'required-entry',
91
+
92
+ )
93
+ );
94
+
95
+ $element = $fieldset->addField('customer_query', 'text', array(
96
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Search Customer'),
97
+ 'name' => 'customer_query',
98
+ ));
99
+
100
+ $element->setAfterElementHtml("
101
+ <button type='button' id='find-customer-btn' data-url='".Mage::helper('adminhtml')->getUrl('adminhtml/notifycustomer_notification/customerfind')."'><span>".Mage::helper('webspeaks_notifycustomer')->__('Find').'</span></button>
102
+ ');
103
+
104
+ $element = $fieldset->addField('customer_id', 'select', array(
105
+ 'name' => 'customer_id',
106
+ 'style' => 'display: none',
107
+ ));
108
+
109
+ $fieldset->addField('send_email', 'select', array(
110
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Send email'),
111
+ 'values' => [
112
+ ['value' => '1', 'label' => 'Yes'],
113
+ ['value' => '0', 'label' => 'No']
114
+ ],
115
+ 'name' => 'send_email',
116
+ "class" => "required-entry",
117
+ "required" => true,
118
+ 'after_element_html' => '<p><small>'.Mage::helper('webspeaks_notifycustomer')->__('Also send email to customer.').'</small></p>',
119
+ ));
120
+
121
+ } else {
122
+ $customer = Mage::getModel('customer/customer')->load($formValues['customer_id']);
123
+ $fieldset->addField(
124
+ 'customer_email',
125
+ 'note',
126
+ array(
127
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Customer'),
128
+ 'text' => $customer->getData('firstname') . ' ' . $customer->getData('middlename') . ' ' . $customer->getData('lastname')
129
+ )
130
+ );
131
+
132
+ $fieldset->addField(
133
+ 'status',
134
+ 'note',
135
+ array(
136
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Status'),
137
+ 'text' => (!$formValues['status']) ? Mage::helper('webspeaks_notifycustomer')->__('Not read') : Mage::helper('webspeaks_notifycustomer')->__('Read')
138
+ )
139
+ );
140
+
141
+ }
142
+
143
+ $form->setValues($formValues);
144
+ return parent::_prepareForm();
145
+ }
146
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Edit/Tabs.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification admin edit tabs
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
25
+ {
26
+ /**
27
+ * Initialize Tabs
28
+ *
29
+ * @access public
30
+ * @author Ultimate Module Creator
31
+ */
32
+ public function __construct()
33
+ {
34
+ parent::__construct();
35
+ $this->setId('notification_tabs');
36
+ $this->setDestElementId('edit_form');
37
+ $this->setTitle(Mage::helper('webspeaks_notifycustomer')->__('Notification'));
38
+ }
39
+
40
+ /**
41
+ * before render html
42
+ *
43
+ * @access protected
44
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Edit_Tabs
45
+ * @author Ultimate Module Creator
46
+ */
47
+ protected function _beforeToHtml()
48
+ {
49
+ $this->addTab(
50
+ 'form_notification',
51
+ array(
52
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Notification'),
53
+ 'title' => Mage::helper('webspeaks_notifycustomer')->__('Notification'),
54
+ 'content' => $this->getLayout()->createBlock(
55
+ 'webspeaks_notifycustomer/adminhtml_notification_edit_tab_form'
56
+ )
57
+ ->toHtml(),
58
+ )
59
+ );
60
+ return parent::_beforeToHtml();
61
+ }
62
+
63
+ /**
64
+ * Retrieve notification entity
65
+ *
66
+ * @access public
67
+ * @return Webspeaks_NotifyCustomer_Model_Notification
68
+ * @author Ultimate Module Creator
69
+ */
70
+ public function getNotification()
71
+ {
72
+ return Mage::registry('current_notification');
73
+ }
74
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Adminhtml/Notification/Grid.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification admin grid block
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Grid extends Mage_Adminhtml_Block_Widget_Grid
25
+ {
26
+ /**
27
+ * constructor
28
+ *
29
+ * @access public
30
+ * @author Ultimate Module Creator
31
+ */
32
+ public function __construct()
33
+ {
34
+ parent::__construct();
35
+ $this->setId('notificationGrid');
36
+ $this->setDefaultSort('entity_id');
37
+ $this->setDefaultDir('ASC');
38
+ $this->setSaveParametersInSession(true);
39
+ $this->setUseAjax(true);
40
+ }
41
+
42
+ protected function _customerNameCondition($collection, $column) {
43
+
44
+ $filterValue = $column->getFilter()->getValue();
45
+ if(!is_null($filterValue)){
46
+ $filterValue = trim($filterValue);
47
+ $filterValue = preg_replace('/[\s]+/', ' ', $filterValue);
48
+
49
+ $whereArr = array();
50
+ $whereArr[] = $collection->getConnection()->quoteInto("ce1.value = ?", $filterValue);
51
+ $whereArr[] = $collection->getConnection()->quoteInto("ce2.value = ?", $filterValue);
52
+ $where = implode(' OR ', $whereArr);
53
+ $collection->getSelect()->where($where);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * prepare collection
59
+ *
60
+ * @access protected
61
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Grid
62
+ * @author Ultimate Module Creator
63
+ */
64
+ protected function _prepareCollection()
65
+ {
66
+ $collection = Mage::getModel('webspeaks_notifycustomer/notification')
67
+ ->getCollection()
68
+ ->addCustomerNameToSelect();
69
+
70
+ $this->setCollection($collection);
71
+ return parent::_prepareCollection();
72
+ }
73
+
74
+ /**
75
+ * prepare grid collection
76
+ *
77
+ * @access protected
78
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Grid
79
+ * @author Ultimate Module Creator
80
+ */
81
+ protected function _prepareColumns()
82
+ {
83
+ $this->addColumn(
84
+ 'entity_id',
85
+ array(
86
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Id'),
87
+ 'index' => 'entity_id',
88
+ 'type' => 'number'
89
+ )
90
+ );
91
+ $this->addColumn(
92
+ 'title',
93
+ array(
94
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Title'),
95
+ 'align' => 'left',
96
+ 'index' => 'title',
97
+ )
98
+ );
99
+ $this->addColumn(
100
+ 'customer_name',
101
+ array(
102
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Customer'),
103
+ 'index' => 'customer_name',
104
+ 'type'=> 'text',
105
+ 'filter_condition_callback' => array($this, '_customerNameCondition')
106
+ )
107
+ );
108
+ $this->addColumn(
109
+ 'status',
110
+ array(
111
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Read By Customer'),
112
+ 'index' => 'status',
113
+ 'type' => 'options',
114
+ 'options' => array(
115
+ '1' => Mage::helper('webspeaks_notifycustomer')->__('Yes'),
116
+ '0' => Mage::helper('webspeaks_notifycustomer')->__('No'),
117
+ )
118
+
119
+ )
120
+ );
121
+ $this->addColumn(
122
+ 'created_at',
123
+ array(
124
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Created at'),
125
+ 'index' => 'created_at',
126
+ 'width' => '120px',
127
+ 'type' => 'datetime',
128
+ )
129
+ );
130
+ $this->addColumn(
131
+ 'action',
132
+ array(
133
+ 'header' => Mage::helper('webspeaks_notifycustomer')->__('Action'),
134
+ 'width' => '100',
135
+ 'type' => 'action',
136
+ 'getter' => 'getId',
137
+ 'actions' => array(
138
+ array(
139
+ 'caption' => Mage::helper('webspeaks_notifycustomer')->__('Edit'),
140
+ 'url' => array('base'=> '*/*/edit'),
141
+ 'field' => 'id'
142
+ )
143
+ ),
144
+ 'filter' => false,
145
+ 'is_system' => true,
146
+ 'sortable' => false,
147
+ )
148
+ );
149
+ $this->addExportType('*/*/exportCsv', Mage::helper('webspeaks_notifycustomer')->__('CSV'));
150
+ $this->addExportType('*/*/exportExcel', Mage::helper('webspeaks_notifycustomer')->__('Excel'));
151
+ $this->addExportType('*/*/exportXml', Mage::helper('webspeaks_notifycustomer')->__('XML'));
152
+ return parent::_prepareColumns();
153
+ }
154
+
155
+ /**
156
+ * prepare mass action
157
+ *
158
+ * @access protected
159
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Grid
160
+ * @author Ultimate Module Creator
161
+ */
162
+ protected function _prepareMassaction()
163
+ {
164
+ $this->setMassactionIdField('entity_id');
165
+ $this->getMassactionBlock()->setFormFieldName('notification');
166
+ $this->getMassactionBlock()->addItem(
167
+ 'delete',
168
+ array(
169
+ 'label'=> Mage::helper('webspeaks_notifycustomer')->__('Delete'),
170
+ 'url' => $this->getUrl('*/*/massDelete'),
171
+ 'confirm' => Mage::helper('webspeaks_notifycustomer')->__('Are you sure?')
172
+ )
173
+ );
174
+ $this->getMassactionBlock()->addItem(
175
+ 'status',
176
+ array(
177
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Change status'),
178
+ 'url' => $this->getUrl('*/*/massStatus', array('_current'=>true)),
179
+ 'additional' => array(
180
+ 'status' => array(
181
+ 'name' => 'status',
182
+ 'type' => 'select',
183
+ 'class' => 'required-entry',
184
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Status'),
185
+ 'values' => array(
186
+ '1' => Mage::helper('webspeaks_notifycustomer')->__('Enabled'),
187
+ '0' => Mage::helper('webspeaks_notifycustomer')->__('Disabled'),
188
+ )
189
+ )
190
+ )
191
+ )
192
+ );
193
+ $this->getMassactionBlock()->addItem(
194
+ 'read',
195
+ array(
196
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Change Read By Customer'),
197
+ 'url' => $this->getUrl('*/*/massRead', array('_current'=>true)),
198
+ 'additional' => array(
199
+ 'flag_read' => array(
200
+ 'name' => 'flag_read',
201
+ 'type' => 'select',
202
+ 'class' => 'required-entry',
203
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Read By Customer'),
204
+ 'values' => array(
205
+ '1' => Mage::helper('webspeaks_notifycustomer')->__('Yes'),
206
+ '0' => Mage::helper('webspeaks_notifycustomer')->__('No'),
207
+ )
208
+
209
+ )
210
+ )
211
+ )
212
+ );
213
+ return $this;
214
+ }
215
+
216
+ /**
217
+ * get the row url
218
+ *
219
+ * @access public
220
+ * @param Webspeaks_NotifyCustomer_Model_Notification
221
+ * @return string
222
+ * @author Ultimate Module Creator
223
+ */
224
+ public function getRowUrl($row)
225
+ {
226
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
227
+ }
228
+
229
+ /**
230
+ * get the grid url
231
+ *
232
+ * @access public
233
+ * @return string
234
+ * @author Ultimate Module Creator
235
+ */
236
+ public function getGridUrl()
237
+ {
238
+ return $this->getUrl('*/*/grid', array('_current'=>true));
239
+ }
240
+
241
+ /**
242
+ * after collection load
243
+ *
244
+ * @access protected
245
+ * @return Webspeaks_NotifyCustomer_Block_Adminhtml_Notification_Grid
246
+ * @author Ultimate Module Creator
247
+ */
248
+ protected function _afterLoadCollection()
249
+ {
250
+ $this->getCollection()->walk('afterLoad');
251
+ parent::_afterLoadCollection();
252
+ }
253
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Notification/Link.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification view block
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Webspeaks
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Notification_Link extends Mage_Core_Block_Template
25
+ {
26
+ public function getNotifBaseUrl()
27
+ {
28
+ return $this->getUrl('notifications/notification');
29
+ }
30
+
31
+ public function getUnreadCount()
32
+ {
33
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
34
+ return Mage::getModel('webspeaks_notifycustomer/notification')
35
+ ->getUnreadCount($customer->getData('entity_id'));
36
+ }
37
+
38
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Notification/List.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification list block
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Notification_List extends Mage_Core_Block_Template
25
+ {
26
+ /**
27
+ * initialize
28
+ *
29
+ * @access public
30
+ * @author Ultimate Module Creator
31
+ */
32
+ public function _construct()
33
+ {
34
+ parent::_construct();
35
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
36
+ $notifications = Mage::getResourceModel('webspeaks_notifycustomer/notification_collection')
37
+ ->addFieldTofilter('customer_id', $customer->getId())
38
+ ->setOrder('entity_id', 'DESC')
39
+ ;
40
+ $notifications->setOrder('title', 'asc');
41
+ $this->setNotifications($notifications);
42
+ }
43
+
44
+ /**
45
+ * prepare the layout
46
+ *
47
+ * @access protected
48
+ * @return Webspeaks_NotifyCustomer_Block_Notification_List
49
+ * @author Ultimate Module Creator
50
+ */
51
+ protected function _prepareLayout()
52
+ {
53
+ parent::_prepareLayout();
54
+ $pager = $this->getLayout()->createBlock(
55
+ 'page/html_pager',
56
+ 'webspeaks_notifycustomer.notification.html.pager'
57
+ )
58
+ ->setCollection($this->getNotifications());
59
+ $this->setChild('pager', $pager);
60
+ $this->getNotifications()->load();
61
+ return $this;
62
+ }
63
+
64
+ /**
65
+ * get the pager html
66
+ *
67
+ * @access public
68
+ * @return string
69
+ * @author Ultimate Module Creator
70
+ */
71
+ public function getPagerHtml()
72
+ {
73
+ return $this->getChildHtml('pager');
74
+ }
75
+ }
app/code/local/Webspeaks/NotifyCustomer/Block/Notification/View.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification view block
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Block_Notification_View extends Mage_Core_Block_Template
25
+ {
26
+ /**
27
+ * get the current notification
28
+ *
29
+ * @access public
30
+ * @return mixed (Webspeaks_NotifyCustomer_Model_Notification|null)
31
+ * @author Ultimate Module Creator
32
+ */
33
+ public function getCurrentNotification()
34
+ {
35
+ return Mage::registry('current_notification');
36
+ }
37
+ }
app/code/local/Webspeaks/NotifyCustomer/Controller/Adminhtml/NotifyCustomer.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * module base admin controller
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Controller_Adminhtml_NotifyCustomer extends Mage_Adminhtml_Controller_Action
25
+ {
26
+ /**
27
+ * upload file and get the uploaded name
28
+ *
29
+ * @access public
30
+ * @param string $input
31
+ * @param string $destinationFolder
32
+ * @param array $data
33
+ * @return string
34
+ * @author Ultimate Module Creator
35
+ */
36
+ protected function _uploadAndGetName($input, $destinationFolder, $data)
37
+ {
38
+ try {
39
+ if (isset($data[$input]['delete'])) {
40
+ return '';
41
+ } else {
42
+ $uploader = new Varien_File_Uploader($input);
43
+ $uploader->setAllowRenameFiles(true);
44
+ $uploader->setFilesDispersion(true);
45
+ $uploader->setAllowCreateFolders(true);
46
+ $result = $uploader->save($destinationFolder);
47
+ return $result['file'];
48
+ }
49
+ } catch (Exception $e) {
50
+ if ($e->getCode() != Varien_File_Uploader::TMP_NAME_EMPTY) {
51
+ throw $e;
52
+ } else {
53
+ if (isset($data[$input]['value'])) {
54
+ return $data[$input]['value'];
55
+ }
56
+ }
57
+ }
58
+ return '';
59
+ }
60
+ }
app/code/local/Webspeaks/NotifyCustomer/Helper/Data.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * NotifyCustomer default helper
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Helper_Data extends Mage_Core_Helper_Abstract
25
+ {
26
+ /**
27
+ * convert array to options
28
+ *
29
+ * @access public
30
+ * @param $options
31
+ * @return array
32
+ * @author Ultimate Module Creator
33
+ */
34
+ public function convertOptions($options)
35
+ {
36
+ $converted = array();
37
+ foreach ($options as $option) {
38
+ if (isset($option['value']) && !is_array($option['value']) &&
39
+ isset($option['label']) && !is_array($option['label'])) {
40
+ $converted[$option['value']] = $option['label'];
41
+ }
42
+ }
43
+ return $converted;
44
+ }
45
+
46
+ public function getCustomerArray($q = false, $customerId = false, $addressId = false)
47
+ {
48
+ $model = Mage::getSingleton('customer/customer');
49
+ $result = $model->getCollection()
50
+ ->addAttributeToSelect(array('entity_id', 'firstname', 'email'))
51
+ ->addAttributeToFilter(
52
+ array(
53
+ array('attribute'=>'firstname', 'like' => "%$q%"),
54
+ array('attribute'=>'lastname', 'like' => "%$q%"),
55
+ array('attribute'=>'email', 'like' => "%$q%"),
56
+ )
57
+ )
58
+ ;
59
+
60
+ $data = [];
61
+ foreach($result as $r) {
62
+ $data[] = [
63
+ 'name' => $r->getData('firstname') . ' ' . $r->getData('lastname') . ' (' . $r->getData('email') . ')',
64
+ 'email' => $r->getData('email'),
65
+ 'id' => $r->getData('entity_id'),
66
+ ];
67
+ }
68
+
69
+ return $data;
70
+ }
71
+
72
+ public function findCustomer($q)
73
+ {
74
+ $customers = $this->getCustomerArray($q);
75
+ return $customers;
76
+ }
77
+
78
+ public function findCustomerByEmail($email)
79
+ {
80
+ $model = Mage::getSingleton('customer/customer');
81
+ $result = $model->getCollection()
82
+ ->addAttributeToFilter('email', $email)
83
+ ->getFirstItem();
84
+ echo $result->getSelect();
85
+ return $result;
86
+ }
87
+
88
+ public function sendEmailToCustomer($data)
89
+ {
90
+ $emailTemplate = Mage::getModel('core/email_template')->loadDefault('ws_notify_customer_eml');
91
+ $from_email = Mage::getStoreConfig('trans_email/ident_general/email'); //fetch sender email Admin
92
+ $from_name = Mage::getStoreConfig('trans_email/ident_general/name'); //fetch sender name Admin
93
+
94
+ $emailTemplateVariables = array();
95
+ $emailTemplateVariables['body'] = $data['message'];
96
+
97
+ //Appending the Custom Variables to Template.
98
+ $processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
99
+
100
+ //Sending E-Mail to Customers.
101
+ $mail = Mage::getModel('core/email')
102
+ ->setToName($data['customer_email'])
103
+ ->setToEmail($data['customer_email'])
104
+ ->setBody($processedTemplate)
105
+ ->setSubject($data['title'])
106
+ ->setFromEmail($from_email)
107
+ ->setFromName($from_name)
108
+ ->setType('html');
109
+
110
+ try {
111
+ //E-Mail Send
112
+ $mail->send();
113
+ }
114
+ catch(Exception $error)
115
+ {
116
+ Mage::getSingleton('core/session')->addError($error->getMessage());
117
+ return false;
118
+ }
119
+ }
120
+ }
app/code/local/Webspeaks/NotifyCustomer/Helper/Notification.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification helper
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Helper_Notification extends Mage_Core_Helper_Abstract
25
+ {
26
+
27
+ /**
28
+ * get the url to the notifications list page
29
+ *
30
+ * @access public
31
+ * @return string
32
+ * @author Ultimate Module Creator
33
+ */
34
+ public function getNotificationsUrl()
35
+ {
36
+ if ($listKey = Mage::getStoreConfig('webspeaks_notifycustomer/notification/url_rewrite_list')) {
37
+ return Mage::getUrl('', array('_direct'=>$listKey));
38
+ }
39
+ return Mage::getUrl('webspeaks_notifycustomer/notification/index');
40
+ }
41
+
42
+ /**
43
+ * check if breadcrumbs can be used
44
+ *
45
+ * @access public
46
+ * @return bool
47
+ * @author Ultimate Module Creator
48
+ */
49
+ public function getUseBreadcrumbs()
50
+ {
51
+ return Mage::getStoreConfigFlag('webspeaks_notifycustomer/notification/breadcrumbs');
52
+ }
53
+ }
app/code/local/Webspeaks/NotifyCustomer/Model/Notification.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification model
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Model_Notification extends Mage_Core_Model_Abstract
25
+ {
26
+ /**
27
+ * Entity code.
28
+ * Can be used as part of method name for entity processing
29
+ */
30
+ const ENTITY = 'webspeaks_notifycustomer_notification';
31
+ const CACHE_TAG = 'webspeaks_notifycustomer_notification';
32
+
33
+ /**
34
+ * Prefix of model events names
35
+ *
36
+ * @var string
37
+ */
38
+ protected $_eventPrefix = 'webspeaks_notifycustomer_notification';
39
+
40
+ /**
41
+ * Parameter name in event
42
+ *
43
+ * @var string
44
+ */
45
+ protected $_eventObject = 'notification';
46
+
47
+ /**
48
+ * constructor
49
+ *
50
+ * @access public
51
+ * @return void
52
+ * @author Webspeaks
53
+ */
54
+ public function _construct()
55
+ {
56
+ parent::_construct();
57
+ $this->_init('webspeaks_notifycustomer/notification');
58
+ }
59
+
60
+ /**
61
+ * before save notification
62
+ *
63
+ * @access protected
64
+ * @return Webspeaks_NotifyCustomer_Model_Notification
65
+ * @author Webspeaks
66
+ */
67
+ protected function _beforeSave()
68
+ {
69
+ parent::_beforeSave();
70
+ $now = Mage::getSingleton('core/date')->gmtDate();
71
+ if ($this->isObjectNew()) {
72
+ $this->setCreatedAt($now);
73
+ }
74
+ $this->setUpdatedAt($now);
75
+ return $this;
76
+ }
77
+
78
+ /**
79
+ * get the url to the notification details page
80
+ *
81
+ * @access public
82
+ * @return string
83
+ * @author Webspeaks
84
+ */
85
+ public function getNotificationUrl()
86
+ {
87
+ return Mage::getUrl('webspeaks_notifycustomer/notification/view', array('id'=>$this->getId()));
88
+ }
89
+
90
+ /**
91
+ * get the notification Message
92
+ *
93
+ * @access public
94
+ * @return string
95
+ * @author Webspeaks
96
+ */
97
+ public function getMessage()
98
+ {
99
+ $message = $this->getData('message');
100
+ $helper = Mage::helper('cms');
101
+ $processor = $helper->getBlockTemplateProcessor();
102
+ $html = $processor->filter($message);
103
+ return $html;
104
+ }
105
+
106
+ /**
107
+ * save notification relation
108
+ *
109
+ * @access public
110
+ * @return Webspeaks_NotifyCustomer_Model_Notification
111
+ * @author Webspeaks
112
+ */
113
+ protected function _afterSave()
114
+ {
115
+ return parent::_afterSave();
116
+ }
117
+
118
+ /**
119
+ * get default values
120
+ *
121
+ * @access public
122
+ * @return array
123
+ * @author Webspeaks
124
+ */
125
+ public function getDefaultValues()
126
+ {
127
+ $values = array();
128
+ $values['status'] = 1;
129
+ return $values;
130
+ }
131
+
132
+ /**
133
+ * Get customer unread count
134
+ *
135
+ * @access public
136
+ * @return array
137
+ * @author Webspeaks
138
+ */
139
+ public function getUnreadCount($customer_id)
140
+ {
141
+ $notifications = Mage::getResourceModel('webspeaks_notifycustomer/notification_collection');
142
+ $notifications->addFieldToFilter('status', 0)
143
+ ->addFieldToFilter('customer_id', $customer_id);
144
+ return $notifications->getSize();
145
+ }
146
+
147
+ /**
148
+ * Get customer notifications
149
+ *
150
+ * @access public
151
+ * @return array
152
+ * @author Webspeaks
153
+ */
154
+ public function getCustomerNotifications($customer_id, $count=null, $fields=[])
155
+ {
156
+ $notifications = Mage::getResourceModel('webspeaks_notifycustomer/notification_collection');
157
+
158
+ if (count($fields)) {
159
+ $notifications->addFieldToSelect($fields);
160
+ }
161
+
162
+ $notifications->addFieldToFilter('customer_id', $customer_id);
163
+
164
+ if ($count) {
165
+ $notifications->setPageSize($count)->setCurPage(1);
166
+ }
167
+
168
+ $notifications->setOrder('entity_id', 'DESC');
169
+ return $notifications;
170
+ }
171
+
172
+ }
app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Notification.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification resource model
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Model_Resource_Notification extends Mage_Core_Model_Resource_Db_Abstract
25
+ {
26
+
27
+ /**
28
+ * constructor
29
+ *
30
+ * @access public
31
+ * @author Ultimate Module Creator
32
+ */
33
+ public function _construct()
34
+ {
35
+ $this->_init('webspeaks_notifycustomer/notification', 'entity_id');
36
+ }
37
+ }
app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Notification/Collection.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification collection resource model
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Webspeaks
23
+ */
24
+ class Webspeaks_NotifyCustomer_Model_Resource_Notification_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
25
+ {
26
+ protected $_joinedFields = array();
27
+
28
+ /**
29
+ * constructor
30
+ *
31
+ * @access public
32
+ * @return void
33
+ * @author Webspeaks
34
+ */
35
+ protected function _construct()
36
+ {
37
+ parent::_construct();
38
+ $this->_init('webspeaks_notifycustomer/notification');
39
+ }
40
+
41
+ /**
42
+ * get notifications as array
43
+ *
44
+ * @access protected
45
+ * @param string $valueField
46
+ * @param string $labelField
47
+ * @param array $additional
48
+ * @return array
49
+ * @author Webspeaks
50
+ */
51
+ protected function _toOptionArray($valueField='entity_id', $labelField='title', $additional=array())
52
+ {
53
+ return parent::_toOptionArray($valueField, $labelField, $additional);
54
+ }
55
+
56
+ /**
57
+ * get options hash
58
+ *
59
+ * @access protected
60
+ * @param string $valueField
61
+ * @param string $labelField
62
+ * @return array
63
+ * @author Webspeaks
64
+ */
65
+ protected function _toOptionHash($valueField='entity_id', $labelField='title')
66
+ {
67
+ return parent::_toOptionHash($valueField, $labelField);
68
+ }
69
+
70
+ /**
71
+ * Get SQL for get record count.
72
+ * Extra GROUP BY strip added.
73
+ *
74
+ * @access public
75
+ * @return Varien_Db_Select
76
+ * @author Webspeaks
77
+ */
78
+ public function getSelectCountSql()
79
+ {
80
+ $countSelect = parent::getSelectCountSql();
81
+ $countSelect->reset(Zend_Db_Select::GROUP);
82
+ return $countSelect;
83
+ }
84
+
85
+ /**
86
+ * Add customer name in grid
87
+ *
88
+ * @access public
89
+ * @return Varien_Db_Select
90
+ * @author Webspeaks
91
+ */
92
+ public function addCustomerNameToSelect()
93
+ {
94
+ $tbl = Mage::getSingleton('core/resource')->getTableName('customer_entity_varchar');
95
+ $firstnameAttr = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'firstname');
96
+ $lastnameAttr = Mage::getModel('eav/entity_attribute')->loadByCode('1', 'lastname');
97
+ $this->getSelect()
98
+ ->join(array('ce1' => $tbl), 'ce1.entity_id=main_table.customer_id', array('firstname' => 'value'))
99
+ ->where('ce1.attribute_id='.$firstnameAttr->getAttributeId()) // Attribute code for firstname.
100
+ ->join(array('ce2' => $tbl), 'ce2.entity_id=main_table.customer_id', array('lastname' => 'value'))
101
+ ->where('ce2.attribute_id='.$lastnameAttr->getAttributeId()) // Attribute code for lastname.
102
+ ->columns(new Zend_Db_Expr("CONCAT(`ce1`.`value`, ' ',`ce2`.`value`) AS customer_name"));
103
+ return $this;
104
+ }
105
+ }
app/code/local/Webspeaks/NotifyCustomer/Model/Resource/Setup.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * NotifyCustomer setup
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
25
+ {
26
+ }
app/code/local/Webspeaks/NotifyCustomer/controllers/Adminhtml/Notifycustomer/NotificationController.php ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification admin controller
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Webspeaks
23
+ */
24
+ class Webspeaks_NotifyCustomer_Adminhtml_Notifycustomer_NotificationController extends Webspeaks_NotifyCustomer_Controller_Adminhtml_NotifyCustomer
25
+ {
26
+ /**
27
+ * init the notification
28
+ *
29
+ * @access protected
30
+ * @return Webspeaks_NotifyCustomer_Model_Notification
31
+ */
32
+ protected function _initNotification()
33
+ {
34
+ $notificationId = (int) $this->getRequest()->getParam('id');
35
+ $notification = Mage::getModel('webspeaks_notifycustomer/notification');
36
+ if ($notificationId) {
37
+ $notification->load($notificationId);
38
+ }
39
+ Mage::register('current_notification', $notification);
40
+ return $notification;
41
+ }
42
+
43
+ /**
44
+ * default action
45
+ *
46
+ * @access public
47
+ * @return void
48
+ * @author Webspeaks
49
+ */
50
+ public function indexAction()
51
+ {
52
+ $this->loadLayout();
53
+ $this->_title(Mage::helper('webspeaks_notifycustomer')->__('Customer Notification'))
54
+ ->_title(Mage::helper('webspeaks_notifycustomer')->__('Notifications'));
55
+ $this->renderLayout();
56
+ }
57
+
58
+ /**
59
+ * grid action
60
+ *
61
+ * @access public
62
+ * @return void
63
+ * @author Webspeaks
64
+ */
65
+ public function gridAction()
66
+ {
67
+ $this->loadLayout()->renderLayout();
68
+ }
69
+
70
+ /**
71
+ * edit notification - action
72
+ *
73
+ * @access public
74
+ * @return void
75
+ * @author Webspeaks
76
+ */
77
+ public function editAction()
78
+ {
79
+ $notificationId = $this->getRequest()->getParam('id');
80
+ $notification = $this->_initNotification();
81
+ if ($notificationId && !$notification->getId()) {
82
+ $this->_getSession()->addError(
83
+ Mage::helper('webspeaks_notifycustomer')->__('This notification no longer exists.')
84
+ );
85
+ $this->_redirect('*/*/');
86
+ return;
87
+ }
88
+ $data = Mage::getSingleton('adminhtml/session')->getNotificationData(true);
89
+ if (!empty($data)) {
90
+ $notification->setData($data);
91
+ }
92
+ Mage::register('notification_data', $notification);
93
+ $this->loadLayout();
94
+ $this->_title(Mage::helper('webspeaks_notifycustomer')->__('Customer Notification'))
95
+ ->_title(Mage::helper('webspeaks_notifycustomer')->__('Notifications'));
96
+ if ($notification->getId()) {
97
+ $this->_title($notification->getTitle());
98
+ } else {
99
+ $this->_title(Mage::helper('webspeaks_notifycustomer')->__('Add notification'));
100
+ }
101
+ if (Mage::getSingleton('cms/wysiwyg_config')->isEnabled()) {
102
+ $this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
103
+ }
104
+ $this->renderLayout();
105
+ }
106
+
107
+ /**
108
+ * new notification action
109
+ *
110
+ * @access public
111
+ * @return void
112
+ * @author Webspeaks
113
+ */
114
+ public function newAction()
115
+ {
116
+ $this->_forward('edit');
117
+ }
118
+
119
+ /**
120
+ * save notification - action
121
+ *
122
+ * @access public
123
+ * @return void
124
+ * @author Webspeaks
125
+ */
126
+ public function saveAction()
127
+ {
128
+ if ($data = $this->getRequest()->getPost('notification')) {
129
+ try {
130
+ $notification = $this->_initNotification();
131
+
132
+ // Find customer's id from email if id does not exist
133
+ if (!$this->getRequest()->getParam('id')) {
134
+ $data['status'] = 0; // unread
135
+
136
+ $customer_id = (int) $data['customer_id'];
137
+ if (!$customer_id) {
138
+ $customer_email = $data['customer_email'];
139
+ $customer = Mage::helper('webspeaks_notifycustomer')->findCustomerByEmail($customer_email);
140
+ if (!$customer || !$customer->getId()) {
141
+ Mage::getSingleton('adminhtml/session')->addError(
142
+ Mage::helper('webspeaks_notifycustomer')->__('Provided customer email does not exist.')
143
+ );
144
+ Mage::getSingleton('adminhtml/session')->setNotificationData($data);
145
+ $this->_redirect('*/*/new');
146
+ return;
147
+ }
148
+ $data['customer_id'] = $customer->getId();
149
+ }
150
+ } else {
151
+ $this->_redirect('*/*/');
152
+ return;
153
+ }
154
+
155
+ $notification->addData($data);
156
+ $notification->save();
157
+
158
+ if ($data['send_email'] == 1) {
159
+ Mage::helper('webspeaks_notifycustomer')->sendEmailToCustomer($data);
160
+ }
161
+
162
+ Mage::getSingleton('adminhtml/session')->addSuccess(
163
+ Mage::helper('webspeaks_notifycustomer')->__('Notification was successfully sent.')
164
+ );
165
+ Mage::getSingleton('adminhtml/session')->setFormData(false);
166
+ if ($this->getRequest()->getParam('back')) {
167
+ $this->_redirect('*/*/edit', array('id' => $notification->getId()));
168
+ return;
169
+ }
170
+ $this->_redirect('*/*/');
171
+ return;
172
+ } catch (Mage_Core_Exception $e) {
173
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
174
+ Mage::getSingleton('adminhtml/session')->setNotificationData($data);
175
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
176
+ return;
177
+ } catch (Exception $e) {
178
+ Mage::logException($e);
179
+ Mage::getSingleton('adminhtml/session')->addError(
180
+ Mage::helper('webspeaks_notifycustomer')->__('There was a problem saving the notification.')
181
+ );
182
+ Mage::getSingleton('adminhtml/session')->setNotificationData($data);
183
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
184
+ return;
185
+ }
186
+ }
187
+ Mage::getSingleton('adminhtml/session')->addError(
188
+ Mage::helper('webspeaks_notifycustomer')->__('Unable to find notification to save.')
189
+ );
190
+ $this->_redirect('*/*/');
191
+ }
192
+
193
+ /**
194
+ * delete notification - action
195
+ *
196
+ * @access public
197
+ * @return void
198
+ * @author Webspeaks
199
+ */
200
+ public function deleteAction()
201
+ {
202
+ if ( $this->getRequest()->getParam('id') > 0) {
203
+ try {
204
+ $notification = Mage::getModel('webspeaks_notifycustomer/notification');
205
+ $notification->setId($this->getRequest()->getParam('id'))->delete();
206
+ Mage::getSingleton('adminhtml/session')->addSuccess(
207
+ Mage::helper('webspeaks_notifycustomer')->__('Notification was successfully deleted.')
208
+ );
209
+ $this->_redirect('*/*/');
210
+ return;
211
+ } catch (Mage_Core_Exception $e) {
212
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
213
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
214
+ } catch (Exception $e) {
215
+ Mage::getSingleton('adminhtml/session')->addError(
216
+ Mage::helper('webspeaks_notifycustomer')->__('There was an error deleting notification.')
217
+ );
218
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
219
+ Mage::logException($e);
220
+ return;
221
+ }
222
+ }
223
+ Mage::getSingleton('adminhtml/session')->addError(
224
+ Mage::helper('webspeaks_notifycustomer')->__('Could not find notification to delete.')
225
+ );
226
+ $this->_redirect('*/*/');
227
+ }
228
+
229
+ /**
230
+ * mass delete notification - action
231
+ *
232
+ * @access public
233
+ * @return void
234
+ * @author Webspeaks
235
+ */
236
+ public function massDeleteAction()
237
+ {
238
+ $notificationIds = $this->getRequest()->getParam('notification');
239
+ if (!is_array($notificationIds)) {
240
+ Mage::getSingleton('adminhtml/session')->addError(
241
+ Mage::helper('webspeaks_notifycustomer')->__('Please select notifications to delete.')
242
+ );
243
+ } else {
244
+ try {
245
+ foreach ($notificationIds as $notificationId) {
246
+ $notification = Mage::getModel('webspeaks_notifycustomer/notification');
247
+ $notification->setId($notificationId)->delete();
248
+ }
249
+ Mage::getSingleton('adminhtml/session')->addSuccess(
250
+ Mage::helper('webspeaks_notifycustomer')->__('Total of %d notifications were successfully deleted.', count($notificationIds))
251
+ );
252
+ } catch (Mage_Core_Exception $e) {
253
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
254
+ } catch (Exception $e) {
255
+ Mage::getSingleton('adminhtml/session')->addError(
256
+ Mage::helper('webspeaks_notifycustomer')->__('There was an error deleting notifications.')
257
+ );
258
+ Mage::logException($e);
259
+ }
260
+ }
261
+ $this->_redirect('*/*/index');
262
+ }
263
+
264
+ /**
265
+ * mass status change - action
266
+ *
267
+ * @access public
268
+ * @return void
269
+ * @author Webspeaks
270
+ */
271
+ public function massStatusAction()
272
+ {
273
+ $notificationIds = $this->getRequest()->getParam('notification');
274
+ if (!is_array($notificationIds)) {
275
+ Mage::getSingleton('adminhtml/session')->addError(
276
+ Mage::helper('webspeaks_notifycustomer')->__('Please select notifications.')
277
+ );
278
+ } else {
279
+ try {
280
+ foreach ($notificationIds as $notificationId) {
281
+ $notification = Mage::getSingleton('webspeaks_notifycustomer/notification')->load($notificationId)
282
+ ->setStatus($this->getRequest()->getParam('status'))
283
+ ->setIsMassupdate(true)
284
+ ->save();
285
+ }
286
+ $this->_getSession()->addSuccess(
287
+ $this->__('Total of %d notifications were successfully updated.', count($notificationIds))
288
+ );
289
+ } catch (Mage_Core_Exception $e) {
290
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
291
+ } catch (Exception $e) {
292
+ Mage::getSingleton('adminhtml/session')->addError(
293
+ Mage::helper('webspeaks_notifycustomer')->__('There was an error updating notifications.')
294
+ );
295
+ Mage::logException($e);
296
+ }
297
+ }
298
+ $this->_redirect('*/*/index');
299
+ }
300
+
301
+ /**
302
+ * mass Read By Customer change - action
303
+ *
304
+ * @access public
305
+ * @return void
306
+ * @author Webspeaks
307
+ */
308
+ public function massReadAction()
309
+ {
310
+ $notificationIds = $this->getRequest()->getParam('notification');
311
+ if (!is_array($notificationIds)) {
312
+ Mage::getSingleton('adminhtml/session')->addError(
313
+ Mage::helper('webspeaks_notifycustomer')->__('Please select notifications.')
314
+ );
315
+ } else {
316
+ try {
317
+ foreach ($notificationIds as $notificationId) {
318
+ $notification = Mage::getSingleton('webspeaks_notifycustomer/notification')->load($notificationId)
319
+ ->setRead($this->getRequest()->getParam('flag_read'))
320
+ ->setIsMassupdate(true)
321
+ ->save();
322
+ }
323
+ $this->_getSession()->addSuccess(
324
+ $this->__('Total of %d notifications were successfully updated.', count($notificationIds))
325
+ );
326
+ } catch (Mage_Core_Exception $e) {
327
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
328
+ } catch (Exception $e) {
329
+ Mage::getSingleton('adminhtml/session')->addError(
330
+ Mage::helper('webspeaks_notifycustomer')->__('There was an error updating notifications.')
331
+ );
332
+ Mage::logException($e);
333
+ }
334
+ }
335
+ $this->_redirect('*/*/index');
336
+ }
337
+
338
+ /**
339
+ * export as csv - action
340
+ *
341
+ * @access public
342
+ * @return void
343
+ * @author Webspeaks
344
+ */
345
+ public function exportCsvAction()
346
+ {
347
+ $fileName = 'notification.csv';
348
+ $content = $this->getLayout()->createBlock('webspeaks_notifycustomer/adminhtml_notification_grid')
349
+ ->getCsv();
350
+ $this->_prepareDownloadResponse($fileName, $content);
351
+ }
352
+
353
+ /**
354
+ * export as MsExcel - action
355
+ *
356
+ * @access public
357
+ * @return void
358
+ * @author Webspeaks
359
+ */
360
+ public function exportExcelAction()
361
+ {
362
+ $fileName = 'notification.xls';
363
+ $content = $this->getLayout()->createBlock('webspeaks_notifycustomer/adminhtml_notification_grid')
364
+ ->getExcelFile();
365
+ $this->_prepareDownloadResponse($fileName, $content);
366
+ }
367
+
368
+ /**
369
+ * export as xml - action
370
+ *
371
+ * @access public
372
+ * @return void
373
+ * @author Webspeaks
374
+ */
375
+ public function exportXmlAction()
376
+ {
377
+ $fileName = 'notification.xml';
378
+ $content = $this->getLayout()->createBlock('webspeaks_notifycustomer/adminhtml_notification_grid')
379
+ ->getXml();
380
+ $this->_prepareDownloadResponse($fileName, $content);
381
+ }
382
+
383
+ /**
384
+ * Check if admin has permissions to visit related pages
385
+ *
386
+ * @access protected
387
+ * @return boolean
388
+ * @author Webspeaks
389
+ */
390
+ protected function _isAllowed()
391
+ {
392
+ return Mage::getSingleton('admin/session')->isAllowed('webspeaks_notifycustomer/notification');
393
+ }
394
+
395
+
396
+ public function customerfindAction()
397
+ {
398
+ $q = $this->getRequest()->getParam('q');
399
+ $result = Mage::helper('webspeaks_notifycustomer')->findCustomer($q);
400
+ echo Mage::helper('core')->jsonEncode($result);
401
+ die;
402
+ }
403
+ }
app/code/local/Webspeaks/NotifyCustomer/controllers/NotificationController.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @ Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification front contrller
19
+ *
20
+ * @category Webspeaks
21
+ * @ Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ class Webspeaks_NotifyCustomer_NotificationController extends Mage_Core_Controller_Front_Action
25
+ {
26
+
27
+ public function preDispatch()
28
+ {
29
+ parent::preDispatch();
30
+ $action = $this->getRequest()->getActionName();
31
+ $loginUrl = Mage::helper('customer')->getLoginUrl();
32
+
33
+ if (!Mage::getSingleton('customer/session')->authenticate($this, $loginUrl)) {
34
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * default action
40
+ *
41
+ * @access public
42
+ * @return void
43
+ *
44
+ */
45
+ public function indexAction()
46
+ {
47
+ $this->loadLayout();
48
+ $this->_initLayoutMessages('catalog/session');
49
+ $this->_initLayoutMessages('customer/session');
50
+ $this->_initLayoutMessages('checkout/session');
51
+ if (Mage::helper('webspeaks_notifycustomer/notification')->getUseBreadcrumbs()) {
52
+ if ($breadcrumbBlock = $this->getLayout()->getBlock('breadcrumbs')) {
53
+ $breadcrumbBlock->addCrumb(
54
+ 'home',
55
+ array(
56
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Home'),
57
+ 'link' => Mage::getUrl(),
58
+ )
59
+ );
60
+ $breadcrumbBlock->addCrumb(
61
+ 'notifications',
62
+ array(
63
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Notifications'),
64
+ 'link' => '',
65
+ )
66
+ );
67
+ }
68
+ }
69
+ $headBlock = $this->getLayout()->getBlock('head');
70
+ if ($headBlock) {
71
+ $headBlock->addLinkRel('canonical', Mage::helper('webspeaks_notifycustomer/notification')->getNotificationsUrl());
72
+ }
73
+ $this->renderLayout();
74
+ }
75
+
76
+ /**
77
+ * init Notification
78
+ *
79
+ * @access protected
80
+ * @return Webspeaks_NotifyCustomer_Model_Notification
81
+ *
82
+ */
83
+ protected function _initNotification()
84
+ {
85
+ $notificationId = $this->getRequest()->getParam('id', 0);
86
+ $notification = Mage::getModel('webspeaks_notifycustomer/notification')
87
+ ->setStoreId(Mage::app()->getStore()->getId())
88
+ ->load($notificationId);
89
+ if (!$notification->getId()) {
90
+ return false;
91
+ }
92
+ return $notification;
93
+ }
94
+
95
+ /**
96
+ * view notification action
97
+ *
98
+ * @access public
99
+ * @return void
100
+ *
101
+ */
102
+ public function viewAction()
103
+ {
104
+ $notification = $this->_initNotification();
105
+ if (!$notification) {
106
+ $this->_forward('no-route');
107
+ return;
108
+ }
109
+ Mage::register('current_notification', $notification);
110
+ $this->loadLayout();
111
+ $this->_initLayoutMessages('catalog/session');
112
+ $this->_initLayoutMessages('customer/session');
113
+ $this->_initLayoutMessages('checkout/session');
114
+ if ($root = $this->getLayout()->getBlock('root')) {
115
+ $root->addBodyClass('notifycustomer-notification notifycustomer-notification' . $notification->getId());
116
+ }
117
+ if (Mage::helper('webspeaks_notifycustomer/notification')->getUseBreadcrumbs()) {
118
+ if ($breadcrumbBlock = $this->getLayout()->getBlock('breadcrumbs')) {
119
+ $breadcrumbBlock->addCrumb(
120
+ 'home',
121
+ array(
122
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Home'),
123
+ 'link' => Mage::getUrl(),
124
+ )
125
+ );
126
+ $breadcrumbBlock->addCrumb(
127
+ 'notifications',
128
+ array(
129
+ 'label' => Mage::helper('webspeaks_notifycustomer')->__('Notifications'),
130
+ 'link' => Mage::helper('webspeaks_notifycustomer/notification')->getNotificationsUrl(),
131
+ )
132
+ );
133
+ $breadcrumbBlock->addCrumb(
134
+ 'notification',
135
+ array(
136
+ 'label' => $notification->getTitle(),
137
+ 'link' => '',
138
+ )
139
+ );
140
+ }
141
+ }
142
+ $headBlock = $this->getLayout()->getBlock('head');
143
+ if ($headBlock) {
144
+ $headBlock->addLinkRel('canonical', $notification->getNotificationUrl());
145
+ }
146
+
147
+ // Mark as read
148
+ $notification->setData('status', 1)->save();
149
+
150
+ $this->renderLayout();
151
+ }
152
+
153
+ /**
154
+ * Get customer notification action
155
+ *
156
+ * @access public
157
+ * @return void
158
+ *
159
+ */
160
+ public function ajax_loadAction()
161
+ {
162
+ if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
163
+ echo json_encode([
164
+ 'status' => 'error',
165
+ 'code' => 'not_logged_in'
166
+ ]);
167
+ exit();
168
+ }
169
+
170
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
171
+ $notifications = Mage::getModel('webspeaks_notifycustomer/notification')
172
+ ->getCustomerNotifications($customer->getData('entity_id'), $count=10, ['title', 'status']);
173
+
174
+ $notif_html = $this->getLayout()
175
+ ->createBlock('webspeaks_notifycustomer/notification_link')
176
+ ->setData('notifications', $notifications)
177
+ ->setTemplate('webspeaks_notifycustomer/notification/pop-message-item.phtml')
178
+ ->toHtml();
179
+
180
+ echo json_encode([
181
+ 'status' => 'success',
182
+ 'notif_html' => $notif_html
183
+ ]);
184
+ }
185
+
186
+ /**
187
+ * Delete customer notification action Ajax
188
+ *
189
+ * @access public
190
+ * @return void
191
+ *
192
+ */
193
+ public function notif_delAction()
194
+ {
195
+ if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
196
+ echo json_encode([
197
+ 'status' => 'error',
198
+ 'code' => 'not_logged_in'
199
+ ]);
200
+ exit();
201
+ }
202
+
203
+ $id = $this->getRequest()->getParam('id');
204
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
205
+ $notification = Mage::getResourceModel('webspeaks_notifycustomer/notification_collection')
206
+ ->addFieldTofilter('customer_id', $customer->getId())
207
+ ->addFieldTofilter('entity_id', $id)
208
+ ->getFirstItem();
209
+ if ($notification && $notification->getId()) {
210
+ $notification->delete();
211
+ echo json_encode([
212
+ 'status' => 'success',
213
+ 'unread_count' => Mage::getModel('webspeaks_notifycustomer/notification')->getUnreadCount($customer->getId())
214
+ ]);
215
+ } else {
216
+ echo json_encode([
217
+ 'status' => 'error'
218
+ ]);
219
+ }
220
+
221
+ }
222
+
223
+ /**
224
+ * Delete customer notification action
225
+ *
226
+ * @access public
227
+ * @return void
228
+ *
229
+ */
230
+ public function deleteAction()
231
+ {
232
+ if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
233
+ $this->_redirect('notifications/notification/');
234
+ return;
235
+ }
236
+
237
+ $id = $this->getRequest()->getParam('id');
238
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
239
+ $notification = Mage::getResourceModel('webspeaks_notifycustomer/notification_collection')
240
+ ->addFieldTofilter('customer_id', $customer->getId())
241
+ ->addFieldTofilter('entity_id', $id)
242
+ ->getFirstItem();
243
+ if ($notification && $notification->getId()) {
244
+ $notification->delete();
245
+ Mage::getSingleton('core/session')->addSuccess(Mage::helper('webspeaks_notifycustomer')->__('Message deleted.'));
246
+ $this->_redirect('notifications/notification');
247
+ } else {
248
+ Mage::getSingleton('core/session')->addError(Mage::helper('webspeaks_notifycustomer')->__('Cannot delete message.'));
249
+ $this->_redirect('notifications/notification');
250
+ }
251
+
252
+ }
253
+ }
app/code/local/Webspeaks/NotifyCustomer/etc/adminhtml.xml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <config>
20
+ <acl>
21
+ <resources>
22
+ <admin>
23
+ <children>
24
+ <system>
25
+ <children>
26
+ <config>
27
+ <children>
28
+ <webspeaks_notifycustomer translate="title" module="webspeaks_notifycustomer">
29
+ <title>NotifyCustomer</title>
30
+ </webspeaks_notifycustomer>
31
+ </children>
32
+ </config>
33
+ </children>
34
+ </system>
35
+ <customer>
36
+ <children>
37
+ <notification translate="title" module="webspeaks_notifycustomer">
38
+ <title>Notification</title>
39
+ <sort_order>100</sort_order>
40
+ </notification>
41
+ </children>
42
+ </customer>
43
+ </children>
44
+ </admin>
45
+ </resources>
46
+ </acl>
47
+ <menu>
48
+ <customer>
49
+ <children>
50
+ <notification translate="title" module="webspeaks_notifycustomer">
51
+ <title>Notification</title>
52
+ <action>adminhtml/notifycustomer_notification</action>
53
+ <sort_order>100</sort_order>
54
+ </notification>
55
+ </children>
56
+ </customer>
57
+ </menu>
58
+ </config>
app/code/local/Webspeaks/NotifyCustomer/etc/config.xml ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <config>
20
+ <modules>
21
+ <Webspeaks_NotifyCustomer>
22
+ <version>0.0.1</version>
23
+ </Webspeaks_NotifyCustomer>
24
+ </modules>
25
+ <global>
26
+ <resources>
27
+ <webspeaks_notifycustomer_setup>
28
+ <setup>
29
+ <module>Webspeaks_NotifyCustomer</module>
30
+ <class>Webspeaks_NotifyCustomer_Model_Resource_Setup</class>
31
+ </setup>
32
+ </webspeaks_notifycustomer_setup>
33
+ </resources>
34
+ <blocks>
35
+ <webspeaks_notifycustomer>
36
+ <class>Webspeaks_NotifyCustomer_Block</class>
37
+ </webspeaks_notifycustomer>
38
+ </blocks>
39
+ <helpers>
40
+ <webspeaks_notifycustomer>
41
+ <class>Webspeaks_NotifyCustomer_Helper</class>
42
+ </webspeaks_notifycustomer>
43
+ </helpers>
44
+ <models>
45
+ <webspeaks_notifycustomer>
46
+ <class>Webspeaks_NotifyCustomer_Model</class>
47
+ <resourceModel>webspeaks_notifycustomer_resource</resourceModel>
48
+ </webspeaks_notifycustomer>
49
+ <webspeaks_notifycustomer_resource>
50
+ <class>Webspeaks_NotifyCustomer_Model_Resource</class>
51
+ <entities>
52
+ <notification>
53
+ <table>webspeaks_notifycustomer_notification</table>
54
+ </notification>
55
+ </entities>
56
+ </webspeaks_notifycustomer_resource>
57
+ </models>
58
+ <template>
59
+ <email>
60
+ <ws_notify_customer_eml module="NotifyCustomer">
61
+ <label>Notifycusomer email template</label>
62
+ <file>ws_notify_customer.html</file>
63
+ <type>html</type>
64
+ </ws_notify_customer_eml>
65
+ </email>
66
+ </template>
67
+ </global>
68
+ <adminhtml>
69
+ <layout>
70
+ <updates>
71
+ <webspeaks_notifycustomer>
72
+ <file>webspeaks_notifycustomer.xml</file>
73
+ </webspeaks_notifycustomer>
74
+ </updates>
75
+ </layout>
76
+ <translate>
77
+ <modules>
78
+ <Webspeaks_NotifyCustomer>
79
+ <files>
80
+ <default>Webspeaks_NotifyCustomer.csv</default>
81
+ </files>
82
+ </Webspeaks_NotifyCustomer>
83
+ </modules>
84
+ </translate>
85
+ </adminhtml>
86
+ <admin>
87
+ <routers>
88
+ <adminhtml>
89
+ <args>
90
+ <modules>
91
+ <Webspeaks_NotifyCustomer before="Mage_Adminhtml">Webspeaks_NotifyCustomer_Adminhtml</Webspeaks_NotifyCustomer>
92
+ </modules>
93
+ </args>
94
+ </adminhtml>
95
+ </routers>
96
+ </admin>
97
+ <frontend>
98
+ <routers>
99
+ <webspeaks_notifycustomer>
100
+ <use>standard</use>
101
+ <args>
102
+ <module>Webspeaks_NotifyCustomer</module>
103
+ <frontName>notifications</frontName>
104
+ </args>
105
+ </webspeaks_notifycustomer>
106
+ </routers>
107
+ <layout>
108
+ <updates>
109
+ <webspeaks_notifycustomer>
110
+ <file>webspeaks_notifycustomer.xml</file>
111
+ </webspeaks_notifycustomer>
112
+ </updates>
113
+ </layout>
114
+ <translate>
115
+ <modules>
116
+ <Webspeaks_NotifyCustomer>
117
+ <files>
118
+ <default>Webspeaks_NotifyCustomer.csv</default>
119
+ </files>
120
+ </Webspeaks_NotifyCustomer>
121
+ </modules>
122
+ </translate>
123
+ </frontend>
124
+ </config>
app/code/local/Webspeaks/NotifyCustomer/etc/system.xml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <!-- <config>
20
+ <tabs>
21
+ <webspeaks translate="label" module="webspeaks_notifycustomer">
22
+ <label>Webspeaks</label>
23
+ <sort_order>2000</sort_order>
24
+ </webspeaks>
25
+ </tabs>
26
+ <sections>
27
+ <webspeaks_notifycustomer translate="label" module="webspeaks_notifycustomer">
28
+ <class>separator-top</class>
29
+ <label>Customer Notification</label>
30
+ <tab>webspeaks</tab>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>100</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ <groups>
37
+ <notification translate="label" module="webspeaks_notifycustomer">
38
+ <label>Notification</label>
39
+ <frontend_type>text</frontend_type>
40
+ <sort_order>0</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ <fields>
45
+ <breadcrumbs translate="label">
46
+ <label>Use Breadcrumbs</label>
47
+ <frontend_type>select</frontend_type>
48
+ <source_model>adminhtml/system_config_source_yesno</source_model>
49
+ <sort_order>10</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>1</show_in_website>
52
+ <show_in_store>1</show_in_store>
53
+ </breadcrumbs>
54
+ </fields>
55
+ </notification>
56
+ </groups>
57
+ </webspeaks_notifycustomer>
58
+ </sections>
59
+ </config>
60
+ -->
app/code/local/Webspeaks/NotifyCustomer/sql/webspeaks_notifycustomer_setup/install-0.0.1.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * NotifyCustomer module install script
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ $this->startSetup();
25
+ $table = $this->getConnection()
26
+ ->newTable($this->getTable('webspeaks_notifycustomer/notification'))
27
+ ->addColumn(
28
+ 'entity_id',
29
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
30
+ null,
31
+ array(
32
+ 'identity' => true,
33
+ 'nullable' => false,
34
+ 'primary' => true,
35
+ ),
36
+ 'Notification ID'
37
+ )
38
+ ->addColumn(
39
+ 'title',
40
+ Varien_Db_Ddl_Table::TYPE_TEXT, 255,
41
+ array(
42
+ 'nullable' => false,
43
+ ),
44
+ 'Title'
45
+ )
46
+ ->addColumn(
47
+ 'message',
48
+ Varien_Db_Ddl_Table::TYPE_TEXT, '64k',
49
+ array(
50
+ 'nullable' => false,
51
+ ),
52
+ 'Message'
53
+ )
54
+ ->addColumn(
55
+ 'customer_id',
56
+ Varien_Db_Ddl_Table::TYPE_INTEGER, null,
57
+ array(
58
+ 'nullable' => false,
59
+ 'unsigned' => true,
60
+ ),
61
+ 'Customer Id'
62
+ )
63
+ ->addColumn(
64
+ 'status',
65
+ Varien_Db_Ddl_Table::TYPE_SMALLINT, null,
66
+ array(),
67
+ 'Read'
68
+ )
69
+ ->addColumn(
70
+ 'updated_at',
71
+ Varien_Db_Ddl_Table::TYPE_TIMESTAMP,
72
+ null,
73
+ array(),
74
+ 'Notification Modification Time'
75
+ )
76
+ ->addColumn(
77
+ 'created_at',
78
+ Varien_Db_Ddl_Table::TYPE_TIMESTAMP,
79
+ null,
80
+ array(),
81
+ 'Notification Creation Time'
82
+ )
83
+ ->setComment('Notification Table');
84
+ $this->getConnection()->createTable($table);
85
+ $this->endSetup();
app/design/adminhtml/default/default/layout/webspeaks_notifycustomer.xml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <layout>
20
+ <adminhtml_notifycustomer_notification_index>
21
+ <reference name="menu">
22
+ <action method="setActive">
23
+ <menupath>webspeaks_notifycustomer/notification</menupath>
24
+ </action>
25
+ </reference>
26
+ <reference name="content">
27
+ <block type="webspeaks_notifycustomer/adminhtml_notification" name="notification" />
28
+
29
+ </reference>
30
+ </adminhtml_notifycustomer_notification_index>
31
+ <adminhtml_notifycustomer_notification_grid>
32
+ <block type="core/text_list" name="root" output="toHtml">
33
+ <block type="webspeaks_notifycustomer/adminhtml_notification_grid" name="notification_grid"/>
34
+ </block>
35
+ </adminhtml_notifycustomer_notification_grid>
36
+
37
+ <!-- Notification add/edit action -->
38
+ <adminhtml_notifycustomer_notification_edit>
39
+ <update handle="editor"/>
40
+
41
+ <reference name="head">
42
+ <action method="addJs"><script>webspeaks/notifycustomer/jquery-1.10.2.min.js</script></action>
43
+ <action method="addJs"><script>webspeaks/notifycustomer/noconflict.js</script></action>
44
+ <action method="addJs"><script>webspeaks/notifycustomer/adminhtml/notify.js</script></action>
45
+ </reference>
46
+
47
+ <reference name="menu">
48
+ <action method="setActive">
49
+ <menupath>webspeaks_notifycustomer/notification</menupath>
50
+ </action>
51
+ </reference>
52
+ <reference name="content">
53
+ <block type="webspeaks_notifycustomer/adminhtml_notification_edit" name="notification_edit"></block>
54
+ </reference>
55
+ <reference name="left">
56
+ <block type="webspeaks_notifycustomer/adminhtml_notification_edit_tabs" name="notification_tabs"></block>
57
+ </reference>
58
+ </adminhtml_notifycustomer_notification_edit>
59
+
60
+ </layout>
app/design/frontend/base/default/layout/webspeaks_notifycustomer.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <layout>
20
+
21
+ <customer_logged_in>
22
+
23
+ <reference name="head">
24
+ <action method="addCss"><stylesheet>webspeaks/notifycustomer/css/notifycustomer.css</stylesheet></action>
25
+ <action method="addJs"><script>webspeaks/notifycustomer/jquery-1.10.2.min.js</script></action>
26
+ <action method="addJs"><script>webspeaks/notifycustomer/notifycustomer.js</script></action>
27
+ </reference>
28
+
29
+ <reference name="top.links">
30
+
31
+ <block type="webspeaks_notifycustomer/notification_link" name="notify_link" template="webspeaks_notifycustomer/notification/link.phtml">
32
+ <!-- <action method="setPosition"><position>1</position></action> -->
33
+ </block>
34
+
35
+ <action method="addLinkBlock">
36
+ <blockName>notify_link</blockName>
37
+ </action>
38
+
39
+ </reference>
40
+ </customer_logged_in>
41
+
42
+ <customer_account translate="label">
43
+ <reference name="customer_account_navigation">
44
+ <action method="addLink">
45
+ <name>notifications_notification</name>
46
+ <path>notifications/notification/</path>
47
+ <label>Messages</label>
48
+ </action>
49
+ </reference>
50
+ </customer_account>
51
+
52
+ <webspeaks_notifycustomer_notification_index translate="label" module="webspeaks_notifycustomer">
53
+ <label>Notifications list</label>
54
+ <update handle="customer_account"/>
55
+ <update handle="page_two_columns_left" />
56
+ <reference name="content">
57
+ <block type="webspeaks_notifycustomer/notification_list" name="notification_list" template="webspeaks_notifycustomer/notification/list.phtml" />
58
+ </reference>
59
+ </webspeaks_notifycustomer_notification_index>
60
+
61
+ <webspeaks_notifycustomer_notification_view translate="label" module="webspeaks_notifycustomer">
62
+ <label>Notification view page</label>
63
+ <update handle="customer_account"/>
64
+ <update handle="page_two_columns_left" />
65
+ <reference name="content">
66
+ <block type="webspeaks_notifycustomer/notification_view" name="notification_view" template="webspeaks_notifycustomer/notification/view.phtml" />
67
+ </reference>
68
+ </webspeaks_notifycustomer_notification_view>
69
+ </layout>
app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/link.phtml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $unread_count = $this->getUnreadCount() ?>
2
+
3
+ <li id="js-header-notif-menu">
4
+
5
+ <a href="javascript:;">
6
+ <?php echo $this->__('Messages'); ?>
7
+ <?php if ($unread_count): ?>
8
+ (<span class="js-notif-unread-count"><?php echo $unread_count ?></span>)
9
+ <?php endif; ?>
10
+ </a>
11
+
12
+ <div class="notif_pop" id="js-header-notif-pop" data-base_url="<?php echo $this->getNotifBaseUrl() ?>">
13
+
14
+ <div class="notif_pop_content">
15
+
16
+ <div class="search-results-container">
17
+ <div class="loader-container">
18
+ <div class="loader"></div>
19
+ </div>
20
+ <div class="notif-results-main"></div>
21
+ </div>
22
+
23
+ </div><!-- //.notif_pop_content -->
24
+
25
+ </div><!-- //.notif_pop -->
26
+
27
+ </li>
app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/list.phtml ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification list template
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ ?>
25
+ <?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
26
+ <?php $_notifications = $this->getNotifications(); ?>
27
+ <div class="page-title notification-title">
28
+ <h1><?php echo Mage::helper('webspeaks_notifycustomer')->__('Messages') ?></h1>
29
+ </div>
30
+ <?php if ($_notifications->getSize() > 0) :?>
31
+ <table class="data-table" id="my-messages-table">
32
+ <thead>
33
+ <tr>
34
+ <th><?php echo $this->__('Message') ?></th>
35
+ <th><?php echo $this->__('Received On') ?></th>
36
+ <th>&nbsp;</th>
37
+ </tr>
38
+ </thead>
39
+ <tbody>
40
+ <?php $_odd = ''; ?>
41
+ <?php foreach ($_notifications as $_notification): ?>
42
+ <?php $status = $_notification->getData('status') ?>
43
+ <tr>
44
+ <td>
45
+ <a href="<?php echo $_notification->getNotificationUrl()?>">
46
+ <?php if ($status == 0) echo '<strong>' ?>
47
+ <?php echo $_notification->getTitle() ?>
48
+ <?php if ($status == 0) echo '</strong>' ?>
49
+ </a>
50
+ </td>
51
+ <td><span class="nobr"><?php echo $this->formatDate($_notification->getCreatedAt()) ?></span></td>
52
+ <td class="a-center">
53
+ <span class="nobr"><a href="<?php echo $this->getUrl('notifications/notification/view', array('id'=>$_notification->getId())) ?>"><?php echo $this->__('View Message') ?></a>
54
+ <span class="separator">|</span> <a href="<?php echo $this->getUrl('notifications/notification/delete', array('id'=>$_notification->getId())) ?>" class=""><?php echo $this->__('Remove') ?></a>
55
+ </span>
56
+ </td>
57
+ </tr>
58
+ <?php endforeach; ?>
59
+ </tbody>
60
+ </table>
61
+ <script type="text/javascript">decorateTable('my-messages-table');</script>
62
+ <?php echo $this->getPagerHtml(); ?>
63
+ <?php else : ?>
64
+ <?php echo Mage::helper('webspeaks_notifycustomer')->__('There are no notifications at this moment');?>
65
+ <?php endif;?>
66
+ </table>
app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/pop-message-item.phtml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php $notifications = $this->getNotifications() ?>
2
+ <?php $unread_count = $this->getUnreadCount() ?>
3
+
4
+ <div class="notif-items">
5
+ <div class="search-panel-header">
6
+ <?php echo $this->__('Notifications') ?>
7
+ <?php if ($unread_count) echo '(<span class="js-notif-unread-count">'.$unread_count .'</span>)' ?>
8
+ <div class="notif-view-all-link"><a href="<?php echo $this->getNotifBaseUrl() ?>"><?php echo $this->__('View All') ?></a></div>
9
+ </div>
10
+
11
+ <?php if ($notifications->getSize()): ?>
12
+ <?php foreach ($notifications as $notification): ?>
13
+ <?php $status = $notification->getData('status') ?>
14
+ <a href="<?php echo $this->getUrl('notifications/notification/view', array('id'=>$notification->getData('entity_id'))) ?>" class="article-link">
15
+ <div class="hover-item__content">
16
+ <div class="article-link-left"></div>
17
+ <div class="article-link-right dark-gray text-left">
18
+ <?php if ($status == 0) echo '<strong>' ?>
19
+ <?php echo $notification->getData('title') ?>
20
+ <?php if ($status == 0) echo '</strong>' ?>
21
+ </div>
22
+ <div class="icon-rem" data-id="<?php echo $notification->getId() ?>" title="<?php echo $this->__('Delete') ?>"></div>
23
+ </div>
24
+ </a>
25
+ <?php endforeach; ?>
26
+ <?php else: ?>
27
+ <p style="padding: 10px;"><?php echo $this->__('There are no notifications at this moment') ?></p>
28
+ <?php endif; ?>
29
+
30
+ </div>
app/design/frontend/base/default/template/webspeaks_notifycustomer/notification/view.phtml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Webspeaks_NotifyCustomer extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the MIT License
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/mit-license.php
11
+ *
12
+ * @category Webspeaks
13
+ * @package Webspeaks_NotifyCustomer
14
+ * @copyright Copyright (c) 2016
15
+ * @license http://opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+ /**
18
+ * Notification view template
19
+ *
20
+ * @category Webspeaks
21
+ * @package Webspeaks_NotifyCustomer
22
+ * @author Ultimate Module Creator
23
+ */
24
+ ?>
25
+ <?php $_notification = $this->getCurrentNotification();?>
26
+ <?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
27
+ <div class="page-title notification-title">
28
+ <h1><?php echo $_notification->getTitle(); ?></h1>
29
+ </div>
30
+ <div class="notification-view">
31
+ <div class="notification-message">
32
+ <?php echo $_notification->getMessage();?>
33
+ </div>
34
+ </div>
app/etc/modules/Webspeaks_NotifyCustomer.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Webspeaks_NotifyCustomer extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the MIT License
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/mit-license.php
12
+ *
13
+ * @category Webspeaks
14
+ * @package Webspeaks_NotifyCustomer
15
+ * @copyright Copyright (c) 2016
16
+ * @license http://opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+ -->
19
+ <config>
20
+ <modules>
21
+ <Webspeaks_NotifyCustomer>
22
+ <active>true</active>
23
+ <codePool>local</codePool>
24
+ <depends>
25
+ <Mage_Core />
26
+ </depends>
27
+ </Webspeaks_NotifyCustomer>
28
+ </modules>
29
+ </config>
app/locale/en_US/template/email/ws_notify_customer.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <!--@subject New Email @-->
2
+
3
+ <div>
4
+ <p>{{var body}}</p>
5
+ </div>
js/webspeaks/notifycustomer/adminhtml/notify.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery.noConflict();
2
+
3
+ jQuery(document).ready(function($) {
4
+ var searchResults = [];
5
+ $('#find-customer-btn').click(function() {
6
+ $('#loading-mask').show();
7
+ var url = $('#find-customer-btn').attr('data-url') + '?q=' +$('#notification_customer_query').val();
8
+ $.getJSON(url, function(data){
9
+ $('#notification_customer_id').empty();
10
+ var options = [];
11
+ options.push('<option value="">---</option>');
12
+ $.each(data, function(index, text) {
13
+ searchResults[text.id] = text.email;
14
+ var option = '<option value="'+text.id+'">'+text.name+'</option>';
15
+ options.push(option);
16
+ });
17
+ $('#notification_customer_id').append(options.join('')).show();
18
+ $('#select-customer-btn').show();
19
+ $('#loading-mask').hide();
20
+ });
21
+ });
22
+
23
+ $('#notification_customer_id').on('change', function() {
24
+ var id = $(this).val();
25
+ if (!id) {
26
+ return false;
27
+ }
28
+ $('#notification_customer_email').val(searchResults[id]);
29
+ });
30
+ });
js/webspeaks/notifycustomer/jquery-1.10.2.min.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
2
+ //@ sourceMappingURL=jquery-1.10.2.min.map
3
+ */
4
+ (function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
5
+ }({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
6
+ u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
js/webspeaks/notifycustomer/noconflict.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Magento
3
+ *
4
+ * NOTICE OF LICENSE
5
+ *
6
+ * This source file is subject to the Academic Free License (AFL 3.0)
7
+ * that is bundled with this package in the file LICENSE_AFL.txt.
8
+ * It is also available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ * If you did not receive a copy of the license and are unable to
11
+ * obtain it through the world-wide-web, please send an email
12
+ * to license@magento.com so we can send you a copy immediately.
13
+ *
14
+ * DISCLAIMER
15
+ *
16
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
17
+ * versions in the future. If you wish to customize Magento for your
18
+ * needs please refer to http://www.magento.com for more information.
19
+ *
20
+ * @category Mage
21
+ * @package js
22
+ * @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com)
23
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
24
+ */
25
+
26
+ // Avoid PrototypeJS conflicts, assign jQuery to $j instead of $
27
+ var $j = jQuery.noConflict();
js/webspeaks/notifycustomer/notifycustomer.js ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Notification Pop up*/
2
+ (function ($) {
3
+ var _notif_loaded = false,
4
+ _notif_loading = false,
5
+ _base_url, $_notif_pop, $loader;
6
+ $(document).ready(function() {
7
+ $notif_pop = $('#js-header-notif-pop');
8
+ _base_url = $notif_pop.data('base_url');
9
+ $loader = $notif_pop.find('.loader-container');
10
+
11
+ $('#js-header-notif-menu').on('mouseover', function() {
12
+ $notif_pop.show();
13
+ if (!_notif_loaded && !_notif_loading) {
14
+ showNotifLoader();
15
+ loadNotifs();
16
+ }
17
+ });
18
+ $('#js-header-notif-menu').on('mouseout', function() {
19
+ $notif_pop.hide();
20
+ });
21
+ $('#js-header-notif-pop').on('click', '.icon-rem', function(e) {
22
+ e.preventDefault();
23
+ e.stopPropagation();
24
+ var id = $(this).data('id');
25
+ deleteNotif(id);
26
+ });
27
+ });
28
+
29
+ var loadNotifs = function() {
30
+ _notif_loading = true;
31
+ jQuery.ajax({
32
+ url: _base_url + 'ajax_load',
33
+ method: 'post',
34
+ dataType: 'json',
35
+ cache: true
36
+ }).done(function(response) {
37
+ if (response.status == 'success' && response.notif_html) {
38
+ $notif_pop.find('.notif-results-main').html(response.notif_html);
39
+ }
40
+ }).fail(function() {
41
+
42
+ }).always(function() {
43
+ _notif_loaded = true;
44
+ _notif_loading = false;
45
+ hideNotifLoader();
46
+ });
47
+ };
48
+
49
+ var deleteNotif = function(id) {
50
+ jQuery.ajax({
51
+ url: _base_url + 'notif_del',
52
+ method: 'post',
53
+ dataType: 'json',
54
+ data: {id:id}
55
+ }).done(function(response) {
56
+ if (response.status == 'success') {
57
+ var $item = $(".icon-rem[data-id='" + id + "']");
58
+ $item.closest('.article-link').slideUp();
59
+ $('.js-notif-unread-count').text(response.unread_count);
60
+ } else {
61
+ alert('Some error occurred.');
62
+ }
63
+ }).fail(function() {
64
+
65
+ }).always(function() {
66
+ });
67
+ };
68
+
69
+ var showNotifLoader = function() {
70
+ $loader.show();
71
+ };
72
+ var hideNotifLoader = function() {
73
+ $loader.hide();
74
+ };
75
+
76
+ })(jQuery);
77
+ /* Notification Pop up*/
package.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Webspeaks_Notifycustomer</name>
4
+ <version>0.0.1</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Notify Customer is simple extension that allows store owner to send notifications and messages to individual customers.&#xD;
10
+ </summary>
11
+ <description>Notify Customer is simple extension that allows store owner to send notifications and messages to individual customers.&#xD;
12
+ The Magento store owners get the get the benefit of getting in touch with customers. Owners can send direct notifications and messages to their customers. This extension can help the store owners in engaging the customers on their site. Send information about any new sale or products directly to the customers inbox and get them engaged on your site.&#xD;
13
+ &#xD;
14
+ Store owners get a rich interface to draft the notifications and messages. Add rich content to your messages and send directly to customers inbox.</description>
15
+ <notes>Notifycustomer for Magento released</notes>
16
+ <authors><author><name>Arvind Bhardwaj</name><user>arvind07</user><email>bhardwajsonheight@gmail.com</email></author></authors>
17
+ <date>2016-03-11</date>
18
+ <time>12:46:04</time>
19
+ <contents><target name="magelocal"><dir name="Webspeaks"><dir name="NotifyCustomer"><dir name="Block"><dir name="Adminhtml"><dir name="Notification"><dir name="Edit"><file name="Form.php" hash="29cadf67df49be16f2f7d644f8ba5ea1"/><dir name="Tab"><file name="Form.php" hash="d601f0c5412491e97d3d0430e283d52a"/></dir><file name="Tabs.php" hash="6c76253d4ba1f8257f1c6b11941818e0"/></dir><file name="Edit.php" hash="db4a704970d914ed7a1501c128a7cb3c"/><file name="Grid.php" hash="dc8a60c8c49d89dacb3f147efd35fe2d"/></dir><file name="Notification.php" hash="c8f046bbdfb9795dfb496c206a9a2240"/></dir><dir name="Notification"><file name="Link.php" hash="42dfe9b5dd56b813fd7fc77d87633f77"/><file name="List.php" hash="4d5d0fb67b909c574bd7ec6d181f5aa6"/><file name="View.php" hash="d69bff83590958716b6ce4270cdeb4fd"/></dir></dir><dir name="Controller"><dir name="Adminhtml"><file name="NotifyCustomer.php" hash="1dc60a960c073566ca73caeb81681253"/></dir></dir><dir name="Helper"><file name="Data.php" hash="a544b61975c12d4923eabf9642af5f4b"/><file name="Notification.php" hash="59634b376988026051b364fa029a6b32"/></dir><dir name="Model"><file name="Notification.php" hash="2a3dc975a872116945514732c10afaf4"/><dir name="Resource"><dir name="Notification"><file name="Collection.php" hash="55f5ac98d7a7bb6711b207abaca8feec"/></dir><file name="Notification.php" hash="137e2919caaf7fb1d552bbbd6c56b976"/><file name="Setup.php" hash="69339ee406507b7f5569abb3793def90"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Notifycustomer"><file name="NotificationController.php" hash="e301e6745c3ba70a493b29fbb706aeef"/></dir></dir><file name="NotificationController.php" hash="1e9a624312b8f6091399082a40720e46"/></dir><dir name="etc"><file name="adminhtml.xml" hash="d789f1909906ecc5cd74118c79dcfbb2"/><file name="config.xml" hash="ebe1fd2c17174499ca5ad88f6059a555"/><file name="system.xml" hash="f9591827fe08c5bd2e82081508c1019e"/></dir><dir name="sql"><dir name="webspeaks_notifycustomer_setup"><file name="install-0.0.1.php" hash="030d185031237b7d93bbc4d9437574f3"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Webspeaks_NotifyCustomer.xml" hash="337f7a4e7e0a6fa650697e0a19ffb2f8"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="webspeaks_notifycustomer.xml" hash="1ab683a616dc0386801ec0da97644d0d"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="webspeaks_notifycustomer.xml" hash="405a7a844fedee64b3bfaab70afeb4ab"/></dir><dir name="template"><dir name="webspeaks_notifycustomer"><dir name="notification"><file name="link.phtml" hash="ed713dae77b72e86f7a7b11e4fb024eb"/><file name="list.phtml" hash="cd9b59ae2e27c12811f8ad25face118c"/><file name="pop-message-item.phtml" hash="01c4d7a76cd2aca7453e66358c574fc8"/><file name="view.phtml" hash="49560919593123ea2d78e8aa094c40f7"/></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="webspeaks"><dir name="notifycustomer"><dir name="css"><file name="notifycustomer.css" hash="257f9b32c789d66f3775911d991c0c89"/></dir><dir name="img"><file name="button-close.png" hash="04d0907b2d7fc3240693497b199f64f5"/><file name="email-icon.png" hash="f22abab0a7f6d9270b4b7d9759176417"/><file name="opc-ajax-loader.gif" hash="f48ee069890b16455c3ddcacee9b5f75"/></dir></dir></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="webspeaks"><dir name="notifycustomer"><dir name="adminhtml"><file name="notify.js" hash="f96c1f2eb9f231ce7f21c0c4d13b184f"/></dir><file name="jquery-1.10.2.min.js" hash="841dc30647f93349b7d8ef61deebe411"/><file name="noconflict.js" hash="cdd83061ca6c0a504a5f4578a0052a1c"/><file name="notifycustomer.js" hash="0d03e4cf049eaae240c8f79e08cfaac3"/></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><file name="ws_notify_customer.html" hash="b169b133943c31cea7bd1cb1c49089c8"/></dir></dir></dir></target></contents>
20
+ <compatible/>
21
+ <dependencies><required><php><min>5.3.0</min><max>7.0.0</max></php></required></dependencies>
22
+ </package>
skin/frontend/base/default/webspeaks/notifycustomer/css/notifycustomer.css ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Notification popup*/
2
+ #js-header-notif-menu {
3
+ position: relative;
4
+ }
5
+ .notif_pop {
6
+ position: absolute;
7
+ display: none;
8
+ top: 32px;
9
+ right: 0px;
10
+ overflow: visible;
11
+ }
12
+ .notif_pop_content {
13
+ width: 420px;
14
+ right: 272px;
15
+ border: 1px solid #ccc;
16
+ background-color: #fff;
17
+ -webkit-border-radius: 0 0 2px 2px;
18
+ -moz-border-radius: 0 0 2px 2px;
19
+ border-radius: 0 0 2px 2px;
20
+ }
21
+ .notif_pop_content:before {
22
+ content: "";
23
+ display: block;
24
+ position: absolute;
25
+ right: 20px;
26
+ top: -20px;
27
+ width: 20px;
28
+ height: 20px;
29
+ border: 10px solid transparent;
30
+ border-bottom-color: #ccc;
31
+ }
32
+ .notif-view-all-link {
33
+ float: right;
34
+ font-weight: normal;
35
+ text-decoration: none;
36
+ }
37
+ .notif-view-all-link a {
38
+ padding: 0 !important;
39
+ }
40
+ .notif-items, .notif-search-results {
41
+ height: 329px;
42
+ padding-bottom: 20px;
43
+ overflow-y: scroll;
44
+ background-color: #fff;
45
+ }
46
+ .suggested-faqs, .notif-items {
47
+ height: 329px;
48
+ padding-bottom: 20px;
49
+ overflow-y: scroll;
50
+ background-color: #fff;
51
+ }
52
+ .search-results-container .loader-container {
53
+ height: 329px;
54
+ }
55
+ .search-results-container .loader-container .loader {
56
+ background: url('../img/opc-ajax-loader.gif');
57
+ height: 48px;
58
+ width: 48px;
59
+ margin: 50% auto;
60
+ }
61
+ .search-panel-header {
62
+ padding: 19px 20px;
63
+ font-size: 14px;
64
+ font-weight: bold;
65
+ background-color: #edefed;
66
+ }
67
+ .article-link {
68
+ display: block;
69
+ position: relative;
70
+ padding: 16px 20px;
71
+ color: #565a5c;
72
+ text-decoration: none;
73
+ font-size: 14px;
74
+ }
75
+ .article-link:hover {
76
+ text-decoration: none;
77
+ }
78
+ .hover-item__content {
79
+ position: relative;
80
+ left: 0;
81
+ border-bottom: 1px solid #dce0e0;
82
+ padding-bottom: 10px;
83
+ }
84
+ .article-link-left {
85
+ width: 32px;
86
+ height: 32px;
87
+ float: none;
88
+ display: inline-block;
89
+ vertical-align: middle;
90
+ background: url('../img/email-icon.png');
91
+ }
92
+ .article-link .article-link-right {
93
+ width: 75%;
94
+ width: -webkit-calc(100% - 42px);
95
+ width: -moz-calc(100% - 42px);
96
+ width: calc(100% - 42px);
97
+ float: none;
98
+ display: inline-block;
99
+ vertical-align: middle;
100
+ text-align: left;
101
+ }
102
+ .notif-items .article-link .article-link-right {
103
+ width: 80%;
104
+ width: -webkit-calc(100% - 66px);
105
+ width: -moz-calc(100% - 66px);
106
+ width: calc(100% - 66px);
107
+ float: none;
108
+ display: inline-block;
109
+ vertical-align: middle;
110
+ }
111
+ .notif-items .article-link .icon-rem {
112
+ display: inline-block;
113
+ float: none;
114
+ vertical-align: middle;
115
+ background: url('../img/button-close.png');
116
+ width: 16px;
117
+ height: 16px;
118
+ }
119
+ /* Notification popup*/
skin/frontend/base/default/webspeaks/notifycustomer/img/button-close.png ADDED
Binary file
skin/frontend/base/default/webspeaks/notifycustomer/img/email-icon.png ADDED
Binary file
skin/frontend/base/default/webspeaks/notifycustomer/img/opc-ajax-loader.gif ADDED
Binary file