Export WordPress data to XML/CSV - Version 0.9.0

Version Description

Download this release

Release Info

Developer soflyy
Plugin Icon 128x128 Export WordPress data to XML/CSV
Version 0.9.0
Comparing to
See all releases

Version 0.9.0

Files changed (104) hide show
  1. actions/admin_init.php +5 -0
  2. actions/admin_menu.php +20 -0
  3. actions/admin_notices.php +30 -0
  4. actions/plugins_loaded.php +9 -0
  5. actions/wp.php +7 -0
  6. actions/wp_ajax_export.php +403 -0
  7. actions/wp_loaded.php +6 -0
  8. actions/wp_session_garbage_collection.php +65 -0
  9. banner-772x250.png +0 -0
  10. classes/arrayaccess.php +141 -0
  11. classes/config.php +91 -0
  12. classes/download.php +39 -0
  13. classes/helper.php +139 -0
  14. classes/input.php +72 -0
  15. classes/session.php +371 -0
  16. config/options.php +11 -0
  17. controllers/admin/export.php +161 -0
  18. controllers/admin/help.php +12 -0
  19. controllers/admin/settings.php +30 -0
  20. controllers/controller.php +102 -0
  21. controllers/controller/admin.php +104 -0
  22. helpers/backward.php +40 -0
  23. helpers/pmxe_functions.php +80 -0
  24. helpers/str_getcsv.php +18 -0
  25. helpers/wp_redirect_or_javascript.php +17 -0
  26. models/export/list.php +8 -0
  27. models/export/record.php +36 -0
  28. models/model.php +198 -0
  29. models/model/list.php +149 -0
  30. models/model/record.php +176 -0
  31. plugin.php +498 -0
  32. readme.txt +41 -0
  33. schema.php +27 -0
  34. screenshot-1.png +0 -0
  35. screenshot-2.png +0 -0
  36. static/css/admin-ie.css +13 -0
  37. static/css/admin-wp-3.8.css +0 -0
  38. static/css/admin.css +1332 -0
  39. static/img/add-ons/acf-thumb.jpg +0 -0
  40. static/img/add-ons/woo-commerce-thumb.jpg +0 -0
  41. static/img/date-picker.gif +0 -0
  42. static/img/down.gif +0 -0
  43. static/img/drag.png +0 -0
  44. static/img/help.png +0 -0
  45. static/img/ico-add-new.png +0 -0
  46. static/img/ico-remove.png +0 -0
  47. static/img/loading.png +0 -0
  48. static/img/progress_animated.gif +0 -0
  49. static/img/screen-options-right-up.gif +0 -0
  50. static/img/screen-options-right.gif +0 -0
  51. static/img/stars.png +0 -0
  52. static/img/xmlicon.png +0 -0
  53. static/js/admin.js +143 -0
  54. static/js/jquery/css/redmond/images/animated-overlay.gif +0 -0
  55. static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  56. static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100_1.png +0 -0
  57. static/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
  58. static/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  59. static/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  60. static/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  61. static/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  62. static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  63. static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  64. static/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png +0 -0
  65. static/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png +0 -0
  66. static/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png +0 -0
  67. static/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png +0 -0
  68. static/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png +0 -0
  69. static/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png +0 -0
  70. static/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png +0 -0
  71. static/js/jquery/css/redmond/jquery-ui.css +1177 -0
  72. static/js/jquery/css/select2/select2-bootstrap.css +87 -0
  73. static/js/jquery/css/select2/select2-spinner.gif +0 -0
  74. static/js/jquery/css/select2/select2.css +617 -0
  75. static/js/jquery/css/select2/select2.png +0 -0
  76. static/js/jquery/css/smoothness/images/tipsy.gif +0 -0
  77. static/js/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  78. static/js/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  79. static/js/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  80. static/js/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  81. static/js/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  82. static/js/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  83. static/js/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  84. static/js/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  85. static/js/jquery/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  86. static/js/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  87. static/js/jquery/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  88. static/js/jquery/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  89. static/js/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  90. static/js/jquery/css/smoothness/jquery-ui.css +405 -0
  91. static/js/jquery/css/smoothness/jquery.tipsy.css +11 -0
  92. static/js/jquery/jquery.mjs.nestedSortable.js +426 -0
  93. static/js/jquery/jquery.tipsy.js +198 -0
  94. static/js/jquery/moment.js +6 -0
  95. static/js/jquery/select2.min.js +22 -0
  96. static/js/jquery/ui.autocomplete.js +606 -0
  97. static/js/jquery/ui.datepicker.js +1636 -0
  98. static/js/pmxe.js +14 -0
  99. views/admin/export/element.php +183 -0
  100. views/admin/export/index.php +61 -0
  101. views/admin/export/process.php +58 -0
  102. views/admin/help/index.php +13 -0
  103. views/admin/settings/index.php +25 -0
  104. views/controller/error.php +3 -0
actions/admin_init.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_admin_init(){
4
+ wp_enqueue_script('pmxe-script', PMXE_ROOT_URL . '/static/js/pmxe.js', array('jquery'), PMXE_VERSION);
5
+ }
actions/admin_menu.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Register plugin specific admin menu
4
+ */
5
+
6
+ function pmxe_admin_menu() {
7
+ global $menu, $submenu;
8
+
9
+ if (current_user_can('manage_options')) { // admin management options
10
+
11
+ add_menu_page(__('WP All Export', 'pmxe_plugin'), __('All Export', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-home', array(PMXE_Plugin::getInstance(), 'adminDispatcher'), PMXE_Plugin::ROOT_URL . '/static/img/xmlicon.png');
12
+ // workaround to rename 1st option to `Home`
13
+ $submenu['pmxe-admin-home'] = array();
14
+ add_submenu_page('pmxe-admin-home', __('Export to XML', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('New Export', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-export', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
15
+ add_submenu_page('pmxe-admin-home', __('Settings', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('Settings', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-settings', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
16
+ add_submenu_page('pmxe-admin-home', __('Support', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('Support', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-help', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
17
+
18
+ }
19
+ }
20
+
actions/admin_notices.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_admin_notices() {
4
+
5
+ // notify user if history folder is not writable
6
+ $uploads = wp_upload_dir();
7
+
8
+ // notify user
9
+ if (!PMXE_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], 'pmxe-admin') !== false) {
10
+ ?>
11
+ <div class="updated"><p>
12
+ <?php printf(
13
+ __('Welcome to WP All Export. We hope you like it. Please send all support requests and feedback to <a href="mailto:support@soflyy.com">support@soflyy.com</a>.<br/><br/><a href="javascript:void(0);" id="dismiss">dismiss</a>', 'pmxe_plugin')
14
+ ) ?>
15
+ </p></div>
16
+ <?php
17
+ }
18
+
19
+ $input = new PMXE_Input();
20
+ $messages = $input->get('pmxe_nt', array());
21
+ if ($messages) {
22
+ is_array($messages) or $messages = array($messages);
23
+ foreach ($messages as $type => $m) {
24
+ in_array((string)$type, array('updated', 'error')) or $type = 'updated';
25
+ ?>
26
+ <div class="<?php echo $type ?>"><p><?php echo $m ?></p></div>
27
+ <?php
28
+ }
29
+ }
30
+ }
actions/plugins_loaded.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_plugins_loaded() {
4
+
5
+ PMXE_Plugin::$session = PMXE_Session::get_instance();
6
+ do_action( 'pmxe_session_start' );
7
+
8
+ return PMXE_Plugin::$session->session_started();
9
+ }
actions/wp.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_wp() {
4
+ if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) {
5
+ wp_schedule_event( time(), 'twicedaily', 'wp_session_garbage_collection' );
6
+ }
7
+ }
actions/wp_ajax_export.php ADDED
@@ -0,0 +1,403 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_wp_ajax_export(){
4
+
5
+ $wp_uploads = wp_upload_dir();
6
+
7
+ $default = PMXE_Plugin::get_default_import_options();
8
+ $exportOptions = (isset(PMXE_Plugin::$session->data['pmxe_export']) ? PMXE_Plugin::$session->data['pmxe_export'] : array()) + $default;
9
+
10
+ wp_reset_postdata();
11
+
12
+ $exportQuery = new WP_Query( array( 'post_type' => $exportOptions['cpt'], 'orderby' => 'title', 'order' => 'ASC', 'posts_per_page' => -1 ));
13
+
14
+ ob_start();
15
+
16
+ switch ($exportOptions['export_to']) {
17
+ case 'xml':
18
+ echo '<?xml version="1.0" encoding="UTF-8"?>';
19
+
20
+ ?>
21
+ <data>
22
+ <?php
23
+ // The Loop
24
+ while ( $exportQuery->have_posts() ) :
25
+
26
+ $exportQuery->the_post();
27
+
28
+ $record = get_post( get_the_ID() );
29
+
30
+ ?>
31
+ <post>
32
+ <post_type><?php echo get_post_type(); ?></post_type>
33
+ <?php if ($exportOptions['is_export_title']): ?><title><?php the_title(); ?></title><?php endif; ?>
34
+
35
+ <?php if ($exportOptions['is_export_content']): ?>
36
+ <content><?php echo '<![CDATA['; the_content(); echo ']]>'; ?></content>
37
+ <?php endif; ?>
38
+
39
+ <?php if ($exportOptions['is_export_custom_fields']): ?>
40
+ <custom_fields>
41
+ <?php foreach (get_post_custom($record->ID) as $cur_meta_key => $cur_meta_val): ?>
42
+ <?php if ( $exportOptions['export_custom_fields_logic'] == 'full_export' or ($exportOptions['export_custom_fields_logic'] == 'only' and in_array($cur_meta_key, $exportOptions['custom_fields_list']))): ?>
43
+ <<?php echo $cur_meta_key; ?>><?php echo '<![CDATA[' . ((!empty($cur_meta_val) and is_array($cur_meta_val) and count($cur_meta_val) == 1) ? $cur_meta_val[0] : serialize($cur_meta_val)) . ']]>'; ?></<?php echo $cur_meta_key;?>>
44
+ <?php endif; ?>
45
+ <?php endforeach; ?>
46
+ </custom_fields>
47
+ <?php endif; ?>
48
+
49
+ <?php if ($exportOptions['is_export_categories']): ?>
50
+ <taxonomies>
51
+ <?php
52
+
53
+ global $wp_taxonomies;
54
+
55
+ foreach ($wp_taxonomies as $key => $obj) {
56
+
57
+ if ($exportOptions['export_categories_logic'] == 'full_export' or ($exportOptions['export_categories_logic'] == 'only' and in_array($obj->name, $exportOptions['taxonomies_list'])))
58
+ {
59
+ $txes_list = get_the_terms($record->ID, $obj->name);
60
+
61
+ if ( ! is_wp_error($txes_list)) {
62
+ $txes_new = array();
63
+ if (!empty($txes_list)):
64
+ foreach ($txes_list as $t) {
65
+ $txes_new[] = $t->slug;
66
+ }
67
+ ?>
68
+ <<?php echo $obj->name; ?>><?php echo implode(', ', $txes_new); ?></<?php echo $obj->name; ?>>
69
+ <?php
70
+ endif;
71
+ }
72
+ }
73
+ }
74
+ ?>
75
+ </taxonomies>
76
+ <?php endif; ?>
77
+
78
+ <?php if ($exportOptions['is_export_images'] and ! empty($exportOptions['export_images_logic'])): ?>
79
+
80
+ <media_gallery>
81
+ <?php
82
+
83
+ $attachment_imgs = get_posts( array(
84
+ 'post_type' => 'attachment',
85
+ 'posts_per_page' => -1,
86
+ 'post_parent' => $record->ID,
87
+ ) );
88
+
89
+ if ( ! empty($attachment_imgs)):
90
+
91
+ foreach ($attachment_imgs as $attach) {
92
+ if ( wp_attachment_is_image( $attach->ID ) ){
93
+ ?>
94
+ <image>
95
+ <?php if (in_array('urls', $exportOptions['export_images_logic'])): ?><url><?php echo wp_get_attachment_url( $attach->ID ); ?></url><?php endif;?>
96
+
97
+ <?php if (in_array('meta_data', $exportOptions['export_images_logic'])): ?>
98
+ <title><?php echo esc_html($attach->post_title); ?></title>
99
+ <caption><?php echo esc_html($attach->post_excerpt); ?></caption>
100
+ <description><?php echo $attach->post_content;?></description>
101
+ <alt><?php echo get_post_meta($record->ID, '_wp_attachment_image_alt'); ?></alt>
102
+ <?php endif; ?>
103
+ </image>
104
+ <?php
105
+ }
106
+ }
107
+
108
+ endif;
109
+
110
+ ?>
111
+ </media_gallery>
112
+
113
+ <?php endif; ?>
114
+
115
+ <?php if ($exportOptions['is_export_other']): ?>
116
+
117
+ <other_stuff>
118
+
119
+ <?php if ($exportOptions['is_export_dates']): ?><date><?php echo get_post_time('U', true); ?></date><?php endif; ?>
120
+ <?php if ($exportOptions['is_export_parent']): ?><parent><?php echo $record->post_parent; ?></parent><?php endif; ?>
121
+ <?php if ($exportOptions['is_export_template']): ?><template><?php echo get_post_meta($record->ID, '_wp_page_template', true); ?></template><?php endif; ?>
122
+ <?php if ($exportOptions['is_export_menu_order']): ?><menu_order><?php echo $record->menu_order; ?></menu_order><?php endif; ?>
123
+ <?php if ($exportOptions['is_export_status']): ?><status><?php echo $record->post_status; ?></status><?php endif; ?>
124
+ <?php if ($exportOptions['is_export_format']): ?><format><?php echo get_post_format($record->ID); ?></format><?php endif; ?>
125
+ <?php if ($exportOptions['is_export_author']): ?><author><?php echo $record->post_author; ?></author><?php endif; ?>
126
+ <?php if ($exportOptions['is_export_slug']): ?><slug><?php echo $record->guid; ?></slug><?php endif; ?>
127
+ <?php if ($exportOptions['is_export_excerpt']): ?><excerpt><?php echo $record->post_excerpt; ?></excerpt><?php endif; ?>
128
+ <?php if ($exportOptions['is_export_attachments']): ?>
129
+ <attachments>
130
+ <?php
131
+
132
+ $attachment_imgs = get_posts( array(
133
+ 'post_type' => 'attachment',
134
+ 'posts_per_page' => -1,
135
+ 'post_parent' => $record->ID,
136
+ ) );
137
+
138
+ if ( ! empty($attachment_imgs)):
139
+
140
+ foreach ($attachment_imgs as $attach) {
141
+ if ( ! wp_attachment_is_image( $attach->ID ) ){
142
+ ?>
143
+ <attach>
144
+ <url><?php echo wp_get_attachment_url( $attach->ID ); ?></url>
145
+ </attach>
146
+ <?php
147
+ }
148
+ }
149
+
150
+ endif;
151
+
152
+ ?>
153
+ </attachments>
154
+ <?php endif; ?>
155
+
156
+ </other_stuff>
157
+
158
+ <?php endif; ?>
159
+
160
+ </post>
161
+
162
+ <?php
163
+ endwhile;
164
+ ?>
165
+
166
+ </data>
167
+ <?php
168
+
169
+ break;
170
+ case 'csv':
171
+
172
+ // Prepare headers
173
+
174
+ $headers = array();
175
+
176
+ $stream = fopen("php://output", 'w');
177
+
178
+ $max_attach_count = 0;
179
+ $max_images_count = 0;
180
+
181
+ $cf = array();
182
+ $taxes = array();
183
+
184
+ $articles = array();
185
+
186
+ while ( $exportQuery->have_posts() ) :
187
+
188
+ $attach_count = 0;
189
+ $images_count = 0;
190
+
191
+ $exportQuery->the_post();
192
+
193
+ $record = get_post( get_the_ID() );
194
+
195
+ $article = array();
196
+
197
+ $article['post_type'] = $record->post_type;
198
+
199
+ if ($exportOptions['is_export_title']) $article['title'] = get_the_title();
200
+ if ($exportOptions['is_export_content']) $article['content'] = get_the_content();
201
+
202
+ if ($exportOptions['is_export_other']):
203
+ if ($exportOptions['is_export_dates']) $article['date'] = get_post_time('U', true);
204
+ if ($exportOptions['is_export_parent']) $article['parent'] = $record->post_parent;
205
+ if ($exportOptions['is_export_template']) $article['template'] = get_post_meta($record->ID, '_wp_page_template', true);
206
+ if ($exportOptions['is_export_menu_order']) $article['menu_order'] = $record->menu_order;
207
+ if ($exportOptions['is_export_status']) $article['status'] = $record->post_status;
208
+ if ($exportOptions['is_export_format']) $article['format'] = get_post_format($record->ID);
209
+ if ($exportOptions['is_export_author']) $article['author'] = $record->post_author;
210
+ if ($exportOptions['is_export_slug']) $article['slug'] = $record->guid;
211
+ if ($exportOptions['is_export_excerpt']) $article['excerpt'] = $record->post_excerpt;
212
+ if ($exportOptions['is_export_attachments']):
213
+ $attachment_imgs = get_posts( array(
214
+ 'post_type' => 'attachment',
215
+ 'posts_per_page' => -1,
216
+ 'post_parent' => $record->ID,
217
+ ) );
218
+
219
+ if ( ! empty($attachment_imgs)):
220
+
221
+ foreach ($attachment_imgs as $key => $attach) {
222
+ if ( ! wp_attachment_is_image( $attach->ID ) ){
223
+ $article['attach_' . ($key + 1)] = wp_get_attachment_url( $attach->ID );
224
+ $attach_count++;
225
+ }
226
+ }
227
+
228
+ if ($attach_count > $max_attach_count) $max_attach_count = $attach_count;
229
+
230
+ endif;
231
+ endif;
232
+ endif;
233
+
234
+ if ($exportOptions['is_export_custom_fields']):
235
+
236
+ foreach (get_post_custom($record->ID) as $cur_meta_key => $cur_meta_val):
237
+ if ( $exportOptions['export_custom_fields_logic'] == 'full_export' or ($exportOptions['export_custom_fields_logic'] == 'only' and in_array($cur_meta_key, $exportOptions['custom_fields_list']))):
238
+ $article['CF_' . $cur_meta_key] = ((!empty($cur_meta_val) and is_array($cur_meta_val) and count($cur_meta_val) == 1) ? $cur_meta_val[0] : serialize($cur_meta_val));
239
+
240
+ if (!in_array('CF_' . $cur_meta_key, $cf)) $cf[] = 'CF_' . $cur_meta_key;
241
+
242
+ endif;
243
+ endforeach;
244
+
245
+ endif;
246
+
247
+ if ($exportOptions['is_export_categories']):
248
+
249
+ global $wp_taxonomies;
250
+
251
+ foreach ($wp_taxonomies as $key => $obj) {
252
+
253
+ if ($exportOptions['export_categories_logic'] == 'full_export' or ($exportOptions['export_categories_logic'] == 'only' and in_array($obj->name, $exportOptions['taxonomies_list'])))
254
+ {
255
+ $txes_list = get_the_terms($record->ID, $obj->name);
256
+
257
+ if ( ! is_wp_error($txes_list)) {
258
+ $txes_new = array();
259
+ if (!empty($txes_list)):
260
+ foreach ($txes_list as $t) {
261
+ $txes_new[] = $t->slug;
262
+ }
263
+ $article['TX_' . $obj->name] = implode('|', $txes_new);
264
+
265
+ if (!in_array('TX_' . $obj->name, $taxes)) $taxes[] = 'TX_' . $obj->name;
266
+
267
+ endif;
268
+ }
269
+ }
270
+ }
271
+
272
+ endif;
273
+
274
+ if ($exportOptions['is_export_images'] and ! empty($exportOptions['export_images_logic'])):
275
+
276
+ $attachment_imgs = get_posts( array(
277
+ 'post_type' => 'attachment',
278
+ 'posts_per_page' => -1,
279
+ 'post_parent' => $record->ID,
280
+ ) );
281
+
282
+ if ( ! empty($attachment_imgs)):
283
+
284
+ foreach ($attachment_imgs as $key => $attach) {
285
+ if ( wp_attachment_is_image( $attach->ID ) ){
286
+ if (in_array('urls', $exportOptions['export_images_logic'])) $article['image_url_' . ($key + 1)] = wp_get_attachment_url( $attach->ID );
287
+
288
+ if (in_array('meta_data', $exportOptions['export_images_logic'])):
289
+ $article['image_title_' . ($key + 1)] = $attach->post_title;
290
+ $article['image_caption_' . ($key + 1)] = $attach->post_excerpt;
291
+ $article['image_description_' . ($key + 1)] = $attach->post_content;
292
+ $article['image_alt_' . ($key + 1)] = get_post_meta($record->ID, '_wp_attachment_image_alt');
293
+ endif;
294
+
295
+ $images_count++;
296
+ }
297
+ }
298
+
299
+ if ($max_images_count > $images_count) $max_images_count = $images_count;
300
+
301
+ endif;
302
+
303
+ endif;
304
+
305
+ $articles[] = $article;
306
+
307
+ //fputcsv($stream, $article);
308
+
309
+ endwhile;
310
+
311
+ $headers[] = 'post_type';
312
+
313
+ if ($exportOptions['is_export_title']) $headers[] = 'title';
314
+ if ($exportOptions['is_export_content']) $headers[] = 'content';
315
+
316
+ if ($exportOptions['is_export_other']):
317
+ if ($exportOptions['is_export_dates']) $headers[] = 'date';
318
+ if ($exportOptions['is_export_parent']) $headers[] = 'parent';
319
+ if ($exportOptions['is_export_template']) $headers[] = 'template';
320
+ if ($exportOptions['is_export_menu_order']) $headers[] = 'menu_order';
321
+ if ($exportOptions['is_export_status']) $headers[] = 'status';
322
+ if ($exportOptions['is_export_format']) $headers[] = 'format';
323
+ if ($exportOptions['is_export_author']) $headers[] = 'author';
324
+ if ($exportOptions['is_export_slug']) $headers[] = 'slug';
325
+ if ($exportOptions['is_export_excerpt']) $headers[] = 'excerpt';
326
+
327
+ for ($i = 0; $i < $max_attach_count; $i++){
328
+ $headers[] = 'attach_' . ($i + 1);
329
+ }
330
+
331
+ endif;
332
+
333
+ if (!empty($cf)){
334
+ foreach ($cf as $cf_key) {
335
+ $headers[] = $cf_key;
336
+ }
337
+ }
338
+
339
+ if (!empty($taxes)){
340
+ foreach ($taxes as $tx) {
341
+ $headers[] = $tx;
342
+ }
343
+ }
344
+
345
+ for ($i = 0; $i < $max_images_count; $i++){
346
+
347
+ if (in_array('urls', $exportOptions['export_images_logic'])) $headers[] = 'image_url_' . ($i + 1);
348
+
349
+ if (in_array('meta_data', $exportOptions['export_images_logic'])):
350
+ $headers[] = 'image_title_' . ($i + 1);
351
+ $headers[] = 'image_caption_' . ($i + 1);
352
+ $headers[] = 'image_description_' . ($i + 1);
353
+ $headers[] = 'image_alt_' . ($i + 1);
354
+ endif;
355
+
356
+ }
357
+
358
+ fputcsv($stream, $headers);
359
+
360
+ foreach ($articles as $article) {
361
+ $line = array();
362
+ foreach ($headers as $header) {
363
+ $line[$header] = (!empty($article[$header])) ? $article[$header] : '';
364
+ }
365
+ fputcsv($stream, $line);
366
+ }
367
+
368
+ break;
369
+
370
+ default:
371
+ # code...
372
+ break;
373
+ }
374
+
375
+ wp_reset_postdata();
376
+
377
+ $export_file = $wp_uploads['path'] . '/' . time() . '.' . $exportOptions['export_to'];
378
+
379
+ if (@file_exists($export_file)) @unlink($export_file);
380
+
381
+ file_put_contents($export_file, ob_get_clean());
382
+
383
+ if ( file_exists($export_file)){
384
+ $wp_filetype = wp_check_filetype(basename($export_file), null );
385
+ $attachment_data = array(
386
+ 'guid' => $wp_uploads['baseurl'] . '/' . _wp_relative_upload_path( $export_file ),
387
+ 'post_mime_type' => $wp_filetype['type'],
388
+ 'post_title' => preg_replace('/\.[^.]+$/', '', basename($export_file)),
389
+ 'post_content' => '',
390
+ 'post_status' => 'inherit'
391
+ );
392
+ $attach_id = wp_insert_attachment( $attachment_data, $export_file );
393
+ }
394
+
395
+ PMXE_Plugin::$session['pmxe_export']['export_file'] = $export_file;
396
+
397
+ pmxe_session_commit();
398
+
399
+ exit(json_encode(array('file' => $export_file))); die;
400
+
401
+ }
402
+
403
+ ?>
actions/wp_loaded.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_wp_loaded() {
4
+
5
+
6
+ }
actions/wp_session_garbage_collection.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmxe_wp_session_garbage_collection() {
4
+ global $wpdb;
5
+
6
+ if ( defined( 'WP_SETUP_CONFIG' ) ) {
7
+ return;
8
+ }
9
+
10
+ $session_mode = PMXE_Plugin::getInstance()->getOption('session_mode');
11
+
12
+ if ( ! defined( 'WP_INSTALLING' ) ) {
13
+ if ($session_mode == 'database'){
14
+ $expiration_keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_pmxe_session_expires_%'" );
15
+
16
+ $now = time();
17
+ $expired_sessions = array();
18
+
19
+ foreach( $expiration_keys as $expiration ) {
20
+ // If the session has expired
21
+ if ( $now > intval( $expiration->option_value ) ) {
22
+ // Get the session ID by parsing the option_name
23
+ $session_id = str_replace("_PMXE_session_expires_", "", $expiration->option_name);
24
+
25
+ $expired_sessions[] = $expiration->option_name;
26
+ $expired_sessions[] = "_PMXE_session_$session_id";
27
+ }
28
+ }
29
+
30
+ // Delete all expired sessions in a single query
31
+ if ( ! empty( $expired_sessions ) ) {
32
+ $option_names = implode( "','", $expired_sessions );
33
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('$option_names')" );
34
+ }
35
+ }
36
+ elseif ($session_mode == 'files'){
37
+ $session_files = scandir( PMXE_ROOT_DIR . '/sessions');
38
+
39
+ if (!empty($session_files)){
40
+ $now = time();
41
+ $expired_sessions = array();
42
+ foreach ($session_files as $key => $file) {
43
+ if ( strpos($file, "_pmxe_session_expires_") !== false){
44
+ $expiration_value = @file_get_contents( PMXE_ROOT_DIR . "/sessions/" . $file );
45
+
46
+ if ($now > intval($expiration_value)){
47
+ $session_id = str_replace("_pmxe_session_expires_", "", $file);
48
+ $expired_sessions[] = $file;
49
+ $expired_sessions[] = "_pmxe_session_$session_id";
50
+ }
51
+ }
52
+ }
53
+ // Delete all expired sessions in a single query
54
+ if ( ! empty( $expired_sessions ) ) {
55
+ foreach ($expired_sessions as $key => $file) {
56
+ @unlink( PMXE_ROOT_DIR . "/sessions/" . $file );
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ // Allow other plugins to hook in to the garbage collection process.
64
+ do_action( 'PMXE_session_cleanup' );
65
+ }
banner-772x250.png ADDED
Binary file
classes/arrayaccess.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Multidimensional ArrayAccess
4
+ *
5
+ * Allows ArrayAccess-like functionality with multidimensional arrays. Fully supports
6
+ * both sets and unsets.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Session
10
+ * @since 3.7.0
11
+ */
12
+
13
+ /**
14
+ * Recursive array class to allow multidimensional array access.
15
+ *
16
+ * @package WordPress
17
+ * @since 3.7.0
18
+ */
19
+ class PMXE_ArrayAccess implements ArrayAccess {
20
+ /**
21
+ * Internal data collection.
22
+ *
23
+ * @var array
24
+ */
25
+ public $container = array();
26
+
27
+ /**
28
+ * Flag whether or not the internal collection has been changed.
29
+ *
30
+ * @var bool
31
+ */
32
+ protected $dirty = false;
33
+
34
+ /**
35
+ * Default object constructor.
36
+ *
37
+ * @param array $data
38
+ */
39
+ protected function __construct( $data = array() ) {
40
+ foreach ( $data as $key => $value ) {
41
+ $this[ $key ] = $value;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Allow deep copies of objects
47
+ */
48
+ public function __clone() {
49
+ foreach ( $this->container as $key => $value ) {
50
+ if ( $value instanceof self ) {
51
+ $this[ $key ] = clone $value;
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Output the data container as a multidimensional array.
58
+ *
59
+ * @return array
60
+ */
61
+ public function toArray() {
62
+ $data = $this->container;
63
+ if (!empty($data)){
64
+ foreach ( $data as $key => $value ) {
65
+ if ( $value instanceof self ) {
66
+ $data[ $key ] = $value->toArray();
67
+ }
68
+ }
69
+ }
70
+ return $data;
71
+ }
72
+
73
+ /*****************************************************************/
74
+ /* ArrayAccess Implementation */
75
+ /*****************************************************************/
76
+
77
+ /**
78
+ * Whether a offset exists
79
+ *
80
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
81
+ *
82
+ * @param mixed $offset An offset to check for.
83
+ *
84
+ * @return boolean true on success or false on failure.
85
+ */
86
+ public function offsetExists( $offset ) {
87
+ return isset( $this->container[ $offset ]) ;
88
+ }
89
+
90
+ /**
91
+ * Offset to retrieve
92
+ *
93
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
94
+ *
95
+ * @param mixed $offset The offset to retrieve.
96
+ *
97
+ * @return mixed Can return all value types.
98
+ */
99
+ public function offsetGet( $offset ) {
100
+ return isset( $this->container[ $offset ] ) ? $this->container[ $offset ] : null;
101
+ }
102
+
103
+ /**
104
+ * Offset to set
105
+ *
106
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
107
+ *
108
+ * @param mixed $offset The offset to assign the value to.
109
+ * @param mixed $value The value to set.
110
+ *
111
+ * @return void
112
+ */
113
+ public function offsetSet( $offset, $data ) {
114
+ if ( is_array( $data ) ) {
115
+ $data = new self( $data );
116
+ }
117
+ if ( $offset === null ) { // don't forget this!
118
+ $this->container[] = $data;
119
+ } else {
120
+ $this->container[ $offset ] = $data;
121
+ }
122
+
123
+ $this->dirty = true;
124
+ }
125
+
126
+ /**
127
+ * Offset to unset
128
+ *
129
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
130
+ *
131
+ * @param mixed $offset The offset to unset.
132
+ *
133
+ * @return void
134
+ */
135
+ public function offsetUnset( $offset ) {
136
+ unset( $this->container[ $offset ] );
137
+
138
+ $this->dirty = true;
139
+ }
140
+ }
141
+ ?>
classes/config.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class to load config files
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Config implements IteratorAggregate {
8
+ /**
9
+ * Config variables stored
10
+ * @var array
11
+ */
12
+ protected $config = array();
13
+ /**
14
+ * List of loaded files in order to avoid loading same file several times
15
+ * @var array
16
+ */
17
+ protected $loaded = array();
18
+
19
+ /**
20
+ * Static method to create config instance from file on disc
21
+ * @param string $filePath
22
+ * @param string[optional] $section
23
+ * @return PMXE_Config
24
+ */
25
+ public static function createFromFile($filePath, $section = NULL) {
26
+ $config = new self();
27
+ return $config->loadFromFile($filePath, $section);
28
+ }
29
+
30
+ /**
31
+ * Load config file
32
+ * @param string $filePath
33
+ * @param string[optional] $section
34
+ * @return PMXE_Config
35
+ */
36
+ public function loadFromFile($filePath, $section = NULL) {
37
+ if ( ! is_null($section)) {
38
+ $this->config[$section] = self::createFromFile($filePath);
39
+ } else {
40
+ $filePath = realpath($filePath);
41
+ if ($filePath and ! in_array($filePath, $this->loaded)) {
42
+ require $filePath;
43
+
44
+ $sandbox = create_function('', "require '$filePath'; if(array_keys(get_defined_vars()) != array('config')) return array(); return \$config;");
45
+ $config = $sandbox();
46
+ $this->loaded[] = $filePath;
47
+ $this->config = array_merge($this->config, $config);
48
+ }
49
+ }
50
+ return $this;
51
+ }
52
+ /**
53
+ * Return value of setting with specified name
54
+ * @param string $field Setting name
55
+ * @param string[optional] $section Section name to look setting in
56
+ * @return mixed
57
+ */
58
+ public function get($field, $section = NULL) {
59
+ return ! is_null($section) ? $this->config[$section]->get($field) : $this->config[$field];
60
+ }
61
+
62
+ /**
63
+ * Magic method for checking whether some config option are set
64
+ * @param string $field
65
+ * @return bool
66
+ */
67
+ public function __isset($field) {
68
+ return isset($this->config[$field]);
69
+ }
70
+ /**
71
+ * Magic method to implement object-like access to config parameters
72
+ * @param string $field
73
+ * @return mixed
74
+ */
75
+ public function __get($field) {
76
+ return $this->config[$field];
77
+ }
78
+
79
+ /**
80
+ * Return all config options as array
81
+ * @return array
82
+ */
83
+ public function toArray($section = NULL) {
84
+ return ! is_null($section) ? $this->config[$section]->toArray() : $this->config;
85
+ }
86
+
87
+ public function getIterator() {
88
+ return new ArrayIterator($this->config);
89
+ }
90
+
91
+ }
classes/download.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PMXE_Download
4
+ {
5
+
6
+ static public function zip($file_name)
7
+ {
8
+
9
+ header('Content-type: application/zip');
10
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
11
+ readfile($file_name);
12
+ die;
13
+ }
14
+
15
+ static public function xls($file_name)
16
+ {
17
+ header("Content-Type: application/vnd.ms-excel; charset=UTF-8");
18
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
19
+ readfile($file_name);
20
+ die;
21
+ }
22
+
23
+ static public function csv($file_name)
24
+ {
25
+ header("Content-Type: text/plain; charset=UTF-8");
26
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
27
+ readfile($file_name);
28
+ die;
29
+ }
30
+
31
+ static public function xml($file_name)
32
+ {
33
+ header("Content-Type: application/xhtml+xml; charset=UTF-8");
34
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
35
+ readfile($file_name);
36
+ die;
37
+ }
38
+
39
+ }
classes/helper.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper class which defnes a namespace for some commonly used functions
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Helper {
8
+ const GLOB_MARK = 1;
9
+ const GLOB_NOSORT = 2;
10
+ const GLOB_ONLYDIR = 4;
11
+
12
+ const GLOB_NODIR = 256;
13
+ const GLOB_PATH = 512;
14
+ const GLOB_NODOTS = 1024;
15
+ const GLOB_RECURSE = 2048;
16
+
17
+ /**
18
+ * A safe empowered glob().
19
+ *
20
+ * Function glob() is prohibited on some server (probably in safe mode)
21
+ * (Message "Warning: glob() has been disabled for security reasons in
22
+ * (script) on line (line)") for security reasons as stated on:
23
+ * http://seclists.org/fulldisclosure/2005/Sep/0001.html
24
+ *
25
+ * safe_glob() intends to replace glob() using readdir() & fnmatch() instead.
26
+ * Supported flags: self::GLOB_MARK, self::GLOB_NOSORT, self::GLOB_ONLYDIR
27
+ * Additional flags: self::GLOB_NODIR, self::GLOB_PATH, self::GLOB_NODOTS, self::GLOB_RECURSE
28
+ * (not original glob() flags)
29
+ * @author BigueNique AT yahoo DOT ca
30
+ * @updates
31
+ * - 080324 Added support for additional flags: self::GLOB_NODIR, self::GLOB_PATH,
32
+ * self::GLOB_NODOTS, self::GLOB_RECURSE
33
+ * - 100607 Recurse is_dir check fixed by Pavel Kulbakin <p.kulbakin@gmail.com>
34
+ */
35
+ public static function safe_glob($pattern, $flags=0) {
36
+ $split = explode('/', str_replace('\\', '/', $pattern));
37
+ $mask = array_pop($split);
38
+ $path = implode('/', $split);
39
+
40
+ if (($dir = @opendir($path . '/')) !== false or ($dir = @opendir($path)) !== false) {
41
+ $glob = array();
42
+ while(($file = readdir($dir)) !== false) {
43
+ // Recurse subdirectories (self::GLOB_RECURSE)
44
+ if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
45
+ $glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
46
+ }
47
+ // Match file mask
48
+ if (self::fnmatch($mask, $file, FNM_CASEFOLD)) {
49
+ if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
50
+ && (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
51
+ && (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
52
+ ) {
53
+ $glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
54
+ }
55
+ }
56
+ }
57
+ closedir($dir);
58
+ if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
59
+ return $glob;
60
+ } else {
61
+ return (strpos($pattern, "*") === false) ? array($pattern) : false;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Prepends $string to each element of $array
67
+ * If $deep is true, will indeed also apply to sub-arrays
68
+ * @author BigueNique AT yahoo DOT ca
69
+ * @since 080324
70
+ */
71
+ public static function array_prepend($array, $string, $deep=false) {
72
+ if(empty($array)||empty($string)) {
73
+ return $array;
74
+ }
75
+ foreach ($array as $key => $element) {
76
+ if (is_array($element)) {
77
+ if ($deep) {
78
+ $array[$key] = self::array_prepend($element,$string,$deep);
79
+ } else {
80
+ trigger_error(__METHOD__ . ': array element', E_USER_WARNING);
81
+ }
82
+ } else {
83
+ $array[$key] = $string.$element;
84
+ }
85
+ }
86
+ return $array;
87
+
88
+ }
89
+
90
+ const FNM_PATHNAME = 1;
91
+ const FNM_NOESCAPE = 2;
92
+ const FNM_PERIOD = 4;
93
+ const FNM_CASEFOLD = 16;
94
+
95
+ /**
96
+ * non-POSIX complient remplacement for the fnmatch
97
+ */
98
+ public static function fnmatch($pattern, $string, $flags = 0) {
99
+
100
+ $modifiers = null;
101
+ $transforms = array(
102
+ '\*' => '.*',
103
+ '\?' => '.',
104
+ '\[\!' => '[^',
105
+ '\[' => '[',
106
+ '\]' => ']',
107
+ '\.' => '\.',
108
+ '\\' => '\\\\',
109
+ '\-' => '-',
110
+ );
111
+
112
+ // Forward slash in string must be in pattern:
113
+ if ($flags & FNM_PATHNAME) {
114
+ $transforms['\*'] = '[^/]*';
115
+ }
116
+
117
+ // Back slash should not be escaped:
118
+ if ($flags & FNM_NOESCAPE) {
119
+ unset($transforms['\\']);
120
+ }
121
+
122
+ // Perform case insensitive match:
123
+ if ($flags & FNM_CASEFOLD) {
124
+ $modifiers .= 'i';
125
+ }
126
+
127
+ // Period at start must be the same as pattern:
128
+ if ($flags & FNM_PERIOD) {
129
+ if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false;
130
+ }
131
+
132
+ $pattern = '#^'
133
+ .strtr(preg_quote($pattern, '#'), $transforms)
134
+ .'$#'
135
+ .$modifiers;
136
+
137
+ return (boolean)preg_match($pattern, $string);
138
+ }
139
+ }
classes/input.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PMXE_Input {
3
+ protected $filters = array('stripslashes');
4
+
5
+ public function read($inputArray, $paramName, $default = NULL) {
6
+ if (is_array($paramName) and ! is_null($default)) {
7
+ throw new Exception('Either array of parameter names with default values as the only argument or param name and default value as seperate arguments are expected.');
8
+ }
9
+ if (is_array($paramName)) {
10
+ foreach ($paramName as $param => $def) {
11
+ if (isset($inputArray[$param])) {
12
+ $paramName[$param] = $this->applyFilters($inputArray[$param]);
13
+ }
14
+ }
15
+ return $paramName;
16
+ } else {
17
+ return isset($inputArray[$paramName]) ? $this->applyFilters($inputArray[$paramName]) : $default;
18
+ }
19
+ }
20
+
21
+ public function get($paramName, $default = NULL) {
22
+ return $this->read($_GET, $paramName, $default);
23
+ }
24
+
25
+ public function post($paramName, $default = NULL) {
26
+ return $this->read($_POST, $paramName, $default);
27
+ }
28
+
29
+ public function cookie($paramName, $default = NULL) {
30
+ return $this->read($_COOKIE, $paramName, $default);
31
+ }
32
+
33
+ public function request($paramName, $default = NULL) {
34
+ return $this->read($_GET + $_POST + $_COOKIE, $paramName, $default);
35
+ }
36
+
37
+ public function getpost($paramName, $default = NULL) {
38
+ return $this->read($_GET + $_POST, $paramName, $default);
39
+ }
40
+
41
+ public function server($paramName, $default = NULL) {
42
+ return $this->read($_SERVER, $paramName, $default);
43
+ }
44
+
45
+ public function addFilter($callback) {
46
+ if ( ! is_callable($callback)) {
47
+ throw new Exception(get_class($this) . '::' . __METHOD__ . ' parameter must be a proper callback function reference.');
48
+ }
49
+ if ( ! in_array($callback, $this->filters)) {
50
+ $this->filters[] = $callback;
51
+ }
52
+ return $this;
53
+ }
54
+
55
+ public function removeFilter($callback) {
56
+ $this->filters = array_diff($this->filters, array($callback));
57
+ return $this;
58
+ }
59
+
60
+ protected function applyFilters($val) {
61
+ if (is_array($val)) {
62
+ foreach ($val as $k => $v) {
63
+ $val[$k] = $this->applyFilters($v);
64
+ }
65
+ } else {
66
+ foreach ($this->filters as $filter) {
67
+ $val = call_user_func($filter, $val);
68
+ }
69
+ }
70
+ return $val;
71
+ }
72
+ }
classes/session.php ADDED
@@ -0,0 +1,371 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WordPress session managment.
4
+ *
5
+ * Standardizes WordPress session data using database-backed options for storage.
6
+ * for storing user session information.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Session
10
+ * @since 3.7.0
11
+ */
12
+
13
+ /**
14
+ * WordPress Session class for managing user session data.
15
+ *
16
+ * @package WordPress
17
+ * @since 3.7.0
18
+ */
19
+ final class PMXE_Session extends PMXE_ArrayAccess implements Iterator, Countable {
20
+ /**
21
+ * ID of the current session.
22
+ *
23
+ * @var string
24
+ */
25
+ protected $session_id;
26
+
27
+ /**
28
+ * Unix timestamp when session expires.
29
+ *
30
+ * @var int
31
+ */
32
+ protected $expires;
33
+
34
+ /**
35
+ * Unix timestamp indicating when the expiration time needs to be reset.
36
+ *
37
+ * @var int
38
+ */
39
+ protected $exp_variant;
40
+
41
+ /**
42
+ * Singleton instance.
43
+ *
44
+ * @var bool|WP_Session
45
+ */
46
+ private static $instance = false;
47
+
48
+ public $data = array();
49
+
50
+ public $session_mode = '';
51
+ /**
52
+ * Retrieve the current session instance.
53
+ *
54
+ * @param bool $session_id Session ID from which to populate data.
55
+ *
56
+ * @return bool|WP_Session
57
+ */
58
+ public static function get_instance() {
59
+ if ( ! self::$instance ) {
60
+ self::$instance = new self();
61
+ }
62
+
63
+ return self::$instance;
64
+ }
65
+
66
+ /**
67
+ * Default constructor.
68
+ * Will rebuild the session collection from the given session ID if it exists. Otherwise, will
69
+ * create a new session with that ID.
70
+ *
71
+ * @param $session_id
72
+ * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
73
+ */
74
+ protected function __construct() {
75
+
76
+ $this->session_mode = PMXE_Plugin::getInstance()->getOption('session_mode');
77
+
78
+ if ($this->session_mode != 'default'){
79
+
80
+ if ( isset( $_COOKIE[PMXE_SESSION_COOKIE] ) ) {
81
+
82
+ $cookie = stripslashes( $_COOKIE[PMXE_SESSION_COOKIE] );
83
+ $cookie_crumbs = explode( '||', $cookie );
84
+
85
+ $this->session_id = (!empty($cookie_crumbs[0])) ? $cookie_crumbs[0] : $this->generate_id();
86
+ $this->expires = $cookie_crumbs[1];
87
+ $this->exp_variant = $cookie_crumbs[2];
88
+
89
+ // Update the session expiration if we're past the variant time
90
+ if ( time() > $this->exp_variant ) {
91
+ $this->set_expiration();
92
+ if ($this->session_mode == 'database'){
93
+ update_option( "_pmxi_session_expires_{$this->session_id}", $this->expires );
94
+ }
95
+ elseif ($this->session_mode == 'files'){
96
+ @file_put_contents(PMXE_ROOT_DIR . "/sessions/_pmxe_session_expires_{$this->session_id}.txt", $this->expires);
97
+ }
98
+ }
99
+
100
+ } else {
101
+ $this->session_id = $this->generate_id();
102
+ $this->set_expiration();
103
+ }
104
+ }
105
+ else{
106
+ try{
107
+ $path = @session_save_path();
108
+ if ( ! @is_dir($path) or ! @is_writable($path)){
109
+ @ini_set("session.save_handler", "files");
110
+ @session_save_path(sys_get_temp_dir());
111
+ }
112
+ } catch (XmlImportException $e) {
113
+
114
+ }
115
+
116
+ // enable sessions
117
+ if ( ! session_id()) @session_start();
118
+ }
119
+
120
+ $this->read_data();
121
+
122
+ $this->set_cookie();
123
+ }
124
+
125
+ /**
126
+ * Set both the expiration time and the expiration variant.
127
+ *
128
+ * If the current time is below the variant, we don't update the session's expiration time. If it's
129
+ * greater than the variant, then we update the expiration time in the database. This prevents
130
+ * writing to the database on every page load for active sessions and only updates the expiration
131
+ * time if we're nearing when the session actually expires.
132
+ *
133
+ * By default, the expiration time is set to 30 minutes.
134
+ * By default, the expiration variant is set to 24 minutes.
135
+ *
136
+ * As a result, the session expiration time - at a maximum - will only be written to the database once
137
+ * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by
138
+ * the browser, and the old session will be queued for deletion by the garbage collector.
139
+ *
140
+ * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
141
+ * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
142
+ */
143
+ protected function set_expiration() {
144
+ $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 );
145
+ $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
146
+ }
147
+
148
+ /**
149
+ * Set the session cookie
150
+ */
151
+ protected function set_cookie() {
152
+ @setcookie( PMXE_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN );
153
+ }
154
+
155
+ /**
156
+ * Generate a cryptographically strong unique ID for the session token.
157
+ *
158
+ * @return string
159
+ */
160
+ protected function generate_id() {
161
+ require_once( ABSPATH . 'wp-includes/class-phpass.php');
162
+ $hasher = new PasswordHash( 8, false );
163
+
164
+ return md5( $hasher->get_random_bytes( 32 ) );
165
+ }
166
+
167
+ /**
168
+ * Read data from a transient for the current session.
169
+ *
170
+ * Automatically resets the expiration time for the session transient to some time in the future.
171
+ *
172
+ * @return array
173
+ */
174
+ protected function read_data() {
175
+ if ($this->session_mode == 'database'){
176
+ $this->container = get_option( "_pmxe_session_{$this->session_id}", array() );
177
+ }
178
+ elseif ($this->session_mode == 'files'){
179
+ $container = @file_get_contents(PMXE_ROOT_DIR . "/sessions/_pmxe_session_{$this->session_id}.txt");
180
+ $this->container = unserialize( (!empty($container)) ? $container : '' );
181
+ }
182
+ else{
183
+ $this['pmxe_export'] = ( ! empty($_SESSION['pmxe_export']) ) ? $_SESSION['pmxe_export'] : array();
184
+ }
185
+
186
+ $this->data = $this->toArray();
187
+
188
+ return $this->container;
189
+ }
190
+
191
+ /**
192
+ * Write the data from the current session to the data storage system.
193
+ */
194
+ public function write_data() {
195
+
196
+ $option_key = "_pmxe_session_{$this->session_id}";
197
+
198
+ $this->data = $this->toArray();
199
+
200
+ // Only write the collection to the DB if it's changed.
201
+ if ($this->session_mode == "database"){
202
+ if ( false === get_option( $option_key ) ) {
203
+ add_option( "_pmxe_session_{$this->session_id}", $this->container, '', 'no' );
204
+ add_option( "_pmxe_session_expires_{$this->session_id}", $this->expires, '', 'no' );
205
+ } else {
206
+ delete_option("_pmxe_session_{$this->session_id}");
207
+ add_option( "_pmxe_session_{$this->session_id}", $this->container, '', 'no' );
208
+ }
209
+ }
210
+ elseif ($this->session_mode == 'files'){
211
+ if ( @file_exists( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt") ){
212
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
213
+ }
214
+ else{
215
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
216
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/_pmxe_session_expires_{$this->session_id}.txt", $this->expires );
217
+ }
218
+ }
219
+ else{
220
+ $session = $this->toArray(); $_SESSION['pmxe_export'] = (!empty($session['pmxe_export'])) ? $session['pmxe_export'] : array();
221
+ }
222
+
223
+ }
224
+
225
+ /**
226
+ * Output the current container contents as a JSON-encoded string.
227
+ *
228
+ * @return string
229
+ */
230
+ public function json_out() {
231
+ return json_encode( $this->container );
232
+ }
233
+
234
+ /**
235
+ * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
236
+ *
237
+ * @param string $data
238
+ *
239
+ * @return bool
240
+ */
241
+ public function json_in( $data ) {
242
+ $array = json_decode( $data );
243
+
244
+ if ( is_array( $array ) ) {
245
+ $this->container = $array;
246
+ return true;
247
+ }
248
+
249
+ return false;
250
+ }
251
+
252
+ /**
253
+ * Regenerate the current session's ID.
254
+ *
255
+ * @param bool $delete_old Flag whether or not to delete the old session data from the server.
256
+ */
257
+ public function regenerate_id( $delete_old = false ) {
258
+ if ( $delete_old ) {
259
+ if ($this->session_mode == "database"){
260
+ delete_option( "_pmxe_session_{$this->session_id}" );
261
+ }
262
+ elseif ($this->session_mode == 'files'){
263
+ @unlink( PMXE_ROOT_DIR . "/sessions/_pmxe_session_{$this->session_id}.txt");
264
+ }
265
+ }
266
+
267
+ $this->session_id = $this->generate_id();
268
+
269
+ $this->set_cookie();
270
+ }
271
+
272
+ /**
273
+ * Check if a session has been initialized.
274
+ *
275
+ * @return bool
276
+ */
277
+ public function session_started() {
278
+ return !!self::$instance;
279
+ }
280
+
281
+ /**
282
+ * Return the read-only cache expiration value.
283
+ *
284
+ * @return int
285
+ */
286
+ public function cache_expiration() {
287
+ return $this->expires;
288
+ }
289
+
290
+ /**
291
+ * Flushes all session variables.
292
+ */
293
+ public function reset() {
294
+ $this->container = array();
295
+ if ($this->session_mode == "default") unset($_SESSION['pmxe_export']);
296
+ }
297
+
298
+ /*****************************************************************/
299
+ /* Iterator Implementation */
300
+ /*****************************************************************/
301
+
302
+ /**
303
+ * Current position of the array.
304
+ *
305
+ * @link http://php.net/manual/en/iterator.current.php
306
+ *
307
+ * @return mixed
308
+ */
309
+ public function current() {
310
+ return current( $this->container );
311
+ }
312
+
313
+ /**
314
+ * Key of the current element.
315
+ *
316
+ * @link http://php.net/manual/en/iterator.key.php
317
+ *
318
+ * @return mixed
319
+ */
320
+ public function key() {
321
+ return key( $this->container );
322
+ }
323
+
324
+ /**
325
+ * Move the internal point of the container array to the next item
326
+ *
327
+ * @link http://php.net/manual/en/iterator.next.php
328
+ *
329
+ * @return void
330
+ */
331
+ public function next() {
332
+ next( $this->container );
333
+ }
334
+
335
+ /**
336
+ * Rewind the internal point of the container array.
337
+ *
338
+ * @link http://php.net/manual/en/iterator.rewind.php
339
+ *
340
+ * @return void
341
+ */
342
+ public function rewind() {
343
+ reset( $this->container );
344
+ }
345
+
346
+ /**
347
+ * Is the current key valid?
348
+ *
349
+ * @link http://php.net/manual/en/iterator.rewind.php
350
+ *
351
+ * @return bool
352
+ */
353
+ public function valid() {
354
+ return $this->offsetExists( $this->key() );
355
+ }
356
+
357
+ /*****************************************************************/
358
+ /* Countable Implementation */
359
+ /*****************************************************************/
360
+
361
+ /**
362
+ * Get the count of elements in the container array.
363
+ *
364
+ * @link http://php.net/manual/en/countable.count.php
365
+ *
366
+ * @return int
367
+ */
368
+ public function count() {
369
+ return count( $this->container );
370
+ }
371
+ }
config/options.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * List of plugin optins, contains only default values, actual values are stored in database
4
+ * and can be changed by corresponding wordpress function calls
5
+ */
6
+ $config = array(
7
+ "dismiss" => 0,
8
+ "dismiss_manage_top" => 0,
9
+ "dismiss_manage_bottom" => 0,
10
+ "session_mode" => 'default',
11
+ );
controllers/admin/export.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Import configuration wizard
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+
8
+ class PMXE_Admin_Export extends PMXE_Controller_Admin {
9
+ protected $isWizard = true; // indicates whether controller is in wizard mode (otherwize it called to be deligated an edit action)
10
+
11
+ protected function init() {
12
+
13
+ parent::init();
14
+
15
+ $action = PMXE_Plugin::getInstance()->getAdminCurrentScreen()->action;
16
+ $this->_step_ready($action);
17
+
18
+ }
19
+
20
+ public function set($var, $val)
21
+ {
22
+ $this->{$var} = $val;
23
+ }
24
+ public function get($var)
25
+ {
26
+ return $this->{$var};
27
+ }
28
+
29
+ /**
30
+ * Checks whether corresponding step of wizard is complete
31
+ * @param string $action
32
+ */
33
+ protected function _step_ready($action) {
34
+
35
+ // step #1: xml selction - has no prerequisites
36
+ if ('index' == $action) return true;
37
+
38
+ if ('element' == $action) return true;
39
+
40
+ if (empty(PMXE_Plugin::$session->data['pmxe_export'])){
41
+ wp_redirect_or_javascript($this->baseUrl); die();
42
+ }
43
+
44
+ if ('process' == $action) return true;
45
+
46
+ }
47
+
48
+ /**
49
+ * Step #1: Choose CPT
50
+ */
51
+ public function index() {
52
+
53
+ $wp_uploads = wp_upload_dir();
54
+
55
+ $this->data['post'] = $post = $this->input->post(array(
56
+ 'cpt' => array(),
57
+ 'export_to' => 'xml'
58
+ ));
59
+
60
+ // Delete history
61
+ foreach (PMXE_Helper::safe_glob(PMXE_ROOT_DIR . '/history/*', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
62
+ @file_exists($filePath) and @unlink($filePath);
63
+ }
64
+
65
+ if ($this->input->post('is_submitted')){
66
+
67
+ pmxe_session_unset();
68
+
69
+ PMXE_Plugin::$session['pmxe_export'] = array(
70
+ 'cpt' => ( ! is_array($post['cpt']) ) ? array($post['cpt']) : $post['cpt']
71
+ );
72
+
73
+ }
74
+
75
+ if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
76
+
77
+ check_admin_referer('choose-cpt', '_wpnonce_choose-cpt');
78
+
79
+ pmxe_session_commit();
80
+
81
+ wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
82
+ }
83
+
84
+ $this->render();
85
+ }
86
+
87
+ /**
88
+ * Step #2: Choose data to export
89
+ */
90
+ public function element()
91
+ {
92
+
93
+ $default = PMXE_Plugin::get_default_import_options();
94
+ $DefaultOptions = (isset(PMXE_Plugin::$session->data['pmxe_export']) ? PMXE_Plugin::$session->data['pmxe_export'] : array()) + $default;
95
+ $post = $this->input->post($DefaultOptions);
96
+
97
+ $this->data['post'] =& $post;
98
+
99
+ $this->data['meta_keys'] = $keys = new PMXE_Model_List();
100
+ $keys->setTable(PMXE_Plugin::getInstance()->getWPPrefix() . 'postmeta');
101
+ $keys->setColumns('meta_id', 'meta_key')->getBy(NULL, "meta_id", NULL, NULL, "meta_key");
102
+
103
+ if ($this->input->post('is_submitted')) {
104
+
105
+ check_admin_referer('element', '_wpnonce_element');
106
+
107
+ if ( ! $this->errors->get_error_codes()) {
108
+
109
+ PMXE_Plugin::$session['pmxe_export']['export_to'] = preg_match('%\W(xml)$%i', trim($post['export_to'])) ? 'xml' : 'csv';
110
+
111
+ pmxe_session_commit();
112
+
113
+ wp_redirect(add_query_arg('action', 'process', $this->baseUrl)); die();
114
+
115
+ }
116
+
117
+ }
118
+
119
+ $this->render();
120
+
121
+ }
122
+
123
+ /**
124
+ * Step #3: Export
125
+ */
126
+ public function process()
127
+ {
128
+
129
+ @set_time_limit(0);
130
+ $this->render();
131
+
132
+ }
133
+
134
+ /**
135
+ * Step #4: Download
136
+ */
137
+ public function download(){
138
+
139
+ $attch_url = PMXE_Plugin::$session->data['pmxe_export']['export_file'];
140
+
141
+ $export_type = PMXE_Plugin::$session->data['pmxe_export']['export_to'];
142
+
143
+ // clear import session
144
+ pmxe_session_unset(); // clear session data (prevent from reimporting the same data on page refresh)
145
+
146
+ switch ($export_type) {
147
+ case 'xml':
148
+ PMXE_download::xml($attch_url);
149
+ break;
150
+ case 'csv':
151
+ PMXE_download::csv($attch_url);
152
+ break;
153
+
154
+ default:
155
+ # code...
156
+ break;
157
+ }
158
+
159
+ }
160
+
161
+ }
controllers/admin/help.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin Help page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Admin_Help extends PMXE_Controller_Admin {
8
+
9
+ public function index() {
10
+ $this->render();
11
+ }
12
+ }
controllers/admin/settings.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin Statistics page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Admin_Settings extends PMXE_Controller_Admin {
8
+
9
+ public function index() {
10
+
11
+ $this->data['post'] = $post = $this->input->post(PMXI_Plugin::getInstance()->getOption());
12
+
13
+ $this->render();
14
+
15
+ }
16
+
17
+ public function dismiss(){
18
+
19
+ PMXE_Plugin::getInstance()->updateOption("dismiss", 1);
20
+
21
+ exit('OK');
22
+ }
23
+
24
+ public function download(){
25
+
26
+ PMXE_download::csv(PMXE_Plugin::ROOT_DIR.'/logs/'.$_GET['file'].'.txt');
27
+
28
+ }
29
+
30
+ }
controllers/controller.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Common logic for all shortcodes plugin implements
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXE_Controller {
8
+ /**
9
+ * Input class instance to retrieve parameters submitted during page request
10
+ * @var PMXE_Input
11
+ */
12
+ protected $input;
13
+ /**
14
+ * Error messages
15
+ * @var WP_Error
16
+ */
17
+ protected $errors;
18
+ /**
19
+ * Associative array of data which will be automatically available as variables when template is rendered
20
+ * @var array
21
+ */
22
+ public $data = array();
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct() {
27
+ $this->input = new PMXE_Input();
28
+ $this->input->addFilter('trim');
29
+
30
+ $this->errors = new WP_Error();
31
+
32
+ $this->init();
33
+ }
34
+
35
+ /**
36
+ * Method to put controller initialization logic to
37
+ */
38
+ protected function init() {}
39
+
40
+ /**
41
+ * Checks wether protocol is HTTPS and redirects user to secure connection if not
42
+ */
43
+ protected function force_ssl() {
44
+ if (force_ssl_admin() && ! is_ssl()) {
45
+ if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
46
+ wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); die();
47
+ } else {
48
+ wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); die();
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Method returning resolved template content
55
+ *
56
+ * @param string[optional] $viewPath Template path to render
57
+ */
58
+ protected function render($viewPath = null) {
59
+ // assume template file name depending on calling function
60
+ if (is_null($viewPath)) {
61
+ $trace = debug_backtrace();
62
+ $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
63
+ }
64
+ // append file extension if not specified
65
+ if ( ! preg_match('%\.php$%', $viewPath)) {
66
+ $viewPath .= '.php';
67
+ }
68
+ $filePath = PMXE_Plugin::ROOT_DIR . '/views/' . $viewPath;
69
+ if (is_file($filePath)) {
70
+ extract($this->data);
71
+ include $filePath;
72
+ } else {
73
+ throw new Exception("Requested template file $filePath is not found.");
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Display list of errors
79
+ *
80
+ * @param string|array|WP_Error[optional] $msgs
81
+ */
82
+ protected function error($msgs = NULL) {
83
+ if (is_null($msgs)) {
84
+ $msgs = $this->errors;
85
+ }
86
+ if (is_wp_error($msgs)) {
87
+ $msgs = $msgs->get_error_messages();
88
+ }
89
+ if ( ! is_array($msgs)) {
90
+ $msgs = array($msgs);
91
+ }
92
+ $this->data['errors'] = $msgs;
93
+
94
+ $viewPathRel = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower(get_class($this)))) . '/error.php';
95
+ if (is_file(PMXE_Plugin::ROOT_DIR . '/views/' . $viewPathRel)) { // if calling controller class has specific error view
96
+ $this->render($viewPathRel);
97
+ } else { // render default error view
98
+ $this->render('controller/error.php');
99
+ }
100
+ }
101
+
102
+ }
controllers/controller/admin.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Introduce special type for controllers which render pages inside admin area
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXE_Controller_Admin extends PMXE_Controller {
8
+ /**
9
+ * Admin page base url (request url without all get parameters but `page`)
10
+ * @var string
11
+ */
12
+ public $baseUrl;
13
+ /**
14
+ * Parameters which is left when baseUrl is detected
15
+ * @var array
16
+ */
17
+ public $baseUrlParamNames = array('page', 'pagenum', 'order', 'order_by', 'type', 's', 'f');
18
+ /**
19
+ * Whether controller is rendered inside wordpress page
20
+ * @var bool
21
+ */
22
+ public $isInline = false;
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct() {
27
+
28
+ $remove = array_diff(array_keys($_GET), $this->baseUrlParamNames);
29
+ if ($remove) {
30
+ $this->baseUrl = remove_query_arg($remove);
31
+ } else {
32
+ $this->baseUrl = $_SERVER['REQUEST_URI'];
33
+ }
34
+ parent::__construct();
35
+
36
+ // add special filter for url fields
37
+ $this->input->addFilter(create_function('$str', 'return "http://" == $str || "ftp://" == $str ? "" : $str;'));
38
+
39
+ // enqueue required sripts and styles
40
+ global $wp_styles;
41
+ if ( ! is_a($wp_styles, 'WP_Styles'))
42
+ $wp_styles = new WP_Styles();
43
+
44
+ wp_enqueue_style('jquery-ui', PMXE_ROOT_URL . '/static/js/jquery/css/redmond/jquery-ui.css');
45
+ wp_enqueue_style('jquery-tipsy', PMXE_ROOT_URL . '/static/js/jquery/css/smoothness/jquery.tipsy.css');
46
+ wp_enqueue_style('pmxe-admin-style', PMXE_ROOT_URL . '/static/css/admin.css');
47
+ wp_enqueue_style('pmxe-admin-style-ie', PMXE_ROOT_URL . '/static/css/admin-ie.css');
48
+ wp_enqueue_style('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/css/select2/select2.css');
49
+ wp_enqueue_style('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/css/select2/select2-bootstrap.css');
50
+ $wp_styles->add_data('pmxe-admin-style-ie', 'conditional', 'lte IE 7');
51
+ wp_enqueue_style('wp-pointer');
52
+
53
+ if ( version_compare(get_bloginfo('version'), '3.8-RC1') >= 0 ){
54
+ wp_enqueue_style('pmxe-admin-style-wp-3.8', PMXE_ROOT_URL . '/static/css/admin-wp-3.8.css');
55
+ }
56
+
57
+ $scheme_color = get_user_option('admin_color') and is_file(PMXE_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css') or $scheme_color = 'fresh';
58
+ if (is_file(PMXE_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css')) {
59
+ wp_enqueue_style('pmxe-admin-style-color', PMXE_ROOT_URL . '/static/css/admin-colors-' . $scheme_color . '.css');
60
+ }
61
+
62
+ wp_enqueue_script('jquery-ui-datepicker', PMXE_ROOT_URL . '/static/js/jquery/ui.datepicker.js', 'jquery-ui-core');
63
+ wp_enqueue_script('jquery-ui-autocomplete', PMXE_ROOT_URL . '/static/js/jquery/ui.autocomplete.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'));
64
+ wp_enqueue_script('jquery-tipsy', PMXE_ROOT_URL . '/static/js/jquery/jquery.tipsy.js', 'jquery');
65
+ wp_enqueue_script('jquery-nestable', PMXE_ROOT_URL . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'jquery-ui-progressbar'));
66
+ wp_enqueue_script('jquery-moment', PMXE_ROOT_URL . '/static/js/jquery/moment.js', 'jquery');
67
+ wp_enqueue_script('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/select2.min.js', 'jquery');
68
+ wp_enqueue_script('wp-pointer');
69
+
70
+ /* load plupload scripts */
71
+ wp_enqueue_script('pmxe-admin-script', PMXE_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
72
+
73
+ }
74
+
75
+ /**
76
+ * @see Controller::render()
77
+ */
78
+ protected function render($viewPath = NULL)
79
+ {
80
+ // assume template file name depending on calling function
81
+ if (is_null($viewPath)) {
82
+ $trace = debug_backtrace();
83
+ $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
84
+ }
85
+
86
+ // render contextual help automatically
87
+ $viewHelpPath = $viewPath;
88
+ // append file extension if not specified
89
+ if ( ! preg_match('%\.php$%', $viewHelpPath)) {
90
+ $viewHelpPath .= '.php';
91
+ }
92
+ $viewHelpPath = preg_replace('%\.php$%', '-help.php', $viewHelpPath);
93
+ $fileHelpPath = PMXE_Plugin::ROOT_DIR . '/views/' . $viewHelpPath;
94
+
95
+ if (is_file($fileHelpPath)) { // there is help file defined
96
+ ob_start();
97
+ include $fileHelpPath;
98
+ add_contextual_help(PMXE_Plugin::getInstance()->getAdminCurrentScreen()->id, ob_get_clean());
99
+ }
100
+
101
+ parent::render($viewPath);
102
+ }
103
+
104
+ }
helpers/backward.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Contains function which were introduced in late wordpress versions
4
+ */
5
+
6
+ if ( ! function_exists('is_network_admin')):
7
+ /**
8
+ * Whether the current request is for a network admin screen /wp-admin/network/
9
+ *
10
+ * Does not inform on whether the user is a network admin! Use capability checks to
11
+ * tell if the user should be accessing a section or not.
12
+ *
13
+ * @since 3.1.0
14
+ *
15
+ * @return bool True if inside WordPress network administration pages.
16
+ */
17
+ function is_network_admin() {
18
+ if ( defined( 'WP_NETWORK_ADMIN' ) )
19
+ return WP_NETWORK_ADMIN;
20
+ return false;
21
+ }
22
+ endif;
23
+
24
+ if ( ! function_exists('is_user_admin')):
25
+ /**
26
+ * Whether the current request is for a user admin screen /wp-admin/user/
27
+ *
28
+ * Does not inform on whether the user is an admin! Use capability checks to
29
+ * tell if the user should be accessing a section or not.
30
+ *
31
+ * @since 3.1.0
32
+ *
33
+ * @return bool True if inside WordPress user administration pages.
34
+ */
35
+ function is_user_admin() {
36
+ if ( defined( 'WP_USER_ADMIN' ) )
37
+ return WP_USER_ADMIN;
38
+ return false;
39
+ }
40
+ endif;
helpers/pmxe_functions.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! function_exists('url_title')){
4
+
5
+ function url_title($str, $separator = 'dash', $lowercase = FALSE)
6
+ {
7
+ if ($separator == 'dash')
8
+ {
9
+ $search = '_';
10
+ $replace = '-';
11
+ }
12
+ else
13
+ {
14
+ $search = '-';
15
+ $replace = '_';
16
+ }
17
+
18
+ $trans = array(
19
+ '&\#\d+?;' => '',
20
+ '&\S+?;' => '',
21
+ '\s+' => $replace,
22
+ '[^a-z0-9\-\._]' => '',
23
+ $replace.'+' => $replace,
24
+ $replace.'$' => $replace,
25
+ '^'.$replace => $replace,
26
+ '\.+$' => ''
27
+ );
28
+
29
+ $str = strip_tags($str);
30
+
31
+ foreach ($trans as $key => $val)
32
+ {
33
+ $str = preg_replace("#".$key."#i", $val, $str);
34
+ }
35
+
36
+ if ($lowercase === TRUE)
37
+ {
38
+ $str = strtolower($str);
39
+ }
40
+
41
+ return trim(stripslashes($str));
42
+ }
43
+ }
44
+
45
+ /* Session */
46
+
47
+ /**
48
+ * Return the current session status.
49
+ *
50
+ * @return int
51
+ */
52
+ function pmxe_session_status() {
53
+
54
+ PMXE_Plugin::$session = PMXE_Session::get_instance();
55
+
56
+ if ( PMXE_Plugin::$session->session_started() ) {
57
+ return PHP_SESSION_ACTIVE;
58
+ }
59
+
60
+ return PHP_SESSION_NONE;
61
+ }
62
+
63
+ /**
64
+ * Unset all session variables.
65
+ */
66
+ function pmxe_session_unset() {
67
+ PMXE_Plugin::$session = PMXE_Session::get_instance();
68
+
69
+ PMXE_Plugin::$session->reset();
70
+ }
71
+
72
+ /**
73
+ * Alias of wp_session_write_close()
74
+ */
75
+ function pmxe_session_commit() {
76
+ PMXE_Plugin::$session = PMXE_Session::get_instance();
77
+ PMXE_Plugin::$session->write_data();
78
+ do_action( 'pmxe_session_commit' );
79
+ }
80
+
helpers/str_getcsv.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! function_exists('str_getcsv')):
3
+ /**
4
+ * str_getcsv function for PHP less than 5.3
5
+ * @see http://php.net/manual/en/function.str-getcsv.php
6
+ * NOTE: function doesn't support escape paramter (in correspondance to fgetcsv not supporting it prior 5.3)
7
+ */
8
+ function str_getcsv($input, $delimiter=',', $enclosure='"') {
9
+ if ("" == $delimiter) $delimiter = ',';
10
+ $temp = fopen("php://memory", "rw");
11
+ fwrite($temp, $input);
12
+ fseek($temp, 0);
13
+ $r = fgetcsv($temp, strlen($input), $delimiter, $enclosure);
14
+ fclose($temp);
15
+ return $r;
16
+ }
17
+
18
+ endif;
helpers/wp_redirect_or_javascript.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! function_exists('wp_redirect_or_javascript')):
3
+ /**
4
+ * For AJAX request outputs javascript specified, otherwise acts like wp_redirect
5
+ * @param string $location
6
+ * @param string[optional] $javascript
7
+ * @param int[optional] $status
8
+ */
9
+ function wp_redirect_or_javascript($location, $javascript = NULL, $status = 302) {
10
+ if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
11
+ is_null($javascript) and $javascript = 'location.href="' . addslashes($location) . '";';
12
+ echo '<script type="text/javascript">' . $javascript . '</script>';
13
+ } else {
14
+ return wp_redirect($location, $status);
15
+ }
16
+ }
17
+ endif;
models/export/list.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PMXE_Import_List extends PMXE_Model_List {
4
+ public function __construct() {
5
+ parent::__construct();
6
+ //$this->setTable(PMXE_Plugin::getInstance()->getTablePrefix() . 'imports');
7
+ }
8
+ }
models/export/record.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class PMXE_Import_Record extends PMXE_Model_Record {
4
+
5
+ /**
6
+ * Initialize model instance
7
+ * @param array[optional] $data Array of record data to initialize object with
8
+ */
9
+ public function __construct($data = array()) {
10
+ parent::__construct($data);
11
+ }
12
+
13
+ /**
14
+ * Perform import operation
15
+ * @param string $xml XML string to import
16
+ * @param callback[optional] $logger Method where progress messages are submmitted
17
+ * @return PMXE_Import_Record
18
+ * @chainable
19
+ */
20
+ public function process($xml, $logger = NULL, $chunk = false, $is_cron = false, $xpath_prefix = '') {
21
+ add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
22
+
23
+
24
+
25
+ remove_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // return any filtering rules back if they has been disabled for import procedure
26
+
27
+ return $this;
28
+ }
29
+
30
+ public function _filter_has_cap_unfiltered_html($caps)
31
+ {
32
+ $caps['unfiltered_html'] = true;
33
+ return $caps;
34
+ }
35
+
36
+ }
models/model.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class for models
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXE_Model extends ArrayObject {
8
+ /**
9
+ * WPDB instance
10
+ * @var wpdb
11
+ */
12
+ protected $wpdb;
13
+ /**
14
+ * Table name the model is linked to
15
+ * @var string
16
+ */
17
+ protected $table;
18
+ /**
19
+ * Array of columns representing primary key
20
+ * @var array
21
+ */
22
+ protected $primary = array('id');
23
+ /**
24
+ * Wether key field is auto_increment (sure make scence only if key s
25
+ * @var bool
26
+ */
27
+ protected $auto_increment = FALSE;
28
+
29
+ /**
30
+ * Cached data retrieved from database
31
+ * @var array
32
+ */
33
+ private static $meta_cache = array();
34
+
35
+ /**
36
+ * Initialize model
37
+ * @param array[optional] $data Array of record data to initialize object with
38
+ */
39
+ public function __construct() {
40
+ $this->wpdb = $GLOBALS['wpdb'];
41
+ }
42
+
43
+ /**
44
+ * Read records from database by specified fields and values
45
+ * When 1st parameter is an array, it expected to be an associative array of field => value pairs to read data by
46
+ * If 2 parameters are set, first one is expected to be a field name and second - it's value
47
+ *
48
+ * @param string|array $field
49
+ * @param mixed[optional] $value
50
+ * @return PMXE_Model
51
+ */
52
+ abstract public function getBy($field = NULL, $value = NULL);
53
+
54
+ /**
55
+ * Magic function to automatically resolve calls like $obj->getBy%FIELD_NAME%
56
+ * @param string $method
57
+ * @param array $args
58
+ * @return PMXE_Model
59
+ */
60
+ public function __call($method, $args) {
61
+ if (preg_match('%^get_?by_?(.+)%i', $method, $mtch)) {
62
+ array_unshift($args, $mtch[1]);
63
+ return call_user_func_array(array($this, 'getBy'), $args);
64
+ } else {
65
+ throw new Exception("Requested method " . get_class($this) . "::$method doesn't exist.");
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Bind model to database table
71
+ * @param string $tableName
72
+ * @return PMXE_Model
73
+ */
74
+ public function setTable($tableName) {
75
+ if ( ! is_null($this->table)) {
76
+ throw new Exception('Table name cannot be changed once being set.');
77
+ }
78
+ $this->table = $tableName;
79
+ if ( ! isset(self::$meta_cache[$this->table])) {
80
+ $tableMeta = $this->wpdb->get_results("SHOW COLUMNS FROM $this->table", ARRAY_A);
81
+ $primary = array();
82
+ $auto_increment = false;
83
+ foreach ($tableMeta as $colMeta) {
84
+ if ('PRI' == $colMeta['Key']) {
85
+ $primary[] = $colMeta['Field'];
86
+ }
87
+ if ('auto_increment' == $colMeta['Extra']) {
88
+ $auto_increment = true;
89
+ break; // no point to iterate futher since auto_increment means corresponding primary key is simple
90
+ }
91
+ }
92
+ self::$meta_cache[$this->table] = array('primary' => $primary, 'auto_increment' => $auto_increment);
93
+ }
94
+ $this->primary = self::$meta_cache[$this->table]['primary'];
95
+ $this->auto_increment = self::$meta_cache[$this->table]['auto_increment'];
96
+
97
+ return $this;
98
+ }
99
+
100
+ /**
101
+ * Return database table name this object is bound to
102
+ * @return string
103
+ */
104
+ public function getTable() {
105
+ return $this->table;
106
+ }
107
+ /**
108
+ * Return column name with table name
109
+ * @param string $col
110
+ * @return string
111
+ */
112
+ public function getFieldName($col) {
113
+ return $this->table . '.' . $col;
114
+ }
115
+
116
+ /**
117
+ * Compose WHERE clause based on parameters provided
118
+ * @param string|array $field
119
+ * @param mixed[optional] $value
120
+ * @param string[optional] $operator AND or OR string, 'AND' by default
121
+ * @return string
122
+ */
123
+ protected function buildWhere($field, $value = NULL, $operator = NULL) {
124
+ if ( ! is_array($field)) {
125
+ $field = array($field => $value);
126
+ } else { // shift arguments
127
+ $operator = $value;
128
+ }
129
+ ! is_null($operator) or $operator = 'AND'; // apply default operator value
130
+
131
+ $where = array();
132
+ foreach ($field as $key => $val) {
133
+ if (is_int($key)) {
134
+ $where[] = '(' . call_user_func_array(array($this, 'buildWhere'), $val) . ')';
135
+ } else {
136
+ if ( ! preg_match('%^(.+?) *(=|<>|!=|<|>|<=|>=| (NOT +)?(IN|(LIKE|REGEXP|RLIKE)( BINARY)?))?$%i', trim($key), $mtch)) {
137
+ throw new Exception('Wrong field name format.');
138
+ }
139
+ $key = $mtch[1];
140
+ if (is_array($val) and (empty($mtch[2]) or 'IN' == strtoupper($mtch[4]))) {
141
+ $op = empty($mtch[2]) ? 'IN' : strtoupper(trim($mtch[2]));
142
+ if (count($val)) $where[] = $this->wpdb->prepare("$key $op (" . implode(', ', array_fill(0, count($val), "%s")) . ")", $val);
143
+ } else {
144
+ $op = empty($mtch[2]) ? '=' : strtoupper(trim($mtch[2]));
145
+ $where[] = $this->wpdb->prepare("$key $op %s", $val);
146
+ }
147
+ }
148
+ }
149
+ return implode(" $operator ", $where);
150
+ }
151
+
152
+
153
+ /**
154
+ * Return associative array with record data
155
+ * @param bool[optional] $serialize Whether returned fields should be serialized
156
+ * @return array
157
+ */
158
+ public function toArray($serialize = FALSE) {
159
+ $result = (array)$this;
160
+ if ($serialize) {
161
+ foreach ($result as $k => $v) {
162
+ if ( ! is_scalar($v)) {
163
+ $result[$k] = serialize($v);
164
+ }
165
+ }
166
+ }
167
+ return $result;
168
+ }
169
+
170
+ /**
171
+ * Check whether object data is empty
172
+ * @return bool
173
+ */
174
+ public function isEmpty() {
175
+ return $this->count() == 0;
176
+ }
177
+
178
+ /**
179
+ * Empty object data
180
+ * @return PMXE_Model
181
+ */
182
+ public function clear() {
183
+ $this->exchangeArray(array());
184
+ return $this;
185
+ }
186
+
187
+ /**
188
+ * Delete all content from model's table
189
+ * @return PMXE_Model
190
+ */
191
+ public function truncateTable() {
192
+ if (FALSE !== $this->wpdb->query("TRUNCATE $this->table")) {
193
+ return $this;
194
+ } else {
195
+ throw new Exception($this->wpdb->last_error);
196
+ }
197
+ }
198
+ }
models/model/list.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Incapsulates behavior for list of database records
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Model_List extends PMXE_Model {
8
+
9
+ /**
10
+ * Total number of records in database which correspond last getBy rule without paging
11
+ * @var int
12
+ */
13
+ protected $total = 0;
14
+
15
+ /**
16
+ * Joined tables
17
+ * @var array
18
+ */
19
+ protected $joined = array();
20
+ /**
21
+ * Columns to select from database
22
+ * @var string
23
+ */
24
+ protected $what = '*';
25
+ /**
26
+ * Sets table to use in conjuction with primary list table
27
+ * @param string $table Table to join
28
+ * @param string $on Condition to join
29
+ * @param string $type Join type (INNER, OUTER, etc)
30
+ * @return PMXE_Model_List
31
+ */
32
+ public function join($table, $on, $type = 'INNER') {
33
+ $this->joined[] = ( ! is_null($type) ? $type . ' ' : '') . 'JOIN ' . $table . ' ON ' . $on;
34
+ return $this;
35
+ }
36
+
37
+ /**
38
+ * Set columns to be selected from database
39
+ * @param array $columns
40
+ * @return PMXE_Model_List
41
+ */
42
+ public function setColumns($columns) {
43
+ is_array($columns) or $columns = func_get_args();
44
+ $this->what = implode(', ', $columns);
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Read records from database by specified fields and values
50
+ * When 1st parameter is an array, it's expected to be an associative array of field => value pairs to read data by
51
+ * When 2nd parameter is a scalar, it's expected to be a field name and second parameter - it's value
52
+ *
53
+ * @param string|array[optional] $field
54
+ * @param mixed[optional] $value
55
+ * @param string[optional] $orderBy Ordering rule
56
+ * @param int[optional] $page Paging paramter used to limit number of records returned
57
+ * @param int[optional] $perPage Page size when paging parameter is used (20 by default)
58
+ * @return PMXE_Model_List
59
+ */
60
+ public function getBy($field = NULL, $value = NULL, $orderBy = NULL, $page = NULL, $perPage = NULL, $groupBy = NULL) {
61
+ if (is_array($field) or is_null($field)) { // when associative array is submitted, do not expect second paramter to be $value, but act as if there is no $value parameter at all
62
+ $groupBy = $perPage; $perPage = $page; $page = $orderBy; $orderBy = $value; $value = NULL;
63
+ }
64
+ ! is_null($perPage) or $perPage = 20; // set default value for page length
65
+ $page = intval($page);
66
+
67
+ $sql = "FROM $this->table ";
68
+ $sql .= implode(' ', $this->joined);
69
+ if ( ! is_null($field)) {
70
+ $sql .= " WHERE " . $this->buildWhere($field, $value);
71
+ }
72
+ if ( ! is_null($groupBy)) {
73
+ $sql .= " GROUP BY $groupBy";
74
+ }
75
+ is_null($orderBy) and $orderBy = implode(', ', $this->primary); // default sort order is by primary key
76
+ $sql .= " ORDER BY $orderBy";
77
+ if ($page > 0) {
78
+ $sql = "SELECT SQL_CALC_FOUND_ROWS $this->what $sql LIMIT " . intval(($page - 1) * $perPage) . ", " . intval($perPage);
79
+ } else {
80
+ $sql = "SELECT $this->what $sql";
81
+ }
82
+ $result = $this->wpdb->get_results($sql, ARRAY_A);
83
+ if (is_array($result)) {
84
+ foreach ($result as $i => $row) {
85
+ foreach ($row as $k => $v) {
86
+ if (is_serialized($v)) {
87
+ $result[$i][$k] = unserialize($v);
88
+ }
89
+ }
90
+ }
91
+ if ($page > 0) {
92
+ $this->total = intval($this->wpdb->get_var('SELECT FOUND_ROWS()'));
93
+ } else {
94
+ $this->total = count($result);
95
+ }
96
+ $this->exchangeArray($result);
97
+ } else {
98
+ $this->total = 0;
99
+ $this->clear();
100
+ }
101
+ return $this;
102
+ }
103
+
104
+ /**
105
+ * Count records in table
106
+ * @param string|array $field
107
+ * @param mixed[optional] $value
108
+ * @return int
109
+ */
110
+ public function countBy($field = NULL, $value = NULL) {
111
+ $sql = "SELECT COUNT(*) FROM $this->table ";
112
+ $sql .= implode(' ', $this->joined);
113
+ if ( ! is_null($field)) {
114
+ $sql .= " WHERE " . $this->buildWhere($field, $value);
115
+ }
116
+ return intval($this->wpdb->get_var($sql));
117
+ }
118
+
119
+ /**
120
+ * Method returns number of rows in database which correspond last getBy query
121
+ * @return int
122
+ */
123
+ public function total() {
124
+ return $this->total;
125
+ }
126
+
127
+ /**
128
+ * Converts elements to instances of specifield class. If includeFields are provided only fields listed are included
129
+ * @param string[optoinal] $elementClass
130
+ * @param array[optional] $includeFields
131
+ * @return PMXE_Model_List
132
+ */
133
+ public function convertRecords($elementClass = NULL, $includeFields = NULL) {
134
+ ! is_null($elementClass) or $elementClass = preg_replace('%List$%', 'Record', get_class($this));
135
+ if ( ! is_subclass_of($elementClass, PMXE_Plugin::PREFIX . 'Model_Record')) {
136
+ throw new Exception("Provideded class name $elementClass must be a subclass of " . PMXE_Plugin::PREFIX . 'Model_Record');
137
+ }
138
+ $records = $this->exchangeArray(array());
139
+ foreach ($records as $r) {
140
+ $data = (array)$r;
141
+ if ( ! is_null($includeFields)) {
142
+ $data = array_intersect_key($data, array_flip($includeFields));
143
+ }
144
+ $this[] = new $elementClass($data);
145
+ }
146
+ return $this;
147
+ }
148
+
149
+ }
models/model/record.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class for models
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Model_Record extends PMXE_Model {
8
+ /**
9
+ * Initialize model
10
+ * @param array[optional] $data Array of record data to initialize object with
11
+ */
12
+ public function __construct($data = array()) {
13
+ parent::__construct();
14
+ if (! is_array($data)) {
15
+ throw new Exception("Array expected as paramenter for " . get_class($this) . "::" . __METHOD__);
16
+ }
17
+ $data and $this->set($data);
18
+ }
19
+
20
+ /**
21
+ * @see PMXE_Model::getBy()
22
+ * @return PMXE_Model_Record
23
+ */
24
+ public function getBy($field = NULL, $value = NULL) {
25
+ if (is_null($field)) {
26
+ throw new Exception("Field parameter is expected at " . get_class($this) . "::" . __METHOD__);
27
+ }
28
+ $sql = "SELECT * FROM $this->table WHERE " . $this->buildWhere($field, $value);
29
+ $result = $this->wpdb->get_row($sql, ARRAY_A);
30
+ if (is_array($result)) {
31
+ foreach ($result as $k => $v) {
32
+ if (is_serialized($v)) {
33
+ $result[$k] = unserialize($v);
34
+ }
35
+ }
36
+ $this->exchangeArray($result);
37
+ } else {
38
+ $this->clear();
39
+ }
40
+ return $this;
41
+ }
42
+
43
+ /**
44
+ * Ger records related to current one
45
+ * @param string $model Class name of model of related records
46
+ * @param array[optoinal] $keyAssoc
47
+ * @return PMXE_Model_List
48
+ */
49
+ public function getRelated($model, $keyAssoc = NULL) {
50
+ $related = new $model();
51
+ if ( ! empty($this->id)) {
52
+ if (is_null($keyAssoc)) {
53
+ $defaultPrefix = strtolower(preg_replace('%^' . strtoupper(PMXE_Plugin::PREFIX) . '|_Record$%', '', get_class($this)));
54
+ $keyAssoc = array();
55
+ foreach ($this->primary as $key) {
56
+ $keyAssoc = array($defaultPrefix . '_' . $key => $key);
57
+ }
58
+ }
59
+ foreach ($keyAssoc as $foreign => $local) {
60
+ $keyAssoc[$foreign] = $this->$local;
61
+ }
62
+ $related->getBy($keyAssoc);
63
+ }
64
+ return $related instanceof PMXE_Model_List ? $related->convertRecords() : $related;
65
+ }
66
+
67
+ /**
68
+ * Saves currently set object data as database record
69
+ * @return PMXE_Model_Record
70
+ */
71
+ public function insert() {
72
+ if ($this->wpdb->insert($this->table, $this->toArray(TRUE))) {
73
+ if (isset($this->auto_increment)) {
74
+ $this[$this->primary[0]] = $this->wpdb->insert_id;
75
+ }
76
+ return $this;
77
+ } else {
78
+ throw new Exception($this->wpdb->last_error);
79
+ }
80
+ }
81
+ /**
82
+ * Update record in database
83
+ * @return PMXE_Model_Record
84
+ */
85
+ public function update() {
86
+ $record = $this->toArray(TRUE);
87
+ $this->wpdb->update($this->table, $record, array_intersect_key($record, array_flip($this->primary)));
88
+ if ($this->wpdb->last_error) {
89
+ throw new Exception($this->wpdb->last_error);
90
+ }
91
+ return $this;
92
+ }
93
+
94
+ /**
95
+ * Delete record form database
96
+ * @return PMXE_Model_Record
97
+ */
98
+ public function delete() {
99
+ if ($this->wpdb->query("DELETE FROM $this->table WHERE " . $this->buildWhere(array_intersect_key($this->toArray(TRUE), array_flip($this->primary))))) {
100
+ return $this;
101
+ } elseif ($this->wpdb->last_error) {
102
+ throw new Exception($this->wpdb->last_error);
103
+ }
104
+ }
105
+ /**
106
+ * Insert or Update the record
107
+ * WARNING: function doesn't check actual record presents in database, it simply tries to insert if no primary key specified and update otherwise
108
+ * @return PMXE_Model_Record
109
+ */
110
+ public function save() {
111
+ if (array_intersect_key($this->toArray(TRUE), array_flip($this->primary))) {
112
+ $this->update();
113
+ } else {
114
+ $this->insert();
115
+ }
116
+ return $this;
117
+ }
118
+
119
+ /**
120
+ * Set record data
121
+ * When 1st parameter is an array, it expected to be an associative array of field => value pairs
122
+ * If 2 parameters are set, first one is expected to be a field name and second - it's value
123
+ *
124
+ * @param string|array $field
125
+ * @param mixed[optional] $value
126
+ * @return PMXE_Model_Record
127
+ */
128
+ public function set($field, $value = NULL) {
129
+ if (is_array($field) and ( ! is_null($value) or 0 == count($field))) {
130
+ throw new Exception(__CLASS__ . "::set method expects either not empty associative array as the only paramter or field name and it's value as two seperate parameters.");
131
+ }
132
+ if (is_array($field)) {
133
+ $this->exchangeArray(array_merge($this->toArray(), $field));
134
+ } else {
135
+ $this[$field] = $value;
136
+ }
137
+
138
+ return $this;
139
+ }
140
+
141
+ /**
142
+ * Magic method to resolved object-like request to record values in format $obj->%FIELD_NAME%
143
+ * @param string $field
144
+ * @return mixed
145
+ */
146
+ public function __get($field) {
147
+ if ( ! $this->offsetExists($field)) {
148
+ throw new Exception("Undefined field $field.");
149
+ }
150
+ return $this[$field];
151
+ }
152
+ /**
153
+ * Magic method to assign values to record fields in format $obj->%FIELD_NAME = value
154
+ * @param string $field
155
+ * @param mixed $value
156
+ */
157
+ public function __set($field, $value) {
158
+ $this[$field] = $value;
159
+ }
160
+ /**
161
+ * Magic method to check wether some record fields are set
162
+ * @param string $field
163
+ * @return bool
164
+ */
165
+ public function __isset($field) {
166
+ return $this->offsetExists($field);
167
+ }
168
+ /**
169
+ * Magic method to unset record fields
170
+ * @param string $field
171
+ */
172
+ public function __unset($field) {
173
+ $this->offsetUnset($field);
174
+ }
175
+
176
+ }
plugin.php ADDED
@@ -0,0 +1,498 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: WP All Export
4
+ Plugin URI: http://wordpress.org/plugins/wp-all-export/
5
+ Description: The most powerful solution for exporting WordPress data to an XML file.
6
+ Version: 0.9.0
7
+ Author: Soflyy
8
+ */
9
+
10
+ if( ! defined( 'PMXE_SESSION_COOKIE' ) )
11
+ define( 'PMXE_SESSION_COOKIE', '_PMXE_session' );
12
+
13
+ /**
14
+ * Plugin root dir with forward slashes as directory separator regardless of actuall DIRECTORY_SEPARATOR value
15
+ * @var string
16
+ */
17
+ define('PMXE_ROOT_DIR', str_replace('\\', '/', dirname(__FILE__)));
18
+ /**
19
+ * Plugin root url for referencing static content
20
+ * @var string
21
+ */
22
+ define('PMXE_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
23
+ /**
24
+ * Plugin prefix for making names unique (be aware that this variable is used in conjuction with naming convention,
25
+ * i.e. in order to change it one must not only modify this constant but also rename all constants, classes and functions which
26
+ * names composed using this prefix)
27
+ * @var string
28
+ */
29
+ define('PMXE_PREFIX', 'pmxe_');
30
+
31
+ define('PMXE_VERSION', '0.9.0');
32
+
33
+ define('PMXE_EDITION', 'free');
34
+
35
+ /**
36
+ * Main plugin file, Introduces MVC pattern
37
+ *
38
+ * @singletone
39
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
40
+ */
41
+ final class PMXE_Plugin {
42
+ /**
43
+ * Singletone instance
44
+ * @var PMXE_Plugin
45
+ */
46
+ protected static $instance;
47
+
48
+ /**
49
+ * Plugin options
50
+ * @var array
51
+ */
52
+ protected $options = array();
53
+
54
+ /**
55
+ * Plugin root dir
56
+ * @var string
57
+ */
58
+ const ROOT_DIR = PMXE_ROOT_DIR;
59
+ /**
60
+ * Plugin root URL
61
+ * @var string
62
+ */
63
+ const ROOT_URL = PMXE_ROOT_URL;
64
+ /**
65
+ * Prefix used for names of shortcodes, action handlers, filter functions etc.
66
+ * @var string
67
+ */
68
+ const PREFIX = PMXE_PREFIX;
69
+ /**
70
+ * Plugin file path
71
+ * @var string
72
+ */
73
+ const FILE = __FILE__;
74
+ /**
75
+ * Max allowed file size (bytes) to import in default mode
76
+ * @var int
77
+ */
78
+ const LARGE_SIZE = 0; // all files will importing in large import mode
79
+
80
+ public static $session;
81
+
82
+ /**
83
+ * Return singletone instance
84
+ * @return PMXE_Plugin
85
+ */
86
+ static public function getInstance() {
87
+ if (self::$instance == NULL) {
88
+ self::$instance = new self();
89
+ }
90
+ return self::$instance;
91
+ }
92
+
93
+ /**
94
+ * Common logic for requestin plugin info fields
95
+ */
96
+ public function __call($method, $args) {
97
+ if (preg_match('%^get(.+)%i', $method, $mtch)) {
98
+ $info = get_plugin_data(self::FILE);
99
+ if (isset($info[$mtch[1]])) {
100
+ return $info[$mtch[1]];
101
+ }
102
+ }
103
+ throw new Exception("Requested method " . get_class($this) . "::$method doesn't exist.");
104
+ }
105
+
106
+ /**
107
+ * Get path to plagin dir relative to wordpress root
108
+ * @param bool[optional] $noForwardSlash Whether path should be returned withot forwarding slash
109
+ * @return string
110
+ */
111
+ public function getRelativePath($noForwardSlash = false) {
112
+ $wp_root = str_replace('\\', '/', ABSPATH);
113
+ return ($noForwardSlash ? '' : '/') . str_replace($wp_root, '', self::ROOT_DIR);
114
+ }
115
+
116
+ /**
117
+ * Check whether plugin is activated as network one
118
+ * @return bool
119
+ */
120
+ public function isNetwork() {
121
+ if ( !is_multisite() )
122
+ return false;
123
+
124
+ $plugins = get_site_option('active_sitewide_plugins');
125
+ if (isset($plugins[plugin_basename(self::FILE)]))
126
+ return true;
127
+
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * Check whether permalinks is enabled
133
+ * @return bool
134
+ */
135
+ public function isPermalinks() {
136
+ global $wp_rewrite;
137
+
138
+ return $wp_rewrite->using_permalinks();
139
+ }
140
+
141
+ /**
142
+ * Return prefix for plugin database tables
143
+ * @return string
144
+ */
145
+ public function getTablePrefix() {
146
+ global $wpdb;
147
+
148
+ //return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix) . self::PREFIX;
149
+ return $wpdb->prefix . self::PREFIX;
150
+ }
151
+
152
+ /**
153
+ * Return prefix for wordpress database tables
154
+ * @return string
155
+ */
156
+ public function getWPPrefix() {
157
+ global $wpdb;
158
+ return ($this->isNetwork()) ? $wpdb->base_prefix : $wpdb->prefix;
159
+ }
160
+
161
+ /**
162
+ * Class constructor containing dispatching logic
163
+ * @param string $rootDir Plugin root dir
164
+ * @param string $pluginFilePath Plugin main file
165
+ */
166
+ protected function __construct() {
167
+
168
+ $this->load_plugin_textdomain();
169
+
170
+ // regirster autoloading method
171
+ if (function_exists('__autoload') and ! in_array('__autoload', spl_autoload_functions())) { // make sure old way of autoloading classes is not broken
172
+ spl_autoload_register('__autoload');
173
+ }
174
+ spl_autoload_register(array($this, '__autoload'));
175
+
176
+ // register helpers
177
+ if (is_dir(self::ROOT_DIR . '/helpers')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/helpers/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
178
+ require_once $filePath;
179
+ }
180
+
181
+ // create history folder
182
+ $uploads = wp_upload_dir();
183
+
184
+ // init plugin options
185
+ $option_name = get_class($this) . '_Options';
186
+ $options_default = PMXE_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
187
+ $this->options = array_intersect_key(get_option($option_name, array()), $options_default) + $options_default;
188
+ $this->options = array_intersect_key($options_default, array_flip(array('info_api_url'))) + $this->options; // make sure hidden options apply upon plugin reactivation
189
+
190
+ update_option($option_name, $this->options);
191
+ $this->options = get_option(get_class($this) . '_Options');
192
+
193
+ register_activation_hook(self::FILE, array($this, '__activation'));
194
+
195
+ // register action handlers
196
+ if (is_dir(self::ROOT_DIR . '/actions')) if (is_dir(self::ROOT_DIR . '/actions')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/actions/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
197
+ require_once $filePath;
198
+ $function = $actionName = basename($filePath, '.php');
199
+ if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
200
+ $actionName = $m[1];
201
+ $priority = intval($m[2]);
202
+ } else {
203
+ $priority = 10;
204
+ }
205
+ add_action($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
206
+ }
207
+
208
+ // register filter handlers
209
+ if (is_dir(self::ROOT_DIR . '/filters')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/filters/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
210
+ require_once $filePath;
211
+ $function = $actionName = basename($filePath, '.php');
212
+ if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
213
+ $actionName = $m[1];
214
+ $priority = intval($m[2]);
215
+ } else {
216
+ $priority = 10;
217
+ }
218
+ add_filter($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
219
+ }
220
+
221
+ // register shortcodes handlers
222
+ if (is_dir(self::ROOT_DIR . '/shortcodes')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/shortcodes/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
223
+ $tag = strtolower(str_replace('/', '_', preg_replace('%^' . preg_quote(self::ROOT_DIR . '/shortcodes/', '%') . '|\.php$%', '', $filePath)));
224
+ add_shortcode($tag, array($this, 'shortcodeDispatcher'));
225
+ }
226
+
227
+ // register admin page pre-dispatcher
228
+ add_action('admin_init', array($this, '__adminInit'));
229
+ }
230
+
231
+ /**
232
+ * pre-dispatching logic for admin page controllers
233
+ */
234
+ public function __adminInit() {
235
+ $input = new PMXE_Input();
236
+ $page = strtolower($input->getpost('page', ''));
237
+ if (preg_match('%^' . preg_quote(str_replace('_', '-', self::PREFIX), '%') . '([\w-]+)$%', $page)) {
238
+ $this->adminDispatcher($page, strtolower($input->getpost('action', 'index')));
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Dispatch shorttag: create corresponding controller instance and call its index method
244
+ * @param array $args Shortcode tag attributes
245
+ * @param string $content Shortcode tag content
246
+ * @param string $tag Shortcode tag name which is being dispatched
247
+ * @return string
248
+ */
249
+ public function shortcodeDispatcher($args, $content, $tag) {
250
+
251
+ $controllerName = self::PREFIX . preg_replace('%(^|_).%e', 'strtoupper("$0")', $tag); // capitalize first letters of class name parts and add prefix
252
+ $controller = new $controllerName();
253
+ if ( ! $controller instanceof PMXE_Controller) {
254
+ throw new Exception("Shortcode `$tag` matches to a wrong controller type.");
255
+ }
256
+ ob_start();
257
+ $controller->index($args, $content);
258
+ return ob_get_clean();
259
+ }
260
+
261
+ /**
262
+ * Dispatch admin page: call corresponding controller based on get parameter `page`
263
+ * The method is called twice: 1st time as handler `parse_header` action and then as admin menu item handler
264
+ * @param string[optional] $page When $page set to empty string ealier buffered content is outputted, otherwise controller is called based on $page value
265
+ */
266
+ public function adminDispatcher($page = '', $action = 'index') {
267
+ static $buffer = NULL;
268
+ static $buffer_callback = NULL;
269
+ if ('' === $page) {
270
+ if ( ! is_null($buffer)) {
271
+ echo '<div class="wrap">';
272
+ echo $buffer;
273
+ do_action('pmxe_action_after');
274
+ echo '</div>';
275
+ } elseif ( ! is_null($buffer_callback)) {
276
+ echo '<div class="wrap">';
277
+ call_user_func($buffer_callback);
278
+ do_action('pmxe_action_after');
279
+ echo '</div>';
280
+ } else {
281
+ throw new Exception('There is no previousely buffered content to display.');
282
+ }
283
+ } else {
284
+ $controllerName = preg_replace('%(^' . preg_quote(self::PREFIX, '%') . '|_).%e', 'strtoupper("$0")', str_replace('-', '_', $page)); // capitalize prefix and first letters of class name parts
285
+ $actionName = str_replace('-', '_', $action);
286
+ if (method_exists($controllerName, $actionName)) {
287
+ $this->_admin_current_screen = (object)array(
288
+ 'id' => $controllerName,
289
+ 'base' => $controllerName,
290
+ 'action' => $actionName,
291
+ 'is_ajax' => isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest',
292
+ 'is_network' => is_network_admin(),
293
+ 'is_user' => is_user_admin(),
294
+ );
295
+ add_filter('current_screen', array($this, 'getAdminCurrentScreen'));
296
+ add_filter('admin_body_class', create_function('', 'return "' . PMXE_Plugin::PREFIX . 'plugin";'));
297
+
298
+ $controller = new $controllerName();
299
+ if ( ! $controller instanceof PMXE_Controller_Admin) {
300
+ throw new Exception("Administration page `$page` matches to a wrong controller type.");
301
+ }
302
+
303
+ if ($this->_admin_current_screen->is_ajax) { // ajax request
304
+ $controller->$action();
305
+ do_action('pmxe_action_after');
306
+ die(); // stop processing since we want to output only what controller is randered, nothing in addition
307
+ } elseif ( ! $controller->isInline) {
308
+ ob_start();
309
+ $controller->$action();
310
+ $buffer = ob_get_clean();
311
+ } else {
312
+ $buffer_callback = array($controller, $action);
313
+ }
314
+ } else { // redirect to dashboard if requested page and/or action don't exist
315
+ wp_redirect(admin_url()); die();
316
+ }
317
+ }
318
+ }
319
+
320
+ protected $_admin_current_screen = NULL;
321
+ public function getAdminCurrentScreen()
322
+ {
323
+ return $this->_admin_current_screen;
324
+ }
325
+
326
+ /**
327
+ * Autoloader
328
+ * It's assumed class name consists of prefix folloed by its name which in turn corresponds to location of source file
329
+ * if `_` symbols replaced by directory path separator. File name consists of prefix folloed by last part in class name (i.e.
330
+ * symbols after last `_` in class name)
331
+ * When class has prefix it's source is looked in `models`, `controllers`, `shortcodes` folders, otherwise it looked in `core` or `library` folder
332
+ *
333
+ * @param string $className
334
+ * @return bool
335
+ */
336
+ public function __autoload($className) {
337
+ $is_prefix = false;
338
+ $filePath = str_replace('_', '/', preg_replace('%^' . preg_quote(self::PREFIX, '%') . '%', '', strtolower($className), 1, $is_prefix)) . '.php';
339
+ if ( ! $is_prefix) { // also check file with original letter case
340
+ $filePathAlt = $className . '.php';
341
+ }
342
+ foreach ($is_prefix ? array('models', 'controllers', 'shortcodes', 'classes') : array('libraries') as $subdir) {
343
+ $path = self::ROOT_DIR . '/' . $subdir . '/' . $filePath;
344
+ if (is_file($path)) {
345
+ require $path;
346
+ return TRUE;
347
+ }
348
+ if ( ! $is_prefix) {
349
+ $pathAlt = self::ROOT_DIR . '/' . $subdir . '/' . $filePathAlt;
350
+ if (is_file($pathAlt)) {
351
+ require $pathAlt;
352
+ return TRUE;
353
+ }
354
+ }
355
+ }
356
+
357
+ return FALSE;
358
+ }
359
+
360
+ /**
361
+ * Get plugin option
362
+ * @param string[optional] $option Parameter to return, all array of options is returned if not set
363
+ * @return mixed
364
+ */
365
+ public function getOption($option = NULL) {
366
+ if (is_null($option)) {
367
+ return $this->options;
368
+ } else if (isset($this->options[$option])) {
369
+ return $this->options[$option];
370
+ } else {
371
+ throw new Exception("Specified option is not defined for the plugin");
372
+ }
373
+ }
374
+ /**
375
+ * Update plugin option value
376
+ * @param string $option Parameter name or array of name => value pairs
377
+ * @param mixed[optional] $value New value for the option, if not set than 1st parameter is supposed to be array of name => value pairs
378
+ * @return array
379
+ */
380
+ public function updateOption($option, $value = NULL) {
381
+ is_null($value) or $option = array($option => $value);
382
+ if (array_diff_key($option, $this->options)) {
383
+ throw new Exception("Specified option is not defined for the plugin");
384
+ }
385
+ $this->options = $option + $this->options;
386
+ update_option(get_class($this) . '_Options', $this->options);
387
+
388
+ return $this->options;
389
+ }
390
+
391
+ /**
392
+ * Plugin activation logic
393
+ */
394
+ public function __activation() {
395
+ // uncaught exception doesn't prevent plugin from being activated, therefore replace it with fatal error so it does
396
+ set_exception_handler(create_function('$e', 'trigger_error($e->getMessage(), E_USER_ERROR);'));
397
+
398
+ // create plugin options
399
+ $option_name = get_class($this) . '_Options';
400
+ $options_default = PMXE_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
401
+ $wpai_options = get_option($option_name, false);
402
+ if ( ! $wpai_options ) update_option($option_name, $options_default);
403
+
404
+ // create/update required database tables
405
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
406
+ require self::ROOT_DIR . '/schema.php';
407
+ global $wpdb;
408
+
409
+ if (function_exists('is_multisite') && is_multisite()) {
410
+ // check if it is a network activation - if so, run the activation function for each blog id
411
+ if (isset($_GET['networkwide']) && ($_GET['networkwide'] == 1)) {
412
+ $old_blog = $wpdb->blogid;
413
+ // Get all blog ids
414
+ $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
415
+ foreach ($blogids as $blog_id) {
416
+ switch_to_blog($blog_id);
417
+ require self::ROOT_DIR . '/schema.php';
418
+ dbDelta($plugin_queries);
419
+ }
420
+ switch_to_blog($old_blog);
421
+ return;
422
+ }
423
+ }
424
+
425
+ dbDelta($plugin_queries);
426
+
427
+ }
428
+
429
+ /**
430
+ * Load Localisation files.
431
+ *
432
+ * Note: the first-loaded translation file overrides any following ones if the same translation is present
433
+ *
434
+ * @access public
435
+ * @return void
436
+ */
437
+ public function load_plugin_textdomain() {
438
+ $locale = apply_filters( 'plugin_locale', get_locale(), 'pmxe_plugin' );
439
+
440
+ load_plugin_textdomain( 'PMXE_plugin', false, dirname( plugin_basename( __FILE__ ) ) . "/i18n/languages" );
441
+ }
442
+
443
+ /**
444
+ * Method returns default import options, main utility of the method is to avoid warnings when new
445
+ * option is introduced but already registered imports don't have it
446
+ */
447
+ public static function get_default_import_options() {
448
+ return array(
449
+ 'cpt' => array(),
450
+ 'export_to' => 'xml',
451
+ 'is_export_title' => 1,
452
+ 'is_export_content' => 1,
453
+ 'custom_fields_list' => array(),
454
+ 'is_export_custom_fields' => 1,
455
+ 'export_custom_fields_logic' => 'full_export',
456
+ 'taxonomies_list' => array(),
457
+ 'is_export_categories' => 1,
458
+ 'export_categories_logic' => 'full_export',
459
+ 'is_export_images' => 1,
460
+ 'export_images_logic' => array('urls', 'meta_data'),
461
+ 'is_export_other' => 1,
462
+ 'is_export_dates' => 1,
463
+ 'is_export_parent' => 1,
464
+ 'is_export_template' => 1,
465
+ 'is_export_menu_order' => 1,
466
+ 'is_export_status' => 1,
467
+ 'is_export_format' => 1,
468
+ 'is_export_author' => 1,
469
+ 'is_export_slug' => 1,
470
+ 'is_export_excerpt' => 1,
471
+ 'is_export_attachments' => 1
472
+ );
473
+ }
474
+
475
+ /*
476
+ * Convert csv to xml
477
+ */
478
+ public static function csv_to_xml($csv_url){
479
+
480
+ include_once(self::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
481
+
482
+ $csv = new PMXE_CsvParser($csv_url);
483
+
484
+ $wp_uploads = wp_upload_dir();
485
+ $tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($csv_url)));
486
+ $xml_file = $wp_uploads['path'] .'/'. $tmpname;
487
+ file_put_contents($xml_file, $csv->toXML());
488
+ return $xml_file;
489
+
490
+ }
491
+
492
+ public static function is_ajax(){
493
+ return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') ? true : false ;
494
+ }
495
+
496
+ }
497
+
498
+ PMXE_Plugin::getInstance();
readme.txt ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Export WordPress data to XML/CSV ===
2
+ Contributors: soflyy
3
+ Tags: wordpress, xml, csv, datafeed, export
4
+ Requires at least: 3.6.1
5
+ Tested up to: 3.8
6
+ Stable tag: 0.9.0
7
+
8
+ ALPHA: WP All Export makes it easy to export WordPress data into an XML file.
9
+
10
+ == Description ==
11
+
12
+ **Use at your own risk. PLEASE don’t leave a rating for us yet.**
13
+
14
+ This is a very early ALPHA version of WP All Export.
15
+
16
+ It’s not complete. There are tons of features that we’re going to put in here, like integration with WP All Import, customizing the export file, etc.
17
+
18
+ **Right now ALL this plugin does is export an XML file.**
19
+
20
+ WP All Export makes it easy to export WordPress data into an XML file.
21
+
22
+ == Installation ==
23
+
24
+ Either: -
25
+
26
+ * Upload the plugin from the Plugins page in WordPress
27
+ * Unzip wp-all-export.zip and upload the contents to /wp-content/plugins/, and then activate the plugin from the Plugins page in WordPress
28
+
29
+
30
+ == Frequently Asked Questions ==
31
+
32
+
33
+ == Screenshots ==
34
+
35
+ 1. New Export
36
+ 2. Export options
37
+
38
+ == Changelog ==
39
+
40
+ = 0.9 =
41
+ * Initial release on WordPress.org.
schema.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin database schema
4
+ * WARNING:
5
+ * dbDelta() doesn't like empty lines in schema string, so don't put them there;
6
+ * WPDB doesn't like NULL values so better not to have them in the tables;
7
+ */
8
+
9
+ /**
10
+ * The database character collate.
11
+ * @var string
12
+ * @global string
13
+ * @name $charset_collate
14
+ */
15
+ $charset_collate = '';
16
+
17
+ // Declare these as global in case schema.php is included from a function.
18
+ global $wpdb, $plugin_queries;
19
+
20
+ if ( ! empty($wpdb->charset))
21
+ $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
22
+ if ( ! empty($wpdb->collate))
23
+ $charset_collate .= " COLLATE $wpdb->collate";
24
+
25
+ $table_prefix = PMXE_Plugin::getInstance()->getTablePrefix();
26
+
27
+ $plugin_queries = false;
screenshot-1.png ADDED
Binary file
screenshot-2.png ADDED
Binary file
static/css/admin-ie.css ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .PMXE_plugin .load-template a.help {
2
+ margin-top: -10px;
3
+ }
4
+ .PMXE_plugin .wrap {
5
+ margin-top: 5px;
6
+ }
7
+ .PMXE_plugin input.button-primary {
8
+ vertical-align: middle;
9
+ }
10
+
11
+ .xml-expander {
12
+ display: inline;
13
+ }
static/css/admin-wp-3.8.css ADDED
File without changes
static/css/admin.css ADDED
@@ -0,0 +1,1332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*@+ common */
2
+ .pmxe_plugin hr {
3
+ height: 1px;
4
+ border-width: 0px;
5
+ color: #ddd;
6
+ background-color: #ddd;
7
+ margin-bottom: 15px;
8
+ }
9
+ .pmxe_plugin a.button {
10
+ /*padding: 5px 10px;
11
+ margin: 1px;
12
+ font-weight: bold;*/
13
+ }
14
+ .pmxe_plugin a.help {
15
+ overflow: hidden;
16
+ text-indent: -99999px;
17
+ display: inline-block;
18
+ width: 16px;
19
+ height: 16px;
20
+ background-repeat: no-repeat;
21
+ background-image: url("../img/help.png");
22
+ vertical-align: middle;
23
+ margin-left: 5px;
24
+ }
25
+ .pmxe_plugin input.datepicker {
26
+ width: 8em;
27
+ }
28
+ .pmxe_plugin button.ui-datepicker-trigger {
29
+ background-image: url("../img/date-picker.gif");
30
+ background-repeat: no-repeat;
31
+ cursor: pointer;
32
+ border: none;
33
+ margin: 1px;
34
+ width: 21px;
35
+ height: 18px;
36
+ vertical-align: middle;
37
+ }
38
+ .pmxe_plugin .progress-msg {
39
+ font-style: italic;
40
+ display: none;
41
+ }
42
+ .pmxe_plugin .inner-content {
43
+ max-width: 700px;
44
+ }
45
+ .pmxe_plugin .loading {
46
+ cursor: progress;
47
+ background-repeat: no-repeat;
48
+ background-position: center;
49
+ }
50
+ .pmxe_plugin .preload {
51
+ background-image: url("../img/loading.png");
52
+ background-repeat: no-repeat;
53
+ background-position: 50% 200px;
54
+ }
55
+ .pmxe_plugin a.add-new {
56
+ font-size: 18px;
57
+ background-color: #eee;
58
+ cursor: pointer;
59
+ padding: 6px 10px 6px 10px;
60
+ line-height: normal;
61
+ font-style: normal;
62
+ color: #464646;
63
+ border-color: #bbb;
64
+ -moz-border-radius: 4px 4px 4px 4px;
65
+ border-radius: 4px;
66
+ border-style: solid;
67
+ border-width: 1px;
68
+ font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;
69
+ text-decoration: none;
70
+ }
71
+ .pmxe_plugin a.add-new:hover {
72
+ border-color: #666666;
73
+ color: #000;
74
+ }
75
+ .pmxe_plugin div.input {
76
+ /*line-height: 25px;
77
+ height: 25px;*/
78
+ min-height: 21px;
79
+ font-size: 12px !important;
80
+ }
81
+ .pmxe_plugin div.input > * {
82
+ vertical-align: middle;
83
+ }
84
+ .pmxe_plugin .options input[type=text], .pmxe_plugin .options select {
85
+ /*background: #fafafa !important;*/
86
+ border: 1px solid #aaa !important;
87
+ font-size: 12px !important;
88
+ }
89
+ .pmxe_plugin .note {
90
+ color: #666666;
91
+ font-size: 9px;
92
+ }
93
+ .pmxe_plugin div.sub {
94
+ padding-left: 20px;
95
+ font-size: 12px;
96
+ }
97
+ /* 2 column layout */
98
+ .pmxe_plugin table.layout {
99
+ clear: both;
100
+ border-collapse: collapse;
101
+ min-width: 770px;
102
+ width: 100%;
103
+ }
104
+ .pmxe_plugin table.layout td {
105
+ vertical-align: top;
106
+ border: none;
107
+ font-size: 12px !important;
108
+ }
109
+ .pmxe_plugin table.layout td.left {
110
+ min-width: 490px;
111
+ width: 70%;
112
+ }
113
+ .pmxe_plugin table.layout td.right {
114
+ padding: 0px 0 16px 20px;
115
+ width: 25%;
116
+ min-width: 260px;
117
+ position: relative;
118
+ }
119
+ .pmxe_plugin table.layout td.left > h2:first-child {
120
+ margin-top: -22px;
121
+ padding: 14px 0 20px;
122
+ }
123
+ .pmxe_plugin table.layout td.left hr {
124
+ clear: both;
125
+ }
126
+ .pmxe_plugin.no-js table.layout td.left > h2:first-child {
127
+ margin-top: 0px;
128
+ }
129
+ .pmxe_plugin table.layout div.left {
130
+ min-width: 490px;
131
+ width: 70%;
132
+ float: left;
133
+ }
134
+ .pmxe_plugin table.layout div.right {
135
+ padding: 0px 0 16px 20px;
136
+ width: 25%;
137
+ /*min-width: 260px; */
138
+ position: relative;
139
+ float: right;
140
+ }
141
+ /*@*/
142
+
143
+ /*@+ Setting Form */
144
+ .pmxe_plugin form.settings {
145
+ width: 700px;
146
+ }
147
+ /*@*/
148
+
149
+ /*@+ Choose File forms */
150
+ .pmxe_plugin form.choose-file {
151
+ padding-top: 20px;
152
+ position: relative;
153
+ }
154
+ .pmxe_plugin form.choose-file h3 {
155
+ margin-bottom: 5px;
156
+ }
157
+ .pmxe_plugin form.choose-file .label {
158
+ font-size: 15px;
159
+ }
160
+ .pmxe_plugin form.choose-file input[type="text"],
161
+ .pmxe_plugin form.choose-file input[type="password"] {
162
+ width: 80px;
163
+ font-size: 12px;
164
+ }
165
+ .pmxe_plugin form.choose-file input.regular-text,
166
+ .pmxe_plugin form.choose-file select.regular-text {
167
+ width: 100%;
168
+ }
169
+ .pmxe_plugin #wpcontent form.choose-file select[name="file"],
170
+ .pmxe_plugin #wpcontent form.choose-file select[name="reimport"] {
171
+ font-size: 12px;
172
+ }
173
+ .pmxe_plugin form.choose-file input[type="submit"].button {
174
+ /*width: 150px;*/
175
+ }
176
+ .pmxe_plugin form.choose-file div.input {
177
+ margin-top: 20px;
178
+ }
179
+ /*@*/
180
+
181
+ /*@+ Choose Elements form */
182
+ .pmxe_plugin form.choose-elements input[type="text"] {
183
+ width: 100%;
184
+ max-width: 300px;
185
+ min-width: 150px;
186
+ }
187
+ /*@*/
188
+
189
+ /*@+ Template form */
190
+ .pmxe_plugin form.template.edit {
191
+ /*width: 700px;*/
192
+ }
193
+ .pmxe_plugin form.template .load-template {
194
+ display: block;
195
+ font-size: 12px;
196
+ }
197
+ .pmxe_plugin form.template .load-template select {
198
+ width: 126px;
199
+ }
200
+
201
+ .pmxe_plugin #poststuff form.template h3 {
202
+ margin: 1em 0 5px 2px;
203
+ font-size: 1.17em;
204
+ padding: 0px;
205
+ }
206
+ .pmxe_plugin #post-preview {
207
+ font-size: 12px;
208
+ }
209
+ .pmxe_plugin #post-preview .error {
210
+ margin: 5px 0;
211
+ }
212
+ .pmxe_plugin h3 .header-option {
213
+ display: block;
214
+ float: right;
215
+ font-size: 12px;
216
+ font-weight: normal;
217
+ }
218
+ /*@*/
219
+
220
+ /*@+ Options form */
221
+ .pmxe_plugin form.options.edit {
222
+ /*width: 700px;*/
223
+ }
224
+
225
+ .pmxe_plugin .post-type-container,
226
+ .pmxe_plugin .file-type-container {
227
+ padding: 4px 10px 10px;
228
+ border: 1px solid transparent;
229
+ }
230
+ .pmxe_plugin .post-type-container.selected,
231
+ .pmxe_plugin .file-type-container.selected {
232
+ background-color: #F1F1F1;
233
+ border: 1px solid #ccc;
234
+ padding-bottom: 10px;
235
+ }
236
+ .pmxe_plugin .post-type-container h3,
237
+ .pmxe_plugin .file-type-container h3 {
238
+ margin: 0px 0px;
239
+ }
240
+ .pmxe_plugin .post-type-container .post-type-options,
241
+ .pmxe_plugin .file-type-container .file-type-options {
242
+ margin: 15px 0px 0 30px;
243
+ }
244
+
245
+ .pmxe_plugin table.form-table {
246
+ clear: none;
247
+ margin-top: 0px;
248
+ }
249
+ .pmxe_plugin .post-type-options table.form-table {
250
+ max-width: 500px;
251
+ }
252
+ .pmxe_plugin .post-type-options table.form-table td.delim {
253
+ width: 50px;
254
+ position: relative;
255
+ display: block;
256
+ }
257
+ .pmxe_plugin .post-type-options table.form-table td.delim input {
258
+ width: 20px;
259
+ }
260
+ .pmxe_plugin table.form-table.custom-params {
261
+ max-width: 700px;
262
+ }
263
+ .pmxe_plugin table.form-table td,
264
+ .pmxe_plugin table.form-table th {
265
+ /*padding: 0;*/
266
+ vertical-align: top;
267
+ }
268
+ .pmxe_plugin .post-type-options table.form-table th {
269
+ width: 100px;
270
+ }
271
+ .pmxe_plugin .post-type-options table.form-table select {
272
+ max-width: 300px;
273
+ width:300px;
274
+ }
275
+ .pmxe_plugin table.form-table thead td {
276
+ font-weight: bold;
277
+ }
278
+ .pmxe_plugin table.form-table.custom-params input {
279
+ margin-left: 0;
280
+ }
281
+ .pmxe_plugin table.form-table tr.template {
282
+ display: none;
283
+ }
284
+ /*@*/
285
+
286
+ /*@+ XML representation */
287
+ .pmxe_plugin .tag {
288
+ background-color: #fff;
289
+ position: absolute;
290
+ width:95%;
291
+ top: 0;
292
+ margin-top: 45px;
293
+ border-top: 1px solid #DFDFDF;
294
+ -moz-border-radius-topleft: 4px;
295
+ -webkit-border-top-left-radius: 4px;
296
+ border-top-left-radius: 4px;
297
+ -moz-border-radius-topright: 4px;
298
+ -webkit-border-top-right-radius: 4px;
299
+ border-top-right-radius: 4px;
300
+ }
301
+
302
+ .pmxe_plugin .options .tag{
303
+ margin-top: 0px;
304
+ }
305
+ .pmxe_plugin .tag .title {
306
+ font-weight: bold;
307
+ padding: 6px 8px;
308
+ color: #464646;
309
+ background: #DFDFDF;
310
+ font-size: 12px;
311
+ border-top: 1px solid #DFDFDF;
312
+ -moz-border-radius-topleft: 4px;
313
+ -webkit-border-top-left-radius: 4px;
314
+ border-top-left-radius: 4px;
315
+ -moz-border-radius-topright: 4px;
316
+ -webkit-border-top-right-radius: 4px;
317
+ border-top-right-radius: 4px;
318
+ }
319
+ .pmxe_plugin .tag .xml {
320
+ max-height: 525px;
321
+ overflow: auto;
322
+ border: 1px solid #DFDFDF;
323
+ border-top:none;
324
+ -moz-border-radius-bottomright: 4px;
325
+ -webkit-border-bottom-right-radius: 4px;
326
+ border-bottom-right-radius: 4px;
327
+ -moz-border-radius-bottomleft: 4px;
328
+ -webkit-border-bottom-left-radius: 4px;
329
+ border-bottom-left-radius: 4px;
330
+ }
331
+ .pmxe_plugin .tag .navigation {
332
+ float: right;
333
+ margin: 2px -12px 0 0;
334
+ }
335
+ .pmxe_plugin .tag .navigation a,
336
+ .pmxe_plugin .tag .navigation span {
337
+ font-weight: bold;
338
+ padding: 0 12px;
339
+ text-decoration: none;
340
+ }
341
+
342
+ @media screen and (max-height: 700px) {
343
+ .pmxe_plugin .tag {
344
+ height:300px;
345
+ }
346
+ .pmxe_plugin .tag .xml {
347
+ max-height: 265px;
348
+ }
349
+ }
350
+
351
+ .xml {
352
+ padding-left: 15px;
353
+ }
354
+ .xml-element {
355
+ border: 1px solid transparent;
356
+ margin: 1px 1px 1px 0;
357
+ }
358
+ .xml-element.selected > .xml-tag.opening .xml-tag-name {
359
+ background-color: #B5E61D;
360
+ }
361
+ .xml-content {
362
+ padding-left: 14px;
363
+ }
364
+ .xml-content.collapsed {
365
+ display: none;
366
+ }
367
+ .xml-content.textonly.short {
368
+ padding-left: 0px;
369
+ display: inline;
370
+ }
371
+ .xml-tag {
372
+ display: inline;
373
+ }
374
+ .xml-tag-name {
375
+ color: #906;
376
+ font-weight: bold;
377
+ }
378
+ .xml-tag.opening .xml-tag-name {
379
+ cursor: pointer;
380
+ }
381
+ .xml-attr-name {
382
+ font-weight: bold;
383
+ cursor: pointer;
384
+ }
385
+ .xml-attr-value {
386
+ color: blue;
387
+ }
388
+ .xml-expander {
389
+ display: inline-block;
390
+ width: 12px;
391
+ margin-left: -12px;
392
+ -moz-user-select: none;
393
+ -khtml-user-select: none;
394
+ -webkit-user-select: none;
395
+ user-select: none;
396
+ cursor: pointer;
397
+ font-family: monospace;
398
+ line-height: 100%;
399
+ text-align: left;
400
+ color: red;
401
+ }
402
+ .xml-more {
403
+ color: red;
404
+ font-size: 80%;
405
+ }
406
+ .xml.resetable .xml-element.lvl-mod4-3 > .xml-content {
407
+ margin-left: -59px;
408
+ margin-right: -8px;
409
+ background-color: #fff;
410
+ border: 1px dashed #906;
411
+ border-left: 2px solid #906;
412
+ border-right: none;
413
+ }
414
+ .xml.resetable .xml-element.lvl-mod4-3 > .xml-content.short {
415
+ margin-left: 0;
416
+ margin-right: 0;
417
+ border: none;
418
+ background-color: inherit;
419
+ }
420
+ /* xml table representation */
421
+ tr.xml-element.selected .xml-tag.opening .xml-tag-name {
422
+ background-color: #B5E61D;
423
+ }
424
+ table.xml td {
425
+ padding-left: 20px;
426
+ }
427
+ table.xml td:first-child {
428
+ width: 1px;
429
+ padding-left: 0px;
430
+ }
431
+
432
+ table.xml,
433
+ table.xml table {
434
+ width: 100%;
435
+ border-collapse:collapse;
436
+ border-spacing:0;
437
+ }
438
+ /*@*/
439
+
440
+ /*@+ table list */
441
+ .pmxe_plugin table.widefat th {
442
+ white-space: nowrap;
443
+ }
444
+ .pmxe_plugin table.widefat th.ASC a {
445
+ background-image: url("../img/screen-options-right-up.gif");
446
+ background-repeat: no-repeat;
447
+ background-position: right center;
448
+ padding-right: 19px;
449
+ }
450
+ .pmxe_plugin table.widefat th.DESC a {
451
+ background-image: url("../img/screen-options-right.gif");
452
+ background-repeat: no-repeat;
453
+ background-position: right center;
454
+ padding-right: 19px;
455
+ }
456
+
457
+ .pmxe_plugin table.widefat.pmxe-admin-imports th.column-id {
458
+ width: 35px;
459
+ }
460
+ .pmxe_plugin table.widefat.pmxe-admin-imports th.column-scheduled {
461
+ width: 85px;
462
+ }
463
+ .pmxe_plugin table.widefat.pmxe-admin-imports th.column-registered_on {
464
+ width: 130px;
465
+ }
466
+ .pmxe_plugin table.widefat.pmxe-admin-imports th.column-post_count {
467
+ width: 105px;
468
+ }
469
+ /*@*/
470
+
471
+ /*@+ fixes */
472
+ .pmxe_plugin input[type="file"] {
473
+ padding: 0; /* FIX height or <input type="file" /> for Safari & Chrome */
474
+ }
475
+ .pmxe_plugin .ui-widget-overlay {
476
+ position: fixed !important; /* FIX: modal dialog overlay in IE 8 */
477
+ background-color: #aaa !important; /* FIX: overlay color */
478
+ }
479
+ .pmxe_plugin .ui-dialog {
480
+ position: absolute !important; /* FIX: for wordpress 3.1 not to add empty space */
481
+ z-index: 999999;
482
+ }
483
+ .pmxe_plugin .ui-autocomplete {
484
+ position: absolute;
485
+ border-color: #ccc #444 #444 #aaa;
486
+ cursor: default;
487
+ -moz-border-radius: 0;
488
+ border-radius: 0;
489
+ max-height: 200px;
490
+ max-width: 700px;
491
+ overflow-y: auto;
492
+ overflow-x: hidden;
493
+ white-space: nowrap;
494
+ font-size: 11px;
495
+ }
496
+ .pmxe_plugin .ui-autocomplete .ui-menu-item {
497
+ padding: 0;
498
+ margin: 0;
499
+ }
500
+ .pmxe_plugin .ui-autocomplete .ui-menu-item a {
501
+ display: block;
502
+ padding: 2px;
503
+ padding-right: 20px; /* space for scroll bar */
504
+ font-size: 11px;
505
+ border: none;
506
+ -moz-border-radius: 0;
507
+ border-radius: 0;
508
+ }
509
+ .pmxe_plugin .ui-autocomplete .ui-menu-item a.ui-state-hover {
510
+ background: #39f;
511
+ color: #fff;
512
+ }
513
+ .pmxe_plugin input.autocomplete {
514
+ background: url("../img/down.gif") no-repeat right top #fff;
515
+ padding-right: 20px;
516
+ cursor: default;
517
+ font-size: 11px !important;
518
+ }
519
+ /*@*/
520
+
521
+ .pmxe_plugin .taglines{
522
+ font-size:13px;
523
+ font-style: italic;
524
+ display: block;
525
+ color: #777;
526
+ }
527
+
528
+ .pmxe_plugin #process{ display:none; }
529
+ .pmxe_plugin .load-options{ float:right; font-size:13px; position: relative; top: -30px; }
530
+ .pmxe_plugin form.options table.layout td.right{
531
+ width: 25%;
532
+ }
533
+ .pmxe_plugin .drag-element{
534
+ background: url("../img/drag.png") top right no-repeat;
535
+ cursor: pointer;
536
+ padding-left: 25px;
537
+ background-position: 0px 1px;
538
+ }
539
+ .sortable li{ position: relative;}
540
+ .pmxe_plugin ol{
541
+ margin-top: 6px;
542
+ list-style: none;
543
+ }
544
+ .pmxe_plugin .no-margin{ margin:0px; }
545
+ .pmxe_plugin .icon-item, .pmxe_plugin .add-new-custom{
546
+ display: inline-block;
547
+ width: 16px;
548
+ height: 16px;
549
+ margin: 0px 3px;
550
+ }
551
+ .pmxe_plugin .add-new-ico, .pmxe_plugin .add-new-custom{
552
+ background: url("../img/ico-add-new.png") no-repeat 0px 4px;
553
+ width:70px;
554
+ height:25px;
555
+ padding-left: 15px;
556
+ color:#21759B;
557
+ }
558
+
559
+ .pmxe_plugin .remove-ico{
560
+ background: url("../img/ico-remove.png") no-repeat;
561
+ top:1px;
562
+ right:0px;
563
+ position: absolute;
564
+ }
565
+
566
+ .pmxe_plugin .hidden{ display: none; }
567
+
568
+ .pmxe_plugin .fs11 { font-size:11px; }
569
+
570
+ .pmxe_plugin .rel { position: relative; }
571
+
572
+ #type_meta_select{ margin-bottom: 10px; height:1.8em; }
573
+
574
+ .upload_process{
575
+ border: none;
576
+ padding: 1px;
577
+ }
578
+
579
+ #large_import_xpath{ display:none; }
580
+ #large_import{ margin:0px 5px; }
581
+ #download_pmxe_log{
582
+ cursor: pointer;
583
+ margin: 5px 0;
584
+ display: none;
585
+ }
586
+ .pmxe_plugin .import_process_bar, .pmxe_plugin .import_percent{
587
+ display: none;
588
+ }
589
+ /*.pmxe_plugin .import_progress{
590
+ font-size: 14px !important;
591
+ }*/
592
+ .pmxe_plugin #processbar{
593
+ text-align: center;
594
+ visibility: hidden;
595
+ height: 37px;
596
+ padding-top: 18px;
597
+ margin-bottom: 20px;
598
+ border: 1px solid #AAAAAA;
599
+ color: #222222;
600
+ position: relative;
601
+ }
602
+ .pmxe_plugin #processbar div{
603
+ background: #aaa;
604
+ height: 55px;
605
+ width: 0%;
606
+ position: absolute;
607
+ opacity: 0.5;
608
+ top:0;
609
+ }
610
+ .pmxe_plugin #import_progress{
611
+ color: #000000;
612
+ font-size: 13px;
613
+ font-weight: bold;
614
+ opacity: 1;
615
+ }
616
+ .pmxe_plugin #right_progress{ float:right; padding-right: 5px; }
617
+ .pmxe_plugin #left_progress{ float:left; padding-left: 5px; }
618
+ .pmxe_plugin #existing_meta_keys{
619
+ margin-bottom: 10px;
620
+ padding: 2px;
621
+ width: 580px;
622
+ }
623
+ .pmxe_plugin #pmxe_tabs{
624
+ /*display: none;*/
625
+ padding-bottom: 20px;
626
+ -moz-border-radius: 4px;
627
+ -khtml-border-radius: 4px;
628
+ -webkit-border-radius: 4px;
629
+ border-radius: 4px;
630
+ }
631
+ .pmxe_plugin .pmxe_tab{
632
+ display: none;
633
+ }
634
+ .pmxe_plugin .ui-widget-header{
635
+ -moz-border-radius: 4px;
636
+ -khtml-border-radius: 4px;
637
+ -webkit-border-radius: 4px;
638
+ border-radius: 4px;
639
+ }
640
+ .pmxe_plugin .ui-tabs .ui-tabs-nav li{
641
+ -moz-border-top-left-radius: 4px;
642
+ -khtml-border-top-left-radius: 4px;
643
+ -webkit-border-top-left-radius: 4px;
644
+ border-top-left-radius: 4px;
645
+ -moz-border-top-right-radius: 4px;
646
+ -khtml-border-top-right-radius: 4px;
647
+ -webkit-border-top-right-radius: 4px;
648
+ border-top-right-radius: 4px;
649
+ }
650
+ /*.pmxe_plugin .ui-widget-header{
651
+ background: #F2FBD9;
652
+ border: 1px solid #F2FBD9;
653
+ }
654
+ .pmxe_plugin .ui-state-default{
655
+ border:none;
656
+ font-size: 12px;
657
+ font-weight: bold;
658
+ background: #F2FBD9;
659
+ }
660
+ .pmxe_plugin .ui-state-active{
661
+ background: #fff;
662
+ }
663
+ .pmxe_plugin .ui-tabs{
664
+ padding: 0px;
665
+ }*/
666
+ #select-files{
667
+ font-size: 11px !important;
668
+ height:25px;
669
+ }
670
+ .pmxe_plugin .progress{
671
+ position: relative;
672
+ visibility: hidden;
673
+ color: #009039;
674
+ font-size: 13px;
675
+ font-weight: bold;
676
+ margin-top: 10px;
677
+ width: 100%;
678
+ text-align: center;
679
+ border:1px solid #4297D7;
680
+ -moz-border-radius: 4px;
681
+ -khtml-border-radius: 4px;
682
+ -webkit-border-radius: 4px;
683
+ border-radius: 4px;
684
+ }
685
+ .pmxe_plugin #progressbar{
686
+ border: medium none;
687
+ left: 0;
688
+ position: absolute;
689
+ text-align: center;
690
+ top: 8px;
691
+ width: 100%;
692
+ font-size: 12px;
693
+ color:#333;
694
+ }
695
+ .pmxe_plugin #file_name{
696
+ font-size: 16px;
697
+ font-weight: bold;
698
+ margin-left: 10px;
699
+ float: right;
700
+ }
701
+ .pmxe_plugin .ui-progressbar .ui-progressbar-value { /*background-image: url("../img/progress_animated.gif");*/ }
702
+ .pmxe_plugin form.choose-file .submit-buttons{
703
+ /*bottom: -125px;
704
+ position: absolute;
705
+ right: -18px; */
706
+ }
707
+ .pmxe_plugin form#basic .submit-buttons{
708
+ display: none;
709
+ }
710
+ .pmxe_plugin fieldset{
711
+ padding: 20px;
712
+ width:auto;
713
+ }
714
+ .pmxe_plugin .right fieldset{
715
+ padding: 15px;
716
+ }
717
+ .pmxe_plugin .right fieldset input{
718
+ max-width:none;
719
+ padding:6px;
720
+ margin:0px
721
+ }
722
+ .pmxe_plugin .right a{
723
+ text-decoration: underline;
724
+ }
725
+ .pmxe_plugin fieldset legend{
726
+ padding: 0px 5px;
727
+ font-weight: bold;
728
+ }
729
+ .pmxe_plugin .options fieldset legend{
730
+ font-size: 1.17em;
731
+ }
732
+ .pmxe_plugin .matches_count{
733
+ font-weight: bold;
734
+ color:#33AA28;
735
+ }
736
+ .pmxe_plugin .xpath_help{
737
+ /*bottom: -40px;*/
738
+ position: relative;
739
+ text-align: center;
740
+ }
741
+ .pmxe_plugin .btns, .pmxe_plugin .btns input, .pmxe_plugin .btns a{
742
+ float: right;
743
+ }
744
+ .pmxe_plugin .btns input{
745
+ height: 19px;
746
+ margin-left: 5px;
747
+ padding-top: 0;
748
+ }
749
+ .pmxe_plugin .btns a{
750
+ font-weight: bold;
751
+ margin: 0 5px;
752
+ padding: 4px 10px;
753
+ width:70px;
754
+ text-align: center;
755
+ }
756
+ .pmxe_plugin .col3{
757
+ /*border-right: 1px solid #CCCCCC;*/
758
+ float: left;
759
+ /*height: 265px;*/
760
+ width:33%;
761
+ margin-bottom: 10px;
762
+ /*padding: 0 1%;*/
763
+ }
764
+ .pmxe_plugin .col3.last{
765
+ border: none;
766
+ }
767
+ .pmxe_plugin .col3 > div{
768
+ /*margin-left: 20px;*/
769
+ }
770
+ .pmxe_plugin .col2{
771
+ float: left;
772
+ width: 50%;
773
+ }
774
+ .pmxe_plugin .col2 fieldset{
775
+ border: 1px solid #CCCCCC;
776
+ margin: 0 5px;
777
+ padding: 5px 2% 5px 5px;
778
+ text-align: center;
779
+ }
780
+ .pmxe_plugin input.small{
781
+ width:25px;
782
+ text-align: center;
783
+ }
784
+ .pmxe_plugin .post_taxonomy{
785
+ margin-bottom: 15px;
786
+ overflow: hidden;
787
+ padding-bottom: 15px;
788
+ }
789
+ .pmxe_plugin .post_taxonomy .delim{
790
+ padding-left: 25px;
791
+ }
792
+ .pmxe_plugin .post_taxonomy .delim .add-new-ico{
793
+ float: right;
794
+ margin-right: 10%;
795
+ margin-top: 5px;
796
+ }
797
+ .pmxe_plugin .post_taxonomy ol.ui-sortable{
798
+ padding-right: 0px;
799
+ }
800
+ .pmxe_plugin .optionsset{
801
+ border:1px solid #ccc;
802
+ }
803
+ .pmxe_plugin .action.remove{
804
+ display: block;
805
+ position: relative;
806
+ }
807
+ .pmxe_plugin .action.remove a{
808
+ background: url("../img/ico-remove.png") no-repeat scroll 0 0 transparent;
809
+ height: 16px;
810
+ position: absolute;
811
+ right: 20px;
812
+ width: 16px;
813
+ }
814
+ .pmxe_plugin .switcher-target-is_keep_former_posts{
815
+ padding-left: 25px;
816
+ }
817
+ .pmxe_plugin form.options{
818
+ position: relative;
819
+ }
820
+ .pmxe_plugin .options_buttons{
821
+ bottom: -75px;
822
+ display: block;
823
+ position: absolute;
824
+ right: 0;
825
+ }
826
+ .pmxe-button{
827
+ border: 1px solid #BBBBBB;
828
+ color: #464646;
829
+ cursor: pointer;
830
+ font-size: 18px !important;
831
+ margin-left: 10px;
832
+ padding: 15px 25px;
833
+ text-decoration: none;
834
+ -moz-border-radius: 3px;
835
+ -khtml-border-radius: 3px;
836
+ -webkit-border-radius: 3px;
837
+ border-radius: 3px;
838
+ }
839
+ .pmxe-button:hover{
840
+ background: #dfdfdf;
841
+ }
842
+ .pmxe_plugin .ui-state-default a{
843
+ font-size: 13px !important;
844
+ }
845
+ .pmxe_plugin .preview{
846
+ float: none;
847
+ /*line-height: 32px;
848
+ position: relative;
849
+ text-align: center;
850
+ text-decoration: none;
851
+ top: -1px;
852
+ vertical-align: middle;*/
853
+ }
854
+ .pmxe_plugin .template-sidebar .tag{
855
+ max-height:550px;
856
+ }
857
+ .pmxe_plugin .options .submit-buttons{
858
+ float: right;
859
+ position: relative;
860
+ text-align: right;
861
+ top: 10px;
862
+ }
863
+ .pmxe_plugin .back{
864
+ color: #21759B;
865
+ font-size: 20px;
866
+ position: relative;
867
+ top: 3px;
868
+ }
869
+ .pmxe_plugin .separated_by{
870
+ float: right;
871
+ font-size: 12px;
872
+ color: #999999;
873
+ margin-right: 20px;
874
+ }
875
+ .pmxe_plugin .delim > label{
876
+ color: #999999;
877
+ font-size: 11px;
878
+ }
879
+ .pmxe_plugin .optionsset > table{
880
+ border-bottom: 1px solid #CCCCCC;
881
+ margin-bottom: 20px;
882
+ width: 100%;
883
+ }
884
+ /* Log Bar - Step 5 */
885
+ .pmxe_plugin #logwrapper{
886
+ border: 1px solid #aaa;
887
+ margin-bottom: 20px;
888
+ }
889
+ .pmxe_plugin #logbar{
890
+ padding: 5px 0px;
891
+ text-align: center;
892
+ margin: 10px 0px;
893
+ border: 1px solid #aaa;
894
+ overflow: auto;
895
+ }
896
+ .pmxe_plugin .optionsset > table:last-child{
897
+ border: none;
898
+ }
899
+ .pmxe_plugin #download_log_separator, .pmxe_plugin #download_log{
900
+ display: none;
901
+ }
902
+ .pmxe_plugin #loglist{
903
+ border: 1px solid #AAAAAA;
904
+ height: 400px;
905
+ overflow: auto;
906
+ }
907
+ .pmxe_plugin #loglist > p{
908
+ margin: 0;
909
+ padding: 3px 5px;
910
+ }
911
+ .pmxe_plugin #loglist > p.odd{
912
+ background: #dfdfdf;
913
+ }
914
+ .pmxe_plugin #process_notice{
915
+ color: red;
916
+ text-align: center;
917
+ }
918
+ .pmxe_plugin .reimported_notify{
919
+ border: 1px solid #AFAFAF;
920
+ margin-bottom: 20px;
921
+ padding: 10px 20px;
922
+ }
923
+ .pmxe_plugin .reimported_notify p span{
924
+ color:#ccc;
925
+ }
926
+ .pmxe_plugin .action_buttons{
927
+ overflow: hidden;
928
+ clear: both;
929
+ padding-bottom: 10px;
930
+ }
931
+ /*.pmxe_plugin .action_buttons a{
932
+ border: 1px solid #BBBBBB;
933
+ -moz-border-radius: 3px;
934
+ -khtml-border-radius: 3px;
935
+ -webkit-border-radius: 3px;
936
+ border-radius: 3px;
937
+ color: #464646;
938
+ cursor: pointer;
939
+ font-size: 18px !important;
940
+ margin-right: 10px;
941
+ padding: 15px 25px;
942
+ text-decoration: none;
943
+ display: block;
944
+ width:25px;
945
+ float: left;
946
+ }
947
+ .pmxe_plugin .action_buttons a:hover{
948
+ background: #dfdfdf;
949
+ }*/
950
+ .pmxe_plugin #current_element{
951
+ color:green;
952
+ }
953
+ .pmxe_plugin #current_xml{ display: none;}
954
+ .pmxe_plugin #goto_element{
955
+ display: block;
956
+ float: left;
957
+ font-size: 18px;
958
+ height: 46px;
959
+ margin-right: 10px;
960
+ min-width: 70px;
961
+ padding-top: 5px;
962
+ text-align: center;
963
+ width: 70px !important;
964
+ }
965
+ .pmxe_plugin .choose-elements table tbody tr td{
966
+ overflow: hidden;
967
+ }
968
+ .pmxe_plugin #plupload-ui h3{
969
+ float: left;
970
+ font-size: 13px;
971
+ font-weight: normal;
972
+ margin-bottom: 0;
973
+ margin-top: 8px;
974
+ }
975
+ .pmxe_plugin #wp-content-media-buttons{
976
+ display: none;
977
+ }
978
+ .pmxe_plugin label{
979
+ /*-webkit-touch-callout: none;
980
+ -webkit-user-select: none;
981
+ -khtml-user-select: none;
982
+ -moz-user-select: none;
983
+ -ms-user-select: none;
984
+ user-select: none;*/
985
+ }
986
+ .pmxe_plugin .large_button{
987
+ /*margin-left: 10px;
988
+ padding: 15px 25px;
989
+ border: 1px solid #C5DBEC;*/
990
+ height: 40px;
991
+ line-height: 39px;
992
+ margin-left: 10px;
993
+ /*width: 90px;*/
994
+ }
995
+ .pmxe_plugin .drag-element .assign_post{
996
+ float: left;
997
+ margin-top: 2px;
998
+ }
999
+ .pmxe_plugin .drag-element .widefat{
1000
+ margin-left: 1%;
1001
+ width: 85%;
1002
+ }
1003
+ .pmxe_plugin .ui-tabs-hide{
1004
+ display: none !important;
1005
+ }
1006
+ .pmxe_plugin .auto_nested{
1007
+ float: left;
1008
+ margin-left: 3px;
1009
+ }
1010
+ .pmxe_plugin .existing_meta_values{
1011
+ clear: both;
1012
+ display: block;
1013
+ margin: 15px;
1014
+ }
1015
+ .pmxe_plugin .custom-params tr td{
1016
+ width: 50%;
1017
+ }
1018
+ .pmxe_plugin .custom-params tr td.action{
1019
+ width:100% !important;
1020
+ }
1021
+ .pmxe_plugin .load_options{
1022
+ height: 0;
1023
+ line-height: 0;
1024
+ margin: 0;
1025
+ padding: 0;
1026
+ position: relative;
1027
+ right: 10px;
1028
+ text-align: right;
1029
+ top: -35px;
1030
+ width: 100%;
1031
+ }
1032
+ .pmxe_plugin .form-field textarea{
1033
+ width:80%;
1034
+ }
1035
+
1036
+ /* Tabs */
1037
+ .pmxe_plugin .nav-tab-wrapper{
1038
+ display: none;
1039
+ }
1040
+ .pmxe_plugin h2.nav-tab-wrapper, h3.nav-tab-wrapper{
1041
+ margin-bottom: 10px;
1042
+ }
1043
+ .pmxe_plugin .nav-tab{
1044
+ margin-right: 0px !important;
1045
+ }
1046
+ .pmxe_plugin h2 .nav-tab{
1047
+ font-size: 18px !important;
1048
+ }
1049
+ .pmxe_plugin #set_encoding{
1050
+ line-height: 25px;
1051
+ position: relative;
1052
+ text-align: center;
1053
+ top: -10px;
1054
+ margin-top: -55px;
1055
+ }
1056
+ .pmxe_plugin #add_encoding{
1057
+ display: none;
1058
+ }
1059
+ .pmxe_plugin #new_encoding{
1060
+ border: 1px solid #BBBBBB;
1061
+ -moz-border-radius: 3px;
1062
+ -khtml-border-radius: 3px;
1063
+ -webkit-border-radius: 3px;
1064
+ border-radius: 3px;
1065
+ }
1066
+ .pmxe_plugin .options #set_encoding{
1067
+ display: none;
1068
+ }
1069
+ .pmxe_plugin .set_csv_delimiter > li{
1070
+ float: left;
1071
+ padding: 0 3px;
1072
+ }
1073
+ /*.pmxe_plugin .set_csv_delimiter > li a.delimiter_selected{
1074
+ font-weight: bold;
1075
+ text-decoration: underline;
1076
+ }
1077
+ .pmxe_plugin .set_csv_delimiter{
1078
+ float: left;
1079
+ padding-top: 3px;
1080
+ }*/
1081
+ .pmxe_plugin .set_csv_delimiter{
1082
+ padding-top: 5px;
1083
+ }
1084
+ .pmxe_plugin input[name="delimiter"]{
1085
+ display: block;
1086
+ float: left;
1087
+ width: 25px !important;
1088
+ height: 25px;
1089
+ min-width: 25px !important;
1090
+ position: relative;
1091
+ top:-5px;
1092
+ padding: 0 3px;
1093
+ text-align: center;
1094
+ }
1095
+ .pmxe_plugin input[name="apply_delimiter"]{
1096
+ border: 1px solid #BBBBBB;
1097
+ -moz-border-radius: 3px;
1098
+ -khtml-border-radius: 3px;
1099
+ -webkit-border-radius: 3px;
1100
+ border-radius: 3px;
1101
+ padding: 3px 5px;
1102
+ margin-left: 10px;
1103
+ position: relative;
1104
+ top:-4px;
1105
+ cursor: pointer;
1106
+ }
1107
+ .pmxe_plugin .go_to{
1108
+ float: left;
1109
+ font-size: 23px;
1110
+ line-height: 38px;
1111
+ text-align: center;
1112
+ }
1113
+ .pmxe_plugin .fix_checkbox{
1114
+ position: relative;
1115
+ margin: 0px !important;
1116
+ }
1117
+ .pmxe_plugin .newline{
1118
+ line-height: 16px;
1119
+ }
1120
+ .pmxe_plugin .button-primary:hover{
1121
+ font-weight: normal;
1122
+ }
1123
+ .pmxe_plugin .hndle{
1124
+ padding: 7px;
1125
+ margin-bottom: 0px;
1126
+ cursor: default !important;
1127
+ }
1128
+ .pmxe_plugin .inside{
1129
+ margin: 0;
1130
+ line-height: 20px;
1131
+ }
1132
+ .pmxe_plugin .inside input[type="text"]{
1133
+ background: #fff;
1134
+ }
1135
+ .pmxe_plugin .postbox{
1136
+ margin: 0;
1137
+ }
1138
+ .pmxe_plugin .txt_center{
1139
+ text-align: center;
1140
+ }
1141
+ .pmxe_plugin div.meta-options{
1142
+ padding: 10px 0px;
1143
+ }
1144
+ .pmxe_plugin input[name^="attribute_name"], .pmxe_plugin input[name^="variable_attribute_name"]{
1145
+ width: 95% !important;
1146
+ }
1147
+ .pmxe_plugin .widefat{
1148
+ background-color: #fff;
1149
+ border-color: #DFDFDF;
1150
+ }
1151
+ .pmxe_plugin #woocommerce-product-data{
1152
+ margin-bottom: 20px;
1153
+ }
1154
+ .pmxe_plugin .set_xpath{
1155
+ left: 0;
1156
+ padding-left: 15px;
1157
+ position: absolute;
1158
+ top: 0;
1159
+ }
1160
+ .pmxe_plugin .chosen-container-multi .chosen-choices li.search-field input[type="text"]{
1161
+ height: 25px !important;
1162
+ width: auto !important;
1163
+ }
1164
+ .pmxe_plugin .chosen-container-multi .chosen-choices{
1165
+ margin: 5px 0px !important;
1166
+ }
1167
+ .pmxe_plugin .pmxe_tips_pointer{
1168
+ position: absolute;
1169
+ right: 0;
1170
+ }
1171
+ .pmxe_plugin .wp-pointer-content{
1172
+ padding: 10px;
1173
+ }
1174
+ .pmxe_plugin .wp-pointer-content ul{
1175
+ margin-left: 20px;
1176
+ }
1177
+ .pmxe_plugin .processing_info{
1178
+ display: none;
1179
+ }
1180
+ .pmxe_plugin input[type="text"][name="tagno"]{
1181
+ margin-left: 5px;
1182
+ padding: 3px;
1183
+ width: 40px;
1184
+ border: 1px solid #BBBBBB;
1185
+ -moz-border-radius: 3px;
1186
+ -khtml-border-radius: 3px;
1187
+ -webkit-border-radius: 3px;
1188
+ border-radius: 3px;
1189
+ text-align: center;
1190
+ }
1191
+ #post-preview div.title{
1192
+ text-align:right;
1193
+ border-bottom: 2px solid #ccc;
1194
+ padding-bottom:5px;
1195
+ font-style:italic;
1196
+ }
1197
+ .pmxe_plugin .pl17{
1198
+ padding-left:17px;
1199
+ }
1200
+
1201
+ /*--------------------------------------------------------------------------
1202
+ *
1203
+ * Add-Ons
1204
+ *
1205
+ *-------------------------------------------------------------------------*/
1206
+
1207
+ .pmxe_plugin #pmxe-add-ons {
1208
+ margin-bottom: 20px;
1209
+ }
1210
+
1211
+ .pmxe_plugin .pmxe-add-on-group {
1212
+ margin-top: 20px;
1213
+ padding-top: 20px;
1214
+ border-top: #F5F5F5 solid 1px;
1215
+ }
1216
+
1217
+ .pmxe_plugin .pmxe-add-on-group:first-child {
1218
+ margin-top: 0;
1219
+ padding-top: 0;
1220
+ border-top: 0 none;
1221
+ }
1222
+
1223
+ .pmxe_plugin .pmxe-add-on {
1224
+ float: left;
1225
+ width: 220px;
1226
+ margin: 10px;
1227
+ }
1228
+
1229
+ .pmxe_plugin .pmxe-add-on h3 {
1230
+ margin-top: 0.5em;
1231
+ }
1232
+
1233
+ .pmxe_plugin .pmxe-add-on h3 a {
1234
+ color: inherit;
1235
+ text-decoration: none;
1236
+ }
1237
+
1238
+ .pmxe_plugin .pmxe-add-on .inner {
1239
+ min-height: 145px;
1240
+ }
1241
+
1242
+ .pmxe_plugin .pmxe-add-on-active .button {
1243
+ padding-left: 4px;
1244
+ }
1245
+
1246
+ .pmxe_plugin .pmxe-sprite-tick {
1247
+ width: 14px;
1248
+ height: 14px;
1249
+ margin: 4px 5px 0 0;
1250
+ background-position: 0px -300px;
1251
+ }
1252
+
1253
+ .pmxe_plugin .wp-box {
1254
+ background: none repeat scroll 0 0 #FFFFFF;
1255
+ border: 1px solid #E1E1E1;
1256
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
1257
+ position: relative;
1258
+ }
1259
+ .pmxe_plugin .wp-box .inner {
1260
+ padding: 15px;
1261
+ }
1262
+ .pmxe_plugin .wp-box .footer{
1263
+ background: none repeat scroll 0 0 #F5F5F5;
1264
+ border-top: 1px solid #E1E1E1;
1265
+ overflow: hidden;
1266
+ padding: 10px;
1267
+ position: absolute;
1268
+ bottom:0;
1269
+ width:91%;
1270
+ }
1271
+
1272
+ #pmxe-add-ons .pmxe-add-on-title {
1273
+ float: left;
1274
+ width: 100%;
1275
+ margin: 25px 0 25px;
1276
+ border-top: #F5F5F5 solid 1px;
1277
+ }
1278
+ .pmxe_plugin .form-table td{
1279
+ padding: 0px;
1280
+ }
1281
+ .pmxe_plugin #pmxe_value{
1282
+ display: inline-block;
1283
+ height: 28px;
1284
+ margin: 0;
1285
+ padding: 3px;
1286
+ position: relative;
1287
+ top: 2px;
1288
+ width: 50px;
1289
+ }
1290
+ .pmxe_plugin #pmxe_add_rule{
1291
+ display: block;
1292
+ float: right;
1293
+ margin: 5px;
1294
+ }
1295
+ .pmxe_plugin #filtering_rules{
1296
+ border: 1px solid;
1297
+ margin: 15px 0;
1298
+ position: relative;
1299
+ }
1300
+ .pmxe_plugin .filtering_rules li{
1301
+ position: relative;
1302
+ }
1303
+ .pmxe_plugin .filtering_rules li .condition{
1304
+ padding: 2px;
1305
+ display: block;
1306
+ }
1307
+ .pmxe_plugin .filtering_rules li .condition label{
1308
+ margin: 0px 3px;
1309
+ }
1310
+ .pmxe_plugin .pmxe_group_rule{
1311
+ margin-left: -55px;
1312
+ }
1313
+ .pmxe_plugin #apply_filters{
1314
+ float: right;
1315
+ }
1316
+ .pmxe_plugin .filtering_rules li strong{
1317
+ text-transform: uppercase;
1318
+ }
1319
+ .pmxe_plugin #pmxe_xml_element{
1320
+ width:180px;
1321
+ }
1322
+ .pmxe_plugin div.input label, .pmxe_plugin .form-field{
1323
+ font-size: 12px !important;
1324
+ }
1325
+ .pmxe_plugin input[type="radio"]{
1326
+ margin-left: 4px;
1327
+ }
1328
+ .pmxe_plugin .main_choise{
1329
+ float: left;
1330
+ margin-right: 5px;
1331
+ padding: 5px 0;
1332
+ }
static/img/add-ons/acf-thumb.jpg ADDED
Binary file
static/img/add-ons/woo-commerce-thumb.jpg ADDED
Binary file
static/img/date-picker.gif ADDED
Binary file
static/img/down.gif ADDED
Binary file
static/img/drag.png ADDED
Binary file
static/img/help.png ADDED
Binary file
static/img/ico-add-new.png ADDED
Binary file
static/img/ico-remove.png ADDED
Binary file
static/img/loading.png ADDED
Binary file
static/img/progress_animated.gif ADDED
Binary file
static/img/screen-options-right-up.gif ADDED
Binary file
static/img/screen-options-right.gif ADDED
Binary file
static/img/stars.png ADDED
Binary file
static/img/xmlicon.png ADDED
Binary file
static/js/admin.js ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * plugin admin area javascript
3
+ */
4
+ (function($){$(function () {
5
+ if ( ! $('body.pmxe_plugin').length) return; // do not execute any code if we are not on plugin page
6
+
7
+ // fix layout position
8
+ setTimeout(function () {
9
+ $('table.layout').length && $('table.layout td.left h2:first-child').css('margin-top', $('.wrap').offset().top - $('table.layout').offset().top);
10
+ }, 10);
11
+
12
+ // help icons
13
+ $('a.help').tipsy({
14
+ gravity: function() {
15
+ var ver = 'n';
16
+ if ($(document).scrollTop() < $(this).offset().top - $('.tipsy').height() - 2) {
17
+ ver = 's';
18
+ }
19
+ var hor = '';
20
+ if ($(this).offset().left + $('.tipsy').width() < $(window).width() + $(document).scrollLeft()) {
21
+ hor = 'w';
22
+ } else if ($(this).offset().left - $('.tipsy').width() > $(document).scrollLeft()) {
23
+ hor = 'e';
24
+ }
25
+ return ver + hor;
26
+ },
27
+ live: true,
28
+ html: true,
29
+ opacity: 1
30
+ }).live('click', function () {
31
+ return false;
32
+ }).each(function () { // fix tipsy title for IE
33
+ $(this).attr('original-title', $(this).attr('title'));
34
+ $(this).removeAttr('title');
35
+ });
36
+
37
+ // swither show/hide logic
38
+ $('input.switcher').live('change', function (e) {
39
+
40
+ if ($(this).is(':radio:checked')) {
41
+ $(this).parents('form').find('input.switcher:radio[name="' + $(this).attr('name') + '"]').not(this).change();
42
+ }
43
+ var $targets = $('.switcher-target-' + $(this).attr('id'));
44
+
45
+ var is_show = $(this).is(':checked'); if ($(this).is('.switcher-reversed')) is_show = ! is_show;
46
+ if (is_show) {
47
+ $targets.fadeIn();
48
+ } else {
49
+ $targets.hide().find('.clear-on-switch').add($targets.filter('.clear-on-switch')).val('');
50
+ }
51
+ }).change();
52
+
53
+ // autoselect input content on click
54
+ $('input.selectable').live('click', function () {
55
+ $(this).select();
56
+ });
57
+
58
+ // input tags with title
59
+ $('input[title]').each(function () {
60
+ var $this = $(this);
61
+ $this.bind('focus', function () {
62
+ if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
63
+ $(this).removeClass('note').val('');
64
+ }
65
+ }).bind('blur', function () {
66
+ if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
67
+ $(this).addClass('note').val($(this).attr('title'));
68
+ }
69
+ }).blur();
70
+ $this.parents('form').bind('submit', function () {
71
+ if ($this.val() == $this.attr('title')) {
72
+ $this.val('');
73
+ }
74
+ });
75
+ });
76
+
77
+ // datepicker
78
+ $('input.datepicker').datepicker({
79
+ dateFormat: 'yy-mm-dd',
80
+ showOn: 'button',
81
+ buttonText: '',
82
+ constrainInput: false,
83
+ showAnim: 'fadeIn',
84
+ showOptions: 'fast'
85
+ }).bind('change', function () {
86
+ var selectedDate = $(this).val();
87
+ var instance = $(this).data('datepicker');
88
+ var date = null;
89
+ if ('' != selectedDate) {
90
+ try {
91
+ date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
92
+ } catch (e) {
93
+ date = null;
94
+ }
95
+ }
96
+ if ($(this).hasClass('range-from')) {
97
+ $(this).parent().find('.datepicker.range-to').datepicker("option", "minDate", date);
98
+ }
99
+ if ($(this).hasClass('range-to')) {
100
+ $(this).parent().find('.datepicker.range-from').datepicker("option", "maxDate", date);
101
+ }
102
+ }).change();
103
+ $('.ui-datepicker').hide(); // fix: make sure datepicker doesn't break wordpress layout upon initialization
104
+
105
+ // no-enter-submit forms
106
+ $('form.no-enter-submit').find('input,select,textarea').not('*[type="submit"]').keydown(function (e) {
107
+ if (13 == e.keyCode) e.preventDefault();
108
+ });
109
+
110
+ // enter-submit form on step 1
111
+ if ($('.pmxe_step_1').length){
112
+ $('body').keydown(function (e) {
113
+ if (13 == e.keyCode){
114
+ $('form.choose-file').submit();
115
+ }
116
+ });
117
+ }
118
+
119
+ // choose file form: option selection dynamic
120
+ // options form: highlight options of selected post type
121
+ $('form.choose-post-type input[name="type"]').click(function() {
122
+ var $container = $(this).parents('.file-type-container');
123
+ $('.file-type-container').not($container).removeClass('selected').find('.file-type-options').hide();
124
+ $container.addClass('selected').find('.file-type-options').show();
125
+ }).filter(':checked').click();
126
+
127
+ // options form: add / remove custom params
128
+ $('.form-table a.action[href="#add"]').live('click', function () {
129
+ var $template = $(this).parents('table').first().find('tr.template');
130
+ $template.clone(true).insertBefore($template).css('display', 'none').removeClass('template').fadeIn();
131
+ return false;
132
+ });
133
+
134
+ $('.form-table .action.remove a').live('click', function () {
135
+ $(this).parents('tr').first().remove();
136
+ return false;
137
+ });
138
+
139
+ $('.pmxe_choosen').each(function(){
140
+ $(this).find(".choosen_input").select2({tags: $(this).find('.choosen_values').html().split(',')});
141
+ });
142
+
143
+ });})(jQuery);
static/js/jquery/css/redmond/images/animated-overlay.gif ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100_1.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png ADDED
Binary file
static/js/jquery/css/redmond/jquery-ui.css ADDED
@@ -0,0 +1,1177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.10.0 - 2013-02-06
2
+ * http://jqueryui.com
3
+ * Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande%2CLucida%20Sans%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=gloss_wave&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=inset_hard&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=glass&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=inset_hard&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=flat&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
5
+ * Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden {
10
+ display: none;
11
+ }
12
+ .ui-helper-hidden-accessible {
13
+ border: 0;
14
+ clip: rect(0 0 0 0);
15
+ height: 1px;
16
+ margin: -1px;
17
+ overflow: hidden;
18
+ padding: 0;
19
+ position: absolute;
20
+ width: 1px;
21
+ }
22
+ .ui-helper-reset {
23
+ margin: 0;
24
+ padding: 0;
25
+ border: 0;
26
+ outline: 0;
27
+ line-height: 1.3;
28
+ text-decoration: none;
29
+ font-size: 100%;
30
+ list-style: none;
31
+ }
32
+ .ui-helper-clearfix:before,
33
+ .ui-helper-clearfix:after {
34
+ content: "";
35
+ display: table;
36
+ }
37
+ .ui-helper-clearfix:after {
38
+ clear: both;
39
+ }
40
+ .ui-helper-clearfix {
41
+ min-height: 0; /* support: IE7 */
42
+ }
43
+ .ui-helper-zfix {
44
+ width: 100%;
45
+ height: 100%;
46
+ top: 0;
47
+ left: 0;
48
+ position: absolute;
49
+ opacity: 0;
50
+ filter:Alpha(Opacity=0);
51
+ }
52
+
53
+ .ui-front {
54
+ z-index: 100;
55
+ }
56
+
57
+
58
+ /* Interaction Cues
59
+ ----------------------------------*/
60
+ .ui-state-disabled {
61
+ cursor: default !important;
62
+ }
63
+
64
+
65
+ /* Icons
66
+ ----------------------------------*/
67
+
68
+ /* states and images */
69
+ .ui-icon {
70
+ display: block;
71
+ text-indent: -99999px;
72
+ overflow: hidden;
73
+ background-repeat: no-repeat;
74
+ }
75
+
76
+
77
+ /* Misc visuals
78
+ ----------------------------------*/
79
+
80
+ /* Overlays */
81
+ .ui-widget-overlay {
82
+ position: fixed;
83
+ top: 0;
84
+ left: 0;
85
+ width: 100%;
86
+ height: 100%;
87
+ }
88
+ .ui-resizable {
89
+ position: relative;
90
+ }
91
+ .ui-resizable-handle {
92
+ position: absolute;
93
+ font-size: 0.1px;
94
+ display: block;
95
+ }
96
+ .ui-resizable-disabled .ui-resizable-handle,
97
+ .ui-resizable-autohide .ui-resizable-handle {
98
+ display: none;
99
+ }
100
+ .ui-resizable-n {
101
+ cursor: n-resize;
102
+ height: 7px;
103
+ width: 100%;
104
+ top: -5px;
105
+ left: 0;
106
+ }
107
+ .ui-resizable-s {
108
+ cursor: s-resize;
109
+ height: 7px;
110
+ width: 100%;
111
+ bottom: -5px;
112
+ left: 0;
113
+ }
114
+ .ui-resizable-e {
115
+ cursor: e-resize;
116
+ width: 7px;
117
+ right: -5px;
118
+ top: 0;
119
+ height: 100%;
120
+ }
121
+ .ui-resizable-w {
122
+ cursor: w-resize;
123
+ width: 7px;
124
+ left: -5px;
125
+ top: 0;
126
+ height: 100%;
127
+ }
128
+ .ui-resizable-se {
129
+ cursor: se-resize;
130
+ width: 12px;
131
+ height: 12px;
132
+ right: 1px;
133
+ bottom: 1px;
134
+ }
135
+ .ui-resizable-sw {
136
+ cursor: sw-resize;
137
+ width: 9px;
138
+ height: 9px;
139
+ left: -5px;
140
+ bottom: -5px;
141
+ }
142
+ .ui-resizable-nw {
143
+ cursor: nw-resize;
144
+ width: 9px;
145
+ height: 9px;
146
+ left: -5px;
147
+ top: -5px;
148
+ }
149
+ .ui-resizable-ne {
150
+ cursor: ne-resize;
151
+ width: 9px;
152
+ height: 9px;
153
+ right: -5px;
154
+ top: -5px;
155
+ }
156
+ .ui-selectable-helper {
157
+ position: absolute;
158
+ z-index: 100;
159
+ border: 1px dotted black;
160
+ }
161
+ .ui-accordion .ui-accordion-header {
162
+ display: block;
163
+ cursor: pointer;
164
+ position: relative;
165
+ margin-top: 2px;
166
+ padding: .5em .5em .5em .7em;
167
+ min-height: 0; /* support: IE7 */
168
+ }
169
+ .ui-accordion .ui-accordion-icons {
170
+ padding-left: 2.2em;
171
+ }
172
+ .ui-accordion .ui-accordion-noicons {
173
+ padding-left: .7em;
174
+ }
175
+ .ui-accordion .ui-accordion-icons .ui-accordion-icons {
176
+ padding-left: 2.2em;
177
+ }
178
+ .ui-accordion .ui-accordion-header .ui-accordion-header-icon {
179
+ position: absolute;
180
+ left: .5em;
181
+ top: 50%;
182
+ margin-top: -8px;
183
+ }
184
+ .ui-accordion .ui-accordion-content {
185
+ padding: 1em 2.2em;
186
+ border-top: 0;
187
+ overflow: auto;
188
+ }
189
+ .ui-autocomplete {
190
+ position: absolute;
191
+ top: 0;
192
+ left: 0;
193
+ cursor: default;
194
+ }
195
+ .ui-button {
196
+ display: inline-block;
197
+ position: relative;
198
+ padding: 0;
199
+ line-height: normal;
200
+ margin-right: .1em;
201
+ cursor: pointer;
202
+ vertical-align: middle;
203
+ text-align: center;
204
+ overflow: visible; /* removes extra width in IE */
205
+ }
206
+ .ui-button,
207
+ .ui-button:visited,
208
+ .ui-button:hover,
209
+ .ui-button:active,
210
+ .large_button:hover {
211
+ background: url("images/ui-bg_glass_75_d0e5f5_1x400.png") repeat-x scroll 50% 50% #D0E5F5;
212
+ border: 1px solid #79B7E7;
213
+ color: #1D5987;
214
+ font-weight: bold;
215
+ }
216
+ /* to make room for the icon, a width needs to be set here */
217
+ .ui-button-icon-only {
218
+ width: 2.2em;
219
+ }
220
+ /* button elements seem to need a little more width */
221
+ button.ui-button-icon-only {
222
+ width: 2.4em;
223
+ }
224
+ .ui-button-icons-only {
225
+ width: 3.4em;
226
+ }
227
+ button.ui-button-icons-only {
228
+ width: 3.7em;
229
+ }
230
+
231
+ /* button text element */
232
+ .ui-button .ui-button-text {
233
+ display: block;
234
+ line-height: normal;
235
+ }
236
+ .ui-button-text-only .ui-button-text {
237
+ padding: .4em 1em;
238
+ }
239
+ .ui-button-icon-only .ui-button-text,
240
+ .ui-button-icons-only .ui-button-text {
241
+ padding: .4em;
242
+ text-indent: -9999999px;
243
+ }
244
+ .ui-button-text-icon-primary .ui-button-text,
245
+ .ui-button-text-icons .ui-button-text {
246
+ padding: .4em 1em .4em 2.1em;
247
+ }
248
+ .ui-button-text-icon-secondary .ui-button-text,
249
+ .ui-button-text-icons .ui-button-text {
250
+ padding: .4em 2.1em .4em 1em;
251
+ }
252
+ .ui-button-text-icons .ui-button-text {
253
+ padding-left: 2.1em;
254
+ padding-right: 2.1em;
255
+ }
256
+ /* no icon support for input elements, provide padding by default */
257
+ input.ui-button {
258
+ padding: .4em 1em;
259
+ }
260
+
261
+ /* button icon element(s) */
262
+ .ui-button-icon-only .ui-icon,
263
+ .ui-button-text-icon-primary .ui-icon,
264
+ .ui-button-text-icon-secondary .ui-icon,
265
+ .ui-button-text-icons .ui-icon,
266
+ .ui-button-icons-only .ui-icon {
267
+ position: absolute;
268
+ top: 50%;
269
+ margin-top: -8px;
270
+ }
271
+ .ui-button-icon-only .ui-icon {
272
+ left: 50%;
273
+ margin-left: -8px;
274
+ }
275
+ .ui-button-text-icon-primary .ui-button-icon-primary,
276
+ .ui-button-text-icons .ui-button-icon-primary,
277
+ .ui-button-icons-only .ui-button-icon-primary {
278
+ left: .5em;
279
+ }
280
+ .ui-button-text-icon-secondary .ui-button-icon-secondary,
281
+ .ui-button-text-icons .ui-button-icon-secondary,
282
+ .ui-button-icons-only .ui-button-icon-secondary {
283
+ right: .5em;
284
+ }
285
+
286
+ /* button sets */
287
+ .ui-buttonset {
288
+ margin-right: 7px;
289
+ }
290
+ .ui-buttonset .ui-button {
291
+ margin-left: 0;
292
+ margin-right: -.3em;
293
+ }
294
+
295
+ /* workarounds */
296
+ /* reset extra padding in Firefox, see h5bp.com/l */
297
+ input.ui-button::-moz-focus-inner,
298
+ button.ui-button::-moz-focus-inner {
299
+ border: 0;
300
+ padding: 0;
301
+ }
302
+ .ui-datepicker {
303
+ width: 17em;
304
+ padding: .2em .2em 0;
305
+ display: none;
306
+ }
307
+ .ui-datepicker .ui-datepicker-header {
308
+ position: relative;
309
+ padding: .2em 0;
310
+ }
311
+ .ui-datepicker .ui-datepicker-prev,
312
+ .ui-datepicker .ui-datepicker-next {
313
+ position: absolute;
314
+ top: 2px;
315
+ width: 1.8em;
316
+ height: 1.8em;
317
+ }
318
+ .ui-datepicker .ui-datepicker-prev-hover,
319
+ .ui-datepicker .ui-datepicker-next-hover {
320
+ top: 1px;
321
+ }
322
+ .ui-datepicker .ui-datepicker-prev {
323
+ left: 2px;
324
+ }
325
+ .ui-datepicker .ui-datepicker-next {
326
+ right: 2px;
327
+ }
328
+ .ui-datepicker .ui-datepicker-prev-hover {
329
+ left: 1px;
330
+ }
331
+ .ui-datepicker .ui-datepicker-next-hover {
332
+ right: 1px;
333
+ }
334
+ .ui-datepicker .ui-datepicker-prev span,
335
+ .ui-datepicker .ui-datepicker-next span {
336
+ display: block;
337
+ position: absolute;
338
+ left: 50%;
339
+ margin-left: -8px;
340
+ top: 50%;
341
+ margin-top: -8px;
342
+ }
343
+ .ui-datepicker .ui-datepicker-title {
344
+ margin: 0 2.3em;
345
+ line-height: 1.8em;
346
+ text-align: center;
347
+ }
348
+ .ui-datepicker .ui-datepicker-title select {
349
+ font-size: 1em;
350
+ margin: 1px 0;
351
+ }
352
+ .ui-datepicker select.ui-datepicker-month-year {
353
+ width: 100%;
354
+ }
355
+ .ui-datepicker select.ui-datepicker-month,
356
+ .ui-datepicker select.ui-datepicker-year {
357
+ width: 49%;
358
+ }
359
+ .ui-datepicker table {
360
+ width: 100%;
361
+ font-size: .9em;
362
+ border-collapse: collapse;
363
+ margin: 0 0 .4em;
364
+ }
365
+ .ui-datepicker th {
366
+ padding: .7em .3em;
367
+ text-align: center;
368
+ font-weight: bold;
369
+ border: 0;
370
+ }
371
+ .ui-datepicker td {
372
+ border: 0;
373
+ padding: 1px;
374
+ }
375
+ .ui-datepicker td span,
376
+ .ui-datepicker td a {
377
+ display: block;
378
+ padding: .2em;
379
+ text-align: right;
380
+ text-decoration: none;
381
+ }
382
+ .ui-datepicker .ui-datepicker-buttonpane {
383
+ background-image: none;
384
+ margin: .7em 0 0 0;
385
+ padding: 0 .2em;
386
+ border-left: 0;
387
+ border-right: 0;
388
+ border-bottom: 0;
389
+ }
390
+ .ui-datepicker .ui-datepicker-buttonpane button {
391
+ float: right;
392
+ margin: .5em .2em .4em;
393
+ cursor: pointer;
394
+ padding: .2em .6em .3em .6em;
395
+ width: auto;
396
+ overflow: visible;
397
+ }
398
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
399
+ float: left;
400
+ }
401
+
402
+ /* with multiple calendars */
403
+ .ui-datepicker.ui-datepicker-multi {
404
+ width: auto;
405
+ }
406
+ .ui-datepicker-multi .ui-datepicker-group {
407
+ float: left;
408
+ }
409
+ .ui-datepicker-multi .ui-datepicker-group table {
410
+ width: 95%;
411
+ margin: 0 auto .4em;
412
+ }
413
+ .ui-datepicker-multi-2 .ui-datepicker-group {
414
+ width: 50%;
415
+ }
416
+ .ui-datepicker-multi-3 .ui-datepicker-group {
417
+ width: 33.3%;
418
+ }
419
+ .ui-datepicker-multi-4 .ui-datepicker-group {
420
+ width: 25%;
421
+ }
422
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
423
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
424
+ border-left-width: 0;
425
+ }
426
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
427
+ clear: left;
428
+ }
429
+ .ui-datepicker-row-break {
430
+ clear: both;
431
+ width: 100%;
432
+ font-size: 0;
433
+ }
434
+
435
+ /* RTL support */
436
+ .ui-datepicker-rtl {
437
+ direction: rtl;
438
+ }
439
+ .ui-datepicker-rtl .ui-datepicker-prev {
440
+ right: 2px;
441
+ left: auto;
442
+ }
443
+ .ui-datepicker-rtl .ui-datepicker-next {
444
+ left: 2px;
445
+ right: auto;
446
+ }
447
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
448
+ right: 1px;
449
+ left: auto;
450
+ }
451
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
452
+ left: 1px;
453
+ right: auto;
454
+ }
455
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
456
+ clear: right;
457
+ }
458
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
459
+ float: left;
460
+ }
461
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
462
+ .ui-datepicker-rtl .ui-datepicker-group {
463
+ float: right;
464
+ }
465
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
466
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
467
+ border-right-width: 0;
468
+ border-left-width: 1px;
469
+ }
470
+ .ui-dialog {
471
+ position: absolute;
472
+ top: 0;
473
+ left: 0;
474
+ padding: .2em;
475
+ outline: 0;
476
+ }
477
+ .ui-dialog .ui-dialog-titlebar {
478
+ padding: .4em 1em;
479
+ position: relative;
480
+ }
481
+ .ui-dialog .ui-dialog-title {
482
+ float: left;
483
+ margin: .1em 0;
484
+ white-space: nowrap;
485
+ width: 90%;
486
+ overflow: hidden;
487
+ text-overflow: ellipsis;
488
+ }
489
+ .ui-dialog .ui-dialog-titlebar-close {
490
+ position: absolute;
491
+ right: .3em;
492
+ top: 50%;
493
+ width: 21px;
494
+ margin: -10px 0 0 0;
495
+ padding: 1px;
496
+ height: 20px;
497
+ }
498
+ .ui-dialog .ui-dialog-content {
499
+ position: relative;
500
+ border: 0;
501
+ padding: .5em 1em;
502
+ background: none;
503
+ overflow: auto;
504
+ }
505
+ .ui-dialog .ui-dialog-buttonpane {
506
+ text-align: left;
507
+ border-width: 1px 0 0 0;
508
+ background-image: none;
509
+ margin-top: .5em;
510
+ padding: .3em 1em .5em .4em;
511
+ }
512
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
513
+ float: right;
514
+ }
515
+ .ui-dialog .ui-dialog-buttonpane button {
516
+ margin: .5em .4em .5em 0;
517
+ cursor: pointer;
518
+ }
519
+ .ui-dialog .ui-resizable-se {
520
+ width: 12px;
521
+ height: 12px;
522
+ right: -5px;
523
+ bottom: -5px;
524
+ background-position: 16px 16px;
525
+ }
526
+ .ui-draggable .ui-dialog-titlebar {
527
+ cursor: move;
528
+ }
529
+ .ui-menu {
530
+ list-style: none;
531
+ padding: 2px;
532
+ margin: 0;
533
+ display: block;
534
+ outline: none;
535
+ }
536
+ .ui-menu .ui-menu {
537
+ margin-top: -3px;
538
+ position: absolute;
539
+ }
540
+ .ui-menu .ui-menu-item {
541
+ margin: 0;
542
+ padding: 0;
543
+ width: 100%;
544
+ }
545
+ .ui-menu .ui-menu-divider {
546
+ margin: 5px -2px 5px -2px;
547
+ height: 0;
548
+ font-size: 0;
549
+ line-height: 0;
550
+ border-width: 1px 0 0 0;
551
+ }
552
+ .ui-menu .ui-menu-item a {
553
+ text-decoration: none;
554
+ display: block;
555
+ padding: 2px .4em;
556
+ line-height: 1.5;
557
+ min-height: 0; /* support: IE7 */
558
+ font-weight: normal;
559
+ }
560
+ .ui-menu .ui-menu-item a.ui-state-focus,
561
+ .ui-menu .ui-menu-item a.ui-state-active {
562
+ font-weight: normal;
563
+ margin: -1px;
564
+ }
565
+
566
+ .ui-menu .ui-state-disabled {
567
+ font-weight: normal;
568
+ margin: .4em 0 .2em;
569
+ line-height: 1.5;
570
+ }
571
+ .ui-menu .ui-state-disabled a {
572
+ cursor: default;
573
+ }
574
+
575
+ /* icon support */
576
+ .ui-menu-icons {
577
+ position: relative;
578
+ }
579
+ .ui-menu-icons .ui-menu-item a {
580
+ position: relative;
581
+ padding-left: 2em;
582
+ }
583
+
584
+ /* left-aligned */
585
+ .ui-menu .ui-icon {
586
+ position: absolute;
587
+ top: .2em;
588
+ left: .2em;
589
+ }
590
+
591
+ /* right-aligned */
592
+ .ui-menu .ui-menu-icon {
593
+ position: static;
594
+ float: right;
595
+ }
596
+ .ui-progressbar {
597
+ height: 2em;
598
+ text-align: left;
599
+ overflow: hidden;
600
+ }
601
+ .ui-progressbar .ui-progressbar-value {
602
+ margin: -1px;
603
+ height: 100%;
604
+ }
605
+ .ui-progressbar .ui-progressbar-overlay {
606
+ background: url("images/animated-overlay.gif");
607
+ height: 100%;
608
+ filter: alpha(opacity=25);
609
+ opacity: 0.25;
610
+ }
611
+ .ui-progressbar-indeterminate .ui-progressbar-value {
612
+ background-image: none;
613
+ }
614
+ .ui-slider {
615
+ position: relative;
616
+ text-align: left;
617
+ }
618
+ .ui-slider .ui-slider-handle {
619
+ position: absolute;
620
+ z-index: 2;
621
+ width: 1.2em;
622
+ height: 1.2em;
623
+ cursor: default;
624
+ }
625
+ .ui-slider .ui-slider-range {
626
+ position: absolute;
627
+ z-index: 1;
628
+ font-size: .7em;
629
+ display: block;
630
+ border: 0;
631
+ background-position: 0 0;
632
+ }
633
+
634
+ /* For IE8 - See #6727 */
635
+ .ui-slider.ui-state-disabled .ui-slider-handle,
636
+ .ui-slider.ui-state-disabled .ui-slider-range {
637
+ filter: inherit;
638
+ }
639
+
640
+ .ui-slider-horizontal {
641
+ height: .8em;
642
+ }
643
+ .ui-slider-horizontal .ui-slider-handle {
644
+ top: -.3em;
645
+ margin-left: -.6em;
646
+ }
647
+ .ui-slider-horizontal .ui-slider-range {
648
+ top: 0;
649
+ height: 100%;
650
+ }
651
+ .ui-slider-horizontal .ui-slider-range-min {
652
+ left: 0;
653
+ }
654
+ .ui-slider-horizontal .ui-slider-range-max {
655
+ right: 0;
656
+ }
657
+
658
+ .ui-slider-vertical {
659
+ width: .8em;
660
+ height: 100px;
661
+ }
662
+ .ui-slider-vertical .ui-slider-handle {
663
+ left: -.3em;
664
+ margin-left: 0;
665
+ margin-bottom: -.6em;
666
+ }
667
+ .ui-slider-vertical .ui-slider-range {
668
+ left: 0;
669
+ width: 100%;
670
+ }
671
+ .ui-slider-vertical .ui-slider-range-min {
672
+ bottom: 0;
673
+ }
674
+ .ui-slider-vertical .ui-slider-range-max {
675
+ top: 0;
676
+ }
677
+ .ui-spinner {
678
+ position: relative;
679
+ display: inline-block;
680
+ overflow: hidden;
681
+ padding: 0;
682
+ vertical-align: middle;
683
+ }
684
+ .ui-spinner-input {
685
+ border: none;
686
+ background: none;
687
+ color: inherit;
688
+ padding: 0;
689
+ margin: .2em 0;
690
+ vertical-align: middle;
691
+ margin-left: .4em;
692
+ margin-right: 22px;
693
+ }
694
+ .ui-spinner-button {
695
+ width: 16px;
696
+ height: 50%;
697
+ font-size: .5em;
698
+ padding: 0;
699
+ margin: 0;
700
+ text-align: center;
701
+ position: absolute;
702
+ cursor: default;
703
+ display: block;
704
+ overflow: hidden;
705
+ right: 0;
706
+ }
707
+ /* more specificity required here to overide default borders */
708
+ .ui-spinner a.ui-spinner-button {
709
+ border-top: none;
710
+ border-bottom: none;
711
+ border-right: none;
712
+ }
713
+ /* vertical centre icon */
714
+ .ui-spinner .ui-icon {
715
+ position: absolute;
716
+ margin-top: -8px;
717
+ top: 50%;
718
+ left: 0;
719
+ }
720
+ .ui-spinner-up {
721
+ top: 0;
722
+ }
723
+ .ui-spinner-down {
724
+ bottom: 0;
725
+ }
726
+
727
+ /* TR overrides */
728
+ .ui-spinner .ui-icon-triangle-1-s {
729
+ /* need to fix icons sprite */
730
+ background-position: -65px -16px;
731
+ }
732
+ .ui-tabs {
733
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
734
+ padding: .2em;
735
+ }
736
+ .ui-tabs .ui-tabs-nav {
737
+ margin: 0;
738
+ padding: .2em .2em 0;
739
+ }
740
+ .ui-tabs .ui-tabs-nav li {
741
+ list-style: none;
742
+ float: left;
743
+ position: relative;
744
+ top: 0;
745
+ margin: 1px .2em 0 0;
746
+ border-bottom: 0;
747
+ padding: 0;
748
+ white-space: nowrap;
749
+ }
750
+ .ui-tabs .ui-tabs-nav li a {
751
+ float: left;
752
+ padding: .5em 1em;
753
+ text-decoration: none;
754
+ }
755
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active {
756
+ margin-bottom: -1px;
757
+ padding-bottom: 1px;
758
+ }
759
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active a,
760
+ .ui-tabs .ui-tabs-nav li.ui-state-disabled a,
761
+ .ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
762
+ cursor: text;
763
+ }
764
+ .ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
765
+ .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
766
+ cursor: pointer;
767
+ }
768
+ .ui-tabs .ui-tabs-panel {
769
+ display: block;
770
+ border-width: 0;
771
+ padding: 1em 1.4em;
772
+ background: none;
773
+ }
774
+ .ui-tooltip {
775
+ padding: 8px;
776
+ position: absolute;
777
+ z-index: 9999;
778
+ max-width: 300px;
779
+ -webkit-box-shadow: 0 0 5px #aaa;
780
+ box-shadow: 0 0 5px #aaa;
781
+ }
782
+ body .ui-tooltip {
783
+ border-width: 2px;
784
+ }
785
+
786
+ /* Component containers
787
+ ----------------------------------*/
788
+ .ui-widget {
789
+ font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
790
+ font-size: 1.1em;
791
+ }
792
+ .ui-widget .ui-widget {
793
+ font-size: 1em;
794
+ }
795
+ .ui-widget input,
796
+ .ui-widget select,
797
+ .ui-widget textarea,
798
+ .ui-widget button {
799
+ font-family: Lucida Grande,Lucida Sans,Arial,sans-serif;
800
+ font-size: 1em;
801
+ }
802
+ .ui-widget-content {
803
+ border: 1px solid #a6c9e2;
804
+ background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x;
805
+ color: #222222;
806
+ }
807
+ .ui-widget-content a {
808
+ color: #222222;
809
+ }
810
+ .ui-widget-header {
811
+ border: 1px solid #4297d7;
812
+ background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x;
813
+ color: #ffffff;
814
+ font-weight: bold;
815
+ }
816
+ .ui-widget-header a {
817
+ color: #ffffff;
818
+ }
819
+
820
+ /* Interaction states
821
+ ----------------------------------*/
822
+ .ui-state-default,
823
+ .ui-widget-content .ui-state-default,
824
+ .ui-widget-header .ui-state-default {
825
+ border: 1px solid #c5dbec;
826
+ background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x;
827
+ font-weight: bold;
828
+ color: #2e6e9e;
829
+ }
830
+ .ui-state-default a,
831
+ .ui-state-default a:link,
832
+ .ui-state-default a:visited {
833
+ color: #2e6e9e;
834
+ text-decoration: none;
835
+ }
836
+ .ui-state-hover,
837
+ .ui-widget-content .ui-state-hover,
838
+ .ui-widget-header .ui-state-hover,
839
+ .ui-state-focus,
840
+ .ui-widget-content .ui-state-focus,
841
+ .ui-widget-header .ui-state-focus {
842
+ border: 1px solid #79b7e7;
843
+ background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x;
844
+ font-weight: bold;
845
+ color: #1d5987;
846
+ }
847
+ .ui-state-hover a,
848
+ .ui-state-hover a:hover,
849
+ .ui-state-hover a:link,
850
+ .ui-state-hover a:visited {
851
+ color: #1d5987;
852
+ text-decoration: none;
853
+ }
854
+ .ui-state-active,
855
+ .ui-widget-content .ui-state-active,
856
+ .ui-widget-header .ui-state-active {
857
+ border: 1px solid #79b7e7;
858
+ background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x;
859
+ font-weight: bold;
860
+ color: #e17009;
861
+ }
862
+ .ui-state-active a,
863
+ .ui-state-active a:link,
864
+ .ui-state-active a:visited {
865
+ color: #e17009;
866
+ text-decoration: none;
867
+ }
868
+
869
+ /* Interaction Cues
870
+ ----------------------------------*/
871
+ .ui-state-highlight,
872
+ .ui-widget-content .ui-state-highlight,
873
+ .ui-widget-header .ui-state-highlight {
874
+ border: 1px solid #fad42e;
875
+ background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x;
876
+ color: #363636;
877
+ }
878
+ .ui-state-highlight a,
879
+ .ui-widget-content .ui-state-highlight a,
880
+ .ui-widget-header .ui-state-highlight a {
881
+ color: #363636;
882
+ }
883
+ .ui-state-error,
884
+ .ui-widget-content .ui-state-error,
885
+ .ui-widget-header .ui-state-error {
886
+ border: 1px solid #cd0a0a;
887
+ background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;
888
+ color: #cd0a0a;
889
+ }
890
+ .ui-state-error a,
891
+ .ui-widget-content .ui-state-error a,
892
+ .ui-widget-header .ui-state-error a {
893
+ color: #cd0a0a;
894
+ }
895
+ .ui-state-error-text,
896
+ .ui-widget-content .ui-state-error-text,
897
+ .ui-widget-header .ui-state-error-text {
898
+ color: #cd0a0a;
899
+ }
900
+ .ui-priority-primary,
901
+ .ui-widget-content .ui-priority-primary,
902
+ .ui-widget-header .ui-priority-primary {
903
+ font-weight: bold;
904
+ }
905
+ .ui-priority-secondary,
906
+ .ui-widget-content .ui-priority-secondary,
907
+ .ui-widget-header .ui-priority-secondary {
908
+ opacity: .7;
909
+ filter:Alpha(Opacity=70);
910
+ font-weight: normal;
911
+ }
912
+ .ui-state-disabled,
913
+ .ui-widget-content .ui-state-disabled,
914
+ .ui-widget-header .ui-state-disabled {
915
+ opacity: .35;
916
+ filter:Alpha(Opacity=35);
917
+ background-image: none;
918
+ }
919
+ .ui-state-disabled .ui-icon {
920
+ filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
921
+ }
922
+
923
+ /* Icons
924
+ ----------------------------------*/
925
+
926
+ /* states and images */
927
+ .ui-icon {
928
+ width: 16px;
929
+ height: 16px;
930
+ background-position: 16px 16px;
931
+ }
932
+ .ui-icon,
933
+ .ui-widget-content .ui-icon {
934
+ background-image: url(images/ui-icons_469bdd_256x240.png);
935
+ }
936
+ .ui-widget-header .ui-icon {
937
+ background-image: url(images/ui-icons_d8e7f3_256x240.png);
938
+ }
939
+ .ui-state-default .ui-icon {
940
+ background-image: url(images/ui-icons_6da8d5_256x240.png);
941
+ }
942
+ .ui-state-hover .ui-icon,
943
+ .ui-state-focus .ui-icon {
944
+ background-image: url(images/ui-icons_217bc0_256x240.png);
945
+ }
946
+ .ui-state-active .ui-icon {
947
+ background-image: url(images/ui-icons_f9bd01_256x240.png);
948
+ }
949
+ .ui-state-highlight .ui-icon {
950
+ background-image: url(images/ui-icons_2e83ff_256x240.png);
951
+ }
952
+ .ui-state-error .ui-icon,
953
+ .ui-state-error-text .ui-icon {
954
+ background-image: url(images/ui-icons_cd0a0a_256x240.png);
955
+ }
956
+
957
+ /* positioning */
958
+ .ui-icon-carat-1-n { background-position: 0 0; }
959
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
960
+ .ui-icon-carat-1-e { background-position: -32px 0; }
961
+ .ui-icon-carat-1-se { background-position: -48px 0; }
962
+ .ui-icon-carat-1-s { background-position: -64px 0; }
963
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
964
+ .ui-icon-carat-1-w { background-position: -96px 0; }
965
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
966
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
967
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
968
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
969
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
970
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
971
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
972
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
973
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
974
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
975
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
976
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
977
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
978
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
979
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
980
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
981
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
982
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
983
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
984
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
985
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
986
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
987
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
988
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
989
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
990
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
991
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
992
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
993
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
994
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
995
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
996
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
997
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
998
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
999
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1000
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1001
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1002
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1003
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1004
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1005
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1006
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1007
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1008
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1009
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1010
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1011
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1012
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1013
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1014
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1015
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1016
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1017
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1018
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1019
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1020
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1021
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1022
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
1023
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1024
+ .ui-icon-extlink { background-position: -32px -80px; }
1025
+ .ui-icon-newwin { background-position: -48px -80px; }
1026
+ .ui-icon-refresh { background-position: -64px -80px; }
1027
+ .ui-icon-shuffle { background-position: -80px -80px; }
1028
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
1029
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1030
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
1031
+ .ui-icon-folder-open { background-position: -16px -96px; }
1032
+ .ui-icon-document { background-position: -32px -96px; }
1033
+ .ui-icon-document-b { background-position: -48px -96px; }
1034
+ .ui-icon-note { background-position: -64px -96px; }
1035
+ .ui-icon-mail-closed { background-position: -80px -96px; }
1036
+ .ui-icon-mail-open { background-position: -96px -96px; }
1037
+ .ui-icon-suitcase { background-position: -112px -96px; }
1038
+ .ui-icon-comment { background-position: -128px -96px; }
1039
+ .ui-icon-person { background-position: -144px -96px; }
1040
+ .ui-icon-print { background-position: -160px -96px; }
1041
+ .ui-icon-trash { background-position: -176px -96px; }
1042
+ .ui-icon-locked { background-position: -192px -96px; }
1043
+ .ui-icon-unlocked { background-position: -208px -96px; }
1044
+ .ui-icon-bookmark { background-position: -224px -96px; }
1045
+ .ui-icon-tag { background-position: -240px -96px; }
1046
+ .ui-icon-home { background-position: 0 -112px; }
1047
+ .ui-icon-flag { background-position: -16px -112px; }
1048
+ .ui-icon-calendar { background-position: -32px -112px; }
1049
+ .ui-icon-cart { background-position: -48px -112px; }
1050
+ .ui-icon-pencil { background-position: -64px -112px; }
1051
+ .ui-icon-clock { background-position: -80px -112px; }
1052
+ .ui-icon-disk { background-position: -96px -112px; }
1053
+ .ui-icon-calculator { background-position: -112px -112px; }
1054
+ .ui-icon-zoomin { background-position: -128px -112px; }
1055
+ .ui-icon-zoomout { background-position: -144px -112px; }
1056
+ .ui-icon-search { background-position: -160px -112px; }
1057
+ .ui-icon-wrench { background-position: -176px -112px; }
1058
+ .ui-icon-gear { background-position: -192px -112px; }
1059
+ .ui-icon-heart { background-position: -208px -112px; }
1060
+ .ui-icon-star { background-position: -224px -112px; }
1061
+ .ui-icon-link { background-position: -240px -112px; }
1062
+ .ui-icon-cancel { background-position: 0 -128px; }
1063
+ .ui-icon-plus { background-position: -16px -128px; }
1064
+ .ui-icon-plusthick { background-position: -32px -128px; }
1065
+ .ui-icon-minus { background-position: -48px -128px; }
1066
+ .ui-icon-minusthick { background-position: -64px -128px; }
1067
+ .ui-icon-close { background-position: -80px -128px; }
1068
+ .ui-icon-closethick { background-position: -96px -128px; }
1069
+ .ui-icon-key { background-position: -112px -128px; }
1070
+ .ui-icon-lightbulb { background-position: -128px -128px; }
1071
+ .ui-icon-scissors { background-position: -144px -128px; }
1072
+ .ui-icon-clipboard { background-position: -160px -128px; }
1073
+ .ui-icon-copy { background-position: -176px -128px; }
1074
+ .ui-icon-contact { background-position: -192px -128px; }
1075
+ .ui-icon-image { background-position: -208px -128px; }
1076
+ .ui-icon-video { background-position: -224px -128px; }
1077
+ .ui-icon-script { background-position: -240px -128px; }
1078
+ .ui-icon-alert { background-position: 0 -144px; }
1079
+ .ui-icon-info { background-position: -16px -144px; }
1080
+ .ui-icon-notice { background-position: -32px -144px; }
1081
+ .ui-icon-help { background-position: -48px -144px; }
1082
+ .ui-icon-check { background-position: -64px -144px; }
1083
+ .ui-icon-bullet { background-position: -80px -144px; }
1084
+ .ui-icon-radio-on { background-position: -96px -144px; }
1085
+ .ui-icon-radio-off { background-position: -112px -144px; }
1086
+ .ui-icon-pin-w { background-position: -128px -144px; }
1087
+ .ui-icon-pin-s { background-position: -144px -144px; }
1088
+ .ui-icon-play { background-position: 0 -160px; }
1089
+ .ui-icon-pause { background-position: -16px -160px; }
1090
+ .ui-icon-seek-next { background-position: -32px -160px; }
1091
+ .ui-icon-seek-prev { background-position: -48px -160px; }
1092
+ .ui-icon-seek-end { background-position: -64px -160px; }
1093
+ .ui-icon-seek-start { background-position: -80px -160px; }
1094
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1095
+ .ui-icon-seek-first { background-position: -80px -160px; }
1096
+ .ui-icon-stop { background-position: -96px -160px; }
1097
+ .ui-icon-eject { background-position: -112px -160px; }
1098
+ .ui-icon-volume-off { background-position: -128px -160px; }
1099
+ .ui-icon-volume-on { background-position: -144px -160px; }
1100
+ .ui-icon-power { background-position: 0 -176px; }
1101
+ .ui-icon-signal-diag { background-position: -16px -176px; }
1102
+ .ui-icon-signal { background-position: -32px -176px; }
1103
+ .ui-icon-battery-0 { background-position: -48px -176px; }
1104
+ .ui-icon-battery-1 { background-position: -64px -176px; }
1105
+ .ui-icon-battery-2 { background-position: -80px -176px; }
1106
+ .ui-icon-battery-3 { background-position: -96px -176px; }
1107
+ .ui-icon-circle-plus { background-position: 0 -192px; }
1108
+ .ui-icon-circle-minus { background-position: -16px -192px; }
1109
+ .ui-icon-circle-close { background-position: -32px -192px; }
1110
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1111
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1112
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1113
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1114
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1115
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1116
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1117
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1118
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
1119
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
1120
+ .ui-icon-circle-check { background-position: -208px -192px; }
1121
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1122
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1123
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
1124
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1125
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1126
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
1127
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1128
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1129
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1130
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1131
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1132
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1133
+
1134
+
1135
+ /* Misc visuals
1136
+ ----------------------------------*/
1137
+
1138
+ /* Corner radius */
1139
+ .ui-corner-all,
1140
+ .ui-corner-top,
1141
+ .ui-corner-left,
1142
+ .ui-corner-tl {
1143
+ border-top-left-radius: 5px;
1144
+ }
1145
+ .ui-corner-all,
1146
+ .ui-corner-top,
1147
+ .ui-corner-right,
1148
+ .ui-corner-tr {
1149
+ border-top-right-radius: 5px;
1150
+ }
1151
+ .ui-corner-all,
1152
+ .ui-corner-bottom,
1153
+ .ui-corner-left,
1154
+ .ui-corner-bl {
1155
+ border-bottom-left-radius: 5px;
1156
+ }
1157
+ .ui-corner-all,
1158
+ .ui-corner-bottom,
1159
+ .ui-corner-right,
1160
+ .ui-corner-br {
1161
+ border-bottom-right-radius: 5px;
1162
+ }
1163
+
1164
+ /* Overlays */
1165
+ .ui-widget-overlay {
1166
+ background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
1167
+ opacity: .3;
1168
+ filter: Alpha(Opacity=30);
1169
+ }
1170
+ .ui-widget-shadow {
1171
+ margin: -8px 0 0 -8px;
1172
+ padding: 8px;
1173
+ background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;
1174
+ opacity: .3;
1175
+ filter: Alpha(Opacity=30);
1176
+ border-radius: 8px;
1177
+ }
static/js/jquery/css/select2/select2-bootstrap.css ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .form-control .select2-choice {
2
+ border: 0;
3
+ border-radius: 2px;
4
+ }
5
+
6
+ .form-control .select2-choice .select2-arrow {
7
+ border-radius: 0 2px 2px 0;
8
+ }
9
+
10
+ .form-control.select2-container {
11
+ height: auto !important;
12
+ padding: 0px;
13
+ }
14
+
15
+ .form-control.select2-container.select2-dropdown-open {
16
+ border-color: #5897FB;
17
+ border-radius: 3px 3px 0 0;
18
+ }
19
+
20
+ .form-control .select2-container.select2-dropdown-open .select2-choices {
21
+ border-radius: 3px 3px 0 0;
22
+ }
23
+
24
+ .form-control.select2-container .select2-choices {
25
+ border: 0 !important;
26
+ border-radius: 3px;
27
+ }
28
+
29
+ .control-group.warning .select2-container .select2-choice,
30
+ .control-group.warning .select2-container .select2-choices,
31
+ .control-group.warning .select2-container-active .select2-choice,
32
+ .control-group.warning .select2-container-active .select2-choices,
33
+ .control-group.warning .select2-dropdown-open.select2-drop-above .select2-choice,
34
+ .control-group.warning .select2-dropdown-open.select2-drop-above .select2-choices,
35
+ .control-group.warning .select2-container-multi.select2-container-active .select2-choices {
36
+ border: 1px solid #C09853 !important;
37
+ }
38
+
39
+ .control-group.warning .select2-container .select2-choice div {
40
+ border-left: 1px solid #C09853 !important;
41
+ background: #FCF8E3 !important;
42
+ }
43
+
44
+ .control-group.error .select2-container .select2-choice,
45
+ .control-group.error .select2-container .select2-choices,
46
+ .control-group.error .select2-container-active .select2-choice,
47
+ .control-group.error .select2-container-active .select2-choices,
48
+ .control-group.error .select2-dropdown-open.select2-drop-above .select2-choice,
49
+ .control-group.error .select2-dropdown-open.select2-drop-above .select2-choices,
50
+ .control-group.error .select2-container-multi.select2-container-active .select2-choices {
51
+ border: 1px solid #B94A48 !important;
52
+ }
53
+
54
+ .control-group.error .select2-container .select2-choice div {
55
+ border-left: 1px solid #B94A48 !important;
56
+ background: #F2DEDE !important;
57
+ }
58
+
59
+ .control-group.info .select2-container .select2-choice,
60
+ .control-group.info .select2-container .select2-choices,
61
+ .control-group.info .select2-container-active .select2-choice,
62
+ .control-group.info .select2-container-active .select2-choices,
63
+ .control-group.info .select2-dropdown-open.select2-drop-above .select2-choice,
64
+ .control-group.info .select2-dropdown-open.select2-drop-above .select2-choices,
65
+ .control-group.info .select2-container-multi.select2-container-active .select2-choices {
66
+ border: 1px solid #3A87AD !important;
67
+ }
68
+
69
+ .control-group.info .select2-container .select2-choice div {
70
+ border-left: 1px solid #3A87AD !important;
71
+ background: #D9EDF7 !important;
72
+ }
73
+
74
+ .control-group.success .select2-container .select2-choice,
75
+ .control-group.success .select2-container .select2-choices,
76
+ .control-group.success .select2-container-active .select2-choice,
77
+ .control-group.success .select2-container-active .select2-choices,
78
+ .control-group.success .select2-dropdown-open.select2-drop-above .select2-choice,
79
+ .control-group.success .select2-dropdown-open.select2-drop-above .select2-choices,
80
+ .control-group.success .select2-container-multi.select2-container-active .select2-choices {
81
+ border: 1px solid #468847 !important;
82
+ }
83
+
84
+ .control-group.success .select2-container .select2-choice div {
85
+ border-left: 1px solid #468847 !important;
86
+ background: #DFF0D8 !important;
87
+ }
static/js/jquery/css/select2/select2-spinner.gif ADDED
Binary file
static/js/jquery/css/select2/select2.css ADDED
@@ -0,0 +1,617 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Version: 3.4.5 Timestamp: Mon Nov 4 08:22:42 PST 2013
3
+ */
4
+ .select2-container {
5
+ margin: 0;
6
+ position: relative;
7
+ display: inline-block;
8
+ /* inline-block for ie7 */
9
+ zoom: 1;
10
+ *display: inline;
11
+ vertical-align: middle;
12
+ width:100%;
13
+ }
14
+
15
+ .select2-container,
16
+ .select2-drop,
17
+ .select2-search,
18
+ .select2-search input {
19
+ /*
20
+ Force border-box so that % widths fit the parent
21
+ container without overlap because of margin/padding.
22
+
23
+ More Info : http://www.quirksmode.org/css/box.html
24
+ */
25
+ -webkit-box-sizing: border-box; /* webkit */
26
+ -moz-box-sizing: border-box; /* firefox */
27
+ box-sizing: border-box; /* css3 */
28
+ }
29
+
30
+ .select2-container .select2-choice {
31
+ display: block;
32
+ height: 26px;
33
+ padding: 0 0 0 8px;
34
+ overflow: hidden;
35
+ position: relative;
36
+
37
+ border: 1px solid #aaa;
38
+ white-space: nowrap;
39
+ line-height: 26px;
40
+ color: #444;
41
+ text-decoration: none;
42
+
43
+ border-radius: 4px;
44
+
45
+ background-clip: padding-box;
46
+
47
+ -webkit-touch-callout: none;
48
+ -webkit-user-select: none;
49
+ -moz-user-select: none;
50
+ -ms-user-select: none;
51
+ user-select: none;
52
+
53
+ background-color: #fff;
54
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
55
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
56
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
57
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
58
+ background-image: linear-gradient(top, #fff 0%, #eee 50%);
59
+ }
60
+
61
+ .select2-container.select2-drop-above .select2-choice {
62
+ border-bottom-color: #aaa;
63
+
64
+ border-radius: 0 0 4px 4px;
65
+
66
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
67
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
68
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
69
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
70
+ background-image: linear-gradient(top, #eee 0%, #fff 90%);
71
+ }
72
+
73
+ .select2-container.select2-allowclear .select2-choice .select2-chosen {
74
+ margin-right: 42px;
75
+ }
76
+
77
+ .select2-container .select2-choice > .select2-chosen {
78
+ margin-right: 26px;
79
+ display: block;
80
+ overflow: hidden;
81
+
82
+ white-space: nowrap;
83
+
84
+ text-overflow: ellipsis;
85
+ }
86
+
87
+ .select2-container .select2-choice abbr {
88
+ display: none;
89
+ width: 12px;
90
+ height: 12px;
91
+ position: absolute;
92
+ right: 24px;
93
+ top: 8px;
94
+
95
+ font-size: 1px;
96
+ text-decoration: none;
97
+
98
+ border: 0;
99
+ background: url('select2.png') right top no-repeat;
100
+ cursor: pointer;
101
+ outline: 0;
102
+ }
103
+
104
+ .select2-container.select2-allowclear .select2-choice abbr {
105
+ display: inline-block;
106
+ }
107
+
108
+ .select2-container .select2-choice abbr:hover {
109
+ background-position: right -11px;
110
+ cursor: pointer;
111
+ }
112
+
113
+ .select2-drop-mask {
114
+ border: 0;
115
+ margin: 0;
116
+ padding: 0;
117
+ position: fixed;
118
+ left: 0;
119
+ top: 0;
120
+ min-height: 100%;
121
+ min-width: 100%;
122
+ height: auto;
123
+ width: auto;
124
+ opacity: 0;
125
+ z-index: 9998;
126
+ /* styles required for IE to work */
127
+ background-color: #fff;
128
+ filter: alpha(opacity=0);
129
+ }
130
+
131
+ .select2-drop {
132
+ width: 100%;
133
+ margin-top: -1px;
134
+ position: absolute;
135
+ z-index: 9999;
136
+ top: 100%;
137
+
138
+ background: #fff;
139
+ color: #000;
140
+ border: 1px solid #aaa;
141
+ border-top: 0;
142
+
143
+ border-radius: 0 0 4px 4px;
144
+
145
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
146
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
147
+ }
148
+
149
+ .select2-drop-auto-width {
150
+ border-top: 1px solid #aaa;
151
+ width: auto;
152
+ }
153
+
154
+ .select2-drop-auto-width .select2-search {
155
+ padding-top: 4px;
156
+ }
157
+
158
+ .select2-drop.select2-drop-above {
159
+ margin-top: 1px;
160
+ border-top: 1px solid #aaa;
161
+ border-bottom: 0;
162
+
163
+ border-radius: 4px 4px 0 0;
164
+
165
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
166
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
167
+ }
168
+
169
+ .select2-drop-active {
170
+ border: 1px solid #5897fb;
171
+ border-top: none;
172
+ }
173
+
174
+ .select2-drop.select2-drop-above.select2-drop-active {
175
+ border-top: 1px solid #5897fb;
176
+ }
177
+
178
+ .select2-container .select2-choice .select2-arrow {
179
+ display: inline-block;
180
+ width: 18px;
181
+ height: 100%;
182
+ position: absolute;
183
+ right: 0;
184
+ top: 0;
185
+
186
+ border-left: 1px solid #aaa;
187
+ border-radius: 0 4px 4px 0;
188
+
189
+ background-clip: padding-box;
190
+
191
+ background: #ccc;
192
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
193
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
194
+ background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
195
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
196
+ background-image: linear-gradient(top, #ccc 0%, #eee 60%);
197
+ }
198
+
199
+ .select2-container .select2-choice .select2-arrow b {
200
+ display: block;
201
+ width: 100%;
202
+ height: 100%;
203
+ background: url('select2.png') no-repeat 0 1px;
204
+ }
205
+
206
+ .select2-search {
207
+ display: inline-block;
208
+ width: 100%;
209
+ min-height: 26px;
210
+ margin: 0;
211
+ padding-left: 4px;
212
+ padding-right: 4px;
213
+
214
+ position: relative;
215
+ z-index: 10000;
216
+
217
+ white-space: nowrap;
218
+ }
219
+
220
+ .select2-search input {
221
+ width: 100%;
222
+ height: auto !important;
223
+ min-height: 26px;
224
+ padding: 4px 20px 4px 5px;
225
+ margin: 0;
226
+
227
+ outline: 0;
228
+ font-family: sans-serif;
229
+ font-size: 1em;
230
+
231
+ border: 1px solid #aaa;
232
+ border-radius: 0;
233
+
234
+ -webkit-box-shadow: none;
235
+ box-shadow: none;
236
+
237
+ background: #fff url('select2.png') no-repeat 100% -22px;
238
+ background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
239
+ background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
240
+ background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
241
+ background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #fff 85%, #eee 99%);
242
+ }
243
+
244
+ .select2-drop.select2-drop-above .select2-search input {
245
+ margin-top: 4px;
246
+ }
247
+
248
+ .select2-search input.select2-active {
249
+ background: #fff url('select2-spinner.gif') no-repeat 100%;
250
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
251
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
252
+ background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
253
+ background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(top, #fff 85%, #eee 99%);
254
+ }
255
+
256
+ .select2-container-active .select2-choice,
257
+ .select2-container-active .select2-choices {
258
+ border: 1px solid #5897fb;
259
+ outline: none;
260
+
261
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
262
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
263
+ }
264
+
265
+ .select2-dropdown-open .select2-choice {
266
+ border-bottom-color: transparent;
267
+ -webkit-box-shadow: 0 1px 0 #fff inset;
268
+ box-shadow: 0 1px 0 #fff inset;
269
+
270
+ border-bottom-left-radius: 0;
271
+ border-bottom-right-radius: 0;
272
+
273
+ background-color: #eee;
274
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
275
+ background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
276
+ background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
277
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
278
+ background-image: linear-gradient(top, #fff 0%, #eee 50%);
279
+ }
280
+
281
+ .select2-dropdown-open.select2-drop-above .select2-choice,
282
+ .select2-dropdown-open.select2-drop-above .select2-choices {
283
+ border: 1px solid #5897fb;
284
+ border-top-color: transparent;
285
+
286
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
287
+ background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
288
+ background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
289
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
290
+ background-image: linear-gradient(bottom, #fff 0%, #eee 50%);
291
+ }
292
+
293
+ .select2-dropdown-open .select2-choice .select2-arrow {
294
+ background: transparent;
295
+ border-left: none;
296
+ filter: none;
297
+ }
298
+ .select2-dropdown-open .select2-choice .select2-arrow b {
299
+ background-position: -18px 1px;
300
+ }
301
+
302
+ /* results */
303
+ .select2-results {
304
+ max-height: 200px;
305
+ padding: 0 0 0 4px;
306
+ margin: 4px 4px 4px 0;
307
+ position: relative;
308
+ overflow-x: hidden;
309
+ overflow-y: auto;
310
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
311
+ }
312
+
313
+ .select2-results ul.select2-result-sub {
314
+ margin: 0;
315
+ padding-left: 0;
316
+ }
317
+
318
+ .select2-results ul.select2-result-sub > li .select2-result-label { padding-left: 20px }
319
+ .select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 40px }
320
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 60px }
321
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 80px }
322
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 100px }
323
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 110px }
324
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label { padding-left: 120px }
325
+
326
+ .select2-results li {
327
+ list-style: none;
328
+ display: list-item;
329
+ background-image: none;
330
+ }
331
+
332
+ .select2-results li.select2-result-with-children > .select2-result-label {
333
+ font-weight: bold;
334
+ }
335
+
336
+ .select2-results .select2-result-label {
337
+ padding: 3px 7px 4px;
338
+ margin: 0;
339
+ cursor: pointer;
340
+
341
+ min-height: 1em;
342
+
343
+ -webkit-touch-callout: none;
344
+ -webkit-user-select: none;
345
+ -moz-user-select: none;
346
+ -ms-user-select: none;
347
+ user-select: none;
348
+ }
349
+
350
+ .select2-results .select2-highlighted {
351
+ background: #3875d7;
352
+ color: #fff;
353
+ }
354
+
355
+ .select2-results li em {
356
+ background: #feffde;
357
+ font-style: normal;
358
+ }
359
+
360
+ .select2-results .select2-highlighted em {
361
+ background: transparent;
362
+ }
363
+
364
+ .select2-results .select2-highlighted ul {
365
+ background: #fff;
366
+ color: #000;
367
+ }
368
+
369
+
370
+ .select2-results .select2-no-results,
371
+ .select2-results .select2-searching,
372
+ .select2-results .select2-selection-limit {
373
+ background: #f4f4f4;
374
+ display: list-item;
375
+ }
376
+
377
+ /*
378
+ disabled look for disabled choices in the results dropdown
379
+ */
380
+ .select2-results .select2-disabled.select2-highlighted {
381
+ color: #666;
382
+ background: #f4f4f4;
383
+ display: list-item;
384
+ cursor: default;
385
+ }
386
+ .select2-results .select2-disabled {
387
+ background: #f4f4f4;
388
+ display: list-item;
389
+ cursor: default;
390
+ }
391
+
392
+ .select2-results .select2-selected {
393
+ display: none;
394
+ }
395
+
396
+ .select2-more-results.select2-active {
397
+ background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
398
+ }
399
+
400
+ .select2-more-results {
401
+ background: #f4f4f4;
402
+ display: list-item;
403
+ }
404
+
405
+ /* disabled styles */
406
+
407
+ .select2-container.select2-container-disabled .select2-choice {
408
+ background-color: #f4f4f4;
409
+ background-image: none;
410
+ border: 1px solid #ddd;
411
+ cursor: default;
412
+ }
413
+
414
+ .select2-container.select2-container-disabled .select2-choice .select2-arrow {
415
+ background-color: #f4f4f4;
416
+ background-image: none;
417
+ border-left: 0;
418
+ }
419
+
420
+ .select2-container.select2-container-disabled .select2-choice abbr {
421
+ display: none;
422
+ }
423
+
424
+
425
+ /* multiselect */
426
+
427
+ .select2-container-multi .select2-choices {
428
+ height: auto !important;
429
+ height: 1%;
430
+ margin: 3px 0px;
431
+ padding: 5px;
432
+ position: relative;
433
+
434
+ border: 1px solid #aaa;
435
+ cursor: text;
436
+ overflow: hidden;
437
+
438
+ background-color: #fff;
439
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
440
+ background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
441
+ background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
442
+ background-image: linear-gradient(top, #eee 1%, #fff 15%);
443
+ }
444
+
445
+ .select2-locked {
446
+ padding: 3px 5px 3px 5px !important;
447
+ }
448
+
449
+ .select2-container-multi .select2-choices {
450
+ min-height: 26px;
451
+ }
452
+
453
+ .select2-container-multi.select2-container-active .select2-choices {
454
+ border: 1px solid #5897fb;
455
+ outline: none;
456
+
457
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
458
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
459
+ }
460
+ .select2-container-multi .select2-choices li {
461
+ float: left;
462
+ list-style: none;
463
+ }
464
+ .select2-container-multi .select2-choices .select2-search-field {
465
+ margin: 0;
466
+ padding: 0;
467
+ white-space: nowrap;
468
+ }
469
+
470
+ .select2-container-multi .select2-choices .select2-search-field input {
471
+ padding: 5px;
472
+ margin: 1px 0;
473
+
474
+ font-family: sans-serif;
475
+ font-size: 100%;
476
+ color: #666;
477
+ outline: 0;
478
+ border: 0;
479
+ -webkit-box-shadow: none;
480
+ box-shadow: none;
481
+ background: transparent !important;
482
+ border:none !important;
483
+ }
484
+
485
+ .select2-container-multi .select2-choices .select2-search-field input.select2-active {
486
+ background: #fff url('select2-spinner.gif') no-repeat 100% !important;
487
+ }
488
+
489
+ .select2-default {
490
+ color: #999 !important;
491
+ }
492
+
493
+ .select2-container-multi .select2-choices .select2-search-choice {
494
+ padding: 3px 5px 3px 18px;
495
+ margin: 3px 0 3px 5px;
496
+ position: relative;
497
+
498
+ line-height: 13px;
499
+ color: #333;
500
+ cursor: default;
501
+ border: 1px solid #aaaaaa;
502
+
503
+ border-radius: 3px;
504
+
505
+ -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
506
+ box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
507
+
508
+ background-clip: padding-box;
509
+
510
+ -webkit-touch-callout: none;
511
+ -webkit-user-select: none;
512
+ -moz-user-select: none;
513
+ -ms-user-select: none;
514
+ user-select: none;
515
+
516
+ background-color: #e4e4e4;
517
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
518
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
519
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
520
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
521
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
522
+ }
523
+ .select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
524
+ cursor: default;
525
+ }
526
+ .select2-container-multi .select2-choices .select2-search-choice-focus {
527
+ background: #d4d4d4;
528
+ }
529
+
530
+ .select2-search-choice-close {
531
+ display: block;
532
+ width: 12px;
533
+ height: 13px;
534
+ position: absolute;
535
+ right: 3px;
536
+ top: 4px;
537
+
538
+ font-size: 1px;
539
+ outline: none;
540
+ background: url('select2.png') right top no-repeat;
541
+ }
542
+
543
+ .select2-container-multi .select2-search-choice-close {
544
+ left: 3px;
545
+ }
546
+
547
+ .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
548
+ background-position: right -11px;
549
+ }
550
+ .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
551
+ background-position: right -11px;
552
+ }
553
+
554
+ /* disabled styles */
555
+ .select2-container-multi.select2-container-disabled .select2-choices {
556
+ background-color: #f4f4f4;
557
+ background-image: none;
558
+ border: 1px solid #ddd;
559
+ cursor: default;
560
+ }
561
+
562
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
563
+ padding: 3px 5px 3px 5px;
564
+ border: 1px solid #ddd;
565
+ background-image: none;
566
+ background-color: #f4f4f4;
567
+ }
568
+
569
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
570
+ background: none;
571
+ }
572
+ /* end multiselect */
573
+
574
+
575
+ .select2-result-selectable .select2-match,
576
+ .select2-result-unselectable .select2-match {
577
+ text-decoration: underline;
578
+ }
579
+
580
+ .select2-offscreen, .select2-offscreen:focus {
581
+ clip: rect(0 0 0 0) !important;
582
+ width: 1px !important;
583
+ height: 1px !important;
584
+ border: 0 !important;
585
+ margin: 0 !important;
586
+ padding: 0 !important;
587
+ overflow: hidden !important;
588
+ position: absolute !important;
589
+ outline: 0 !important;
590
+ left: 0px !important;
591
+ top: 0px !important;
592
+ }
593
+
594
+ .select2-display-none {
595
+ display: none;
596
+ }
597
+
598
+ .select2-measure-scrollbar {
599
+ position: absolute;
600
+ top: -10000px;
601
+ left: -10000px;
602
+ width: 100px;
603
+ height: 100px;
604
+ overflow: scroll;
605
+ }
606
+ /* Retina-ize icons */
607
+
608
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) {
609
+ .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice .select2-arrow b {
610
+ background-image: url('select2x2.png') !important;
611
+ background-repeat: no-repeat !important;
612
+ background-size: 60px 40px !important;
613
+ }
614
+ .select2-search input {
615
+ background-position: 100% -21px !important;
616
+ }
617
+ }
static/js/jquery/css/select2/select2.png ADDED
Binary file
static/js/jquery/css/smoothness/images/tipsy.gif ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-icons_222222_256x240.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-icons_454545_256x240.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-icons_888888_256x240.png ADDED
Binary file
static/js/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png ADDED
Binary file
static/js/jquery/css/smoothness/jquery-ui.css ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI CSS Framework
3
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
4
+ * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
5
+ */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden { display: none; }
10
+ .ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
11
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
12
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
13
+ .ui-helper-clearfix { display: inline-block; }
14
+ /* required comment for clearfix to work in Opera \*/
15
+ * html .ui-helper-clearfix { height:1%; }
16
+ .ui-helper-clearfix { display:block; }
17
+ /* end clearfix */
18
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
19
+
20
+
21
+ /* Interaction Cues
22
+ ----------------------------------*/
23
+ .ui-state-disabled { cursor: default !important; }
24
+
25
+
26
+ /* Icons
27
+ ----------------------------------*/
28
+
29
+ /* states and images */
30
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
31
+
32
+
33
+ /* Misc visuals
34
+ ----------------------------------*/
35
+
36
+ /* Overlays */
37
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
38
+
39
+ /*
40
+ * jQuery UI CSS Framework
41
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
42
+ * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
43
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
44
+ */
45
+
46
+
47
+ /* Component containers
48
+ ----------------------------------*/
49
+ .ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 0.85em; }
50
+ .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
51
+ .ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
52
+ .ui-widget-content a { color: #222222; }
53
+ .ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
54
+ .ui-widget-header a { color: #222222; }
55
+
56
+ /* Interaction states
57
+ ----------------------------------*/
58
+ .ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; outline: none; }
59
+ .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; outline: none; }
60
+ .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
61
+ .ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; outline: none; }
62
+ .ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; outline: none; }
63
+ .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; outline: none; text-decoration: none; }
64
+
65
+ /* Interaction Cues
66
+ ----------------------------------*/
67
+ .ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
68
+ .ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; }
69
+ .ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
70
+ .ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; }
71
+ .ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; }
72
+ .ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
73
+ .ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
74
+ .ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
75
+
76
+ /* Icons
77
+ ----------------------------------*/
78
+
79
+ /* states and images */
80
+ .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
81
+ .ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
82
+ .ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }
83
+ .ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
84
+ .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
85
+ .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
86
+ .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
87
+ .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
88
+
89
+ /* positioning */
90
+ .ui-icon-carat-1-n { background-position: 0 0; }
91
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
92
+ .ui-icon-carat-1-e { background-position: -32px 0; }
93
+ .ui-icon-carat-1-se { background-position: -48px 0; }
94
+ .ui-icon-carat-1-s { background-position: -64px 0; }
95
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
96
+ .ui-icon-carat-1-w { background-position: -96px 0; }
97
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
98
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
99
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
100
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
101
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
102
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
103
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
104
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
105
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
106
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
107
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
108
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
109
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
110
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
111
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
112
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
113
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
114
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
115
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
116
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
117
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
118
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
119
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
120
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
121
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
122
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
123
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
124
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
125
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
126
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
127
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
128
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
129
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
130
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
131
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
132
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
133
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
134
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
135
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
136
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
137
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
138
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
139
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
140
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
141
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
142
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
143
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
144
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
145
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
146
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
147
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
148
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
149
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
150
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
151
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
152
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
153
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
154
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
155
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
156
+ .ui-icon-extlink { background-position: -32px -80px; }
157
+ .ui-icon-newwin { background-position: -48px -80px; }
158
+ .ui-icon-refresh { background-position: -64px -80px; }
159
+ .ui-icon-shuffle { background-position: -80px -80px; }
160
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
161
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
162
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
163
+ .ui-icon-folder-open { background-position: -16px -96px; }
164
+ .ui-icon-document { background-position: -32px -96px; }
165
+ .ui-icon-document-b { background-position: -48px -96px; }
166
+ .ui-icon-note { background-position: -64px -96px; }
167
+ .ui-icon-mail-closed { background-position: -80px -96px; }
168
+ .ui-icon-mail-open { background-position: -96px -96px; }
169
+ .ui-icon-suitcase { background-position: -112px -96px; }
170
+ .ui-icon-comment { background-position: -128px -96px; }
171
+ .ui-icon-person { background-position: -144px -96px; }
172
+ .ui-icon-print { background-position: -160px -96px; }
173
+ .ui-icon-trash { background-position: -176px -96px; }
174
+ .ui-icon-locked { background-position: -192px -96px; }
175
+ .ui-icon-unlocked { background-position: -208px -96px; }
176
+ .ui-icon-bookmark { background-position: -224px -96px; }
177
+ .ui-icon-tag { background-position: -240px -96px; }
178
+ .ui-icon-home { background-position: 0 -112px; }
179
+ .ui-icon-flag { background-position: -16px -112px; }
180
+ .ui-icon-calendar { background-position: -32px -112px; }
181
+ .ui-icon-cart { background-position: -48px -112px; }
182
+ .ui-icon-pencil { background-position: -64px -112px; }
183
+ .ui-icon-clock { background-position: -80px -112px; }
184
+ .ui-icon-disk { background-position: -96px -112px; }
185
+ .ui-icon-calculator { background-position: -112px -112px; }
186
+ .ui-icon-zoomin { background-position: -128px -112px; }
187
+ .ui-icon-zoomout { background-position: -144px -112px; }
188
+ .ui-icon-search { background-position: -160px -112px; }
189
+ .ui-icon-wrench { background-position: -176px -112px; }
190
+ .ui-icon-gear { background-position: -192px -112px; }
191
+ .ui-icon-heart { background-position: -208px -112px; }
192
+ .ui-icon-star { background-position: -224px -112px; }
193
+ .ui-icon-link { background-position: -240px -112px; }
194
+ .ui-icon-cancel { background-position: 0 -128px; }
195
+ .ui-icon-plus { background-position: -16px -128px; }
196
+ .ui-icon-plusthick { background-position: -32px -128px; }
197
+ .ui-icon-minus { background-position: -48px -128px; }
198
+ .ui-icon-minusthick { background-position: -64px -128px; }
199
+ .ui-icon-close { background-position: -80px -128px; }
200
+ .ui-icon-closethick { background-position: -96px -128px; }
201
+ .ui-icon-key { background-position: -112px -128px; }
202
+ .ui-icon-lightbulb { background-position: -128px -128px; }
203
+ .ui-icon-scissors { background-position: -144px -128px; }
204
+ .ui-icon-clipboard { background-position: -160px -128px; }
205
+ .ui-icon-copy { background-position: -176px -128px; }
206
+ .ui-icon-contact { background-position: -192px -128px; }
207
+ .ui-icon-image { background-position: -208px -128px; }
208
+ .ui-icon-video { background-position: -224px -128px; }
209
+ .ui-icon-script { background-position: -240px -128px; }
210
+ .ui-icon-alert { background-position: 0 -144px; }
211
+ .ui-icon-info { background-position: -16px -144px; }
212
+ .ui-icon-notice { background-position: -32px -144px; }
213
+ .ui-icon-help { background-position: -48px -144px; }
214
+ .ui-icon-check { background-position: -64px -144px; }
215
+ .ui-icon-bullet { background-position: -80px -144px; }
216
+ .ui-icon-radio-off { background-position: -96px -144px; }
217
+ .ui-icon-radio-on { background-position: -112px -144px; }
218
+ .ui-icon-pin-w { background-position: -128px -144px; }
219
+ .ui-icon-pin-s { background-position: -144px -144px; }
220
+ .ui-icon-play { background-position: 0 -160px; }
221
+ .ui-icon-pause { background-position: -16px -160px; }
222
+ .ui-icon-seek-next { background-position: -32px -160px; }
223
+ .ui-icon-seek-prev { background-position: -48px -160px; }
224
+ .ui-icon-seek-end { background-position: -64px -160px; }
225
+ .ui-icon-seek-first { background-position: -80px -160px; }
226
+ .ui-icon-stop { background-position: -96px -160px; }
227
+ .ui-icon-eject { background-position: -112px -160px; }
228
+ .ui-icon-volume-off { background-position: -128px -160px; }
229
+ .ui-icon-volume-on { background-position: -144px -160px; }
230
+ .ui-icon-power { background-position: 0 -176px; }
231
+ .ui-icon-signal-diag { background-position: -16px -176px; }
232
+ .ui-icon-signal { background-position: -32px -176px; }
233
+ .ui-icon-battery-0 { background-position: -48px -176px; }
234
+ .ui-icon-battery-1 { background-position: -64px -176px; }
235
+ .ui-icon-battery-2 { background-position: -80px -176px; }
236
+ .ui-icon-battery-3 { background-position: -96px -176px; }
237
+ .ui-icon-circle-plus { background-position: 0 -192px; }
238
+ .ui-icon-circle-minus { background-position: -16px -192px; }
239
+ .ui-icon-circle-close { background-position: -32px -192px; }
240
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
241
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
242
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
243
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
244
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
245
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
246
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
247
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
248
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
249
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
250
+ .ui-icon-circle-check { background-position: -208px -192px; }
251
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
252
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
253
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
254
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
255
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
256
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
257
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
258
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
259
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
260
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
261
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
262
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
263
+
264
+
265
+ /* Misc visuals
266
+ ----------------------------------*/
267
+
268
+ /* Corner radius */
269
+ .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
270
+ .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
271
+ .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
272
+ .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
273
+ .ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
274
+ .ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
275
+ .ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
276
+ .ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
277
+ .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
278
+
279
+ /* Overlays */
280
+ .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
281
+ .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Resizable
282
+ ----------------------------------*/
283
+ .ui-resizable { position: relative;}
284
+ .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
285
+ .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
286
+ .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; }
287
+ .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; }
288
+ .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; }
289
+ .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; }
290
+ .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
291
+ .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
292
+ .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
293
+ .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Accordion
294
+ ----------------------------------*/
295
+ .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
296
+ .ui-accordion .ui-accordion-li-fix { display: inline; }
297
+ .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
298
+ .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; }
299
+ .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
300
+ .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; }
301
+ .ui-accordion .ui-accordion-content-active { display: block; }/* Dialog
302
+ ----------------------------------*/
303
+ .ui-dialog { position: relative; padding: .2em; width: 300px; }
304
+ .ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; }
305
+ .ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; }
306
+ .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
307
+ .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
308
+ .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
309
+ .ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
310
+ .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
311
+ .ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
312
+ .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
313
+ .ui-draggable .ui-dialog-titlebar { cursor: move; }
314
+ /* Slider
315
+ ----------------------------------*/
316
+ .ui-slider { position: relative; text-align: left; }
317
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
318
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; }
319
+
320
+ .ui-slider-horizontal { height: .8em; }
321
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
322
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
323
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
324
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
325
+
326
+ .ui-slider-vertical { width: .8em; height: 100px; }
327
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
328
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
329
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
330
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs
331
+ ----------------------------------*/
332
+ .ui-tabs { padding: .2em; zoom: 1; }
333
+ .ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
334
+ .ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
335
+ .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
336
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
337
+ .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
338
+ .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
339
+ .ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
340
+ .ui-tabs .ui-tabs-hide { display: none !important; }
341
+ /* Datepicker
342
+ ----------------------------------*/
343
+ .ui-datepicker { width: 17em; padding: .2em .2em 0; }
344
+ .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
345
+ .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
346
+ .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
347
+ .ui-datepicker .ui-datepicker-prev { left:2px; }
348
+ .ui-datepicker .ui-datepicker-next { right:2px; }
349
+ .ui-datepicker .ui-datepicker-prev-hover { left:1px; }
350
+ .ui-datepicker .ui-datepicker-next-hover { right:1px; }
351
+ .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
352
+ .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
353
+ .ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; }
354
+ .ui-datepicker select.ui-datepicker-month-year {width: 100%;}
355
+ .ui-datepicker select.ui-datepicker-month,
356
+ .ui-datepicker select.ui-datepicker-year { width: 49%;}
357
+ .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; }
358
+ .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
359
+ .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
360
+ .ui-datepicker td { border: 0; padding: 1px; }
361
+ .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
362
+ .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
363
+ .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
364
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
365
+
366
+ /* with multiple calendars */
367
+ .ui-datepicker.ui-datepicker-multi { width:auto; }
368
+ .ui-datepicker-multi .ui-datepicker-group { float:left; }
369
+ .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
370
+ .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
371
+ .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
372
+ .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
373
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
374
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
375
+ .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
376
+ .ui-datepicker-row-break { clear:both; width:100%; }
377
+
378
+ /* RTL support */
379
+ .ui-datepicker-rtl { direction: rtl; }
380
+ .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
381
+ .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
382
+ .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
383
+ .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
384
+ .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
385
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
386
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
387
+ .ui-datepicker-rtl .ui-datepicker-group { float:right; }
388
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
389
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
390
+
391
+ /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
392
+ .ui-datepicker-cover {
393
+ display: none; /*sorry for IE5*/
394
+ display/**/: block; /*sorry for IE5*/
395
+ position: absolute; /*must have*/
396
+ z-index: -1; /*must have*/
397
+ filter: mask(); /*must have*/
398
+ top: -4px; /*must have*/
399
+ left: -4px; /*must have*/
400
+ width: 200px; /*must have*/
401
+ height: 200px; /*must have*/
402
+ }/* Progressbar
403
+ ----------------------------------*/
404
+ .ui-progressbar { height:2em; text-align: left; }
405
+ .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
static/js/jquery/css/smoothness/jquery.tipsy.css ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ .tipsy { padding: 5px; font-size: 0.85em; position: absolute; z-index: 100000; line-height: 1.3em; max-width: 320px;}
2
+ .tipsy-inner { padding: 2px 4px 2px 4px; background-color: white; border: 1px solid #333;}
3
+ .tipsy-arrow { position: absolute; background: url('images/tipsy.gif') no-repeat top left; width: 9px; height: 5px; }
4
+ .tipsy-n .tipsy-arrow { top: 0; left: 50%; margin-left: -4px; }
5
+ .tipsy-nw .tipsy-arrow { top: 0; left: 10px; }
6
+ .tipsy-ne .tipsy-arrow { top: 0; right: 10px; }
7
+ .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -4px; background-position: bottom left; }
8
+ .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; background-position: bottom left; }
9
+ .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; background-position: bottom left; }
10
+ .tipsy-e .tipsy-arrow { top: 50%; margin-top: -4px; right: 0; width: 5px; height: 9px; background-position: top right; }
11
+ .tipsy-w .tipsy-arrow { top: 50%; margin-top: -4px; left: 0; width: 5px; height: 9px; }
static/js/jquery/jquery.mjs.nestedSortable.js ADDED
@@ -0,0 +1,426 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Nested Sortable
3
+ * v 1.3.5 / 21 jun 2012
4
+ * http://mjsarfatti.com/code/nestedSortable
5
+ *
6
+ * Depends on:
7
+ * jquery.ui.sortable.js 1.8+
8
+ *
9
+ * Copyright (c) 2010-2012 Manuele J Sarfatti
10
+ * Licensed under the MIT License
11
+ * http://www.opensource.org/licenses/mit-license.php
12
+ */
13
+
14
+ (function($) {
15
+
16
+ $.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
17
+
18
+ options: {
19
+ tabSize: 20,
20
+ disableNesting: 'mjs-nestedSortable-no-nesting',
21
+ errorClass: 'mjs-nestedSortable-error',
22
+ listType: 'ol',
23
+ maxLevels: 0,
24
+ protectRoot: false,
25
+ rootID: null,
26
+ rtl: false,
27
+ isAllowed: function(item, parent) { return true; }
28
+ },
29
+
30
+ _create: function() {
31
+ this.element.data('sortable', this.element.data('nestedSortable'));
32
+
33
+ if (!this.element.is(this.options.listType))
34
+ throw new Error('nestedSortable: Please check the listType option is set to your actual list type');
35
+
36
+ return $.ui.sortable.prototype._create.apply(this, arguments);
37
+ },
38
+
39
+ destroy: function() {
40
+ this.element
41
+ .removeData("nestedSortable")
42
+ .unbind(".nestedSortable");
43
+ return $.ui.sortable.prototype.destroy.apply(this, arguments);
44
+ },
45
+
46
+ _mouseDrag: function(event) {
47
+
48
+ //Compute the helpers position
49
+ this.position = this._generatePosition(event);
50
+ this.positionAbs = this._convertPositionTo("absolute");
51
+
52
+ if (!this.lastPositionAbs) {
53
+ this.lastPositionAbs = this.positionAbs;
54
+ }
55
+
56
+ //Do scrolling
57
+ if(this.options.scroll) {
58
+ var o = this.options, scrolled = false;
59
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
60
+
61
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
62
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
63
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
64
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
65
+
66
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
67
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
68
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
69
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
70
+
71
+ } else {
72
+
73
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
74
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
75
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
76
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
77
+
78
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
79
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
80
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
81
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
82
+
83
+ }
84
+
85
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
86
+ $.ui.ddmanager.prepareOffsets(this, event);
87
+ }
88
+
89
+ //Regenerate the absolute position used for position checks
90
+ this.positionAbs = this._convertPositionTo("absolute");
91
+
92
+ // Find the top offset before rearrangement,
93
+ var previousTopOffset = this.placeholder.offset().top;
94
+
95
+ //Set the helper position
96
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
97
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
98
+
99
+ //Rearrange
100
+ for (var i = this.items.length - 1; i >= 0; i--) {
101
+
102
+ //Cache variables and intersection, continue if no intersection
103
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
104
+ if (!intersection) continue;
105
+
106
+ if(itemElement != this.currentItem[0] //cannot intersect with itself
107
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
108
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
109
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
110
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
111
+ ) {
112
+
113
+ $(itemElement).mouseenter();
114
+
115
+ this.direction = intersection == 1 ? "down" : "up";
116
+
117
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
118
+ $(itemElement).mouseleave();
119
+ this._rearrange(event, item);
120
+ } else {
121
+ break;
122
+ }
123
+
124
+ // Clear emtpy ul's/ol's
125
+ this._clearEmpty(itemElement);
126
+
127
+ this._trigger("change", event, this._uiHash());
128
+ break;
129
+ }
130
+ }
131
+
132
+ var parentItem = (this.placeholder[0].parentNode.parentNode &&
133
+ $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
134
+ ? $(this.placeholder[0].parentNode.parentNode)
135
+ : null,
136
+ level = this._getLevel(this.placeholder),
137
+ childLevels = this._getChildLevels(this.helper);
138
+
139
+ // To find the previous sibling in the list, keep backtracking until we hit a valid list item.
140
+ var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
141
+ if (previousItem != null) {
142
+ while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) {
143
+ if (previousItem[0].previousSibling) {
144
+ previousItem = $(previousItem[0].previousSibling);
145
+ } else {
146
+ previousItem = null;
147
+ break;
148
+ }
149
+ }
150
+ }
151
+
152
+ // To find the next sibling in the list, keep stepping forward until we hit a valid list item.
153
+ var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null;
154
+ if (nextItem != null) {
155
+ while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) {
156
+ if (nextItem[0].nextSibling) {
157
+ nextItem = $(nextItem[0].nextSibling);
158
+ } else {
159
+ nextItem = null;
160
+ break;
161
+ }
162
+ }
163
+ }
164
+
165
+ var newList = document.createElement(o.listType);
166
+
167
+ this.beyondMaxLevels = 0;
168
+
169
+ // If the item is moved to the left, send it to its parent's level unless there are siblings below it.
170
+ if (parentItem != null && nextItem == null &&
171
+ (o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth()) ||
172
+ !o.rtl && (this.positionAbs.left < parentItem.offset().left))) {
173
+ parentItem.after(this.placeholder[0]);
174
+ this._clearEmpty(parentItem[0]);
175
+ this._trigger("change", event, this._uiHash());
176
+ }
177
+ // If the item is below a sibling and is moved to the right, make it a child of that sibling.
178
+ else if (previousItem != null &&
179
+ (o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize) ||
180
+ !o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize))) {
181
+ this._isAllowed(previousItem, level, level+childLevels+1);
182
+ if (!previousItem.children(o.listType).length) {
183
+ previousItem[0].appendChild(newList);
184
+ }
185
+ // If this item is being moved from the top, add it to the top of the list.
186
+ if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
187
+ previousItem.children(o.listType).prepend(this.placeholder);
188
+ }
189
+ // Otherwise, add it to the bottom of the list.
190
+ else {
191
+ previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
192
+ }
193
+ this._trigger("change", event, this._uiHash());
194
+ }
195
+ else {
196
+ this._isAllowed(parentItem, level, level+childLevels);
197
+ }
198
+
199
+ //Post events to containers
200
+ this._contactContainers(event);
201
+
202
+ //Interconnect with droppables
203
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
204
+
205
+ //Call callbacks
206
+ this._trigger('sort', event, this._uiHash());
207
+
208
+ this.lastPositionAbs = this.positionAbs;
209
+ return false;
210
+
211
+ },
212
+
213
+ _mouseStop: function(event, noPropagation) {
214
+
215
+ // If the item is in a position not allowed, send it back
216
+ if (this.beyondMaxLevels) {
217
+
218
+ this.placeholder.removeClass(this.options.errorClass);
219
+
220
+ if (this.domPosition.prev) {
221
+ $(this.domPosition.prev).after(this.placeholder);
222
+ } else {
223
+ $(this.domPosition.parent).prepend(this.placeholder);
224
+ }
225
+
226
+ this._trigger("revert", event, this._uiHash());
227
+
228
+ }
229
+
230
+ // Clean last empty ul/ol
231
+ for (var i = this.items.length - 1; i >= 0; i--) {
232
+ var item = this.items[i].item[0];
233
+ this._clearEmpty(item);
234
+ }
235
+
236
+ $.ui.sortable.prototype._mouseStop.apply(this, arguments);
237
+
238
+ },
239
+
240
+ serialize: function(options) {
241
+
242
+ var o = $.extend({}, this.options, options),
243
+ items = this._getItemsAsjQuery(o && o.connected),
244
+ str = [];
245
+
246
+ $(items).each(function() {
247
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '')
248
+ .match(o.expression || (/(.+)[-=_](.+)/)),
249
+ pid = ($(o.item || this).parent(o.listType)
250
+ .parent(o.items)
251
+ .attr(o.attribute || 'id') || '')
252
+ .match(o.expression || (/(.+)[-=_](.+)/));
253
+
254
+ if (res) {
255
+ str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
256
+ + '='
257
+ + (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
258
+ }
259
+ });
260
+
261
+ if(!str.length && o.key) {
262
+ str.push(o.key + '=');
263
+ }
264
+
265
+ return str.join('&');
266
+
267
+ },
268
+
269
+ toHierarchy: function(options) {
270
+
271
+ var o = $.extend({}, this.options, options),
272
+ sDepth = o.startDepthCount || 0,
273
+ ret = [];
274
+
275
+ $(this.element).children(o.items).each(function () {
276
+ var level = _recursiveItems(this);
277
+ ret.push(level);
278
+ });
279
+
280
+ return ret;
281
+
282
+ function _recursiveItems(item) {
283
+ var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
284
+ if (id) {
285
+ var currentItem = {"id" : id[2]};
286
+ if ($(item).children(o.listType).children(o.items).length > 0) {
287
+ currentItem.children = [];
288
+ $(item).children(o.listType).children(o.items).each(function() {
289
+ var level = _recursiveItems(this);
290
+ currentItem.children.push(level);
291
+ });
292
+ }
293
+ return currentItem;
294
+ }
295
+ }
296
+ },
297
+
298
+ toArray: function(options) {
299
+
300
+ var o = $.extend({}, this.options, options),
301
+ sDepth = o.startDepthCount || 0,
302
+ ret = [],
303
+ left = 2;
304
+
305
+ /*ret.push({
306
+ "item_id": o.rootID,
307
+ "parent_id": 'none',
308
+ "depth": sDepth,
309
+ "left": '1',
310
+ "right": ($(o.items, this.element).length + 1) * 2
311
+ });*/
312
+
313
+ $(this.element).children(o.items).each(function () {
314
+ left = _recursiveArray(this, sDepth + 1, left);
315
+ });
316
+
317
+ ret = ret.sort(function(a,b){ return (a.left - b.left); });
318
+
319
+ return ret;
320
+
321
+ function _recursiveArray(item, depth, left) {
322
+
323
+ var right = left + 1,
324
+ id,
325
+ pid;
326
+
327
+ if ($(item).children(o.listType).children(o.items).length > 0) {
328
+ depth ++;
329
+ $(item).children(o.listType).children(o.items).each(function () {
330
+ right = _recursiveArray($(this), depth, right);
331
+ });
332
+ depth --;
333
+ }
334
+
335
+ id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
336
+
337
+ if (depth === sDepth + 1) {
338
+ pid = o.rootID;
339
+ } else {
340
+ var parentItem = ($(item).parent(o.listType)
341
+ .parent(o.items)
342
+ .attr(o.attribute || 'id'))
343
+ .match(o.expression || (/(.+)[-=_](.+)/));
344
+ pid = parentItem[2];
345
+ }
346
+
347
+ if (id) {
348
+ ret.push({"item_id": id[2], "parent_id": pid, "delim": $(item).parents('.post_taxonomy:first').find('input.tax_delim').val(), "left": left, "right": right, "xpath":$(item).find('input.widefat').val(), "assign":$(item).find('input.assign_post:first').is(':checked'), "auto_nested":$(item).parents('.post_taxonomy:first').find('input.taxonomy_auto_nested').is(':checked')});
349
+ }
350
+
351
+ left = right + 1;
352
+ return left;
353
+ }
354
+
355
+ },
356
+
357
+ _clearEmpty: function(item) {
358
+
359
+ var emptyList = $(item).children(this.options.listType);
360
+ if (emptyList.length && !emptyList.children().length) {
361
+ emptyList.remove();
362
+ }
363
+
364
+ },
365
+
366
+ _getLevel: function(item) {
367
+
368
+ var level = 1;
369
+
370
+ if (this.options.listType) {
371
+ var list = item.closest(this.options.listType);
372
+ while (list && list.length > 0 &&
373
+ !list.is('.ui-sortable')) {
374
+ level++;
375
+ list = list.parent().closest(this.options.listType);
376
+ }
377
+ }
378
+
379
+ return level;
380
+ },
381
+
382
+ _getChildLevels: function(parent, depth) {
383
+ var self = this,
384
+ o = this.options,
385
+ result = 0;
386
+ depth = depth || 0;
387
+
388
+ $(parent).children(o.listType).children(o.items).each(function (index, child) {
389
+ result = Math.max(self._getChildLevels(child, depth + 1), result);
390
+ });
391
+
392
+ return depth ? result + 1 : result;
393
+ },
394
+
395
+ _isAllowed: function(parentItem, level, levels) {
396
+ var o = this.options,
397
+ isRoot = $(this.domPosition.parent).hasClass('ui-sortable') ? true : false,
398
+ maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list
399
+
400
+ // Is the root protected?
401
+ // Are we trying to nest under a no-nest?
402
+ // Are we nesting too deep?
403
+ if (!o.isAllowed(parentItem, this.placeholder) ||
404
+ parentItem && parentItem.hasClass(o.disableNesting) ||
405
+ o.protectRoot && (parentItem == null && !isRoot || isRoot && level > 1)) {
406
+ this.placeholder.addClass(o.errorClass);
407
+ if (maxLevels < levels && maxLevels != 0) {
408
+ this.beyondMaxLevels = levels - maxLevels;
409
+ } else {
410
+ this.beyondMaxLevels = 1;
411
+ }
412
+ } else {
413
+ if (maxLevels < levels && maxLevels != 0) {
414
+ this.placeholder.addClass(o.errorClass);
415
+ this.beyondMaxLevels = levels - maxLevels;
416
+ } else {
417
+ this.placeholder.removeClass(o.errorClass);
418
+ this.beyondMaxLevels = 0;
419
+ }
420
+ }
421
+ }
422
+
423
+ }));
424
+
425
+ $.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options);
426
+ })(jQuery);
static/js/jquery/jquery.tipsy.js ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // tipsy, facebook style tooltips for jquery
2
+ // version 1.0.0a
3
+ // (c) 2008-2010 jason frame [jason@onehackoranother.com]
4
+ // releated under the MIT license
5
+
6
+ (function($) {
7
+
8
+ function fixTitle($ele) {
9
+ if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') {
10
+ $ele.attr('original-title', $ele.attr('title') || '').removeAttr('title');
11
+ }
12
+ }
13
+
14
+ function Tipsy(element, options) {
15
+ this.$element = $(element);
16
+ this.options = options;
17
+ this.enabled = true;
18
+ fixTitle(this.$element);
19
+ }
20
+
21
+ Tipsy.prototype = {
22
+ show: function() {
23
+ var title = this.getTitle();
24
+ if (title && this.enabled) {
25
+ var $tip = this.tip();
26
+
27
+ $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
28
+ $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
29
+ $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
30
+
31
+ var pos = $.extend({}, this.$element.offset(), {
32
+ width: this.$element[0].offsetWidth,
33
+ height: this.$element[0].offsetHeight
34
+ });
35
+
36
+ var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight;
37
+ var gravity = (typeof this.options.gravity == 'function')
38
+ ? this.options.gravity.call(this.$element[0])
39
+ : this.options.gravity;
40
+
41
+ var tp;
42
+ switch (gravity.charAt(0)) {
43
+ case 'n':
44
+ tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
45
+ break;
46
+ case 's':
47
+ tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
48
+ break;
49
+ case 'e':
50
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
51
+ break;
52
+ case 'w':
53
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
54
+ break;
55
+ }
56
+
57
+ if (gravity.length == 2) {
58
+ if (gravity.charAt(1) == 'w') {
59
+ tp.left = pos.left + pos.width / 2 - 15;
60
+ } else {
61
+ tp.left = pos.left + pos.width / 2 - actualWidth + 15;
62
+ }
63
+ }
64
+
65
+ $tip.css(tp).addClass('tipsy-' + gravity);
66
+
67
+ if (this.options.fade) {
68
+ $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
69
+ } else {
70
+ $tip.css({visibility: 'visible', opacity: this.options.opacity});
71
+ }
72
+ }
73
+ },
74
+
75
+ hide: function() {
76
+ if (this.options.fade) {
77
+ this.tip().stop().fadeOut(function() { $(this).remove(); });
78
+ } else {
79
+ this.tip().remove();
80
+ }
81
+ },
82
+
83
+ getTitle: function() {
84
+ var title, $e = this.$element, o = this.options;
85
+ fixTitle($e);
86
+ var title, o = this.options;
87
+ if (typeof o.title == 'string') {
88
+ title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
89
+ } else if (typeof o.title == 'function') {
90
+ title = o.title.call($e[0]);
91
+ }
92
+ title = ('' + title).replace(/(^\s*|\s*$)/, "");
93
+ return title || o.fallback;
94
+ },
95
+
96
+ tip: function() {
97
+ if (!this.$tip) {
98
+ this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"/></div>');
99
+ }
100
+ return this.$tip;
101
+ },
102
+
103
+ validate: function() {
104
+ if (!this.$element[0].parentNode) {
105
+ this.hide();
106
+ this.$element = null;
107
+ this.options = null;
108
+ }
109
+ },
110
+
111
+ enable: function() { this.enabled = true; },
112
+ disable: function() { this.enabled = false; },
113
+ toggleEnabled: function() { this.enabled = !this.enabled; }
114
+ };
115
+
116
+ $.fn.tipsy = function(options) {
117
+
118
+ if (options === true) {
119
+ return this.data('tipsy');
120
+ } else if (typeof options == 'string') {
121
+ return this.data('tipsy')[options]();
122
+ }
123
+
124
+ options = $.extend({}, $.fn.tipsy.defaults, options);
125
+
126
+ function get(ele) {
127
+ var tipsy = $.data(ele, 'tipsy');
128
+ if (!tipsy) {
129
+ tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
130
+ $.data(ele, 'tipsy', tipsy);
131
+ }
132
+ return tipsy;
133
+ }
134
+
135
+ function enter() {
136
+ var tipsy = get(this);
137
+ tipsy.hoverState = 'in';
138
+ if (options.delayIn == 0) {
139
+ tipsy.show();
140
+ } else {
141
+ setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
142
+ }
143
+ };
144
+
145
+ function leave() {
146
+ var tipsy = get(this);
147
+ tipsy.hoverState = 'out';
148
+ if (options.delayOut == 0) {
149
+ tipsy.hide();
150
+ } else {
151
+ setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
152
+ }
153
+ };
154
+
155
+ if (!options.live) this.each(function() { get(this); });
156
+
157
+ if (options.trigger != 'manual') {
158
+ var binder = options.live ? 'live' : 'bind',
159
+ eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
160
+ eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
161
+ this[binder](eventIn, enter)[binder](eventOut, leave);
162
+ }
163
+
164
+ return this;
165
+
166
+ };
167
+
168
+ $.fn.tipsy.defaults = {
169
+ delayIn: 0,
170
+ delayOut: 0,
171
+ fade: false,
172
+ fallback: '',
173
+ gravity: 'n',
174
+ html: false,
175
+ live: false,
176
+ offset: 0,
177
+ opacity: 0.8,
178
+ title: 'title',
179
+ trigger: 'hover'
180
+ };
181
+
182
+ // Overwrite this method to provide options on a per-element basis.
183
+ // For example, you could store the gravity in a 'tipsy-gravity' attribute:
184
+ // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
185
+ // (remember - do not modify 'options' in place!)
186
+ $.fn.tipsy.elementOptions = function(ele, options) {
187
+ return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
188
+ };
189
+
190
+ $.fn.tipsy.autoNS = function() {
191
+ return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
192
+ };
193
+
194
+ $.fn.tipsy.autoWE = function() {
195
+ return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
196
+ };
197
+
198
+ })(jQuery);
static/js/jquery/moment.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ // moment.js
2
+ // version : 1.7.2
3
+ // author : Tim Wood
4
+ // license : MIT
5
+ // momentjs.com
6
+ (function(a){function E(a,b,c,d){var e=c.lang();return e[a].call?e[a](c,d):e[a][b]}function F(a,b){return function(c){return K(a.call(this,c),b)}}function G(a){return function(b){var c=a.call(this,b);return c+this.lang().ordinal(c)}}function H(a,b,c){this._d=a,this._isUTC=!!b,this._a=a._a||null,this._lang=c||!1}function I(a){var b=this._data={},c=a.years||a.y||0,d=a.months||a.M||0,e=a.weeks||a.w||0,f=a.days||a.d||0,g=a.hours||a.h||0,h=a.minutes||a.m||0,i=a.seconds||a.s||0,j=a.milliseconds||a.ms||0;this._milliseconds=j+i*1e3+h*6e4+g*36e5,this._days=f+e*7,this._months=d+c*12,b.milliseconds=j%1e3,i+=J(j/1e3),b.seconds=i%60,h+=J(i/60),b.minutes=h%60,g+=J(h/60),b.hours=g%24,f+=J(g/24),f+=e*7,b.days=f%30,d+=J(f/30),b.months=d%12,c+=J(d/12),b.years=c,this._lang=!1}function J(a){return a<0?Math.ceil(a):Math.floor(a)}function K(a,b){var c=a+"";while(c.length<b)c="0"+c;return c}function L(a,b,c){var d=b._milliseconds,e=b._days,f=b._months,g;d&&a._d.setTime(+a+d*c),e&&a.date(a.date()+e*c),f&&(g=a.date(),a.date(1).month(a.month()+f*c).date(Math.min(g,a.daysInMonth())))}function M(a){return Object.prototype.toString.call(a)==="[object Array]"}function N(a,b){var c=Math.min(a.length,b.length),d=Math.abs(a.length-b.length),e=0,f;for(f=0;f<c;f++)~~a[f]!==~~b[f]&&e++;return e+d}function O(a,b,c,d){var e,f,g=[];for(e=0;e<7;e++)g[e]=a[e]=a[e]==null?e===2?1:0:a[e];return a[7]=g[7]=b,a[8]!=null&&(g[8]=a[8]),a[3]+=c||0,a[4]+=d||0,f=new Date(0),b?(f.setUTCFullYear(a[0],a[1],a[2]),f.setUTCHours(a[3],a[4],a[5],a[6])):(f.setFullYear(a[0],a[1],a[2]),f.setHours(a[3],a[4],a[5],a[6])),f._a=g,f}function P(a,c){var d,e,g=[];!c&&h&&(c=require("./lang/"+a));for(d=0;d<i.length;d++)c[i[d]]=c[i[d]]||f.en[i[d]];for(d=0;d<12;d++)e=b([2e3,d]),g[d]=new RegExp("^"+(c.months[d]||c.months(e,""))+"|^"+(c.monthsShort[d]||c.monthsShort(e,"")).replace(".",""),"i");return c.monthsParse=c.monthsParse||g,f[a]=c,c}function Q(a){var c=typeof a=="string"&&a||a&&a._lang||null;return c?f[c]||P(c):b}function R(a){return a.match(/\[.*\]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function S(a){var b=a.match(k),c,d;for(c=0,d=b.length;c<d;c++)D[b[c]]?b[c]=D[b[c]]:b[c]=R(b[c]);return function(e){var f="";for(c=0;c<d;c++)f+=typeof b[c].call=="function"?b[c].call(e,a):b[c];return f}}function T(a,b){function d(b){return a.lang().longDateFormat[b]||b}var c=5;while(c--&&l.test(b))b=b.replace(l,d);return A[b]||(A[b]=S(b)),A[b](a)}function U(a){switch(a){case"DDDD":return p;case"YYYY":return q;case"S":case"SS":case"SSS":case"DDD":return o;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":case"a":case"A":return r;case"Z":case"ZZ":return s;case"T":return t;case"MM":case"DD":case"YY":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":return n;default:return new RegExp(a.replace("\\",""))}}function V(a,b,c,d){var e,f;switch(a){case"M":case"MM":c[1]=b==null?0:~~b-1;break;case"MMM":case"MMMM":for(e=0;e<12;e++)if(Q().monthsParse[e].test(b)){c[1]=e,f=!0;break}f||(c[8]=!1);break;case"D":case"DD":case"DDD":case"DDDD":b!=null&&(c[2]=~~b);break;case"YY":c[0]=~~b+(~~b>70?1900:2e3);break;case"YYYY":c[0]=~~Math.abs(b);break;case"a":case"A":d.isPm=(b+"").toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b;break;case"S":case"SS":case"SSS":c[6]=~~(("0."+b)*1e3);break;case"Z":case"ZZ":d.isUTC=!0,e=(b+"").match(x),e&&e[1]&&(d.tzh=~~e[1]),e&&e[2]&&(d.tzm=~~e[2]),e&&e[0]==="+"&&(d.tzh=-d.tzh,d.tzm=-d.tzm)}b==null&&(c[8]=!1)}function W(a,b){var c=[0,0,1,0,0,0,0],d={tzh:0,tzm:0},e=b.match(k),f,g;for(f=0;f<e.length;f++)g=(U(e[f]).exec(a)||[])[0],g&&(a=a.slice(a.indexOf(g)+g.length)),D[e[f]]&&V(e[f],g,c,d);return d.isPm&&c[3]<12&&(c[3]+=12),d.isPm===!1&&c[3]===12&&(c[3]=0),O(c,d.isUTC,d.tzh,d.tzm)}function X(a,b){var c,d=a.match(m)||[],e,f=99,g,h,i;for(g=0;g<b.length;g++)h=W(a,b[g]),e=T(new H(h),b[g]).match(m)||[],i=N(d,e),i<f&&(f=i,c=h);return c}function Y(a){var b="YYYY-MM-DDT",c;if(u.exec(a)){for(c=0;c<4;c++)if(w[c][1].exec(a)){b+=w[c][0];break}return s.exec(a)?W(a,b+" Z"):W(a,b)}return new Date(a)}function Z(a,b,c,d,e){var f=e.relativeTime[a];return typeof f=="function"?f(b||1,!!c,a,d):f.replace(/%d/i,b||1)}function $(a,b,c){var e=d(Math.abs(a)/1e3),f=d(e/60),g=d(f/60),h=d(g/24),i=d(h/365),j=e<45&&["s",e]||f===1&&["m"]||f<45&&["mm",f]||g===1&&["h"]||g<22&&["hh",g]||h===1&&["d"]||h<=25&&["dd",h]||h<=45&&["M"]||h<345&&["MM",d(h/30)]||i===1&&["y"]||["yy",i];return j[2]=b,j[3]=a>0,j[4]=c,Z.apply({},j)}function _(a,c){b.fn[a]=function(a){var b=this._isUTC?"UTC":"";return a!=null?(this._d["set"+b+c](a),this):this._d["get"+b+c]()}}function ab(a){b.duration.fn[a]=function(){return this._data[a]}}function bb(a,c){b.duration.fn["as"+a]=function(){return+this/c}}var b,c="1.7.2",d=Math.round,e,f={},g="en",h=typeof module!="undefined"&&module.exports,i="months|monthsShort|weekdays|weekdaysShort|weekdaysMin|longDateFormat|calendar|relativeTime|ordinal|meridiem".split("|"),j=/^\/?Date\((\-?\d+)/i,k=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|zz?|ZZ?|.)/g,l=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?)/g,m=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,n=/\d\d?/,o=/\d{1,3}/,p=/\d{3}/,q=/\d{1,4}/,r=/[0-9a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+/i,s=/Z|[\+\-]\d\d:?\d\d/i,t=/T/i,u=/^\s*\d{4}-\d\d-\d\d(T(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,v="YYYY-MM-DDTHH:mm:ssZ",w=[["HH:mm:ss.S",/T\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/T\d\d:\d\d:\d\d/],["HH:mm",/T\d\d:\d\d/],["HH",/T\d\d/]],x=/([\+\-]|\d\d)/gi,y="Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"),z={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},A={},B="DDD w M D d".split(" "),C="M D H h m s w".split(" "),D={M:function(){return this.month()+1},MMM:function(a){return E("monthsShort",this.month(),this,a)},MMMM:function(a){return E("months",this.month(),this,a)},D:function(){return this.date()},DDD:function(){var a=new Date(this.year(),this.month(),this.date()),b=new Date(this.year(),0,1);return~~((a-b)/864e5+1.5)},d:function(){return this.day()},dd:function(a){return E("weekdaysMin",this.day(),this,a)},ddd:function(a){return E("weekdaysShort",this.day(),this,a)},dddd:function(a){return E("weekdays",this.day(),this,a)},w:function(){var a=new Date(this.year(),this.month(),this.date()-this.day()+5),b=new Date(a.getFullYear(),0,4);return~~((a-b)/864e5/7+1.5)},YY:function(){return K(this.year()%100,2)},YYYY:function(){return K(this.year(),4)},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return K(~~(this.milliseconds()/10),2)},SSS:function(){return K(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(a/60),2)+":"+K(~~a%60,2)},ZZ:function(){var a=-this.zone(),b="+";return a<0&&(a=-a,b="-"),b+K(~~(10*a/6),4)}};while(B.length)e=B.pop(),D[e+"o"]=G(D[e]);while(C.length)e=C.pop(),D[e+e]=F(D[e],2);D.DDDD=F(D.DDD,3),b=function(c,d){if(c===null||c==="")return null;var e,f;return b.isMoment(c)?new H(new Date(+c._d),c._isUTC,c._lang):(d?M(d)?e=X(c,d):e=W(c,d):(f=j.exec(c),e=c===a?new Date:f?new Date(+f[1]):c instanceof Date?c:M(c)?O(c):typeof c=="string"?Y(c):new Date(c)),new H(e))},b.utc=function(a,c){return M(a)?new H(O(a,!0),!0):(typeof a=="string"&&!s.exec(a)&&(a+=" +0000",c&&(c+=" Z")),b(a,c).utc())},b.unix=function(a){return b(a*1e3)},b.duration=function(a,c){var d=b.isDuration(a),e=typeof a=="number",f=d?a._data:e?{}:a,g;return e&&(c?f[c]=a:f.milliseconds=a),g=new I(f),d&&(g._lang=a._lang),g},b.humanizeDuration=function(a,c,d){return b.duration(a,c===!0?null:c).humanize(c===!0?!0:d)},b.version=c,b.defaultFormat=v,b.lang=function(a,c){var d;if(!a)return g;(c||!f[a])&&P(a,c);if(f[a]){for(d=0;d<i.length;d++)b[i[d]]=f[a][i[d]];b.monthsParse=f[a].monthsParse,g=a}},b.langData=Q,b.isMoment=function(a){return a instanceof H},b.isDuration=function(a){return a instanceof I},b.lang("en",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinal:function(a){var b=a%10;return~~(a%100/10)===1?"th":b===1?"st":b===2?"nd":b===3?"rd":"th"}}),b.fn=H.prototype={clone:function(){return b(this)},valueOf:function(){return+this._d},unix:function(){return Math.floor(+this._d/1e3)},toString:function(){return this._d.toString()},toDate:function(){return this._d},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds(),!!this._isUTC]},isValid:function(){return this._a?this._a[8]!=null?!!this._a[8]:!N(this._a,(this._a[7]?b.utc(this._a):b(this._a)).toArray()):!isNaN(this._d.getTime())},utc:function(){return this._isUTC=!0,this},local:function(){return this._isUTC=!1,this},format:function(a){return T(this,a?a:b.defaultFormat)},add:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,1),this},subtract:function(a,c){var d=c?b.duration(+c,a):b.duration(a);return L(this,d,-1),this},diff:function(a,c,e){var f=this._isUTC?b(a).utc():b(a).local(),g=(this.zone()-f.zone())*6e4,h=this._d-f._d-g,i=this.year()-f.year(),j=this.month()-f.month(),k=this.date()-f.date(),l;return c==="months"?l=i*12+j+k/30:c==="years"?l=i+(j+k/30)/12:l=c==="seconds"?h/1e3:c==="minutes"?h/6e4:c==="hours"?h/36e5:c==="days"?h/864e5:c==="weeks"?h/6048e5:h,e?l:d(l)},from:function(a,c){return b.duration(this.diff(a)).lang(this._lang).humanize(!c)},fromNow:function(a){return this.from(b(),a)},calendar:function(){var a=this.diff(b().sod(),"days",!0),c=this.lang().calendar,d=c.sameElse,e=a<-6?d:a<-1?c.lastWeek:a<0?c.lastDay:a<1?c.sameDay:a<2?c.nextDay:a<7?c.nextWeek:d;return this.format(typeof e=="function"?e.apply(this):e)},isLeapYear:function(){var a=this.year();return a%4===0&&a%100!==0||a%400===0},isDST:function(){return this.zone()<b([this.year()]).zone()||this.zone()<b([this.year(),5]).zone()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return a==null?b:this.add({d:a-b})},startOf:function(a){switch(a.replace(/s$/,"")){case"year":this.month(0);case"month":this.date(1);case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return this},endOf:function(a){return this.startOf(a).add(a.replace(/s?$/,"s"),1).subtract("ms",1)},sod:function(){return this.clone().startOf("day")},eod:function(){return this.clone().endOf("day")},zone:function(){return this._isUTC?0:this._d.getTimezoneOffset()},daysInMonth:function(){return b.utc([this.year(),this.month()+1,0]).date()},lang:function(b){return b===a?Q(this):(this._lang=b,this)}};for(e=0;e<y.length;e++)_(y[e].toLowerCase(),y[e]);_("year","FullYear"),b.duration.fn=I.prototype={weeks:function(){return J(this.days()/7)},valueOf:function(){return this._milliseconds+this._days*864e5+this._months*2592e6},humanize:function(a){var b=+this,c=this.lang().relativeTime,d=$(b,!a,this.lang()),e=b<=0?c.past:c.future;return a&&(typeof e=="function"?d=e(d):d=e.replace(/%s/i,d)),d},lang:b.fn.lang};for(e in z)z.hasOwnProperty(e)&&(bb(e,z[e]),ab(e.toLowerCase()));bb("Weeks",6048e5),h&&(module.exports=b),typeof ender=="undefined"&&(this.moment=b),typeof define=="function"&&define.amd&&define("moment",[],function(){return b})}).call(this);
static/js/jquery/select2.min.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Copyright 2012 Igor Vaynberg
3
+
4
+ Version: 3.4.5 Timestamp: Mon Nov 4 08:22:42 PST 2013
5
+
6
+ This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
7
+ General Public License version 2 (the "GPL License"). You may choose either license to govern your
8
+ use of this software only upon the condition that you accept all of the terms of either the Apache
9
+ License or the GPL License.
10
+
11
+ You may obtain a copy of the Apache License and the GPL License at:
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+ http://www.gnu.org/licenses/gpl-2.0.html
15
+
16
+ Unless required by applicable law or agreed to in writing, software distributed under the Apache License
17
+ or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
18
+ either express or implied. See the Apache License and the GPL License for the specific language governing
19
+ permissions and limitations under the Apache License and the GPL License.
20
+ */
21
+ !function(a){"undefined"==typeof a.fn.each2&&a.extend(a.fn,{each2:function(b){for(var c=a([0]),d=-1,e=this.length;++d<e&&(c.context=c[0]=this[d])&&b.call(c[0],d,c)!==!1;);return this}})}(jQuery),function(a,b){"use strict";function n(a){var b,c,d,e;if(!a||a.length<1)return a;for(b="",c=0,d=a.length;d>c;c++)e=a.charAt(c),b+=m[e]||e;return b}function o(a,b){for(var c=0,d=b.length;d>c;c+=1)if(q(a,b[c]))return c;return-1}function p(){var b=a(l);b.appendTo("body");var c={width:b.width()-b[0].clientWidth,height:b.height()-b[0].clientHeight};return b.remove(),c}function q(a,c){return a===c?!0:a===b||c===b?!1:null===a||null===c?!1:a.constructor===String?a+""==c+"":c.constructor===String?c+""==a+"":!1}function r(b,c){var d,e,f;if(null===b||b.length<1)return[];for(d=b.split(c),e=0,f=d.length;f>e;e+=1)d[e]=a.trim(d[e]);return d}function s(a){return a.outerWidth(!1)-a.width()}function t(c){var d="keyup-change-value";c.on("keydown",function(){a.data(c,d)===b&&a.data(c,d,c.val())}),c.on("keyup",function(){var e=a.data(c,d);e!==b&&c.val()!==e&&(a.removeData(c,d),c.trigger("keyup-change"))})}function u(c){c.on("mousemove",function(c){var d=i;(d===b||d.x!==c.pageX||d.y!==c.pageY)&&a(c.target).trigger("mousemove-filtered",c)})}function v(a,c,d){d=d||b;var e;return function(){var b=arguments;window.clearTimeout(e),e=window.setTimeout(function(){c.apply(d,b)},a)}}function w(a){var c,b=!1;return function(){return b===!1&&(c=a(),b=!0),c}}function x(a,b){var c=v(a,function(a){b.trigger("scroll-debounced",a)});b.on("scroll",function(a){o(a.target,b.get())>=0&&c(a)})}function y(a){a[0]!==document.activeElement&&window.setTimeout(function(){var d,b=a[0],c=a.val().length;a.focus(),a.is(":visible")&&b===document.activeElement&&(b.setSelectionRange?b.setSelectionRange(c,c):b.createTextRange&&(d=b.createTextRange(),d.collapse(!1),d.select()))},0)}function z(b){b=a(b)[0];var c=0,d=0;if("selectionStart"in b)c=b.selectionStart,d=b.selectionEnd-c;else if("selection"in document){b.focus();var e=document.selection.createRange();d=document.selection.createRange().text.length,e.moveStart("character",-b.value.length),c=e.text.length-d}return{offset:c,length:d}}function A(a){a.preventDefault(),a.stopPropagation()}function B(a){a.preventDefault(),a.stopImmediatePropagation()}function C(b){if(!h){var c=b[0].currentStyle||window.getComputedStyle(b[0],null);h=a(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle,fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),h.attr("class","select2-sizer"),a("body").append(h)}return h.text(b.val()),h.width()}function D(b,c,d){var e,g,f=[];e=b.attr("class"),e&&(e=""+e,a(e.split(" ")).each2(function(){0===this.indexOf("select2-")&&f.push(this)})),e=c.attr("class"),e&&(e=""+e,a(e.split(" ")).each2(function(){0!==this.indexOf("select2-")&&(g=d(this),g&&f.push(g))})),b.attr("class",f.join(" "))}function E(a,b,c,d){var e=n(a.toUpperCase()).indexOf(n(b.toUpperCase())),f=b.length;return 0>e?(c.push(d(a)),void 0):(c.push(d(a.substring(0,e))),c.push("<span class='select2-match'>"),c.push(d(a.substring(e,e+f))),c.push("</span>"),c.push(d(a.substring(e+f,a.length))),void 0)}function F(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})}function G(c){var d,e=null,f=c.quietMillis||100,g=c.url,h=this;return function(i){window.clearTimeout(d),d=window.setTimeout(function(){var d=c.data,f=g,j=c.transport||a.fn.select2.ajaxDefaults.transport,k={type:c.type||"GET",cache:c.cache||!1,jsonpCallback:c.jsonpCallback||b,dataType:c.dataType||"json"},l=a.extend({},a.fn.select2.ajaxDefaults.params,k);d=d?d.call(h,i.term,i.page,i.context):null,f="function"==typeof f?f.call(h,i.term,i.page,i.context):f,e&&e.abort(),c.params&&(a.isFunction(c.params)?a.extend(l,c.params.call(h)):a.extend(l,c.params)),a.extend(l,{url:f,dataType:c.dataType,data:d,success:function(a){var b=c.results(a,i.page);i.callback(b)}}),e=j.call(h,l)},f)}}function H(b){var d,e,c=b,f=function(a){return""+a.text};a.isArray(c)&&(e=c,c={results:e}),a.isFunction(c)===!1&&(e=c,c=function(){return e});var g=c();return g.text&&(f=g.text,a.isFunction(f)||(d=g.text,f=function(a){return a[d]})),function(b){var g,d=b.term,e={results:[]};return""===d?(b.callback(c()),void 0):(g=function(c,e){var h,i;if(c=c[0],c.children){h={};for(i in c)c.hasOwnProperty(i)&&(h[i]=c[i]);h.children=[],a(c.children).each2(function(a,b){g(b,h.children)}),(h.children.length||b.matcher(d,f(h),c))&&e.push(h)}else b.matcher(d,f(c),c)&&e.push(c)},a(c().results).each2(function(a,b){g(b,e.results)}),b.callback(e),void 0)}}function I(c){var d=a.isFunction(c);return function(e){var f=e.term,g={results:[]};a(d?c():c).each(function(){var a=this.text!==b,c=a?this.text:this;(""===f||e.matcher(f,c))&&g.results.push(a?this:{id:this,text:this})}),e.callback(g)}}function J(b,c){if(a.isFunction(b))return!0;if(!b)return!1;throw new Error(c+" must be a function or a falsy value")}function K(b){return a.isFunction(b)?b():b}function L(b){var c=0;return a.each(b,function(a,b){b.children?c+=L(b.children):c++}),c}function M(a,c,d,e){var h,i,j,k,l,f=a,g=!1;if(!e.createSearchChoice||!e.tokenSeparators||e.tokenSeparators.length<1)return b;for(;;){for(i=-1,j=0,k=e.tokenSeparators.length;k>j&&(l=e.tokenSeparators[j],i=a.indexOf(l),!(i>=0));j++);if(0>i)break;if(h=a.substring(0,i),a=a.substring(i+l.length),h.length>0&&(h=e.createSearchChoice.call(this,h,c),h!==b&&null!==h&&e.id(h)!==b&&null!==e.id(h))){for(g=!1,j=0,k=c.length;k>j;j++)if(q(e.id(h),e.id(c[j]))){g=!0;break}g||d(h)}}return f!==a?a:void 0}function N(b,c){var d=function(){};return d.prototype=new b,d.prototype.constructor=d,d.prototype.parent=b.prototype,d.prototype=a.extend(d.prototype,c),d}if(window.Select2===b){var c,d,e,f,g,h,j,k,i={x:0,y:0},c={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(a){switch(a=a.which?a.which:a){case c.LEFT:case c.RIGHT:case c.UP:case c.DOWN:return!0}return!1},isControl:function(a){var b=a.which;switch(b){case c.SHIFT:case c.CTRL:case c.ALT:return!0}return a.metaKey?!0:!1},isFunctionKey:function(a){return a=a.which?a.which:a,a>=112&&123>=a}},l="<div class='select2-measure-scrollbar'></div>",m={"\u24b6":"A","\uff21":"A","\xc0":"A","\xc1":"A","\xc2":"A","\u1ea6":"A","\u1ea4":"A","\u1eaa":"A","\u1ea8":"A","\xc3":"A","\u0100":"A","\u0102":"A","\u1eb0":"A","\u1eae":"A","\u1eb4":"A","\u1eb2":"A","\u0226":"A","\u01e0":"A","\xc4":"A","\u01de":"A","\u1ea2":"A","\xc5":"A","\u01fa":"A","\u01cd":"A","\u0200":"A","\u0202":"A","\u1ea0":"A","\u1eac":"A","\u1eb6":"A","\u1e00":"A","\u0104":"A","\u023a":"A","\u2c6f":"A","\ua732":"AA","\xc6":"AE","\u01fc":"AE","\u01e2":"AE","\ua734":"AO","\ua736":"AU","\ua738":"AV","\ua73a":"AV","\ua73c":"AY","\u24b7":"B","\uff22":"B","\u1e02":"B","\u1e04":"B","\u1e06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24b8":"C","\uff23":"C","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\xc7":"C","\u1e08":"C","\u0187":"C","\u023b":"C","\ua73e":"C","\u24b9":"D","\uff24":"D","\u1e0a":"D","\u010e":"D","\u1e0c":"D","\u1e10":"D","\u1e12":"D","\u1e0e":"D","\u0110":"D","\u018b":"D","\u018a":"D","\u0189":"D","\ua779":"D","\u01f1":"DZ","\u01c4":"DZ","\u01f2":"Dz","\u01c5":"Dz","\u24ba":"E","\uff25":"E","\xc8":"E","\xc9":"E","\xca":"E","\u1ec0":"E","\u1ebe":"E","\u1ec4":"E","\u1ec2":"E","\u1ebc":"E","\u0112":"E","\u1e14":"E","\u1e16":"E","\u0114":"E","\u0116":"E","\xcb":"E","\u1eba":"E","\u011a":"E","\u0204":"E","\u0206":"E","\u1eb8":"E","\u1ec6":"E","\u0228":"E","\u1e1c":"E","\u0118":"E","\u1e18":"E","\u1e1a":"E","\u0190":"E","\u018e":"E","\u24bb":"F","\uff26":"F","\u1e1e":"F","\u0191":"F","\ua77b":"F","\u24bc":"G","\uff27":"G","\u01f4":"G","\u011c":"G","\u1e20":"G","\u011e":"G","\u0120":"G","\u01e6":"G","\u0122":"G","\u01e4":"G","\u0193":"G","\ua7a0":"G","\ua77d":"G","\ua77e":"G","\u24bd":"H","\uff28":"H","\u0124":"H","\u1e22":"H","\u1e26":"H","\u021e":"H","\u1e24":"H","\u1e28":"H","\u1e2a":"H","\u0126":"H","\u2c67":"H","\u2c75":"H","\ua78d":"H","\u24be":"I","\uff29":"I","\xcc":"I","\xcd":"I","\xce":"I","\u0128":"I","\u012a":"I","\u012c":"I","\u0130":"I","\xcf":"I","\u1e2e":"I","\u1ec8":"I","\u01cf":"I","\u0208":"I","\u020a":"I","\u1eca":"I","\u012e":"I","\u1e2c":"I","\u0197":"I","\u24bf":"J","\uff2a":"J","\u0134":"J","\u0248":"J","\u24c0":"K","\uff2b":"K","\u1e30":"K","\u01e8":"K","\u1e32":"K","\u0136":"K","\u1e34":"K","\u0198":"K","\u2c69":"K","\ua740":"K","\ua742":"K","\ua744":"K","\ua7a2":"K","\u24c1":"L","\uff2c":"L","\u013f":"L","\u0139":"L","\u013d":"L","\u1e36":"L","\u1e38":"L","\u013b":"L","\u1e3c":"L","\u1e3a":"L","\u0141":"L","\u023d":"L","\u2c62":"L","\u2c60":"L","\ua748":"L","\ua746":"L","\ua780":"L","\u01c7":"LJ","\u01c8":"Lj","\u24c2":"M","\uff2d":"M","\u1e3e":"M","\u1e40":"M","\u1e42":"M","\u2c6e":"M","\u019c":"M","\u24c3":"N","\uff2e":"N","\u01f8":"N","\u0143":"N","\xd1":"N","\u1e44":"N","\u0147":"N","\u1e46":"N","\u0145":"N","\u1e4a":"N","\u1e48":"N","\u0220":"N","\u019d":"N","\ua790":"N","\ua7a4":"N","\u01ca":"NJ","\u01cb":"Nj","\u24c4":"O","\uff2f":"O","\xd2":"O","\xd3":"O","\xd4":"O","\u1ed2":"O","\u1ed0":"O","\u1ed6":"O","\u1ed4":"O","\xd5":"O","\u1e4c":"O","\u022c":"O","\u1e4e":"O","\u014c":"O","\u1e50":"O","\u1e52":"O","\u014e":"O","\u022e":"O","\u0230":"O","\xd6":"O","\u022a":"O","\u1ece":"O","\u0150":"O","\u01d1":"O","\u020c":"O","\u020e":"O","\u01a0":"O","\u1edc":"O","\u1eda":"O","\u1ee0":"O","\u1ede":"O","\u1ee2":"O","\u1ecc":"O","\u1ed8":"O","\u01ea":"O","\u01ec":"O","\xd8":"O","\u01fe":"O","\u0186":"O","\u019f":"O","\ua74a":"O","\ua74c":"O","\u01a2":"OI","\ua74e":"OO","\u0222":"OU","\u24c5":"P","\uff30":"P","\u1e54":"P","\u1e56":"P","\u01a4":"P","\u2c63":"P","\ua750":"P","\ua752":"P","\ua754":"P","\u24c6":"Q","\uff31":"Q","\ua756":"Q","\ua758":"Q","\u024a":"Q","\u24c7":"R","\uff32":"R","\u0154":"R","\u1e58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1e5a":"R","\u1e5c":"R","\u0156":"R","\u1e5e":"R","\u024c":"R","\u2c64":"R","\ua75a":"R","\ua7a6":"R","\ua782":"R","\u24c8":"S","\uff33":"S","\u1e9e":"S","\u015a":"S","\u1e64":"S","\u015c":"S","\u1e60":"S","\u0160":"S","\u1e66":"S","\u1e62":"S","\u1e68":"S","\u0218":"S","\u015e":"S","\u2c7e":"S","\ua7a8":"S","\ua784":"S","\u24c9":"T","\uff34":"T","\u1e6a":"T","\u0164":"T","\u1e6c":"T","\u021a":"T","\u0162":"T","\u1e70":"T","\u1e6e":"T","\u0166":"T","\u01ac":"T","\u01ae":"T","\u023e":"T","\ua786":"T","\ua728":"TZ","\u24ca":"U","\uff35":"U","\xd9":"U","\xda":"U","\xdb":"U","\u0168":"U","\u1e78":"U","\u016a":"U","\u1e7a":"U","\u016c":"U","\xdc":"U","\u01db":"U","\u01d7":"U","\u01d5":"U","\u01d9":"U","\u1ee6":"U","\u016e":"U","\u0170":"U","\u01d3":"U","\u0214":"U","\u0216":"U","\u01af":"U","\u1eea":"U","\u1ee8":"U","\u1eee":"U","\u1eec":"U","\u1ef0":"U","\u1ee4":"U","\u1e72":"U","\u0172":"U","\u1e76":"U","\u1e74":"U","\u0244":"U","\u24cb":"V","\uff36":"V","\u1e7c":"V","\u1e7e":"V","\u01b2":"V","\ua75e":"V","\u0245":"V","\ua760":"VY","\u24cc":"W","\uff37":"W","\u1e80":"W","\u1e82":"W","\u0174":"W","\u1e86":"W","\u1e84":"W","\u1e88":"W","\u2c72":"W","\u24cd":"X","\uff38":"X","\u1e8a":"X","\u1e8c":"X","\u24ce":"Y","\uff39":"Y","\u1ef2":"Y","\xdd":"Y","\u0176":"Y","\u1ef8":"Y","\u0232":"Y","\u1e8e":"Y","\u0178":"Y","\u1ef6":"Y","\u1ef4":"Y","\u01b3":"Y","\u024e":"Y","\u1efe":"Y","\u24cf":"Z","\uff3a":"Z","\u0179":"Z","\u1e90":"Z","\u017b":"Z","\u017d":"Z","\u1e92":"Z","\u1e94":"Z","\u01b5":"Z","\u0224":"Z","\u2c7f":"Z","\u2c6b":"Z","\ua762":"Z","\u24d0":"a","\uff41":"a","\u1e9a":"a","\xe0":"a","\xe1":"a","\xe2":"a","\u1ea7":"a","\u1ea5":"a","\u1eab":"a","\u1ea9":"a","\xe3":"a","\u0101":"a","\u0103":"a","\u1eb1":"a","\u1eaf":"a","\u1eb5":"a","\u1eb3":"a","\u0227":"a","\u01e1":"a","\xe4":"a","\u01df":"a","\u1ea3":"a","\xe5":"a","\u01fb":"a","\u01ce":"a","\u0201":"a","\u0203":"a","\u1ea1":"a","\u1ead":"a","\u1eb7":"a","\u1e01":"a","\u0105":"a","\u2c65":"a","\u0250":"a","\ua733":"aa","\xe6":"ae","\u01fd":"ae","\u01e3":"ae","\ua735":"ao","\ua737":"au","\ua739":"av","\ua73b":"av","\ua73d":"ay","\u24d1":"b","\uff42":"b","\u1e03":"b","\u1e05":"b","\u1e07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24d2":"c","\uff43":"c","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\xe7":"c","\u1e09":"c","\u0188":"c","\u023c":"c","\ua73f":"c","\u2184":"c","\u24d3":"d","\uff44":"d","\u1e0b":"d","\u010f":"d","\u1e0d":"d","\u1e11":"d","\u1e13":"d","\u1e0f":"d","\u0111":"d","\u018c":"d","\u0256":"d","\u0257":"d","\ua77a":"d","\u01f3":"dz","\u01c6":"dz","\u24d4":"e","\uff45":"e","\xe8":"e","\xe9":"e","\xea":"e","\u1ec1":"e","\u1ebf":"e","\u1ec5":"e","\u1ec3":"e","\u1ebd":"e","\u0113":"e","\u1e15":"e","\u1e17":"e","\u0115":"e","\u0117":"e","\xeb":"e","\u1ebb":"e","\u011b":"e","\u0205":"e","\u0207":"e","\u1eb9":"e","\u1ec7":"e","\u0229":"e","\u1e1d":"e","\u0119":"e","\u1e19":"e","\u1e1b":"e","\u0247":"e","\u025b":"e","\u01dd":"e","\u24d5":"f","\uff46":"f","\u1e1f":"f","\u0192":"f","\ua77c":"f","\u24d6":"g","\uff47":"g","\u01f5":"g","\u011d":"g","\u1e21":"g","\u011f":"g","\u0121":"g","\u01e7":"g","\u0123":"g","\u01e5":"g","\u0260":"g","\ua7a1":"g","\u1d79":"g","\ua77f":"g","\u24d7":"h","\uff48":"h","\u0125":"h","\u1e23":"h","\u1e27":"h","\u021f":"h","\u1e25":"h","\u1e29":"h","\u1e2b":"h","\u1e96":"h","\u0127":"h","\u2c68":"h","\u2c76":"h","\u0265":"h","\u0195":"hv","\u24d8":"i","\uff49":"i","\xec":"i","\xed":"i","\xee":"i","\u0129":"i","\u012b":"i","\u012d":"i","\xef":"i","\u1e2f":"i","\u1ec9":"i","\u01d0":"i","\u0209":"i","\u020b":"i","\u1ecb":"i","\u012f":"i","\u1e2d":"i","\u0268":"i","\u0131":"i","\u24d9":"j","\uff4a":"j","\u0135":"j","\u01f0":"j","\u0249":"j","\u24da":"k","\uff4b":"k","\u1e31":"k","\u01e9":"k","\u1e33":"k","\u0137":"k","\u1e35":"k","\u0199":"k","\u2c6a":"k","\ua741":"k","\ua743":"k","\ua745":"k","\ua7a3":"k","\u24db":"l","\uff4c":"l","\u0140":"l","\u013a":"l","\u013e":"l","\u1e37":"l","\u1e39":"l","\u013c":"l","\u1e3d":"l","\u1e3b":"l","\u017f":"l","\u0142":"l","\u019a":"l","\u026b":"l","\u2c61":"l","\ua749":"l","\ua781":"l","\ua747":"l","\u01c9":"lj","\u24dc":"m","\uff4d":"m","\u1e3f":"m","\u1e41":"m","\u1e43":"m","\u0271":"m","\u026f":"m","\u24dd":"n","\uff4e":"n","\u01f9":"n","\u0144":"n","\xf1":"n","\u1e45":"n","\u0148":"n","\u1e47":"n","\u0146":"n","\u1e4b":"n","\u1e49":"n","\u019e":"n","\u0272":"n","\u0149":"n","\ua791":"n","\ua7a5":"n","\u01cc":"nj","\u24de":"o","\uff4f":"o","\xf2":"o","\xf3":"o","\xf4":"o","\u1ed3":"o","\u1ed1":"o","\u1ed7":"o","\u1ed5":"o","\xf5":"o","\u1e4d":"o","\u022d":"o","\u1e4f":"o","\u014d":"o","\u1e51":"o","\u1e53":"o","\u014f":"o","\u022f":"o","\u0231":"o","\xf6":"o","\u022b":"o","\u1ecf":"o","\u0151":"o","\u01d2":"o","\u020d":"o","\u020f":"o","\u01a1":"o","\u1edd":"o","\u1edb":"o","\u1ee1":"o","\u1edf":"o","\u1ee3":"o","\u1ecd":"o","\u1ed9":"o","\u01eb":"o","\u01ed":"o","\xf8":"o","\u01ff":"o","\u0254":"o","\ua74b":"o","\ua74d":"o","\u0275":"o","\u01a3":"oi","\u0223":"ou","\ua74f":"oo","\u24df":"p","\uff50":"p","\u1e55":"p","\u1e57":"p","\u01a5":"p","\u1d7d":"p","\ua751":"p","\ua753":"p","\ua755":"p","\u24e0":"q","\uff51":"q","\u024b":"q","\ua757":"q","\ua759":"q","\u24e1":"r","\uff52":"r","\u0155":"r","\u1e59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1e5b":"r","\u1e5d":"r","\u0157":"r","\u1e5f":"r","\u024d":"r","\u027d":"r","\ua75b":"r","\ua7a7":"r","\ua783":"r","\u24e2":"s","\uff53":"s","\xdf":"s","\u015b":"s","\u1e65":"s","\u015d":"s","\u1e61":"s","\u0161":"s","\u1e67":"s","\u1e63":"s","\u1e69":"s","\u0219":"s","\u015f":"s","\u023f":"s","\ua7a9":"s","\ua785":"s","\u1e9b":"s","\u24e3":"t","\uff54":"t","\u1e6b":"t","\u1e97":"t","\u0165":"t","\u1e6d":"t","\u021b":"t","\u0163":"t","\u1e71":"t","\u1e6f":"t","\u0167":"t","\u01ad":"t","\u0288":"t","\u2c66":"t","\ua787":"t","\ua729":"tz","\u24e4":"u","\uff55":"u","\xf9":"u","\xfa":"u","\xfb":"u","\u0169":"u","\u1e79":"u","\u016b":"u","\u1e7b":"u","\u016d":"u","\xfc":"u","\u01dc":"u","\u01d8":"u","\u01d6":"u","\u01da":"u","\u1ee7":"u","\u016f":"u","\u0171":"u","\u01d4":"u","\u0215":"u","\u0217":"u","\u01b0":"u","\u1eeb":"u","\u1ee9":"u","\u1eef":"u","\u1eed":"u","\u1ef1":"u","\u1ee5":"u","\u1e73":"u","\u0173":"u","\u1e77":"u","\u1e75":"u","\u0289":"u","\u24e5":"v","\uff56":"v","\u1e7d":"v","\u1e7f":"v","\u028b":"v","\ua75f":"v","\u028c":"v","\ua761":"vy","\u24e6":"w","\uff57":"w","\u1e81":"w","\u1e83":"w","\u0175":"w","\u1e87":"w","\u1e85":"w","\u1e98":"w","\u1e89":"w","\u2c73":"w","\u24e7":"x","\uff58":"x","\u1e8b":"x","\u1e8d":"x","\u24e8":"y","\uff59":"y","\u1ef3":"y","\xfd":"y","\u0177":"y","\u1ef9":"y","\u0233":"y","\u1e8f":"y","\xff":"y","\u1ef7":"y","\u1e99":"y","\u1ef5":"y","\u01b4":"y","\u024f":"y","\u1eff":"y","\u24e9":"z","\uff5a":"z","\u017a":"z","\u1e91":"z","\u017c":"z","\u017e":"z","\u1e93":"z","\u1e95":"z","\u01b6":"z","\u0225":"z","\u0240":"z","\u2c6c":"z","\ua763":"z"};j=a(document),g=function(){var a=1;return function(){return a++}}(),j.on("mousemove",function(a){i.x=a.pageX,i.y=a.pageY}),d=N(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(c){var d,e,f=".select2-results";this.opts=c=this.prepareOpts(c),this.id=c.id,c.element.data("select2")!==b&&null!==c.element.data("select2")&&c.element.data("select2").destroy(),this.container=this.createContainer(),this.containerId="s2id_"+(c.element.attr("id")||"autogen"+g()),this.containerSelector="#"+this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.body=w(function(){return c.element.closest("body")}),D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",c.element.attr("style")),this.container.css(K(c.containerCss)),this.container.addClass(K(c.containerCssClass)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",A),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(c.dropdownCssClass)),this.dropdown.data("select2",this),this.dropdown.on("click",A),this.results=d=this.container.find(f),this.search=e=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",A),u(this.results),this.dropdown.on("mousemove-filtered touchstart touchmove touchend",f,this.bind(this.highlightUnderEvent)),x(80,this.results),this.dropdown.on("scroll-debounced",f,this.bind(this.loadMoreIfNeeded)),a(this.container).on("change",".select2-input",function(a){a.stopPropagation()}),a(this.dropdown).on("change",".select2-input",function(a){a.stopPropagation()}),a.fn.mousewheel&&d.mousewheel(function(a,b,c,e){var f=d.scrollTop();e>0&&0>=f-e?(d.scrollTop(0),A(a)):0>e&&d.get(0).scrollHeight-d.scrollTop()+e<=d.height()&&(d.scrollTop(d.get(0).scrollHeight-d.height()),A(a))}),t(e),e.on("keyup-change input paste",this.bind(this.updateResults)),e.on("focus",function(){e.addClass("select2-focused")}),e.on("blur",function(){e.removeClass("select2-focused")}),this.dropdown.on("mouseup",f,this.bind(function(b){a(b.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(b),this.selectHighlighted(b))})),this.dropdown.on("click mouseup mousedown",function(a){a.stopPropagation()}),a.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==c.maximumInputLength&&this.search.attr("maxlength",c.maximumInputLength);var h=c.element.prop("disabled");h===b&&(h=!1),this.enable(!h);var i=c.element.prop("readonly");i===b&&(i=!1),this.readonly(i),k=k||p(),this.autofocus=c.element.prop("autofocus"),c.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.nextSearchTerm=b},destroy:function(){var a=this.opts.element,c=a.data("select2");this.close(),this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),c!==b&&(c.container.remove(),c.dropdown.remove(),a.removeClass("select2-offscreen").removeData("select2").off(".select2").prop("autofocus",this.autofocus||!1),this.elementTabIndex?a.attr({tabindex:this.elementTabIndex}):a.removeAttr("tabindex"),a.show())},optionToData:function(a){return a.is("option")?{id:a.prop("value"),text:a.text(),element:a.get(),css:a.attr("class"),disabled:a.prop("disabled"),locked:q(a.attr("locked"),"locked")||q(a.data("locked"),!0)}:a.is("optgroup")?{text:a.attr("label"),children:[],element:a.get(),css:a.attr("class")}:void 0},prepareOpts:function(c){var d,e,f,g,h=this;if(d=c.element,"select"===d.get(0).tagName.toLowerCase()&&(this.select=e=c.element),e&&a.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in c)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a <select> element.")}),c=a.extend({},{populateResults:function(d,e,f){var g,i=this.opts.id;g=function(d,e,j){var k,l,m,n,o,p,q,r,s,t;for(d=c.sortResults(d,e,f),k=0,l=d.length;l>k;k+=1)m=d[k],o=m.disabled===!0,n=!o&&i(m)!==b,p=m.children&&m.children.length>0,q=a("<li></li>"),q.addClass("select2-results-dept-"+j),q.addClass("select2-result"),q.addClass(n?"select2-result-selectable":"select2-result-unselectable"),o&&q.addClass("select2-disabled"),p&&q.addClass("select2-result-with-children"),q.addClass(h.opts.formatResultCssClass(m)),r=a(document.createElement("div")),r.addClass("select2-result-label"),t=c.formatResult(m,r,f,h.opts.escapeMarkup),t!==b&&r.html(t),q.append(r),p&&(s=a("<ul></ul>"),s.addClass("select2-result-sub"),g(m.children,s,j+1),q.append(s)),q.data("select2-data",m),e.append(q)},g(e,d,0)}},a.fn.select2.defaults,c),"function"!=typeof c.id&&(f=c.id,c.id=function(a){return a[f]}),a.isArray(c.element.data("select2Tags"))){if("tags"in c)throw"tags specified as both an attribute 'data-select2-tags' and in options of Select2 "+c.element.attr("id");c.tags=c.element.data("select2Tags")}if(e?(c.query=this.bind(function(a){var f,g,i,c={results:[],more:!1},e=a.term;i=function(b,c){var d;b.is("option")?a.matcher(e,b.text(),b)&&c.push(h.optionToData(b)):b.is("optgroup")&&(d=h.optionToData(b),b.children().each2(function(a,b){i(b,d.children)}),d.children.length>0&&c.push(d))},f=d.children(),this.getPlaceholder()!==b&&f.length>0&&(g=this.getPlaceholderOption(),g&&(f=f.not(g))),f.each2(function(a,b){i(b,c.results)}),a.callback(c)}),c.id=function(a){return a.id},c.formatResultCssClass=function(a){return a.css}):"query"in c||("ajax"in c?(g=c.element.data("ajax-url"),g&&g.length>0&&(c.ajax.url=g),c.query=G.call(c.element,c.ajax)):"data"in c?c.query=H(c.data):"tags"in c&&(c.query=I(c.tags),c.createSearchChoice===b&&(c.createSearchChoice=function(b){return{id:a.trim(b),text:a.trim(b)}}),c.initSelection===b&&(c.initSelection=function(b,d){var e=[];a(r(b.val(),c.separator)).each(function(){var b={id:this,text:this},d=c.tags;a.isFunction(d)&&(d=d()),a(d).each(function(){return q(this.id,b.id)?(b=this,!1):void 0}),e.push(b)}),d(e)}))),"function"!=typeof c.query)throw"query function not defined for Select2 "+c.element.attr("id");return c},monitorSource:function(){var c,d,a=this.opts.element;a.on("change.select2",this.bind(function(){this.opts.element.data("select2-change-triggered")!==!0&&this.initSelection()})),c=this.bind(function(){var c=a.prop("disabled");c===b&&(c=!1),this.enable(!c);var d=a.prop("readonly");d===b&&(d=!1),this.readonly(d),D(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.addClass(K(this.opts.containerCssClass)),D(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(K(this.opts.dropdownCssClass))}),a.on("propertychange.select2",c),this.mutationCallback===b&&(this.mutationCallback=function(a){a.forEach(c)}),d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver,d!==b&&(this.propertyObserver&&(delete this.propertyObserver,this.propertyObserver=null),this.propertyObserver=new d(this.mutationCallback),this.propertyObserver.observe(a.get(0),{attributes:!0,subtree:!1}))},triggerSelect:function(b){var c=a.Event("select2-selecting",{val:this.id(b),object:b});return this.opts.element.trigger(c),!c.isDefaultPrevented()},triggerChange:function(b){b=b||{},b=a.extend({},b,{type:"change",val:this.val()}),this.opts.element.data("select2-change-triggered",!0),this.opts.element.trigger(b),this.opts.element.data("select2-change-triggered",!1),this.opts.element.click(),this.opts.blurOnChange&&this.opts.element.blur()},isInterfaceEnabled:function(){return this.enabledInterface===!0},enableInterface:function(){var a=this._enabled&&!this._readonly,b=!a;return a===this.enabledInterface?!1:(this.container.toggleClass("select2-container-disabled",b),this.close(),this.enabledInterface=a,!0)},enable:function(a){a===b&&(a=!0),this._enabled!==a&&(this._enabled=a,this.opts.element.prop("disabled",!a),this.enableInterface())},disable:function(){this.enable(!1)},readonly:function(a){return a===b&&(a=!1),this._readonly===a?!1:(this._readonly=a,this.opts.element.prop("readonly",a),this.enableInterface(),!0)},opened:function(){return this.container.hasClass("select2-dropdown-open")},positionDropdown:function(){var t,u,v,w,x,b=this.dropdown,c=this.container.offset(),d=this.container.outerHeight(!1),e=this.container.outerWidth(!1),f=b.outerHeight(!1),g=a(window),h=g.width(),i=g.height(),j=g.scrollLeft()+h,l=g.scrollTop()+i,m=c.top+d,n=c.left,o=l>=m+f,p=c.top-f>=this.body().scrollTop(),q=b.outerWidth(!1),r=j>=n+q,s=b.hasClass("select2-drop-above");s?(u=!0,!p&&o&&(v=!0,u=!1)):(u=!1,!o&&p&&(v=!0,u=!0)),v&&(b.hide(),c=this.container.offset(),d=this.container.outerHeight(!1),e=this.container.outerWidth(!1),f=b.outerHeight(!1),j=g.scrollLeft()+h,l=g.scrollTop()+i,m=c.top+d,n=c.left,q=b.outerWidth(!1),r=j>=n+q,b.show()),this.opts.dropdownAutoWidth?(x=a(".select2-results",b)[0],b.addClass("select2-drop-auto-width"),b.css("width",""),q=b.outerWidth(!1)+(x.scrollHeight===x.clientHeight?0:k.width),q>e?e=q:q=e,r=j>=n+q):this.container.removeClass("select2-drop-auto-width"),"static"!==this.body().css("position")&&(t=this.body().offset(),m-=t.top,n-=t.left),r||(n=c.left+e-q),w={left:n,width:e},u?(w.bottom=i-c.top,w.top="auto",this.container.addClass("select2-drop-above"),b.addClass("select2-drop-above")):(w.top=m,w.bottom="auto",this.container.removeClass("select2-drop-above"),b.removeClass("select2-drop-above")),w=a.extend(w,K(this.opts.dropdownCss)),b.css(w)},shouldOpen:function(){var b;return this.opened()?!1:this._enabled===!1||this._readonly===!0?!1:(b=a.Event("select2-opening"),this.opts.element.trigger(b),!b.isDefaultPrevented())},clearDropdownAlignmentPreference:function(){this.container.removeClass("select2-drop-above"),this.dropdown.removeClass("select2-drop-above")},open:function(){return this.shouldOpen()?(this.opening(),!0):!1},opening:function(){var f,b=this.containerId,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.addClass("select2-dropdown-open").addClass("select2-container-active"),this.clearDropdownAlignmentPreference(),this.dropdown[0]!==this.body().children().last()[0]&&this.dropdown.detach().appendTo(this.body()),f=a("#select2-drop-mask"),0==f.length&&(f=a(document.createElement("div")),f.attr("id","select2-drop-mask").attr("class","select2-drop-mask"),f.hide(),f.appendTo(this.body()),f.on("mousedown touchstart click",function(b){var d,c=a("#select2-drop");c.length>0&&(d=c.data("select2"),d.opts.selectOnBlur&&d.selectHighlighted({noFocus:!0}),d.close({focus:!0}),b.preventDefault(),b.stopPropagation())})),this.dropdown.prev()[0]!==f[0]&&this.dropdown.before(f),a("#select2-drop").removeAttr("id"),this.dropdown.attr("id","select2-drop"),f.show(),this.positionDropdown(),this.dropdown.show(),this.positionDropdown(),this.dropdown.addClass("select2-drop-active");var g=this;this.container.parents().add(window).each(function(){a(this).on(d+" "+c+" "+e,function(){g.positionDropdown()})})},close:function(){if(this.opened()){var b=this.containerId,c="scroll."+b,d="resize."+b,e="orientationchange."+b;this.container.parents().add(window).each(function(){a(this).off(c).off(d).off(e)}),this.clearDropdownAlignmentPreference(),a("#select2-drop-mask").hide(),this.dropdown.removeAttr("id"),this.dropdown.hide(),this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active"),this.results.empty(),this.clearSearch(),this.search.removeClass("select2-active"),this.opts.element.trigger(a.Event("select2-close"))}},externalSearch:function(a){this.open(),this.search.val(a),this.updateResults(!1)},clearSearch:function(){},getMaximumSelectionSize:function(){return K(this.opts.maximumSelectionSize)},ensureHighlightVisible:function(){var c,d,e,f,g,h,i,b=this.results;if(d=this.highlight(),!(0>d)){if(0==d)return b.scrollTop(0),void 0;c=this.findHighlightableChoices().find(".select2-result-label"),e=a(c[d]),f=e.offset().top+e.outerHeight(!0),d===c.length-1&&(i=b.find("li.select2-more-results"),i.length>0&&(f=i.offset().top+i.outerHeight(!0))),g=b.offset().top+b.outerHeight(!0),f>g&&b.scrollTop(b.scrollTop()+(f-g)),h=e.offset().top-b.offset().top,0>h&&"none"!=e.css("display")&&b.scrollTop(b.scrollTop()+h)}},findHighlightableChoices:function(){return this.results.find(".select2-result-selectable:not(.select2-disabled, .select2-selected)")},moveHighlight:function(b){for(var c=this.findHighlightableChoices(),d=this.highlight();d>-1&&d<c.length;){d+=b;var e=a(c[d]);if(e.hasClass("select2-result-selectable")&&!e.hasClass("select2-disabled")&&!e.hasClass("select2-selected")){this.highlight(d);break}}},highlight:function(b){var d,e,c=this.findHighlightableChoices();return 0===arguments.length?o(c.filter(".select2-highlighted")[0],c.get()):(b>=c.length&&(b=c.length-1),0>b&&(b=0),this.removeHighlight(),d=a(c[b]),d.addClass("select2-highlighted"),this.ensureHighlightVisible(),e=d.data("select2-data"),e&&this.opts.element.trigger({type:"select2-highlight",val:this.id(e),choice:e}),void 0)},removeHighlight:function(){this.results.find(".select2-highlighted").removeClass("select2-highlighted")},countSelectableResults:function(){return this.findHighlightableChoices().length},highlightUnderEvent:function(b){var c=a(b.target).closest(".select2-result-selectable");if(c.length>0&&!c.is(".select2-highlighted")){var d=this.findHighlightableChoices();this.highlight(d.index(c))}else 0==c.length&&this.removeHighlight()},loadMoreIfNeeded:function(){var c,a=this.results,b=a.find("li.select2-more-results"),d=this.resultsPage+1,e=this,f=this.search.val(),g=this.context;0!==b.length&&(c=b.offset().top-a.offset().top-a.height(),c<=this.opts.loadMorePadding&&(b.addClass("select2-active"),this.opts.query({element:this.opts.element,term:f,page:d,context:g,matcher:this.opts.matcher,callback:this.bind(function(c){e.opened()&&(e.opts.populateResults.call(this,a,c.results,{term:f,page:d,context:g}),e.postprocessResults(c,!1,!1),c.more===!0?(b.detach().appendTo(a).text(e.opts.formatLoadMore(d+1)),window.setTimeout(function(){e.loadMoreIfNeeded()},10)):b.remove(),e.positionDropdown(),e.resultsPage=d,e.context=c.context,this.opts.element.trigger({type:"select2-loaded",items:c}))})})))},tokenize:function(){},updateResults:function(c){function m(){d.removeClass("select2-active"),h.positionDropdown()}function n(a){e.html(a),m()}var g,i,l,d=this.search,e=this.results,f=this.opts,h=this,j=d.val(),k=a.data(this.container,"select2-last-term");if((c===!0||!k||!q(j,k))&&(a.data(this.container,"select2-last-term",j),c===!0||this.showSearchInput!==!1&&this.opened())){l=++this.queryCount;var o=this.getMaximumSelectionSize();if(o>=1&&(g=this.data(),a.isArray(g)&&g.length>=o&&J(f.formatSelectionTooBig,"formatSelectionTooBig")))return n("<li class='select2-selection-limit'>"+f.formatSelectionTooBig(o)+"</li>"),void 0;if(d.val().length<f.minimumInputLength)return J(f.formatInputTooShort,"formatInputTooShort")?n("<li class='select2-no-results'>"+f.formatInputTooShort(d.val(),f.minimumInputLength)+"</li>"):n(""),c&&this.showSearch&&this.showSearch(!0),void 0;
22
+ if(f.maximumInputLength&&d.val().length>f.maximumInputLength)return J(f.formatInputTooLong,"formatInputTooLong")?n("<li class='select2-no-results'>"+f.formatInputTooLong(d.val(),f.maximumInputLength)+"</li>"):n(""),void 0;f.formatSearching&&0===this.findHighlightableChoices().length&&n("<li class='select2-searching'>"+f.formatSearching()+"</li>"),d.addClass("select2-active"),this.removeHighlight(),i=this.tokenize(),i!=b&&null!=i&&d.val(i),this.resultsPage=1,f.query({element:f.element,term:d.val(),page:this.resultsPage,context:null,matcher:f.matcher,callback:this.bind(function(g){var i;if(l==this.queryCount){if(!this.opened())return this.search.removeClass("select2-active"),void 0;if(this.context=g.context===b?null:g.context,this.opts.createSearchChoice&&""!==d.val()&&(i=this.opts.createSearchChoice.call(h,d.val(),g.results),i!==b&&null!==i&&h.id(i)!==b&&null!==h.id(i)&&0===a(g.results).filter(function(){return q(h.id(this),h.id(i))}).length&&g.results.unshift(i)),0===g.results.length&&J(f.formatNoMatches,"formatNoMatches"))return n("<li class='select2-no-results'>"+f.formatNoMatches(d.val())+"</li>"),void 0;e.empty(),h.opts.populateResults.call(this,e,g.results,{term:d.val(),page:this.resultsPage,context:null}),g.more===!0&&J(f.formatLoadMore,"formatLoadMore")&&(e.append("<li class='select2-more-results'>"+h.opts.escapeMarkup(f.formatLoadMore(this.resultsPage))+"</li>"),window.setTimeout(function(){h.loadMoreIfNeeded()},10)),this.postprocessResults(g,c),m(),this.opts.element.trigger({type:"select2-loaded",items:g})}})})}},cancel:function(){this.close()},blur:function(){this.opts.selectOnBlur&&this.selectHighlighted({noFocus:!0}),this.close(),this.container.removeClass("select2-container-active"),this.search[0]===document.activeElement&&this.search.blur(),this.clearSearch(),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")},focusSearch:function(){y(this.search)},selectHighlighted:function(a){var b=this.highlight(),c=this.results.find(".select2-highlighted"),d=c.closest(".select2-result").data("select2-data");d?(this.highlight(b),this.onSelect(d,a)):a&&a.noFocus&&this.close()},getPlaceholder:function(){var a;return this.opts.element.attr("placeholder")||this.opts.element.attr("data-placeholder")||this.opts.element.data("placeholder")||this.opts.placeholder||((a=this.getPlaceholderOption())!==b?a.text():b)},getPlaceholderOption:function(){if(this.select){var a=this.select.children("option").first();if(this.opts.placeholderOption!==b)return"first"===this.opts.placeholderOption&&a||"function"==typeof this.opts.placeholderOption&&this.opts.placeholderOption(this.select);if(""===a.text()&&""===a.val())return a}},initContainerWidth:function(){function c(){var c,d,e,f,g,h;if("off"===this.opts.width)return null;if("element"===this.opts.width)return 0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px";if("copy"===this.opts.width||"resolve"===this.opts.width){if(c=this.opts.element.attr("style"),c!==b)for(d=c.split(";"),f=0,g=d.length;g>f;f+=1)if(h=d[f].replace(/\s/g,""),e=h.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i),null!==e&&e.length>=1)return e[1];return"resolve"===this.opts.width?(c=this.opts.element.css("width"),c.indexOf("%")>0?c:0===this.opts.element.outerWidth(!1)?"auto":this.opts.element.outerWidth(!1)+"px"):null}return a.isFunction(this.opts.width)?this.opts.width():this.opts.width}var d=c.call(this);null!==d&&this.container.css("width",d)}}),e=N(d,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container"}).html(["<a href='javascript:void(0)' onclick='return false;' class='select2-choice' tabindex='-1'>"," <span class='select2-chosen'>&nbsp;</span><abbr class='select2-search-choice-close'></abbr>"," <span class='select2-arrow'><b></b></span>","</a>","<input class='select2-focusser select2-offscreen' type='text'/>","<div class='select2-drop select2-display-none'>"," <div class='select2-search'>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'/>"," </div>"," <ul class='select2-results'>"," </ul>","</div>"].join(""));return b},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var c,d,e;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.search.focus(),c=this.search.get(0),c.createTextRange?(d=c.createTextRange(),d.collapse(!1),d.select()):c.setSelectionRange&&(e=this.search.val().length,c.setSelectionRange(e,e)),""===this.search.val()&&this.nextSearchTerm!=b&&(this.search.val(this.nextSearchTerm),this.search.select()),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(a.Event("select2-open"))},close:function(a){this.opened()&&(this.parent.close.apply(this,arguments),a=a||{focus:!0},this.focusser.removeAttr("disabled"),a.focus&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.removeAttr("disabled"),this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.removeAttr("disabled"),this.focusser.focus()},destroy:function(){a("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments)},initContainer:function(){var b,d=this.container,e=this.dropdown;this.opts.minimumResultsForSearch<0?this.showSearch(!1):this.showSearch(!0),this.selection=b=d.find(".select2-choice"),this.focusser=d.find(".select2-focusser"),this.focusser.attr("id","s2id_autogen"+g()),a("label[for='"+this.opts.element.attr("id")+"']").attr("for",this.focusser.attr("id")),this.focusser.attr("tabindex",this.elementTabIndex),this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()){if(a.which===c.PAGE_UP||a.which===c.PAGE_DOWN)return A(a),void 0;switch(a.which){case c.UP:case c.DOWN:return this.moveHighlight(a.which===c.UP?-1:1),A(a),void 0;case c.ENTER:return this.selectHighlighted(),A(a),void 0;case c.TAB:return this.selectHighlighted({noFocus:!0}),void 0;case c.ESC:return this.cancel(a),A(a),void 0}}})),this.search.on("blur",this.bind(function(){document.activeElement===this.body().get(0)&&window.setTimeout(this.bind(function(){this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&a.which!==c.TAB&&!c.isControl(a)&&!c.isFunctionKey(a)&&a.which!==c.ESC){if(this.opts.openOnEnter===!1&&a.which===c.ENTER)return A(a),void 0;if(a.which==c.DOWN||a.which==c.UP||a.which==c.ENTER&&this.opts.openOnEnter){if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return;return this.open(),A(a),void 0}return a.which==c.DELETE||a.which==c.BACKSPACE?(this.opts.allowClear&&this.clear(),A(a),void 0):void 0}})),t(this.focusser),this.focusser.on("keyup-change input",this.bind(function(a){if(this.opts.minimumResultsForSearch>=0){if(a.stopPropagation(),this.opened())return;this.open()}})),b.on("mousedown","abbr",this.bind(function(a){this.isInterfaceEnabled()&&(this.clear(),B(a),this.close(),this.selection.focus())})),b.on("mousedown",this.bind(function(b){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),A(b)})),e.on("mousedown",this.bind(function(){this.search.focus()})),b.on("focus",this.bind(function(a){A(a)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(a.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.setPlaceholder()},clear:function(b){var c=this.selection.data("select2-data");if(c){var d=a.Event("select2-clearing");if(this.opts.element.trigger(d),d.isDefaultPrevented())return;var e=this.getPlaceholderOption();this.opts.element.val(e?e.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),b!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.setPlaceholder())})}},isPlaceholderOptionSelected:function(){var a;return this.getPlaceholder()?(a=this.getPlaceholderOption())!==b&&a.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===b||null===this.opts.element.val():!1},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=a.find("option").filter(function(){return this.selected});b(c.optionToData(d))}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=c.val(),f=null;b.query({matcher:function(a,c,d){var g=q(e,b.id(d));return g&&(f=d),g},callback:a.isFunction(d)?function(){d(f)}:a.noop})}),b},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===b?b:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var a=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&a!==b){if(this.select&&this.getPlaceholderOption()===b)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(a,b,c){var d=0,e=this;if(this.findHighlightableChoices().each2(function(a,b){return q(e.id(b.data("select2-data")),e.opts.element.val())?(d=a,!1):void 0}),c!==!1&&(b===!0&&d>=0?this.highlight(d):this.highlight(0)),b===!0){var g=this.opts.minimumResultsForSearch;g>=0&&this.showSearch(L(a.results)>=g)}},showSearch:function(b){this.showSearchInput!==b&&(this.showSearchInput=b,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!b),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!b),a(this.dropdown,this.container).toggleClass("select2-with-searchbox",b))},onSelect:function(a,b){if(this.triggerSelect(a)){var c=this.opts.element.val(),d=this.data();this.opts.element.val(this.id(a)),this.updateSelection(a),this.opts.element.trigger({type:"select2-selected",val:this.id(a),choice:a}),this.nextSearchTerm=this.opts.nextSearchTerm(a,this.search.val()),this.close(),b&&b.noFocus||this.focusser.focus(),q(c,this.id(a))||this.triggerChange({added:a,removed:d})}},updateSelection:function(a){var d,e,c=this.selection.find(".select2-chosen");this.selection.data("select2-data",a),c.empty(),null!==a&&(d=this.opts.formatSelection(a,c,this.opts.escapeMarkup)),d!==b&&c.append(d),e=this.opts.formatSelectionCssClass(a,c),e!==b&&c.addClass(e),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==b&&this.container.addClass("select2-allowclear")},val:function(){var a,c=!1,d=null,e=this,f=this.data();if(0===arguments.length)return this.opts.element.val();if(a=arguments[0],arguments.length>1&&(c=arguments[1]),this.select)this.select.val(a).find("option").filter(function(){return this.selected}).each2(function(a,b){return d=e.optionToData(b),!1}),this.updateSelection(d),this.setPlaceholder(),c&&this.triggerChange({added:d,removed:f});else{if(!a&&0!==a)return this.clear(c),void 0;if(this.opts.initSelection===b)throw new Error("cannot call val() if initSelection() is not defined");this.opts.element.val(a),this.opts.initSelection(this.opts.element,function(a){e.opts.element.val(a?e.id(a):""),e.updateSelection(a),e.setPlaceholder(),c&&e.triggerChange({added:a,removed:f})})}},clearSearch:function(){this.search.val(""),this.focusser.val("")},data:function(a){var c,d=!1;return 0===arguments.length?(c=this.selection.data("select2-data"),c==b&&(c=null),c):(arguments.length>1&&(d=arguments[1]),a?(c=this.data(),this.opts.element.val(a?this.id(a):""),this.updateSelection(a),d&&this.triggerChange({added:a,removed:c})):this.clear(d),void 0)}}),f=N(d,{createContainer:function(){var b=a(document.createElement("div")).attr({"class":"select2-container select2-container-multi"}).html(["<ul class='select2-choices'>"," <li class='select2-search-field'>"," <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>"," </li>","</ul>","<div class='select2-drop select2-drop-multi select2-display-none'>"," <ul class='select2-results'>"," </ul>","</div>"].join(""));return b},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=[];a.find("option").filter(function(){return this.selected}).each2(function(a,b){d.push(c.optionToData(b))}),b(d)}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=r(c.val(),b.separator),f=[];b.query({matcher:function(c,d,g){var h=a.grep(e,function(a){return q(a,b.id(g))}).length;return h&&f.push(g),h},callback:a.isFunction(d)?function(){for(var a=[],c=0;c<e.length;c++)for(var g=e[c],h=0;h<f.length;h++){var i=f[h];if(q(g,b.id(i))){a.push(i),f.splice(h,1);break}}d(a)}:a.noop})}),b},selectChoice:function(a){var b=this.container.find(".select2-search-choice-focus");b.length&&a&&a[0]==b[0]||(b.length&&this.opts.element.trigger("choice-deselected",b),b.removeClass("select2-search-choice-focus"),a&&a.length&&(this.close(),a.addClass("select2-search-choice-focus"),this.opts.element.trigger("choice-selected",a)))},destroy:function(){a("label[for='"+this.search.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments)},initContainer:function(){var d,b=".select2-choices";this.searchContainer=this.container.find(".select2-search-field"),this.selection=d=this.container.find(b);var e=this;this.selection.on("click",".select2-search-choice:not(.select2-locked)",function(){e.search[0].focus(),e.selectChoice(a(this))}),this.search.attr("id","s2id_autogen"+g()),a("label[for='"+this.opts.element.attr("id")+"']").attr("for",this.search.attr("id")),this.search.on("input paste",this.bind(function(){this.isInterfaceEnabled()&&(this.opened()||this.open())})),this.search.attr("tabindex",this.elementTabIndex),this.keydowns=0,this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()){++this.keydowns;var b=d.find(".select2-search-choice-focus"),e=b.prev(".select2-search-choice:not(.select2-locked)"),f=b.next(".select2-search-choice:not(.select2-locked)"),g=z(this.search);if(b.length&&(a.which==c.LEFT||a.which==c.RIGHT||a.which==c.BACKSPACE||a.which==c.DELETE||a.which==c.ENTER)){var h=b;return a.which==c.LEFT&&e.length?h=e:a.which==c.RIGHT?h=f.length?f:null:a.which===c.BACKSPACE?(this.unselect(b.first()),this.search.width(10),h=e.length?e:f):a.which==c.DELETE?(this.unselect(b.first()),this.search.width(10),h=f.length?f:null):a.which==c.ENTER&&(h=null),this.selectChoice(h),A(a),h&&h.length||this.open(),void 0}if((a.which===c.BACKSPACE&&1==this.keydowns||a.which==c.LEFT)&&0==g.offset&&!g.length)return this.selectChoice(d.find(".select2-search-choice:not(.select2-locked)").last()),A(a),void 0;if(this.selectChoice(null),this.opened())switch(a.which){case c.UP:case c.DOWN:return this.moveHighlight(a.which===c.UP?-1:1),A(a),void 0;case c.ENTER:return this.selectHighlighted(),A(a),void 0;case c.TAB:return this.selectHighlighted({noFocus:!0}),this.close(),void 0;case c.ESC:return this.cancel(a),A(a),void 0}if(a.which!==c.TAB&&!c.isControl(a)&&!c.isFunctionKey(a)&&a.which!==c.BACKSPACE&&a.which!==c.ESC){if(a.which===c.ENTER){if(this.opts.openOnEnter===!1)return;if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return}this.open(),(a.which===c.PAGE_UP||a.which===c.PAGE_DOWN)&&A(a),a.which===c.ENTER&&A(a)}}})),this.search.on("keyup",this.bind(function(){this.keydowns=0,this.resizeSearch()})),this.search.on("blur",this.bind(function(b){this.container.removeClass("select2-container-active"),this.search.removeClass("select2-focused"),this.selectChoice(null),this.opened()||this.clearSearch(),b.stopImmediatePropagation(),this.opts.element.trigger(a.Event("select2-blur"))})),this.container.on("click",b,this.bind(function(b){this.isInterfaceEnabled()&&(a(b.target).closest(".select2-search-choice").length>0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.open(),this.focusSearch(),b.preventDefault()))})),this.container.on("focus",b,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.addClass("select2-offscreen"),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var c=this;this.opts.initSelection.call(null,this.opts.element,function(a){a!==b&&null!==a&&(c.updateSelection(a),c.close(),c.clearSearch())})}},clearSearch:function(){var a=this.getPlaceholder(),c=this.getMaxSearchWidth();a!==b&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(a).addClass("select2-default"),this.search.width(c>0?c:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.updateResults(!0),this.search.focus(),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(b){var c=[],d=[],e=this;a(b).each(function(){o(e.id(this),c)<0&&(c.push(e.id(this)),d.push(this))}),b=d,this.selection.find(".select2-search-choice").remove(),a(b).each(function(){e.addSelectedChoice(this)}),e.postprocessResults()},tokenize:function(){var a=this.search.val();a=this.opts.tokenizer.call(this,a,this.data(),this.bind(this.onSelect),this.opts),null!=a&&a!=b&&(this.search.val(a),a.length>0&&this.open())},onSelect:function(a,b){this.triggerSelect(a)&&(this.addSelectedChoice(a),this.opts.element.trigger({type:"selected",val:this.id(a),choice:a}),(this.select||!this.opts.closeOnSelect)&&this.postprocessResults(a,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()&&this.updateResults(!0),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:a}),b&&b.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(c){var j,k,d=!c.locked,e=a("<li class='select2-search-choice'> <div></div> <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a></li>"),f=a("<li class='select2-search-choice select2-locked'><div></div></li>"),g=d?e:f,h=this.id(c),i=this.getVal();j=this.opts.formatSelection(c,g.find("div"),this.opts.escapeMarkup),j!=b&&g.find("div").replaceWith("<div>"+j+"</div>"),k=this.opts.formatSelectionCssClass(c,g.find("div")),k!=b&&g.addClass(k),d&&g.find(".select2-search-choice-close").on("mousedown",A).on("click dblclick",this.bind(function(b){this.isInterfaceEnabled()&&(a(b.target).closest(".select2-search-choice").fadeOut("fast",this.bind(function(){this.unselect(a(b.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),this.close(),this.focusSearch()})).dequeue(),A(b))})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),g.data("select2-data",c),g.insertBefore(this.searchContainer),i.push(h),this.setVal(i)},unselect:function(b){var d,e,c=this.getVal();if(b=b.closest(".select2-search-choice"),0===b.length)throw"Invalid argument: "+b+". Must be .select2-search-choice";if(d=b.data("select2-data")){for(;(e=o(this.id(d),c))>=0;)c.splice(e,1),this.setVal(c),this.select&&this.postprocessResults();var f=a.Event("select2-removing");f.val=this.id(d),f.choice=d,this.opts.element.trigger(f),f.isDefaultPrevented()||(b.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(d),choice:d}),this.triggerChange({removed:d}))}},postprocessResults:function(a,b,c){var d=this.getVal(),e=this.results.find(".select2-result"),f=this.results.find(".select2-result-with-children"),g=this;e.each2(function(a,b){var c=g.id(b.data("select2-data"));o(c,d)>=0&&(b.addClass("select2-selected"),b.find(".select2-result-selectable").addClass("select2-selected"))}),f.each2(function(a,b){b.is(".select2-result-selectable")||0!==b.find(".select2-result-selectable:not(.select2-selected)").length||b.addClass("select2-selected")}),-1==this.highlight()&&c!==!1&&g.highlight(0),!this.opts.createSearchChoice&&!e.filter(".select2-result:not(.select2-selected)").length>0&&(!a||a&&!a.more&&0===this.results.find(".select2-no-results").length)&&J(g.opts.formatNoMatches,"formatNoMatches")&&this.results.append("<li class='select2-no-results'>"+g.opts.formatNoMatches(g.search.val())+"</li>")},getMaxSearchWidth:function(){return this.selection.width()-s(this.search)},resizeSearch:function(){var a,b,c,d,e,f=s(this.search);a=C(this.search)+10,b=this.search.offset().left,c=this.selection.width(),d=this.selection.offset().left,e=c-(b-d)-f,a>e&&(e=c-f),40>e&&(e=c-f),0>=e&&(e=a),this.search.width(Math.floor(e))},getVal:function(){var a;return this.select?(a=this.select.val(),null===a?[]:a):(a=this.opts.element.val(),r(a,this.opts.separator))},setVal:function(b){var c;this.select?this.select.val(b):(c=[],a(b).each(function(){o(this,c)<0&&c.push(this)}),this.opts.element.val(0===c.length?"":c.join(this.opts.separator)))},buildChangeDetails:function(a,b){for(var b=b.slice(0),a=a.slice(0),c=0;c<b.length;c++)for(var d=0;d<a.length;d++)q(this.opts.id(b[c]),this.opts.id(a[d]))&&(b.splice(c,1),c>0&&c--,a.splice(d,1),d--);return{added:b,removed:a}},val:function(c,d){var e,f=this;if(0===arguments.length)return this.getVal();if(e=this.data(),e.length||(e=[]),!c&&0!==c)return this.opts.element.val(""),this.updateSelection([]),this.clearSearch(),d&&this.triggerChange({added:this.data(),removed:e}),void 0;if(this.setVal(c),this.select)this.opts.initSelection(this.select,this.bind(this.updateSelection)),d&&this.triggerChange(this.buildChangeDetails(e,this.data()));else{if(this.opts.initSelection===b)throw new Error("val() cannot be called if initSelection() is not defined");this.opts.initSelection(this.opts.element,function(b){var c=a.map(b,f.id);f.setVal(c),f.updateSelection(b),f.clearSearch(),d&&f.triggerChange(f.buildChangeDetails(e,f.data()))})}this.clearSearch()},onSortStart:function(){if(this.select)throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var b=[],c=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){b.push(c.opts.id(a(this).data("select2-data")))}),this.setVal(b),this.triggerChange()},data:function(b,c){var e,f,d=this;return 0===arguments.length?this.selection.find(".select2-search-choice").map(function(){return a(this).data("select2-data")}).get():(f=this.data(),b||(b=[]),e=a.map(b,function(a){return d.opts.id(a)}),this.setVal(e),this.updateSelection(b),this.clearSearch(),c&&this.triggerChange(this.buildChangeDetails(f,this.data())),void 0)}}),a.fn.select2=function(){var d,g,h,i,j,c=Array.prototype.slice.call(arguments,0),k=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],l=["opened","isFocused","container","dropdown"],m=["val","data"],n={search:"externalSearch"};return this.each(function(){if(0===c.length||"object"==typeof c[0])d=0===c.length?{}:a.extend({},c[0]),d.element=a(this),"select"===d.element.get(0).tagName.toLowerCase()?j=d.element.prop("multiple"):(j=d.multiple||!1,"tags"in d&&(d.multiple=j=!0)),g=j?new f:new e,g.init(d);else{if("string"!=typeof c[0])throw"Invalid arguments to select2 plugin: "+c;if(o(c[0],k)<0)throw"Unknown method: "+c[0];if(i=b,g=a(this).data("select2"),g===b)return;if(h=c[0],"container"===h?i=g.container:"dropdown"===h?i=g.dropdown:(n[h]&&(h=n[h]),i=g[h].apply(g,c.slice(1))),o(c[0],l)>=0||o(c[0],m)&&1==c.length)return!1}}),i===b?this:i},a.fn.select2.defaults={width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c,d){var e=[];return E(a.text,c.term,e,d),e.join("")},formatSelection:function(a,c,d){return a?d(a.text):b},sortResults:function(a){return a},formatResultCssClass:function(){return b},formatSelectionCssClass:function(){return b},formatNoMatches:function(){return"No matches found"},formatInputTooShort:function(a,b){var c=b-a.length;return"Please enter "+c+" more character"+(1==c?"":"s")},formatInputTooLong:function(a,b){var c=a.length-b;return"Please delete "+c+" character"+(1==c?"":"s")},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(){return"Loading more results..."},formatSearching:function(){return"Searching..."},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(a){return a.id},matcher:function(a,b){return n(""+b).toUpperCase().indexOf(n(""+a).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:M,escapeMarkup:F,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(a){return a},adaptDropdownCssClass:function(){return null},nextSearchTerm:function(){return b}},a.fn.select2.ajaxDefaults={transport:a.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:G,local:H,tags:I},util:{debounce:v,markMatch:E,escapeMarkup:F,stripDiacritics:n},"class":{"abstract":d,single:e,multi:f}}}}(jQuery);
static/js/jquery/ui.autocomplete.js ADDED
@@ -0,0 +1,606 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Autocomplete 1.8.10
3
+ *
4
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Autocomplete
9
+ *
10
+ * Depends:
11
+ * jquery.ui.core.js
12
+ * jquery.ui.widget.js
13
+ * jquery.ui.position.js
14
+ */
15
+ (function( $, undefined ) {
16
+
17
+ // used to prevent race conditions with remote data sources
18
+ var requestIndex = 0;
19
+
20
+ $.widget( "ui.autocomplete", {
21
+ options: {
22
+ appendTo: "body",
23
+ delay: 300,
24
+ minLength: 1,
25
+ position: {
26
+ my: "left top",
27
+ at: "left bottom",
28
+ collision: "none"
29
+ },
30
+ source: null
31
+ },
32
+
33
+ pending: 0,
34
+
35
+ _create: function() {
36
+ var self = this,
37
+ doc = this.element[ 0 ].ownerDocument,
38
+ suppressKeyPress;
39
+
40
+ this.element
41
+ .addClass( "ui-autocomplete-input" )
42
+ .attr( "autocomplete", "off" )
43
+ // TODO verify these actually work as intended
44
+ .attr({
45
+ role: "textbox",
46
+ "aria-autocomplete": "list",
47
+ "aria-haspopup": "true"
48
+ })
49
+ .bind( "keydown.autocomplete", function( event ) {
50
+ if ( self.options.disabled || self.element.attr( "readonly" ) ) {
51
+ return;
52
+ }
53
+
54
+ suppressKeyPress = false;
55
+ var keyCode = $.ui.keyCode;
56
+ switch( event.keyCode ) {
57
+ case keyCode.PAGE_UP:
58
+ self._move( "previousPage", event );
59
+ break;
60
+ case keyCode.PAGE_DOWN:
61
+ self._move( "nextPage", event );
62
+ break;
63
+ case keyCode.UP:
64
+ self._move( "previous", event );
65
+ // prevent moving cursor to beginning of text field in some browsers
66
+ event.preventDefault();
67
+ break;
68
+ case keyCode.DOWN:
69
+ self._move( "next", event );
70
+ // prevent moving cursor to end of text field in some browsers
71
+ event.preventDefault();
72
+ break;
73
+ case keyCode.ENTER:
74
+ case keyCode.NUMPAD_ENTER:
75
+ // when menu is open and has focus
76
+ if ( self.menu.active ) {
77
+ // #6055 - Opera still allows the keypress to occur
78
+ // which causes forms to submit
79
+ suppressKeyPress = true;
80
+ event.preventDefault();
81
+ }
82
+ //passthrough - ENTER and TAB both select the current element
83
+ case keyCode.TAB:
84
+ if ( !self.menu.active ) {
85
+ return;
86
+ }
87
+ self.menu.select( event );
88
+ break;
89
+ case keyCode.ESCAPE:
90
+ self.element.val( self.term );
91
+ self.close( event );
92
+ break;
93
+ default:
94
+ // keypress is triggered before the input value is changed
95
+ clearTimeout( self.searching );
96
+ self.searching = setTimeout(function() {
97
+ // only search if the value has changed
98
+ if ( self.term != self.element.val() ) {
99
+ self.selectedItem = null;
100
+ self.search( null, event );
101
+ }
102
+ }, self.options.delay );
103
+ break;
104
+ }
105
+ })
106
+ .bind( "keypress.autocomplete", function( event ) {
107
+ if ( suppressKeyPress ) {
108
+ suppressKeyPress = false;
109
+ event.preventDefault();
110
+ }
111
+ })
112
+ .bind( "focus.autocomplete", function() {
113
+ if ( self.options.disabled ) {
114
+ return;
115
+ }
116
+
117
+ self.selectedItem = null;
118
+ self.previous = self.element.val();
119
+ })
120
+ .bind( "blur.autocomplete", function( event ) {
121
+ if ( self.options.disabled ) {
122
+ return;
123
+ }
124
+
125
+ clearTimeout( self.searching );
126
+ // clicks on the menu (or a button to trigger a search) will cause a blur event
127
+ self.closing = setTimeout(function() {
128
+ self.close( event );
129
+ self._change( event );
130
+ }, 150 );
131
+ });
132
+ this._initSource();
133
+ this.response = function() {
134
+ return self._response.apply( self, arguments );
135
+ };
136
+ this.menu = $( "<ul></ul>" )
137
+ .addClass( "ui-autocomplete" )
138
+ .appendTo( $( this.options.appendTo || "body", doc )[0] )
139
+ // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
140
+ .mousedown(function( event ) {
141
+ // clicking on the scrollbar causes focus to shift to the body
142
+ // but we can't detect a mouseup or a click immediately afterward
143
+ // so we have to track the next mousedown and close the menu if
144
+ // the user clicks somewhere outside of the autocomplete
145
+ var menuElement = self.menu.element[ 0 ];
146
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
147
+ setTimeout(function() {
148
+ $( document ).one( 'mousedown', function( event ) {
149
+ if ( event.target !== self.element[ 0 ] &&
150
+ event.target !== menuElement &&
151
+ !$.ui.contains( menuElement, event.target ) ) {
152
+ self.close();
153
+ }
154
+ });
155
+ }, 1 );
156
+ }
157
+
158
+ // use another timeout to make sure the blur-event-handler on the input was already triggered
159
+ setTimeout(function() {
160
+ clearTimeout( self.closing );
161
+ }, 13);
162
+ })
163
+ .menu({
164
+ focus: function( event, ui ) {
165
+ var item = ui.item.data( "item.autocomplete" );
166
+ if ( false !== self._trigger( "focus", event, { item: item } ) ) {
167
+ // use value to match what will end up in the input, if it was a key event
168
+ if ( /^key/.test(event.originalEvent.type) ) {
169
+ self.element.val( item.value );
170
+ }
171
+ }
172
+ },
173
+ selected: function( event, ui ) {
174
+ var item = ui.item.data( "item.autocomplete" ),
175
+ previous = self.previous;
176
+
177
+ // only trigger when focus was lost (click on menu)
178
+ if ( self.element[0] !== doc.activeElement ) {
179
+ self.element.focus();
180
+ self.previous = previous;
181
+ // #6109 - IE triggers two focus events and the second
182
+ // is asynchronous, so we need to reset the previous
183
+ // term synchronously and asynchronously :-(
184
+ setTimeout(function() {
185
+ self.previous = previous;
186
+ self.selectedItem = item;
187
+ }, 1);
188
+ }
189
+
190
+ if ( false !== self._trigger( "select", event, { item: item } ) ) {
191
+ self.element.val( item.value );
192
+ }
193
+ // reset the term after the select event
194
+ // this allows custom select handling to work properly
195
+ self.term = self.element.val();
196
+
197
+ self.close( event );
198
+ self.selectedItem = item;
199
+ },
200
+ blur: function( event, ui ) {
201
+ // don't set the value of the text field if it's already correct
202
+ // this prevents moving the cursor unnecessarily
203
+ if ( self.menu.element.is(":visible") &&
204
+ ( self.element.val() !== self.term ) ) {
205
+ self.element.val( self.term );
206
+ }
207
+ }
208
+ })
209
+ .zIndex( this.element.zIndex() + 1 )
210
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
211
+ .css({ top: 0, left: 0 })
212
+ .data( "menu" );
213
+ if ( $.fn.bgiframe ) {
214
+ this.menu.element.bgiframe();
215
+ }
216
+ },
217
+
218
+ destroy: function() {
219
+ this.element
220
+ .removeClass( "ui-autocomplete-input" )
221
+ .removeAttr( "autocomplete" )
222
+ .removeAttr( "role" )
223
+ .removeAttr( "aria-autocomplete" )
224
+ .removeAttr( "aria-haspopup" );
225
+ this.menu.element.remove();
226
+ $.Widget.prototype.destroy.call( this );
227
+ },
228
+
229
+ _setOption: function( key, value ) {
230
+ $.Widget.prototype._setOption.apply( this, arguments );
231
+ if ( key === "source" ) {
232
+ this._initSource();
233
+ }
234
+ if ( key === "appendTo" ) {
235
+ this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
236
+ }
237
+ if ( key === "disabled" && value && this.xhr ) {
238
+ this.xhr.abort();
239
+ }
240
+ },
241
+
242
+ _initSource: function() {
243
+ var self = this,
244
+ array,
245
+ url;
246
+ if ( $.isArray(this.options.source) ) {
247
+ array = this.options.source;
248
+ this.source = function( request, response ) {
249
+ response( $.ui.autocomplete.filter(array, request.term) );
250
+ };
251
+ } else if ( typeof this.options.source === "string" ) {
252
+ url = this.options.source;
253
+ this.source = function( request, response ) {
254
+ if ( self.xhr ) {
255
+ self.xhr.abort();
256
+ }
257
+ self.xhr = $.ajax({
258
+ url: url,
259
+ data: request,
260
+ dataType: "json",
261
+ autocompleteRequest: ++requestIndex,
262
+ success: function( data, status ) {
263
+ if ( this.autocompleteRequest === requestIndex ) {
264
+ response( data );
265
+ }
266
+ },
267
+ error: function() {
268
+ if ( this.autocompleteRequest === requestIndex ) {
269
+ response( [] );
270
+ }
271
+ }
272
+ });
273
+ };
274
+ } else {
275
+ this.source = this.options.source;
276
+ }
277
+ },
278
+
279
+ search: function( value, event ) {
280
+ value = value != null ? value : this.element.val();
281
+
282
+ // always save the actual value, not the one passed as an argument
283
+ this.term = this.element.val();
284
+
285
+ if ( value.length < this.options.minLength ) {
286
+ return this.close( event );
287
+ }
288
+
289
+ clearTimeout( this.closing );
290
+ if ( this._trigger( "search", event ) === false ) {
291
+ return;
292
+ }
293
+
294
+ return this._search( value );
295
+ },
296
+
297
+ _search: function( value ) {
298
+ this.pending++;
299
+ this.element.addClass( "ui-autocomplete-loading" );
300
+
301
+ this.source( { term: value }, this.response );
302
+ },
303
+
304
+ _response: function( content ) {
305
+ if ( !this.options.disabled && content && content.length ) {
306
+ content = this._normalize( content );
307
+ this._suggest( content );
308
+ this._trigger( "open" );
309
+ } else {
310
+ this.close();
311
+ }
312
+ this.pending--;
313
+ if ( !this.pending ) {
314
+ this.element.removeClass( "ui-autocomplete-loading" );
315
+ }
316
+ },
317
+
318
+ close: function( event ) {
319
+ clearTimeout( this.closing );
320
+ if ( this.menu.element.is(":visible") ) {
321
+ this.menu.element.hide();
322
+ this.menu.deactivate();
323
+ this._trigger( "close", event );
324
+ }
325
+ },
326
+
327
+ _change: function( event ) {
328
+ if ( this.previous !== this.element.val() ) {
329
+ this._trigger( "change", event, { item: this.selectedItem } );
330
+ }
331
+ },
332
+
333
+ _normalize: function( items ) {
334
+ // assume all items have the right format when the first item is complete
335
+ if ( items.length && items[0].label && items[0].value ) {
336
+ return items;
337
+ }
338
+ return $.map( items, function(item) {
339
+ if ( typeof item === "string" ) {
340
+ return {
341
+ label: item,
342
+ value: item
343
+ };
344
+ }
345
+ return $.extend({
346
+ label: item.label || item.value,
347
+ value: item.value || item.label
348
+ }, item );
349
+ });
350
+ },
351
+
352
+ _suggest: function( items ) {
353
+ var ul = this.menu.element
354
+ .empty()
355
+ .zIndex( this.element.zIndex() + 1 );
356
+ this._renderMenu( ul, items );
357
+ // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
358
+ this.menu.deactivate();
359
+ this.menu.refresh();
360
+
361
+ // size and position menu
362
+ ul.show();
363
+ this._resizeMenu();
364
+ ul.position( $.extend({
365
+ of: this.element
366
+ }, this.options.position ));
367
+ },
368
+
369
+ _resizeMenu: function() {
370
+ var ul = this.menu.element;
371
+ ul.outerWidth( Math.max(
372
+ ul.width( "" ).outerWidth(),
373
+ this.element.outerWidth()
374
+ ) );
375
+ },
376
+
377
+ _renderMenu: function( ul, items ) {
378
+ var self = this;
379
+ $.each( items, function( index, item ) {
380
+ self._renderItem( ul, item );
381
+ });
382
+ },
383
+
384
+ _renderItem: function( ul, item) {
385
+ return $( "<li></li>" )
386
+ .data( "item.autocomplete", item )
387
+ .append( $( "<a></a>" ).text( item.label ) )
388
+ .appendTo( ul );
389
+ },
390
+
391
+ _move: function( direction, event ) {
392
+ if ( !this.menu.element.is(":visible") ) {
393
+ this.search( null, event );
394
+ return;
395
+ }
396
+ if ( this.menu.first() && /^previous/.test(direction) ||
397
+ this.menu.last() && /^next/.test(direction) ) {
398
+ this.element.val( this.term );
399
+ this.menu.deactivate();
400
+ return;
401
+ }
402
+ this.menu[ direction ]( event );
403
+ },
404
+
405
+ widget: function() {
406
+ return this.menu.element;
407
+ }
408
+ });
409
+
410
+ $.extend( $.ui.autocomplete, {
411
+ escapeRegex: function( value ) {
412
+ return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
413
+ },
414
+ filter: function(array, term) {
415
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
416
+ return $.grep( array, function(value) {
417
+ return matcher.test( value.label || value.value || value );
418
+ });
419
+ }
420
+ });
421
+
422
+ }( jQuery ));
423
+
424
+ /*
425
+ * jQuery UI Menu (not officially released)
426
+ *
427
+ * This widget isn't yet finished and the API is subject to change. We plan to finish
428
+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
429
+ * as long as you're okay with migrating your code later on. We can help with that, too.
430
+ *
431
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
432
+ * Dual licensed under the MIT or GPL Version 2 licenses.
433
+ * http://jquery.org/license
434
+ *
435
+ * http://docs.jquery.com/UI/Menu
436
+ *
437
+ * Depends:
438
+ * jquery.ui.core.js
439
+ * jquery.ui.widget.js
440
+ */
441
+ (function($) {
442
+
443
+ $.widget("ui.menu", {
444
+ _create: function() {
445
+ var self = this;
446
+ this.element
447
+ .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
448
+ .attr({
449
+ role: "listbox",
450
+ "aria-activedescendant": "ui-active-menuitem"
451
+ })
452
+ .click(function( event ) {
453
+ if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
454
+ return;
455
+ }
456
+ // temporary
457
+ event.preventDefault();
458
+ self.select( event );
459
+ });
460
+ this.refresh();
461
+ },
462
+
463
+ refresh: function() {
464
+ var self = this;
465
+
466
+ // don't refresh list items that are already adapted
467
+ var items = this.element.children("li:not(.ui-menu-item):has(a)")
468
+ .addClass("ui-menu-item")
469
+ .attr("role", "menuitem");
470
+
471
+ items.children("a")
472
+ .addClass("ui-corner-all")
473
+ .attr("tabindex", -1)
474
+ // mouseenter doesn't work with event delegation
475
+ .mouseenter(function( event ) {
476
+ self.activate( event, $(this).parent() );
477
+ })
478
+ .mouseleave(function() {
479
+ self.deactivate();
480
+ });
481
+ },
482
+
483
+ activate: function( event, item ) {
484
+ this.deactivate();
485
+ if (this.hasScroll()) {
486
+ var offset = item.offset().top - this.element.offset().top,
487
+ scroll = this.element.attr("scrollTop"),
488
+ elementHeight = this.element.height();
489
+ if (offset < 0) {
490
+ this.element.attr("scrollTop", scroll + offset);
491
+ } else if (offset >= elementHeight) {
492
+ this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
493
+ }
494
+ }
495
+ this.active = item.eq(0)
496
+ .children("a")
497
+ .addClass("ui-state-hover")
498
+ .attr("id", "ui-active-menuitem")
499
+ .end();
500
+ this._trigger("focus", event, { item: item });
501
+ },
502
+
503
+ deactivate: function() {
504
+ if (!this.active) { return; }
505
+
506
+ this.active.children("a")
507
+ .removeClass("ui-state-hover")
508
+ .removeAttr("id");
509
+ this._trigger("blur");
510
+ this.active = null;
511
+ },
512
+
513
+ next: function(event) {
514
+ this.move("next", ".ui-menu-item:first", event);
515
+ },
516
+
517
+ previous: function(event) {
518
+ this.move("prev", ".ui-menu-item:last", event);
519
+ },
520
+
521
+ first: function() {
522
+ return this.active && !this.active.prevAll(".ui-menu-item").length;
523
+ },
524
+
525
+ last: function() {
526
+ return this.active && !this.active.nextAll(".ui-menu-item").length;
527
+ },
528
+
529
+ move: function(direction, edge, event) {
530
+ if (!this.active) {
531
+ this.activate(event, this.element.children(edge));
532
+ return;
533
+ }
534
+ var next = this.active[direction + "All"](".ui-menu-item").eq(0);
535
+ if (next.length) {
536
+ this.activate(event, next);
537
+ } else {
538
+ this.activate(event, this.element.children(edge));
539
+ }
540
+ },
541
+
542
+ // TODO merge with previousPage
543
+ nextPage: function(event) {
544
+ if (this.hasScroll()) {
545
+ // TODO merge with no-scroll-else
546
+ if (!this.active || this.last()) {
547
+ this.activate(event, this.element.children(".ui-menu-item:first"));
548
+ return;
549
+ }
550
+ var base = this.active.offset().top,
551
+ height = this.element.height(),
552
+ result = this.element.children(".ui-menu-item").filter(function() {
553
+ var close = $(this).offset().top - base - height + $(this).height();
554
+ // TODO improve approximation
555
+ return close < 10 && close > -10;
556
+ });
557
+
558
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
559
+ if (!result.length) {
560
+ result = this.element.children(".ui-menu-item:last");
561
+ }
562
+ this.activate(event, result);
563
+ } else {
564
+ this.activate(event, this.element.children(".ui-menu-item")
565
+ .filter(!this.active || this.last() ? ":first" : ":last"));
566
+ }
567
+ },
568
+
569
+ // TODO merge with nextPage
570
+ previousPage: function(event) {
571
+ if (this.hasScroll()) {
572
+ // TODO merge with no-scroll-else
573
+ if (!this.active || this.first()) {
574
+ this.activate(event, this.element.children(".ui-menu-item:last"));
575
+ return;
576
+ }
577
+
578
+ var base = this.active.offset().top,
579
+ height = this.element.height();
580
+ result = this.element.children(".ui-menu-item").filter(function() {
581
+ var close = $(this).offset().top - base + height - $(this).height();
582
+ // TODO improve approximation
583
+ return close < 10 && close > -10;
584
+ });
585
+
586
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
587
+ if (!result.length) {
588
+ result = this.element.children(".ui-menu-item:first");
589
+ }
590
+ this.activate(event, result);
591
+ } else {
592
+ this.activate(event, this.element.children(".ui-menu-item")
593
+ .filter(!this.active || this.first() ? ":last" : ":first"));
594
+ }
595
+ },
596
+
597
+ hasScroll: function() {
598
+ return this.element.height() < this.element.attr("scrollHeight");
599
+ },
600
+
601
+ select: function( event ) {
602
+ this._trigger("selected", event, { item: this.active });
603
+ }
604
+ });
605
+
606
+ }(jQuery));
static/js/jquery/ui.datepicker.js ADDED
@@ -0,0 +1,1636 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI Datepicker 1.7.3
3
+ *
4
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Datepicker
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ */
13
+
14
+ (function($) { // hide the namespace
15
+
16
+ $.extend($.ui, { datepicker: { version: "1.7.3" } });
17
+
18
+ var PROP_NAME = 'datepicker';
19
+
20
+ /* Date picker manager.
21
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
22
+ Settings for (groups of) date pickers are maintained in an instance object,
23
+ allowing multiple different settings on the same page. */
24
+
25
+ function Datepicker() {
26
+ this.debug = false; // Change this to true to start debugging
27
+ this._curInst = null; // The current instance in use
28
+ this._keyEvent = false; // If the last event was a key event
29
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
30
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
31
+ this._inDialog = false; // True if showing within a "dialog", false if not
32
+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
33
+ this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
34
+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
35
+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
36
+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
37
+ this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
38
+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
39
+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
40
+ this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
41
+ this.regional = []; // Available regional settings, indexed by language code
42
+ this.regional[''] = { // Default regional settings
43
+ closeText: 'Done', // Display text for close link
44
+ prevText: 'Prev', // Display text for previous month link
45
+ nextText: 'Next', // Display text for next month link
46
+ currentText: 'Today', // Display text for current month link
47
+ monthNames: ['January','February','March','April','May','June',
48
+ 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
49
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
50
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
51
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
52
+ dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
53
+ dateFormat: 'mm/dd/yy', // See format options on parseDate
54
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
55
+ isRTL: false // True if right-to-left language, false if left-to-right
56
+ };
57
+ this._defaults = { // Global defaults for all the date picker instances
58
+ showOn: 'focus', // 'focus' for popup on focus,
59
+ // 'button' for trigger button, or 'both' for either
60
+ showAnim: 'show', // Name of jQuery animation for popup
61
+ showOptions: {}, // Options for enhanced animations
62
+ defaultDate: null, // Used when field is blank: actual date,
63
+ // +/-number for offset from today, null for today
64
+ appendText: '', // Display text following the input box, e.g. showing the format
65
+ buttonText: '...', // Text for trigger button
66
+ buttonImage: '', // URL for trigger button image
67
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
68
+ hideIfNoPrevNext: false, // True to hide next/previous month links
69
+ // if not applicable, false to just disable them
70
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
71
+ gotoCurrent: false, // True if today link goes back to current selection instead
72
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
73
+ changeYear: false, // True if year can be selected directly, false if only prev/next
74
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
75
+ yearRange: '-10:+10', // Range of years to display in drop-down,
76
+ // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
77
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
78
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
79
+ // takes a Date and returns the number of the week for it
80
+ shortYearCutoff: '+10', // Short year values < this are in the current century,
81
+ // > this are in the previous century,
82
+ // string value starting with '+' for current year + value
83
+ minDate: null, // The earliest selectable date, or null for no limit
84
+ maxDate: null, // The latest selectable date, or null for no limit
85
+ duration: 'normal', // Duration of display/closure
86
+ beforeShowDay: null, // Function that takes a date and returns an array with
87
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
88
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
89
+ beforeShow: null, // Function that takes an input field and
90
+ // returns a set of custom settings for the date picker
91
+ onSelect: null, // Define a callback function when a date is selected
92
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
93
+ onClose: null, // Define a callback function when the datepicker is closed
94
+ numberOfMonths: 1, // Number of months to show at a time
95
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
96
+ stepMonths: 1, // Number of months to step back/forward
97
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
98
+ altField: '', // Selector for an alternate field to store selected dates into
99
+ altFormat: '', // The date format to use for the alternate field
100
+ constrainInput: true, // The input is constrained by the current date format
101
+ showButtonPanel: false // True to show button panel, false to not show it
102
+ };
103
+ $.extend(this._defaults, this.regional['']);
104
+ this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>');
105
+ }
106
+
107
+ $.extend(Datepicker.prototype, {
108
+ /* Class name added to elements to indicate already configured with a date picker. */
109
+ markerClassName: 'hasDatepicker',
110
+
111
+ /* Debug logging (if enabled). */
112
+ log: function () {
113
+ if (this.debug)
114
+ console.log.apply('', arguments);
115
+ },
116
+
117
+ /* Override the default settings for all instances of the date picker.
118
+ @param settings object - the new settings to use as defaults (anonymous object)
119
+ @return the manager object */
120
+ setDefaults: function(settings) {
121
+ extendRemove(this._defaults, settings || {});
122
+ return this;
123
+ },
124
+
125
+ /* Attach the date picker to a jQuery selection.
126
+ @param target element - the target input field or division or span
127
+ @param settings object - the new settings to use for this date picker instance (anonymous) */
128
+ _attachDatepicker: function(target, settings) {
129
+ // check for settings on the control itself - in namespace 'date:'
130
+ var inlineSettings = null;
131
+ for (var attrName in this._defaults) {
132
+ var attrValue = target.getAttribute('date:' + attrName);
133
+ if (attrValue) {
134
+ inlineSettings = inlineSettings || {};
135
+ try {
136
+ inlineSettings[attrName] = eval(attrValue);
137
+ } catch (err) {
138
+ inlineSettings[attrName] = attrValue;
139
+ }
140
+ }
141
+ }
142
+ var nodeName = target.nodeName.toLowerCase();
143
+ var inline = (nodeName == 'div' || nodeName == 'span');
144
+ if (!target.id)
145
+ target.id = 'dp' + (++this.uuid);
146
+ var inst = this._newInst($(target), inline);
147
+ inst.settings = $.extend({}, settings || {}, inlineSettings || {});
148
+ if (nodeName == 'input') {
149
+ this._connectDatepicker(target, inst);
150
+ } else if (inline) {
151
+ this._inlineDatepicker(target, inst);
152
+ }
153
+ },
154
+
155
+ /* Create a new instance object. */
156
+ _newInst: function(target, inline) {
157
+ var id = target[0].id.replace(/([:\[\]\.])/g, '\\\\$1'); // escape jQuery meta chars
158
+ return {id: id, input: target, // associated target
159
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
160
+ drawMonth: 0, drawYear: 0, // month being drawn
161
+ inline: inline, // is datepicker inline or not
162
+ dpDiv: (!inline ? this.dpDiv : // presentation div
163
+ $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
164
+ },
165
+
166
+ /* Attach the date picker to an input field. */
167
+ _connectDatepicker: function(target, inst) {
168
+ var input = $(target);
169
+ inst.append = $([]);
170
+ inst.trigger = $([]);
171
+ if (input.hasClass(this.markerClassName))
172
+ return;
173
+ var appendText = this._get(inst, 'appendText');
174
+ var isRTL = this._get(inst, 'isRTL');
175
+ if (appendText) {
176
+ inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
177
+ input[isRTL ? 'before' : 'after'](inst.append);
178
+ }
179
+ var showOn = this._get(inst, 'showOn');
180
+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
181
+ input.focus(this._showDatepicker);
182
+ if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
183
+ var buttonText = this._get(inst, 'buttonText');
184
+ var buttonImage = this._get(inst, 'buttonImage');
185
+ inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
186
+ $('<img/>').addClass(this._triggerClass).
187
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
188
+ $('<button type="button"></button>').addClass(this._triggerClass).
189
+ html(buttonImage == '' ? buttonText : $('<img/>').attr(
190
+ { src:buttonImage, alt:buttonText, title:buttonText })));
191
+ input[isRTL ? 'before' : 'after'](inst.trigger);
192
+ inst.trigger.click(function() {
193
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
194
+ $.datepicker._hideDatepicker();
195
+ else
196
+ $.datepicker._showDatepicker(target);
197
+ return false;
198
+ });
199
+ }
200
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).
201
+ bind("setData.datepicker", function(event, key, value) {
202
+ inst.settings[key] = value;
203
+ }).bind("getData.datepicker", function(event, key) {
204
+ return this._get(inst, key);
205
+ });
206
+ $.data(target, PROP_NAME, inst);
207
+ },
208
+
209
+ /* Attach an inline date picker to a div. */
210
+ _inlineDatepicker: function(target, inst) {
211
+ var divSpan = $(target);
212
+ if (divSpan.hasClass(this.markerClassName))
213
+ return;
214
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv).
215
+ bind("setData.datepicker", function(event, key, value){
216
+ inst.settings[key] = value;
217
+ }).bind("getData.datepicker", function(event, key){
218
+ return this._get(inst, key);
219
+ });
220
+ $.data(target, PROP_NAME, inst);
221
+ this._setDate(inst, this._getDefaultDate(inst));
222
+ this._updateDatepicker(inst);
223
+ this._updateAlternate(inst);
224
+ },
225
+
226
+ /* Pop-up the date picker in a "dialog" box.
227
+ @param input element - ignored
228
+ @param dateText string - the initial date to display (in the current format)
229
+ @param onSelect function - the function(dateText) to call when a date is selected
230
+ @param settings object - update the dialog date picker instance's settings (anonymous object)
231
+ @param pos int[2] - coordinates for the dialog's position within the screen or
232
+ event - with x/y coordinates or
233
+ leave empty for default (screen centre)
234
+ @return the manager object */
235
+ _dialogDatepicker: function(input, dateText, onSelect, settings, pos) {
236
+ var inst = this._dialogInst; // internal instance
237
+ if (!inst) {
238
+ var id = 'dp' + (++this.uuid);
239
+ this._dialogInput = $('<input type="text" id="' + id +
240
+ '" size="1" style="position: absolute; top: -100px;"/>');
241
+ this._dialogInput.keydown(this._doKeyDown);
242
+ $('body').append(this._dialogInput);
243
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
244
+ inst.settings = {};
245
+ $.data(this._dialogInput[0], PROP_NAME, inst);
246
+ }
247
+ extendRemove(inst.settings, settings || {});
248
+ this._dialogInput.val(dateText);
249
+
250
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
251
+ if (!this._pos) {
252
+ var browserWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
253
+ var browserHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
254
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
255
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
256
+ this._pos = // should use actual width/height below
257
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
258
+ }
259
+
260
+ // move input on screen for focus, but hidden behind dialog
261
+ this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
262
+ inst.settings.onSelect = onSelect;
263
+ this._inDialog = true;
264
+ this.dpDiv.addClass(this._dialogClass);
265
+ this._showDatepicker(this._dialogInput[0]);
266
+ if ($.blockUI)
267
+ $.blockUI(this.dpDiv);
268
+ $.data(this._dialogInput[0], PROP_NAME, inst);
269
+ return this;
270
+ },
271
+
272
+ /* Detach a datepicker from its control.
273
+ @param target element - the target input field or division or span */
274
+ _destroyDatepicker: function(target) {
275
+ var $target = $(target);
276
+ var inst = $.data(target, PROP_NAME);
277
+ if (!$target.hasClass(this.markerClassName)) {
278
+ return;
279
+ }
280
+ var nodeName = target.nodeName.toLowerCase();
281
+ $.removeData(target, PROP_NAME);
282
+ if (nodeName == 'input') {
283
+ inst.append.remove();
284
+ inst.trigger.remove();
285
+ $target.removeClass(this.markerClassName).
286
+ unbind('focus', this._showDatepicker).
287
+ unbind('keydown', this._doKeyDown).
288
+ unbind('keypress', this._doKeyPress);
289
+ } else if (nodeName == 'div' || nodeName == 'span')
290
+ $target.removeClass(this.markerClassName).empty();
291
+ },
292
+
293
+ /* Enable the date picker to a jQuery selection.
294
+ @param target element - the target input field or division or span */
295
+ _enableDatepicker: function(target) {
296
+ var $target = $(target);
297
+ var inst = $.data(target, PROP_NAME);
298
+ if (!$target.hasClass(this.markerClassName)) {
299
+ return;
300
+ }
301
+ var nodeName = target.nodeName.toLowerCase();
302
+ if (nodeName == 'input') {
303
+ target.disabled = false;
304
+ inst.trigger.filter('button').
305
+ each(function() { this.disabled = false; }).end().
306
+ filter('img').css({opacity: '1.0', cursor: ''});
307
+ }
308
+ else if (nodeName == 'div' || nodeName == 'span') {
309
+ var inline = $target.children('.' + this._inlineClass);
310
+ inline.children().removeClass('ui-state-disabled');
311
+ }
312
+ this._disabledInputs = $.map(this._disabledInputs,
313
+ function(value) { return (value == target ? null : value); }); // delete entry
314
+ },
315
+
316
+ /* Disable the date picker to a jQuery selection.
317
+ @param target element - the target input field or division or span */
318
+ _disableDatepicker: function(target) {
319
+ var $target = $(target);
320
+ var inst = $.data(target, PROP_NAME);
321
+ if (!$target.hasClass(this.markerClassName)) {
322
+ return;
323
+ }
324
+ var nodeName = target.nodeName.toLowerCase();
325
+ if (nodeName == 'input') {
326
+ target.disabled = true;
327
+ inst.trigger.filter('button').
328
+ each(function() { this.disabled = true; }).end().
329
+ filter('img').css({opacity: '0.5', cursor: 'default'});
330
+ }
331
+ else if (nodeName == 'div' || nodeName == 'span') {
332
+ var inline = $target.children('.' + this._inlineClass);
333
+ inline.children().addClass('ui-state-disabled');
334
+ }
335
+ this._disabledInputs = $.map(this._disabledInputs,
336
+ function(value) { return (value == target ? null : value); }); // delete entry
337
+ this._disabledInputs[this._disabledInputs.length] = target;
338
+ },
339
+
340
+ /* Is the first field in a jQuery collection disabled as a datepicker?
341
+ @param target element - the target input field or division or span
342
+ @return boolean - true if disabled, false if enabled */
343
+ _isDisabledDatepicker: function(target) {
344
+ if (!target) {
345
+ return false;
346
+ }
347
+ for (var i = 0; i < this._disabledInputs.length; i++) {
348
+ if (this._disabledInputs[i] == target)
349
+ return true;
350
+ }
351
+ return false;
352
+ },
353
+
354
+ /* Retrieve the instance data for the target control.
355
+ @param target element - the target input field or division or span
356
+ @return object - the associated instance data
357
+ @throws error if a jQuery problem getting data */
358
+ _getInst: function(target) {
359
+ try {
360
+ return $.data(target, PROP_NAME);
361
+ }
362
+ catch (err) {
363
+ throw 'Missing instance data for this datepicker';
364
+ }
365
+ },
366
+
367
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
368
+ @param target element - the target input field or division or span
369
+ @param name object - the new settings to update or
370
+ string - the name of the setting to change or retrieve,
371
+ when retrieving also 'all' for all instance settings or
372
+ 'defaults' for all global defaults
373
+ @param value any - the new value for the setting
374
+ (omit if above is an object or to retrieve a value) */
375
+ _optionDatepicker: function(target, name, value) {
376
+ var inst = this._getInst(target);
377
+ if (arguments.length == 2 && typeof name == 'string') {
378
+ return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
379
+ (inst ? (name == 'all' ? $.extend({}, inst.settings) :
380
+ this._get(inst, name)) : null));
381
+ }
382
+ var settings = name || {};
383
+ if (typeof name == 'string') {
384
+ settings = {};
385
+ settings[name] = value;
386
+ }
387
+ if (inst) {
388
+ if (this._curInst == inst) {
389
+ this._hideDatepicker(null);
390
+ }
391
+ var date = this._getDateDatepicker(target);
392
+ extendRemove(inst.settings, settings);
393
+ this._setDateDatepicker(target, date);
394
+ this._updateDatepicker(inst);
395
+ }
396
+ },
397
+
398
+ // change method deprecated
399
+ _changeDatepicker: function(target, name, value) {
400
+ this._optionDatepicker(target, name, value);
401
+ },
402
+
403
+ /* Redraw the date picker attached to an input field or division.
404
+ @param target element - the target input field or division or span */
405
+ _refreshDatepicker: function(target) {
406
+ var inst = this._getInst(target);
407
+ if (inst) {
408
+ this._updateDatepicker(inst);
409
+ }
410
+ },
411
+
412
+ /* Set the dates for a jQuery selection.
413
+ @param target element - the target input field or division or span
414
+ @param date Date - the new date
415
+ @param endDate Date - the new end date for a range (optional) */
416
+ _setDateDatepicker: function(target, date, endDate) {
417
+ var inst = this._getInst(target);
418
+ if (inst) {
419
+ this._setDate(inst, date, endDate);
420
+ this._updateDatepicker(inst);
421
+ this._updateAlternate(inst);
422
+ }
423
+ },
424
+
425
+ /* Get the date(s) for the first entry in a jQuery selection.
426
+ @param target element - the target input field or division or span
427
+ @return Date - the current date or
428
+ Date[2] - the current dates for a range */
429
+ _getDateDatepicker: function(target) {
430
+ var inst = this._getInst(target);
431
+ if (inst && !inst.inline)
432
+ this._setDateFromField(inst);
433
+ return (inst ? this._getDate(inst) : null);
434
+ },
435
+
436
+ /* Handle keystrokes. */
437
+ _doKeyDown: function(event) {
438
+ var inst = $.datepicker._getInst(event.target);
439
+ var handled = true;
440
+ var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
441
+ inst._keyEvent = true;
442
+ if ($.datepicker._datepickerShowing)
443
+ switch (event.keyCode) {
444
+ case 9: $.datepicker._hideDatepicker(null, '');
445
+ break; // hide on tab out
446
+ case 13: var sel = $('td.' + $.datepicker._dayOverClass +
447
+ ', td.' + $.datepicker._currentClass, inst.dpDiv);
448
+ if (sel[0])
449
+ $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
450
+ else
451
+ $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
452
+ return false; // don't submit the form
453
+ break; // select the value on enter
454
+ case 27: $.datepicker._hideDatepicker(null, $.datepicker._get(inst, 'duration'));
455
+ break; // hide on escape
456
+ case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
457
+ -$.datepicker._get(inst, 'stepBigMonths') :
458
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
459
+ break; // previous month/year on page up/+ ctrl
460
+ case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
461
+ +$.datepicker._get(inst, 'stepBigMonths') :
462
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
463
+ break; // next month/year on page down/+ ctrl
464
+ case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
465
+ handled = event.ctrlKey || event.metaKey;
466
+ break; // clear on ctrl or command +end
467
+ case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
468
+ handled = event.ctrlKey || event.metaKey;
469
+ break; // current on ctrl or command +home
470
+ case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
471
+ handled = event.ctrlKey || event.metaKey;
472
+ // -1 day on ctrl or command +left
473
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
474
+ -$.datepicker._get(inst, 'stepBigMonths') :
475
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
476
+ // next month/year on alt +left on Mac
477
+ break;
478
+ case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
479
+ handled = event.ctrlKey || event.metaKey;
480
+ break; // -1 week on ctrl or command +up
481
+ case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
482
+ handled = event.ctrlKey || event.metaKey;
483
+ // +1 day on ctrl or command +right
484
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
485
+ +$.datepicker._get(inst, 'stepBigMonths') :
486
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
487
+ // next month/year on alt +right
488
+ break;
489
+ case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
490
+ handled = event.ctrlKey || event.metaKey;
491
+ break; // +1 week on ctrl or command +down
492
+ default: handled = false;
493
+ }
494
+ else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
495
+ $.datepicker._showDatepicker(this);
496
+ else {
497
+ handled = false;
498
+ }
499
+ if (handled) {
500
+ event.preventDefault();
501
+ event.stopPropagation();
502
+ }
503
+ },
504
+
505
+ /* Filter entered characters - based on date format. */
506
+ _doKeyPress: function(event) {
507
+ var inst = $.datepicker._getInst(event.target);
508
+ if ($.datepicker._get(inst, 'constrainInput')) {
509
+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
510
+ var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
511
+ return event.ctrlKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
512
+ }
513
+ },
514
+
515
+ /* Pop-up the date picker for a given input field.
516
+ @param input element - the input field attached to the date picker or
517
+ event - if triggered by focus */
518
+ _showDatepicker: function(input) {
519
+ input = input.target || input;
520
+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
521
+ input = $('input', input.parentNode)[0];
522
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
523
+ return;
524
+ var inst = $.datepicker._getInst(input);
525
+ var beforeShow = $.datepicker._get(inst, 'beforeShow');
526
+ extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
527
+ $.datepicker._hideDatepicker(null, '');
528
+ $.datepicker._lastInput = input;
529
+ $.datepicker._setDateFromField(inst);
530
+ if ($.datepicker._inDialog) // hide cursor
531
+ input.value = '';
532
+ if (!$.datepicker._pos) { // position below input
533
+ $.datepicker._pos = $.datepicker._findPos(input);
534
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
535
+ }
536
+ var isFixed = false;
537
+ $(input).parents().each(function() {
538
+ isFixed |= $(this).css('position') == 'fixed';
539
+ return !isFixed;
540
+ });
541
+ if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
542
+ $.datepicker._pos[0] -= document.documentElement.scrollLeft;
543
+ $.datepicker._pos[1] -= document.documentElement.scrollTop;
544
+ }
545
+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
546
+ $.datepicker._pos = null;
547
+ inst.rangeStart = null;
548
+ // determine sizing offscreen
549
+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
550
+ $.datepicker._updateDatepicker(inst);
551
+ // fix width for dynamic number of date pickers
552
+ // and adjust position before showing
553
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
554
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
555
+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
556
+ left: offset.left + 'px', top: offset.top + 'px'});
557
+ if (!inst.inline) {
558
+ var showAnim = $.datepicker._get(inst, 'showAnim') || 'show';
559
+ var duration = $.datepicker._get(inst, 'duration');
560
+ var postProcess = function() {
561
+ $.datepicker._datepickerShowing = true;
562
+ if ($.browser.msie && parseInt($.browser.version,10) < 7) // fix IE < 7 select problems
563
+ $('iframe.ui-datepicker-cover').css({width: inst.dpDiv.width() + 4,
564
+ height: inst.dpDiv.height() + 4});
565
+ };
566
+ if ($.effects && $.effects[showAnim])
567
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
568
+ else
569
+ inst.dpDiv[showAnim](duration, postProcess);
570
+ if (duration == '')
571
+ postProcess();
572
+ if (inst.input[0].type != 'hidden')
573
+ inst.input[0].focus();
574
+ $.datepicker._curInst = inst;
575
+ }
576
+ },
577
+
578
+ /* Generate the date picker content. */
579
+ _updateDatepicker: function(inst) {
580
+ var dims = {width: inst.dpDiv.width() + 4,
581
+ height: inst.dpDiv.height() + 4};
582
+ var self = this;
583
+ inst.dpDiv.empty().append(this._generateHTML(inst))
584
+ .find('iframe.ui-datepicker-cover').
585
+ css({width: dims.width, height: dims.height})
586
+ .end()
587
+ .find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
588
+ .bind('mouseout', function(){
589
+ $(this).removeClass('ui-state-hover');
590
+ if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
591
+ if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
592
+ })
593
+ .bind('mouseover', function(){
594
+ if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
595
+ $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
596
+ $(this).addClass('ui-state-hover');
597
+ if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
598
+ if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
599
+ }
600
+ })
601
+ .end()
602
+ .find('.' + this._dayOverClass + ' a')
603
+ .trigger('mouseover')
604
+ .end();
605
+ var numMonths = this._getNumberOfMonths(inst);
606
+ var cols = numMonths[1];
607
+ var width = 17;
608
+ if (cols > 1) {
609
+ inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
610
+ } else {
611
+ inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
612
+ }
613
+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
614
+ 'Class']('ui-datepicker-multi');
615
+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
616
+ 'Class']('ui-datepicker-rtl');
617
+ if (inst.input && inst.input[0].type != 'hidden' && inst == $.datepicker._curInst)
618
+ $(inst.input[0]).focus();
619
+ },
620
+
621
+ /* Check positioning to remain on screen. */
622
+ _checkOffset: function(inst, offset, isFixed) {
623
+ var dpWidth = inst.dpDiv.outerWidth();
624
+ var dpHeight = inst.dpDiv.outerHeight();
625
+ var inputWidth = inst.input ? inst.input.outerWidth() : 0;
626
+ var inputHeight = inst.input ? inst.input.outerHeight() : 0;
627
+ var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();
628
+ var viewHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) + $(document).scrollTop();
629
+
630
+ offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
631
+ offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
632
+ offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
633
+
634
+ // now check if datepicker is showing outside window viewport - move to a better place if so.
635
+ offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;
636
+ offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;
637
+
638
+ return offset;
639
+ },
640
+
641
+ /* Find an object's position on the screen. */
642
+ _findPos: function(obj) {
643
+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
644
+ obj = obj.nextSibling;
645
+ }
646
+ var position = $(obj).offset();
647
+ return [position.left, position.top];
648
+ },
649
+
650
+ /* Hide the date picker from view.
651
+ @param input element - the input field attached to the date picker
652
+ @param duration string - the duration over which to close the date picker */
653
+ _hideDatepicker: function(input, duration) {
654
+ var inst = this._curInst;
655
+ if (!inst || (input && inst != $.data(input, PROP_NAME)))
656
+ return;
657
+ if (inst.stayOpen)
658
+ this._selectDate('#' + inst.id, this._formatDate(inst,
659
+ inst.currentDay, inst.currentMonth, inst.currentYear));
660
+ inst.stayOpen = false;
661
+ if (this._datepickerShowing) {
662
+ duration = (duration != null ? duration : this._get(inst, 'duration'));
663
+ var showAnim = this._get(inst, 'showAnim');
664
+ var postProcess = function() {
665
+ $.datepicker._tidyDialog(inst);
666
+ };
667
+ if (duration != '' && $.effects && $.effects[showAnim])
668
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'),
669
+ duration, postProcess);
670
+ else
671
+ inst.dpDiv[(duration == '' ? 'hide' : (showAnim == 'slideDown' ? 'slideUp' :
672
+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide')))](duration, postProcess);
673
+ if (duration == '')
674
+ this._tidyDialog(inst);
675
+ var onClose = this._get(inst, 'onClose');
676
+ if (onClose)
677
+ onClose.apply((inst.input ? inst.input[0] : null),
678
+ [(inst.input ? inst.input.val() : ''), inst]); // trigger custom callback
679
+ this._datepickerShowing = false;
680
+ this._lastInput = null;
681
+ if (this._inDialog) {
682
+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
683
+ if ($.blockUI) {
684
+ $.unblockUI();
685
+ $('body').append(this.dpDiv);
686
+ }
687
+ }
688
+ this._inDialog = false;
689
+ }
690
+ this._curInst = null;
691
+ },
692
+
693
+ /* Tidy up after a dialog display. */
694
+ _tidyDialog: function(inst) {
695
+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
696
+ },
697
+
698
+ /* Close date picker if clicked elsewhere. */
699
+ _checkExternalClick: function(event) {
700
+ if (!$.datepicker._curInst)
701
+ return;
702
+ var $target = $(event.target);
703
+ if (($target.parents('#' + $.datepicker._mainDivId).length == 0) &&
704
+ !$target.hasClass($.datepicker.markerClassName) &&
705
+ !$target.hasClass($.datepicker._triggerClass) &&
706
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
707
+ $.datepicker._hideDatepicker(null, '');
708
+ },
709
+
710
+ /* Adjust one of the date sub-fields. */
711
+ _adjustDate: function(id, offset, period) {
712
+ var target = $(id);
713
+ var inst = this._getInst(target[0]);
714
+ if (this._isDisabledDatepicker(target[0])) {
715
+ return;
716
+ }
717
+ this._adjustInstDate(inst, offset +
718
+ (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
719
+ period);
720
+ this._updateDatepicker(inst);
721
+ },
722
+
723
+ /* Action for current link. */
724
+ _gotoToday: function(id) {
725
+ var target = $(id);
726
+ var inst = this._getInst(target[0]);
727
+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
728
+ inst.selectedDay = inst.currentDay;
729
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
730
+ inst.drawYear = inst.selectedYear = inst.currentYear;
731
+ }
732
+ else {
733
+ var date = new Date();
734
+ inst.selectedDay = date.getDate();
735
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
736
+ inst.drawYear = inst.selectedYear = date.getFullYear();
737
+ }
738
+ this._notifyChange(inst);
739
+ this._adjustDate(target);
740
+ },
741
+
742
+ /* Action for selecting a new month/year. */
743
+ _selectMonthYear: function(id, select, period) {
744
+ var target = $(id);
745
+ var inst = this._getInst(target[0]);
746
+ inst._selectingMonthYear = false;
747
+ inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
748
+ inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
749
+ parseInt(select.options[select.selectedIndex].value,10);
750
+ this._notifyChange(inst);
751
+ this._adjustDate(target);
752
+ },
753
+
754
+ /* Restore input focus after not changing month/year. */
755
+ _clickMonthYear: function(id) {
756
+ var target = $(id);
757
+ var inst = this._getInst(target[0]);
758
+ if (inst.input && inst._selectingMonthYear && !$.browser.msie)
759
+ inst.input[0].focus();
760
+ inst._selectingMonthYear = !inst._selectingMonthYear;
761
+ },
762
+
763
+ /* Action for selecting a day. */
764
+ _selectDay: function(id, month, year, td) {
765
+ var target = $(id);
766
+ if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
767
+ return;
768
+ }
769
+ var inst = this._getInst(target[0]);
770
+ inst.selectedDay = inst.currentDay = $('a', td).html();
771
+ inst.selectedMonth = inst.currentMonth = month;
772
+ inst.selectedYear = inst.currentYear = year;
773
+ if (inst.stayOpen) {
774
+ inst.endDay = inst.endMonth = inst.endYear = null;
775
+ }
776
+ this._selectDate(id, this._formatDate(inst,
777
+ inst.currentDay, inst.currentMonth, inst.currentYear));
778
+ if (inst.stayOpen) {
779
+ inst.rangeStart = this._daylightSavingAdjust(
780
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay));
781
+ this._updateDatepicker(inst);
782
+ }
783
+ },
784
+
785
+ /* Erase the input field and hide the date picker. */
786
+ _clearDate: function(id) {
787
+ var target = $(id);
788
+ var inst = this._getInst(target[0]);
789
+ inst.stayOpen = false;
790
+ inst.endDay = inst.endMonth = inst.endYear = inst.rangeStart = null;
791
+ this._selectDate(target, '');
792
+ },
793
+
794
+ /* Update the input field with the selected date. */
795
+ _selectDate: function(id, dateStr) {
796
+ var target = $(id);
797
+ var inst = this._getInst(target[0]);
798
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
799
+ if (inst.input)
800
+ inst.input.val(dateStr);
801
+ this._updateAlternate(inst);
802
+ var onSelect = this._get(inst, 'onSelect');
803
+ if (onSelect)
804
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
805
+ else if (inst.input)
806
+ inst.input.trigger('change'); // fire the change event
807
+ if (inst.inline)
808
+ this._updateDatepicker(inst);
809
+ else if (!inst.stayOpen) {
810
+ this._hideDatepicker(null, this._get(inst, 'duration'));
811
+ this._lastInput = inst.input[0];
812
+ if (typeof(inst.input[0]) != 'object')
813
+ inst.input[0].focus(); // restore focus
814
+ this._lastInput = null;
815
+ }
816
+ },
817
+
818
+ /* Update any alternate field to synchronise with the main field. */
819
+ _updateAlternate: function(inst) {
820
+ var altField = this._get(inst, 'altField');
821
+ if (altField) { // update alternate field too
822
+ var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
823
+ var date = this._getDate(inst);
824
+ dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
825
+ $(altField).each(function() { $(this).val(dateStr); });
826
+ }
827
+ },
828
+
829
+ /* Set as beforeShowDay function to prevent selection of weekends.
830
+ @param date Date - the date to customise
831
+ @return [boolean, string] - is this date selectable?, what is its CSS class? */
832
+ noWeekends: function(date) {
833
+ var day = date.getDay();
834
+ return [(day > 0 && day < 6), ''];
835
+ },
836
+
837
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
838
+ @param date Date - the date to get the week for
839
+ @return number - the number of the week within the year that contains this date */
840
+ iso8601Week: function(date) {
841
+ var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
842
+ var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
843
+ var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
844
+ firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
845
+ if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
846
+ checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
847
+ return $.datepicker.iso8601Week(checkDate);
848
+ } else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
849
+ firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
850
+ if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
851
+ return 1;
852
+ }
853
+ }
854
+ return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
855
+ },
856
+
857
+ /* Parse a string value into a date object.
858
+ See formatDate below for the possible formats.
859
+
860
+ @param format string - the expected format of the date
861
+ @param value string - the date in the above format
862
+ @param settings Object - attributes include:
863
+ shortYearCutoff number - the cutoff year for determining the century (optional)
864
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
865
+ dayNames string[7] - names of the days from Sunday (optional)
866
+ monthNamesShort string[12] - abbreviated names of the months (optional)
867
+ monthNames string[12] - names of the months (optional)
868
+ @return Date - the extracted date value or null if value is blank */
869
+ parseDate: function (format, value, settings) {
870
+ if (format == null || value == null)
871
+ throw 'Invalid arguments';
872
+ value = (typeof value == 'object' ? value.toString() : value + '');
873
+ if (value == '')
874
+ return null;
875
+ var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
876
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
877
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
878
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
879
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
880
+ var year = -1;
881
+ var month = -1;
882
+ var day = -1;
883
+ var doy = -1;
884
+ var literal = false;
885
+ // Check whether a format character is doubled
886
+ var lookAhead = function(match) {
887
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
888
+ if (matches)
889
+ iFormat++;
890
+ return matches;
891
+ };
892
+ // Extract a number from the string value
893
+ var getNumber = function(match) {
894
+ lookAhead(match);
895
+ var origSize = (match == '@' ? 14 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)));
896
+ var size = origSize;
897
+ var num = 0;
898
+ while (size > 0 && iValue < value.length &&
899
+ value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
900
+ num = num * 10 + parseInt(value.charAt(iValue++),10);
901
+ size--;
902
+ }
903
+ if (size == origSize)
904
+ throw 'Missing number at position ' + iValue;
905
+ return num;
906
+ };
907
+ // Extract a name from the string value and convert to an index
908
+ var getName = function(match, shortNames, longNames) {
909
+ var names = (lookAhead(match) ? longNames : shortNames);
910
+ var size = 0;
911
+ for (var j = 0; j < names.length; j++)
912
+ size = Math.max(size, names[j].length);
913
+ var name = '';
914
+ var iInit = iValue;
915
+ while (size > 0 && iValue < value.length) {
916
+ name += value.charAt(iValue++);
917
+ for (var i = 0; i < names.length; i++)
918
+ if (name == names[i])
919
+ return i + 1;
920
+ size--;
921
+ }
922
+ throw 'Unknown name at position ' + iInit;
923
+ };
924
+ // Confirm that a literal character matches the string value
925
+ var checkLiteral = function() {
926
+ if (value.charAt(iValue) != format.charAt(iFormat))
927
+ throw 'Unexpected literal at position ' + iValue;
928
+ iValue++;
929
+ };
930
+ var iValue = 0;
931
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
932
+ if (literal)
933
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
934
+ literal = false;
935
+ else
936
+ checkLiteral();
937
+ else
938
+ switch (format.charAt(iFormat)) {
939
+ case 'd':
940
+ day = getNumber('d');
941
+ break;
942
+ case 'D':
943
+ getName('D', dayNamesShort, dayNames);
944
+ break;
945
+ case 'o':
946
+ doy = getNumber('o');
947
+ break;
948
+ case 'm':
949
+ month = getNumber('m');
950
+ break;
951
+ case 'M':
952
+ month = getName('M', monthNamesShort, monthNames);
953
+ break;
954
+ case 'y':
955
+ year = getNumber('y');
956
+ break;
957
+ case '@':
958
+ var date = new Date(getNumber('@'));
959
+ year = date.getFullYear();
960
+ month = date.getMonth() + 1;
961
+ day = date.getDate();
962
+ break;
963
+ case "'":
964
+ if (lookAhead("'"))
965
+ checkLiteral();
966
+ else
967
+ literal = true;
968
+ break;
969
+ default:
970
+ checkLiteral();
971
+ }
972
+ }
973
+ if (year == -1)
974
+ year = new Date().getFullYear();
975
+ else if (year < 100)
976
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
977
+ (year <= shortYearCutoff ? 0 : -100);
978
+ if (doy > -1) {
979
+ month = 1;
980
+ day = doy;
981
+ do {
982
+ var dim = this._getDaysInMonth(year, month - 1);
983
+ if (day <= dim)
984
+ break;
985
+ month++;
986
+ day -= dim;
987
+ } while (true);
988
+ }
989
+ var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
990
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
991
+ throw 'Invalid date'; // E.g. 31/02/*
992
+ return date;
993
+ },
994
+
995
+ /* Standard date formats. */
996
+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
997
+ COOKIE: 'D, dd M yy',
998
+ ISO_8601: 'yy-mm-dd',
999
+ RFC_822: 'D, d M y',
1000
+ RFC_850: 'DD, dd-M-y',
1001
+ RFC_1036: 'D, d M y',
1002
+ RFC_1123: 'D, d M yy',
1003
+ RFC_2822: 'D, d M yy',
1004
+ RSS: 'D, d M y', // RFC 822
1005
+ TIMESTAMP: '@',
1006
+ W3C: 'yy-mm-dd', // ISO 8601
1007
+
1008
+ /* Format a date object into a string value.
1009
+ The format can be combinations of the following:
1010
+ d - day of month (no leading zero)
1011
+ dd - day of month (two digit)
1012
+ o - day of year (no leading zeros)
1013
+ oo - day of year (three digit)
1014
+ D - day name short
1015
+ DD - day name long
1016
+ m - month of year (no leading zero)
1017
+ mm - month of year (two digit)
1018
+ M - month name short
1019
+ MM - month name long
1020
+ y - year (two digit)
1021
+ yy - year (four digit)
1022
+ @ - Unix timestamp (ms since 01/01/1970)
1023
+ '...' - literal text
1024
+ '' - single quote
1025
+
1026
+ @param format string - the desired format of the date
1027
+ @param date Date - the date value to format
1028
+ @param settings Object - attributes include:
1029
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
1030
+ dayNames string[7] - names of the days from Sunday (optional)
1031
+ monthNamesShort string[12] - abbreviated names of the months (optional)
1032
+ monthNames string[12] - names of the months (optional)
1033
+ @return string - the date in the above format */
1034
+ formatDate: function (format, date, settings) {
1035
+ if (!date)
1036
+ return '';
1037
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
1038
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
1039
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
1040
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
1041
+ // Check whether a format character is doubled
1042
+ var lookAhead = function(match) {
1043
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
1044
+ if (matches)
1045
+ iFormat++;
1046
+ return matches;
1047
+ };
1048
+ // Format a number, with leading zero if necessary
1049
+ var formatNumber = function(match, value, len) {
1050
+ var num = '' + value;
1051
+ if (lookAhead(match))
1052
+ while (num.length < len)
1053
+ num = '0' + num;
1054
+ return num;
1055
+ };
1056
+ // Format a name, short or long as requested
1057
+ var formatName = function(match, value, shortNames, longNames) {
1058
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
1059
+ };
1060
+ var output = '';
1061
+ var literal = false;
1062
+ if (date)
1063
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
1064
+ if (literal)
1065
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1066
+ literal = false;
1067
+ else
1068
+ output += format.charAt(iFormat);
1069
+ else
1070
+ switch (format.charAt(iFormat)) {
1071
+ case 'd':
1072
+ output += formatNumber('d', date.getDate(), 2);
1073
+ break;
1074
+ case 'D':
1075
+ output += formatName('D', date.getDay(), dayNamesShort, dayNames);
1076
+ break;
1077
+ case 'o':
1078
+ var doy = date.getDate();
1079
+ for (var m = date.getMonth() - 1; m >= 0; m--)
1080
+ doy += this._getDaysInMonth(date.getFullYear(), m);
1081
+ output += formatNumber('o', doy, 3);
1082
+ break;
1083
+ case 'm':
1084
+ output += formatNumber('m', date.getMonth() + 1, 2);
1085
+ break;
1086
+ case 'M':
1087
+ output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
1088
+ break;
1089
+ case 'y':
1090
+ output += (lookAhead('y') ? date.getFullYear() :
1091
+ (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
1092
+ break;
1093
+ case '@':
1094
+ output += date.getTime();
1095
+ break;
1096
+ case "'":
1097
+ if (lookAhead("'"))
1098
+ output += "'";
1099
+ else
1100
+ literal = true;
1101
+ break;
1102
+ default:
1103
+ output += format.charAt(iFormat);
1104
+ }
1105
+ }
1106
+ return output;
1107
+ },
1108
+
1109
+ /* Extract all possible characters from the date format. */
1110
+ _possibleChars: function (format) {
1111
+ var chars = '';
1112
+ var literal = false;
1113
+ for (var iFormat = 0; iFormat < format.length; iFormat++)
1114
+ if (literal)
1115
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
1116
+ literal = false;
1117
+ else
1118
+ chars += format.charAt(iFormat);
1119
+ else
1120
+ switch (format.charAt(iFormat)) {
1121
+ case 'd': case 'm': case 'y': case '@':
1122
+ chars += '0123456789';
1123
+ break;
1124
+ case 'D': case 'M':
1125
+ return null; // Accept anything
1126
+ case "'":
1127
+ if (lookAhead("'"))
1128
+ chars += "'";
1129
+ else
1130
+ literal = true;
1131
+ break;
1132
+ default:
1133
+ chars += format.charAt(iFormat);
1134
+ }
1135
+ return chars;
1136
+ },
1137
+
1138
+ /* Get a setting value, defaulting if necessary. */
1139
+ _get: function(inst, name) {
1140
+ return inst.settings[name] !== undefined ?
1141
+ inst.settings[name] : this._defaults[name];
1142
+ },
1143
+
1144
+ /* Parse existing date and initialise date picker. */
1145
+ _setDateFromField: function(inst) {
1146
+ var dateFormat = this._get(inst, 'dateFormat');
1147
+ var dates = inst.input ? inst.input.val() : null;
1148
+ inst.endDay = inst.endMonth = inst.endYear = null;
1149
+ var date = defaultDate = this._getDefaultDate(inst);
1150
+ var settings = this._getFormatConfig(inst);
1151
+ try {
1152
+ date = this.parseDate(dateFormat, dates, settings) || defaultDate;
1153
+ } catch (event) {
1154
+ this.log(event);
1155
+ date = defaultDate;
1156
+ }
1157
+ inst.selectedDay = date.getDate();
1158
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1159
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1160
+ inst.currentDay = (dates ? date.getDate() : 0);
1161
+ inst.currentMonth = (dates ? date.getMonth() : 0);
1162
+ inst.currentYear = (dates ? date.getFullYear() : 0);
1163
+ this._adjustInstDate(inst);
1164
+ },
1165
+
1166
+ /* Retrieve the default date shown on opening. */
1167
+ _getDefaultDate: function(inst) {
1168
+ var date = this._determineDate(this._get(inst, 'defaultDate'), new Date());
1169
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1170
+ var maxDate = this._getMinMaxDate(inst, 'max');
1171
+ date = (minDate && date < minDate ? minDate : date);
1172
+ date = (maxDate && date > maxDate ? maxDate : date);
1173
+ return date;
1174
+ },
1175
+
1176
+ /* A date may be specified as an exact value or a relative one. */
1177
+ _determineDate: function(date, defaultDate) {
1178
+ var offsetNumeric = function(offset) {
1179
+ var date = new Date();
1180
+ date.setDate(date.getDate() + offset);
1181
+ return date;
1182
+ };
1183
+ var offsetString = function(offset, getDaysInMonth) {
1184
+ var date = new Date();
1185
+ var year = date.getFullYear();
1186
+ var month = date.getMonth();
1187
+ var day = date.getDate();
1188
+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
1189
+ var matches = pattern.exec(offset);
1190
+ while (matches) {
1191
+ switch (matches[2] || 'd') {
1192
+ case 'd' : case 'D' :
1193
+ day += parseInt(matches[1],10); break;
1194
+ case 'w' : case 'W' :
1195
+ day += parseInt(matches[1],10) * 7; break;
1196
+ case 'm' : case 'M' :
1197
+ month += parseInt(matches[1],10);
1198
+ day = Math.min(day, getDaysInMonth(year, month));
1199
+ break;
1200
+ case 'y': case 'Y' :
1201
+ year += parseInt(matches[1],10);
1202
+ day = Math.min(day, getDaysInMonth(year, month));
1203
+ break;
1204
+ }
1205
+ matches = pattern.exec(offset);
1206
+ }
1207
+ return new Date(year, month, day);
1208
+ };
1209
+ date = (date == null ? defaultDate :
1210
+ (typeof date == 'string' ? offsetString(date, this._getDaysInMonth) :
1211
+ (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : date)));
1212
+ date = (date && date.toString() == 'Invalid Date' ? defaultDate : date);
1213
+ if (date) {
1214
+ date.setHours(0);
1215
+ date.setMinutes(0);
1216
+ date.setSeconds(0);
1217
+ date.setMilliseconds(0);
1218
+ }
1219
+ return this._daylightSavingAdjust(date);
1220
+ },
1221
+
1222
+ /* Handle switch to/from daylight saving.
1223
+ Hours may be non-zero on daylight saving cut-over:
1224
+ > 12 when midnight changeover, but then cannot generate
1225
+ midnight datetime, so jump to 1AM, otherwise reset.
1226
+ @param date (Date) the date to check
1227
+ @return (Date) the corrected date */
1228
+ _daylightSavingAdjust: function(date) {
1229
+ if (!date) return null;
1230
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
1231
+ return date;
1232
+ },
1233
+
1234
+ /* Set the date(s) directly. */
1235
+ _setDate: function(inst, date, endDate) {
1236
+ var clear = !(date);
1237
+ var origMonth = inst.selectedMonth;
1238
+ var origYear = inst.selectedYear;
1239
+ date = this._determineDate(date, new Date());
1240
+ inst.selectedDay = inst.currentDay = date.getDate();
1241
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = date.getMonth();
1242
+ inst.drawYear = inst.selectedYear = inst.currentYear = date.getFullYear();
1243
+ if (origMonth != inst.selectedMonth || origYear != inst.selectedYear)
1244
+ this._notifyChange(inst);
1245
+ this._adjustInstDate(inst);
1246
+ if (inst.input) {
1247
+ inst.input.val(clear ? '' : this._formatDate(inst));
1248
+ }
1249
+ },
1250
+
1251
+ /* Retrieve the date(s) directly. */
1252
+ _getDate: function(inst) {
1253
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
1254
+ this._daylightSavingAdjust(new Date(
1255
+ inst.currentYear, inst.currentMonth, inst.currentDay)));
1256
+ return startDate;
1257
+ },
1258
+
1259
+ /* Generate the HTML for the current state of the date picker. */
1260
+ _generateHTML: function(inst) {
1261
+ var today = new Date();
1262
+ today = this._daylightSavingAdjust(
1263
+ new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
1264
+ var isRTL = this._get(inst, 'isRTL');
1265
+ var showButtonPanel = this._get(inst, 'showButtonPanel');
1266
+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
1267
+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
1268
+ var numMonths = this._getNumberOfMonths(inst);
1269
+ var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
1270
+ var stepMonths = this._get(inst, 'stepMonths');
1271
+ var stepBigMonths = this._get(inst, 'stepBigMonths');
1272
+ var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
1273
+ var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
1274
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1275
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1276
+ var maxDate = this._getMinMaxDate(inst, 'max');
1277
+ var drawMonth = inst.drawMonth - showCurrentAtPos;
1278
+ var drawYear = inst.drawYear;
1279
+ if (drawMonth < 0) {
1280
+ drawMonth += 12;
1281
+ drawYear--;
1282
+ }
1283
+ if (maxDate) {
1284
+ var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
1285
+ maxDate.getMonth() - numMonths[1] + 1, maxDate.getDate()));
1286
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
1287
+ while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
1288
+ drawMonth--;
1289
+ if (drawMonth < 0) {
1290
+ drawMonth = 11;
1291
+ drawYear--;
1292
+ }
1293
+ }
1294
+ }
1295
+ inst.drawMonth = drawMonth;
1296
+ inst.drawYear = drawYear;
1297
+ var prevText = this._get(inst, 'prevText');
1298
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
1299
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
1300
+ this._getFormatConfig(inst)));
1301
+ var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
1302
+ '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
1303
+ ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
1304
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
1305
+ var nextText = this._get(inst, 'nextText');
1306
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
1307
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
1308
+ this._getFormatConfig(inst)));
1309
+ var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
1310
+ '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
1311
+ ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
1312
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
1313
+ var currentText = this._get(inst, 'currentText');
1314
+ var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
1315
+ currentText = (!navigationAsDateFormat ? currentText :
1316
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
1317
+ var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
1318
+ var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
1319
+ (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#' + inst.id + '\');"' +
1320
+ '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
1321
+ var firstDay = parseInt(this._get(inst, 'firstDay'),10);
1322
+ firstDay = (isNaN(firstDay) ? 0 : firstDay);
1323
+ var dayNames = this._get(inst, 'dayNames');
1324
+ var dayNamesShort = this._get(inst, 'dayNamesShort');
1325
+ var dayNamesMin = this._get(inst, 'dayNamesMin');
1326
+ var monthNames = this._get(inst, 'monthNames');
1327
+ var monthNamesShort = this._get(inst, 'monthNamesShort');
1328
+ var beforeShowDay = this._get(inst, 'beforeShowDay');
1329
+ var showOtherMonths = this._get(inst, 'showOtherMonths');
1330
+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
1331
+ var endDate = inst.endDay ? this._daylightSavingAdjust(
1332
+ new Date(inst.endYear, inst.endMonth, inst.endDay)) : currentDate;
1333
+ var defaultDate = this._getDefaultDate(inst);
1334
+ var html = '';
1335
+ for (var row = 0; row < numMonths[0]; row++) {
1336
+ var group = '';
1337
+ for (var col = 0; col < numMonths[1]; col++) {
1338
+ var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
1339
+ var cornerClass = ' ui-corner-all';
1340
+ var calender = '';
1341
+ if (isMultiMonth) {
1342
+ calender += '<div class="ui-datepicker-group ui-datepicker-group-';
1343
+ switch (col) {
1344
+ case 0: calender += 'first'; cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
1345
+ case numMonths[1]-1: calender += 'last'; cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
1346
+ default: calender += 'middle'; cornerClass = ''; break;
1347
+ }
1348
+ calender += '">';
1349
+ }
1350
+ calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
1351
+ (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
1352
+ (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
1353
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
1354
+ selectedDate, row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
1355
+ '</div><table class="ui-datepicker-calendar"><thead>' +
1356
+ '<tr>';
1357
+ var thead = '';
1358
+ for (var dow = 0; dow < 7; dow++) { // days of the week
1359
+ var day = (dow + firstDay) % 7;
1360
+ thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
1361
+ '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
1362
+ }
1363
+ calender += thead + '</tr></thead><tbody>';
1364
+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
1365
+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
1366
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
1367
+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
1368
+ var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
1369
+ var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
1370
+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
1371
+ calender += '<tr>';
1372
+ var tbody = '';
1373
+ for (var dow = 0; dow < 7; dow++) { // create date picker days
1374
+ var daySettings = (beforeShowDay ?
1375
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
1376
+ var otherMonth = (printDate.getMonth() != drawMonth);
1377
+ var unselectable = otherMonth || !daySettings[0] ||
1378
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
1379
+ tbody += '<td class="' +
1380
+ ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
1381
+ (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
1382
+ ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
1383
+ (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
1384
+ // or defaultDate is current printedDate and defaultDate is selectedDate
1385
+ ' ' + this._dayOverClass : '') + // highlight selected day
1386
+ (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
1387
+ (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
1388
+ (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1389
+ ' ' + this._currentClass : '') + // highlight selected day
1390
+ (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
1391
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
1392
+ (unselectable ? '' : ' onclick="DP_jQuery.datepicker._selectDay(\'#' +
1393
+ inst.id + '\',' + drawMonth + ',' + drawYear + ', this);return false;"') + '>' + // actions
1394
+ (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
1395
+ (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
1396
+ (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
1397
+ (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ? // in current range
1398
+ ' ui-state-active' : '') + // highlight selected day
1399
+ '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
1400
+ printDate.setDate(printDate.getDate() + 1);
1401
+ printDate = this._daylightSavingAdjust(printDate);
1402
+ }
1403
+ calender += tbody + '</tr>';
1404
+ }
1405
+ drawMonth++;
1406
+ if (drawMonth > 11) {
1407
+ drawMonth = 0;
1408
+ drawYear++;
1409
+ }
1410
+ calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
1411
+ ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
1412
+ group += calender;
1413
+ }
1414
+ html += group;
1415
+ }
1416
+ html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
1417
+ '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
1418
+ inst._keyEvent = false;
1419
+ return html;
1420
+ },
1421
+
1422
+ /* Generate the month and year header. */
1423
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
1424
+ selectedDate, secondary, monthNames, monthNamesShort) {
1425
+ minDate = (inst.rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
1426
+ var changeMonth = this._get(inst, 'changeMonth');
1427
+ var changeYear = this._get(inst, 'changeYear');
1428
+ var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
1429
+ var html = '<div class="ui-datepicker-title">';
1430
+ var monthHtml = '';
1431
+ // month selection
1432
+ if (secondary || !changeMonth)
1433
+ monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span> ';
1434
+ else {
1435
+ var inMinYear = (minDate && minDate.getFullYear() == drawYear);
1436
+ var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
1437
+ monthHtml += '<select class="ui-datepicker-month" ' +
1438
+ 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
1439
+ 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1440
+ '>';
1441
+ for (var month = 0; month < 12; month++) {
1442
+ if ((!inMinYear || month >= minDate.getMonth()) &&
1443
+ (!inMaxYear || month <= maxDate.getMonth()))
1444
+ monthHtml += '<option value="' + month + '"' +
1445
+ (month == drawMonth ? ' selected="selected"' : '') +
1446
+ '>' + monthNamesShort[month] + '</option>';
1447
+ }
1448
+ monthHtml += '</select>';
1449
+ }
1450
+ if (!showMonthAfterYear)
1451
+ html += monthHtml + ((secondary || changeMonth || changeYear) && (!(changeMonth && changeYear)) ? '&#xa0;' : '');
1452
+ // year selection
1453
+ if (secondary || !changeYear)
1454
+ html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
1455
+ else {
1456
+ // determine range of years to display
1457
+ var years = this._get(inst, 'yearRange').split(':');
1458
+ var year = 0;
1459
+ var endYear = 0;
1460
+ if (years.length != 2) {
1461
+ year = drawYear - 10;
1462
+ endYear = drawYear + 10;
1463
+ } else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
1464
+ year = drawYear + parseInt(years[0], 10);
1465
+ endYear = drawYear + parseInt(years[1], 10);
1466
+ } else {
1467
+ year = parseInt(years[0], 10);
1468
+ endYear = parseInt(years[1], 10);
1469
+ }
1470
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
1471
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
1472
+ html += '<select class="ui-datepicker-year" ' +
1473
+ 'onchange="DP_jQuery.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
1474
+ 'onclick="DP_jQuery.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
1475
+ '>';
1476
+ for (; year <= endYear; year++) {
1477
+ html += '<option value="' + year + '"' +
1478
+ (year == drawYear ? ' selected="selected"' : '') +
1479
+ '>' + year + '</option>';
1480
+ }
1481
+ html += '</select>';
1482
+ }
1483
+ if (showMonthAfterYear)
1484
+ html += (secondary || changeMonth || changeYear ? '&#xa0;' : '') + monthHtml;
1485
+ html += '</div>'; // Close datepicker_header
1486
+ return html;
1487
+ },
1488
+
1489
+ /* Adjust one of the date sub-fields. */
1490
+ _adjustInstDate: function(inst, offset, period) {
1491
+ var year = inst.drawYear + (period == 'Y' ? offset : 0);
1492
+ var month = inst.drawMonth + (period == 'M' ? offset : 0);
1493
+ var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
1494
+ (period == 'D' ? offset : 0);
1495
+ var date = this._daylightSavingAdjust(new Date(year, month, day));
1496
+ // ensure it is within the bounds set
1497
+ var minDate = this._getMinMaxDate(inst, 'min', true);
1498
+ var maxDate = this._getMinMaxDate(inst, 'max');
1499
+ date = (minDate && date < minDate ? minDate : date);
1500
+ date = (maxDate && date > maxDate ? maxDate : date);
1501
+ inst.selectedDay = date.getDate();
1502
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
1503
+ inst.drawYear = inst.selectedYear = date.getFullYear();
1504
+ if (period == 'M' || period == 'Y')
1505
+ this._notifyChange(inst);
1506
+ },
1507
+
1508
+ /* Notify change of month/year. */
1509
+ _notifyChange: function(inst) {
1510
+ var onChange = this._get(inst, 'onChangeMonthYear');
1511
+ if (onChange)
1512
+ onChange.apply((inst.input ? inst.input[0] : null),
1513
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
1514
+ },
1515
+
1516
+ /* Determine the number of months to show. */
1517
+ _getNumberOfMonths: function(inst) {
1518
+ var numMonths = this._get(inst, 'numberOfMonths');
1519
+ return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
1520
+ },
1521
+
1522
+ /* Determine the current maximum date - ensure no time components are set - may be overridden for a range. */
1523
+ _getMinMaxDate: function(inst, minMax, checkRange) {
1524
+ var date = this._determineDate(this._get(inst, minMax + 'Date'), null);
1525
+ return (!checkRange || !inst.rangeStart ? date :
1526
+ (!date || inst.rangeStart > date ? inst.rangeStart : date));
1527
+ },
1528
+
1529
+ /* Find the number of days in a given month. */
1530
+ _getDaysInMonth: function(year, month) {
1531
+ return 32 - new Date(year, month, 32).getDate();
1532
+ },
1533
+
1534
+ /* Find the day of the week of the first of a month. */
1535
+ _getFirstDayOfMonth: function(year, month) {
1536
+ return new Date(year, month, 1).getDay();
1537
+ },
1538
+
1539
+ /* Determines if we should allow a "next/prev" month display change. */
1540
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
1541
+ var numMonths = this._getNumberOfMonths(inst);
1542
+ var date = this._daylightSavingAdjust(new Date(
1543
+ curYear, curMonth + (offset < 0 ? offset : numMonths[1]), 1));
1544
+ if (offset < 0)
1545
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
1546
+ return this._isInRange(inst, date);
1547
+ },
1548
+
1549
+ /* Is the given date in the accepted range? */
1550
+ _isInRange: function(inst, date) {
1551
+ // during range selection, use minimum of selected date and range start
1552
+ var newMinDate = (!inst.rangeStart ? null : this._daylightSavingAdjust(
1553
+ new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay)));
1554
+ newMinDate = (newMinDate && inst.rangeStart < newMinDate ? inst.rangeStart : newMinDate);
1555
+ var minDate = newMinDate || this._getMinMaxDate(inst, 'min');
1556
+ var maxDate = this._getMinMaxDate(inst, 'max');
1557
+ return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
1558
+ },
1559
+
1560
+ /* Provide the configuration settings for formatting/parsing. */
1561
+ _getFormatConfig: function(inst) {
1562
+ var shortYearCutoff = this._get(inst, 'shortYearCutoff');
1563
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
1564
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
1565
+ return {shortYearCutoff: shortYearCutoff,
1566
+ dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
1567
+ monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
1568
+ },
1569
+
1570
+ /* Format the given date for display. */
1571
+ _formatDate: function(inst, day, month, year) {
1572
+ if (!day) {
1573
+ inst.currentDay = inst.selectedDay;
1574
+ inst.currentMonth = inst.selectedMonth;
1575
+ inst.currentYear = inst.selectedYear;
1576
+ }
1577
+ var date = (day ? (typeof day == 'object' ? day :
1578
+ this._daylightSavingAdjust(new Date(year, month, day))) :
1579
+ this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
1580
+ return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
1581
+ }
1582
+ });
1583
+
1584
+ /* jQuery extend now ignores nulls! */
1585
+ function extendRemove(target, props) {
1586
+ $.extend(target, props);
1587
+ for (var name in props)
1588
+ if (props[name] == null || props[name] == undefined)
1589
+ target[name] = props[name];
1590
+ return target;
1591
+ };
1592
+
1593
+ /* Determine whether an object is an array. */
1594
+ function isArray(a) {
1595
+ return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
1596
+ (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
1597
+ };
1598
+
1599
+ /* Invoke the datepicker functionality.
1600
+ @param options string - a command, optionally followed by additional parameters or
1601
+ Object - settings for attaching new datepicker functionality
1602
+ @return jQuery object */
1603
+ $.fn.datepicker = function(options){
1604
+
1605
+ /* Initialise the date picker. */
1606
+ if (!$.datepicker.initialized) {
1607
+ $(document).mousedown($.datepicker._checkExternalClick).
1608
+ find('body').append($.datepicker.dpDiv);
1609
+ $.datepicker.initialized = true;
1610
+ }
1611
+
1612
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
1613
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate'))
1614
+ return $.datepicker['_' + options + 'Datepicker'].
1615
+ apply($.datepicker, [this[0]].concat(otherArgs));
1616
+ if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
1617
+ return $.datepicker['_' + options + 'Datepicker'].
1618
+ apply($.datepicker, [this[0]].concat(otherArgs));
1619
+ return this.each(function() {
1620
+ typeof options == 'string' ?
1621
+ $.datepicker['_' + options + 'Datepicker'].
1622
+ apply($.datepicker, [this].concat(otherArgs)) :
1623
+ $.datepicker._attachDatepicker(this, options);
1624
+ });
1625
+ };
1626
+
1627
+ $.datepicker = new Datepicker(); // singleton instance
1628
+ $.datepicker.initialized = false;
1629
+ $.datepicker.uuid = new Date().getTime();
1630
+ $.datepicker.version = "1.7.3";
1631
+
1632
+ // Workaround for #4055
1633
+ // Add another global to avoid noConflict issues with inline event handlers
1634
+ window.DP_jQuery = $;
1635
+
1636
+ })(jQuery);
static/js/pmxe.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * plugin javascript
3
+ */
4
+ (function($){$(function () {
5
+
6
+ $('#dismiss').click(function(){
7
+
8
+ $(this).parents('div.updated:first').slideUp();
9
+ $.post('admin.php?page=pmxe-admin-settings&action=dismiss', {dismiss: true}, function (data) {
10
+
11
+ }, 'html');
12
+ });
13
+
14
+ });})(jQuery);
views/admin/export/element.php ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="layout pmxe_step_2">
2
+ <tr>
3
+ <td class="left">
4
+ <h2><?php _e('Export to XML/CSV - Step 2: Choose Which data to export', 'pmxe_plugin') ?></h2>
5
+
6
+ <?php if ($this->errors->get_error_codes()): ?>
7
+ <?php $this->error() ?>
8
+ <?php endif; ?>
9
+
10
+ <h3><?php printf('Selected custom post types for export: %s', implode(", ", $post['cpt'])); ?></h3>
11
+
12
+ <fieldset class="optionsset">
13
+ <legend><?php _e('Data to export', 'pmxe_plugin'); ?></legend>
14
+ <form method="post" class="choose-export-data no-enter-submit" enctype="multipart/form-data" autocomplete="off">
15
+ <input type="hidden" name="is_submitted" value="1" />
16
+ <div class="input">
17
+
18
+ <div class="input">
19
+ <input type="hidden" name="is_export_title" value="0" />
20
+ <input type="checkbox" id="is_export_title" name="is_export_title" value="1" <?php echo $post['is_export_title'] ? 'checked="checked"': '' ?> />
21
+ <label for="is_export_title"><?php _e('Post Title', 'pmxe_plugin') ?></label>
22
+ </div>
23
+ <div class="input">
24
+ <input type="hidden" name="is_export_content" value="0" />
25
+ <input type="checkbox" id="is_export_content" name="is_export_content" value="1" <?php echo $post['is_export_content'] ? 'checked="checked"': '' ?> />
26
+ <label for="is_export_content"><?php _e('Post Content', 'pmxe_plugin') ?></label>
27
+ </div>
28
+
29
+ <div class="input">
30
+ <input type="hidden" name="custom_fields_list" value="0" />
31
+ <input type="hidden" name="is_export_custom_fields" value="0" />
32
+ <input type="checkbox" id="is_export_custom_fields" name="is_export_custom_fields" value="1" <?php echo $post['is_export_custom_fields'] ? 'checked="checked"': '' ?> class="switcher"/>
33
+ <label for="is_export_custom_fields"><?php _e('Custom Fields', 'pmxe_plugin') ?></label>
34
+ <div class="switcher-target-is_export_custom_fields" style="padding-left:17px;">
35
+ <?php
36
+ $existing_meta_keys = array();
37
+ $hide_fields = array('_wp_page_template', '_edit_lock', '_edit_last', '_wp_trash_meta_status', '_wp_trash_meta_time');
38
+ if (!empty($meta_keys) and $meta_keys->count()):
39
+ foreach ($meta_keys as $meta_key) { if (in_array($meta_key['meta_key'], $hide_fields) or strpos($meta_key['meta_key'], '_wp') === 0) continue;
40
+ $existing_meta_keys[] = $meta_key['meta_key'];
41
+ }
42
+ endif;
43
+ ?>
44
+ <div class="input">
45
+ <input type="radio" id="export_custom_fields_logic_only" name="export_custom_fields_logic" value="only" <?php echo ( "only" == $post['export_custom_fields_logic'] ) ? 'checked="checked"': '' ?> class="switcher"/>
46
+ <label for="export_custom_fields_logic_only"><?php _e('I only need a data from a few custom fields. Export these custom fields.', 'pmxe_plugin') ?></label>
47
+ <div class="switcher-target-export_custom_fields_logic_only pmxe_choosen" style="padding-left:17px;">
48
+
49
+ <span class="hidden choosen_values"><?php if (!empty($existing_meta_keys)) echo implode(',', $existing_meta_keys);?></span>
50
+ <input class="choosen_input" value="<?php if (!empty($post['custom_fields_list']) and "only" == $post['export_custom_fields_logic']) echo implode(',', $post['custom_fields_list']); ?>" type="hidden" name="custom_fields_list"/>
51
+ </div>
52
+ </div>
53
+ <div class="input">
54
+ <input type="radio" id="export_custom_fields_logic_full_update" name="export_custom_fields_logic" value="full_export" <?php echo ( "full_export" == $post['export_custom_fields_logic'] ) ? 'checked="checked"': '' ?> class="switcher"/>
55
+ <label for="export_custom_fields_logic_full_update"><?php _e('I want a gaint messy data file that\'s confusing and hard to read. Export ALL Cutom Fields.', 'pmxe_plugin') ?></label>
56
+ </div>
57
+ </div>
58
+ </div>
59
+
60
+ <div class="input">
61
+ <input type="hidden" name="taxonomies_list" value="0" />
62
+ <input type="hidden" name="is_export_categories" value="0" />
63
+ <input type="checkbox" id="is_export_categories" name="is_export_categories" value="1" class="switcher" <?php echo $post['is_export_categories'] ? 'checked="checked"': '' ?> />
64
+ <label for="is_export_categories"><?php _e('Taxonomies (incl. Categories and Tags)', 'pmxe_plugin') ?></label>
65
+ <div class="switcher-target-is_export_categories" style="padding-left:17px;">
66
+ <div class="input" style="margin-bottom:3px;">
67
+ <input type="radio" id="export_categories_logic_full_update" name="export_categories_logic" value="full_export" <?php echo ( "full_export" == $post['export_categories_logic'] ) ? 'checked="checked"': '' ?> class="switcher"/>
68
+ <label for="export_categories_logic_full_update" style="position:relative; top:1px;"><?php _e('Export all taxonomies', 'pmxe_plugin') ?></label>
69
+ </div>
70
+ <?php
71
+ global $wp_taxonomies;
72
+ $existing_taxonomies = array();
73
+
74
+ foreach ($wp_taxonomies as $key => $obj) {
75
+ $existing_taxonomies[] = $obj->name;
76
+ }
77
+
78
+ ?>
79
+ <div class="input" style="margin-bottom:3px;">
80
+ <input type="radio" id="export_categories_logic_only" name="export_categories_logic" value="only" <?php echo ( "only" == $post['export_categories_logic'] ) ? 'checked="checked"': '' ?> class="switcher"/>
81
+ <label for="export_categories_logic_only" style="position:relative; top:1px;"><?php _e('Only export these taxonomies.', 'pmxe_plugin') ?></label>
82
+ <div class="switcher-target-export_categories_logic_only pmxe_choosen" style="padding-left:17px;">
83
+ <span class="hidden choosen_values"><?php if (!empty($existing_taxonomies)) echo implode(',', $existing_taxonomies);?></span>
84
+ <input class="choosen_input" value="<?php if (!empty($post['taxonomies_list']) and "only" == $post['export_categories_logic']) echo implode(',', $post['taxonomies_list']); ?>" type="hidden" name="taxonomies_list"/>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <div class="input">
91
+ <input type="hidden" name="is_export_images" value="0" />
92
+ <input type="checkbox" id="is_export_images" name="is_export_images" value="1" <?php echo $post['is_export_images'] ? 'checked="checked"': '' ?> class="switcher" />
93
+ <label for="is_export_images"><?php _e('Media Gallery', 'pmxe_plugin') ?></label>
94
+ <div class="switcher-target-is_export_images" style="padding-left:17px;">
95
+ <div class="input" style="margin-bottom:3px;">
96
+ <input type="checkbox" id="export_images_logic_urls" name="export_images_logic[]" value="urls" <?php echo ( in_array("urls", $post['export_images_logic']) ) ? 'checked="checked"': '' ?> />
97
+ <label for="export_images_logic_urls" style="position:relative; top:1px;"><?php _e('Image URLs', 'pmxe_plugin') ?></label>
98
+ </div>
99
+ <div class="input" style="margin-bottom:3px;">
100
+ <input type="checkbox" id="export_images_logic_meta_data" name="export_images_logic[]" value="meta_data" <?php echo ( in_array("meta_data", $post['export_images_logic']) ) ? 'checked="checked"': '' ?> />
101
+ <label for="export_images_logic_meta_data" style="position:relative; top:1px;"><?php _e('Import Meta Data', 'pmxe_plugin') ?></label>
102
+ </div>
103
+ </div>
104
+ </div>
105
+
106
+ <div class="input">
107
+ <input type="hidden" name="is_export_other" value="0" />
108
+ <input type="checkbox" id="is_export_other" name="is_export_other" value="1" <?php echo $post['is_export_other'] ? 'checked="checked"': '' ?> class="switcher" />
109
+ <label for="is_export_other"><?php _e('Other Stuff', 'pmxe_plugin') ?></label>
110
+ <div class="switcher-target-is_export_other" style="padding-left:17px;">
111
+ <div class="input">
112
+ <input type="hidden" name="is_export_dates" value="0" />
113
+ <input type="checkbox" id="is_export_dates" name="is_export_dates" value="1" <?php echo $post['is_export_dates'] ? 'checked="checked"': '' ?> />
114
+ <label for="is_export_dates"><?php _e('Dates', 'pmxe_plugin') ?></label>
115
+ </div>
116
+ <div class="input">
117
+ <input type="hidden" name="is_export_parent" value="0" />
118
+ <input type="checkbox" id="is_export_parent" name="is_export_parent" value="1" <?php echo $post['is_export_parent'] ? 'checked="checked"': '' ?> />
119
+ <label for="is_export_parent"><?php _e('Parent', 'pmxe_plugin') ?></label>
120
+ </div>
121
+ <div class="input">
122
+ <input type="hidden" name="is_export_template" value="0" />
123
+ <input type="checkbox" id="is_export_template" name="is_export_template" value="1" <?php echo $post['is_export_template'] ? 'checked="checked"': '' ?> />
124
+ <label for="is_export_template"><?php _e('Template', 'pmxe_plugin') ?></label>
125
+ </div>
126
+ <div class="input">
127
+ <input type="hidden" name="is_export_menu_order" value="0" />
128
+ <input type="checkbox" id="is_export_menu_order" name="is_export_menu_order" value="1" <?php echo $post['is_export_menu_order'] ? 'checked="checked"': '' ?> />
129
+ <label for="is_export_menu_order"><?php _e('Order', 'pmxe_plugin') ?></label>
130
+ </div>
131
+ <div class="input">
132
+ <input type="hidden" name="is_export_status" value="0" />
133
+ <input type="checkbox" id="is_export_status" name="is_export_status" value="1" <?php echo $post['is_export_status'] ? 'checked="checked"': '' ?> />
134
+ <label for="is_export_status"><?php _e('Status', 'pmxe_plugin') ?></label>
135
+ </div>
136
+ <div class="input">
137
+ <input type="hidden" name="is_export_format" value="0" />
138
+ <input type="checkbox" id="is_export_format" name="is_export_format" value="1" <?php echo $post['is_export_format'] ? 'checked="checked"': '' ?> />
139
+ <label for="is_export_format"><?php _e('Format', 'pmxe_plugin') ?></label>
140
+ </div>
141
+ <div class="input">
142
+ <input type="hidden" name="is_export_author" value="0" />
143
+ <input type="checkbox" id="is_export_author" name="is_export_author" value="1" <?php echo $post['is_export_author'] ? 'checked="checked"': '' ?> />
144
+ <label for="is_export_author"><?php _e('Author', 'pmxe_plugin') ?></label>
145
+ </div>
146
+ <div class="input">
147
+ <input type="hidden" name="is_export_slug" value="0" />
148
+ <input type="checkbox" id="is_export_slug" name="is_export_slug" value="1" <?php echo $post['is_export_slug'] ? 'checked="checked"': '' ?> />
149
+ <label for="is_export_slug"><?php _e('Slug', 'pmxe_plugin') ?></label>
150
+ </div>
151
+ <div class="input">
152
+ <input type="hidden" name="is_export_excerpt" value="0" />
153
+ <input type="checkbox" id="is_export_excerpt" name="is_export_excerpt" value="1" <?php echo $post['is_export_excerpt'] ? 'checked="checked"': '' ?> />
154
+ <label for="is_export_excerpt"><?php _e('Excerpt/Short Description', 'pmxe_plugin') ?></label>
155
+ </div>
156
+ <div class="input">
157
+ <input type="hidden" name="is_export_attachments" value="0" />
158
+ <input type="checkbox" id="is_export_attachments" name="is_export_attachments" value="1" <?php echo $post['is_export_attachments'] ? 'checked="checked"': '' ?> />
159
+ <label for="is_export_attachments"><?php _e('Attachment URLs', 'pmxe_plugin') ?></label>
160
+ </div>
161
+
162
+ </div>
163
+ </div>
164
+ </div>
165
+ <p class="submit-buttons" style="text-align:right;">
166
+ <?php wp_nonce_field('element', '_wpnonce_element') ?>
167
+ <input type="hidden" name="is_submitted" value="1" />
168
+
169
+ <a href="<?php echo $this->baseUrl ?>" class="back"><?php _e('Back', 'pmxe_plugin') ?></a>
170
+
171
+ <input type="submit" class="button button-primary button-hero large_button" name="export_to" value="<?php _e('Export XML', 'pmxe_plugin') ?>" />
172
+
173
+ <input type="submit" class="button button-primary button-hero large_button" name="export_to" value="<?php _e('Export CSV', 'pmxe_plugin') ?>" />
174
+
175
+ </p>
176
+ </form>
177
+ </fieldset>
178
+ </td>
179
+ <td class="right">
180
+ &nbsp;
181
+ </td>
182
+ </tr>
183
+ </table>
views/admin/export/index.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="layout pmxe_step_1">
2
+ <tr>
3
+ <td class="left">
4
+ <h2><?php _e('Export to XML/CSV - Step 1: Choose Which posts to export', 'pmxe_plugin') ?></h2>
5
+
6
+ <?php if ($this->errors->get_error_codes()): ?>
7
+ <?php $this->error() ?>
8
+ <?php endif ?>
9
+
10
+ <?php do_action('pmxe_choose_file_header'); ?>
11
+ <form method="post" class="choose-post-type no-enter-submit" enctype="multipart/form-data" autocomplete="off">
12
+ <input type="hidden" name="is_submitted" value="1" />
13
+ <?php wp_nonce_field('type_specific-cpt', '_wpnonce_type_specific-cpt') ?>
14
+ <div class="file-type-container">
15
+ <h3>
16
+ <input type="radio" id="type_specific" name="type" value="specific" checked="checked" />
17
+ <label for="type_specific"><?php _e('Export a specific post type', 'pmxe_plugin') ?></label>
18
+ </h3>
19
+ <div class="file-type-options">
20
+ <?php $custom_types = get_post_types(array('_builtin' => false), 'objects'); ?>
21
+ <select name="cpt">
22
+ <option value="post"><?php _e('Posts','pmxe_plugin');?></option>
23
+ <option value="page"><?php _e('Pages','pmxe_plugin');?></option>
24
+ <?php if (count($custom_types)): ?>
25
+ <?php foreach ($custom_types as $key => $ct):?>
26
+ <option value="<?php echo $key;?>"><?php echo $ct->labels->name; ?></option>
27
+ <?php endforeach ?>
28
+ <?php endif ?>
29
+ </select>
30
+ </div>
31
+ </div>
32
+ <div class="file-type-container">
33
+ <h3>
34
+ <input type="radio" id="type_multiple" name="type" value="url" />
35
+ <label for="type_multiple"><?php _e('Export multiple post types', 'pmxe_plugin') ?></label>
36
+ </h3>
37
+ <div class="file-type-options">
38
+ <input type="checkbox" name="cpt[]" value="post" id="posts"/> <label for="posts"><?php _e('Posts', 'pmxe_plugin'); ?></label>
39
+ <input type="checkbox" name="cpt[]" value="page" id="pages"/> <label for="pages"><?php _e('Pages', 'pmxe_plugin'); ?></label>
40
+ <?php if (count($custom_types)): ?>
41
+ <?php foreach ($custom_types as $key => $ct):?>
42
+ <input type="checkbox" name="cpt[]" value="<?php echo $key; ?>" id="<?php echo $key; ?>"/> <label for="<?php echo $key; ?>"><?php echo $ct->labels->name ?></label>
43
+ <?php endforeach ?>
44
+ <?php endif ?>
45
+ </div>
46
+ </div>
47
+ <div id="url_upload_status"></div>
48
+ <p class="submit-buttons">
49
+ <input type="hidden" name="is_submitted" value="1" />
50
+ <?php wp_nonce_field('choose-cpt', '_wpnonce_choose-cpt') ?>
51
+ <input type="submit" class="button button-primary button-hero large_button" value="<?php _e('Next', 'pmxe_plugin') ?>" id="advanced_upload"/>
52
+ </p>
53
+ <br />
54
+ <table><tr><td class="note"></td></tr></table>
55
+ </form>
56
+ </td>
57
+ <td class="right">
58
+ &nbsp;
59
+ </td>
60
+ </tr>
61
+ </table>
views/admin/export/process.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="layout pmxe_step_3">
2
+ <tr>
3
+ <td class="left">
4
+ <h2><?php _e('Export XML - <span id="status">Exporting...</span>', 'pmxe_plugin') ?></h2>
5
+
6
+ <hr />
7
+ <p id="process_notice"><?php _e('Exporting may take some time. Please do not close your browser or refresh the page until the process is complete.', 'pmxe_plugin') ?></p>
8
+
9
+ </td>
10
+ <td class="right">
11
+ &nbsp;
12
+ </td>
13
+ </tr>
14
+ </table>
15
+
16
+ <script type="text/javascript">
17
+ //<![CDATA[
18
+ (function($){
19
+ $('#status').each(function () {
20
+ var $this = $(this);
21
+ if ($this.html().match(/\.{3}$/)) {
22
+ var dots = 0;
23
+ var status = $this.html().replace(/\.{3}$/, '');
24
+ var interval ;
25
+ interval = setInterval(function () {
26
+ if ($this.html().match(new RegExp(status + '\\.{1,3}$', ''))) {
27
+ $this.html(status + '...'.substr(0, dots++ % 3 + 1));
28
+ } else {
29
+ $('#process_notice').hide();
30
+ clearInterval(interval);
31
+ }
32
+ }, 1000);
33
+ }
34
+ });
35
+
36
+ var request = {
37
+ action:'export',
38
+ };
39
+
40
+ $.ajax({
41
+ type: 'POST',
42
+ url: ajaxurl,
43
+ data: request,
44
+ success: function(response) {
45
+ $('#status').html('Complete');
46
+ window.onbeforeunload = false;
47
+ window.location.href = "<?php echo add_query_arg('action', 'download', $this->baseUrl); ?>";
48
+ },
49
+ dataType: "json"
50
+ });
51
+
52
+ window.onbeforeunload = function () {
53
+ return 'WARNING:\nExport process in under way, leaving the page will interrupt\nthe operation and most likely to cause leftovers in posts.';
54
+ };
55
+ })(jQuery);
56
+
57
+ //]]>
58
+ </script>
views/admin/help/index.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <h2><?php _e('WP All Export Support', 'PMXE_plugin') ?></h2>
2
+
3
+ <table class="layout">
4
+ <tr>
5
+ <td class="left">
6
+ <p style='font-size: 1.3em;'>
7
+ <b>E-mail</b> - <a href='mailto:support@soflyy.com'>support@soflyy.com</a><br />
8
+ <b>Support page</b> - <a href='http://www.wpallimport.com/support?utm_source=wordpress.org&utm_medium=support&utm_campaign=free+plugin' target='_blank'>http://www.wpallimport.com/support</a>
9
+ </p>
10
+ </td>
11
+ <td class="right">&nbsp;</td>
12
+ </tr>
13
+ </table>
views/admin/settings/index.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <form class="settings" method="post" action="<?php echo $this->baseUrl ?>" enctype="multipart/form-data">
2
+
3
+ <h2><?php _e('WP All Export Settings', 'pmxe_plugin') ?></h2>
4
+ <hr />
5
+ <?php if ($this->errors->get_error_codes()): ?>
6
+ <?php $this->error() ?>
7
+ <?php endif ?>
8
+
9
+ </form>
10
+ <br />
11
+
12
+ <form name="settings" method="post" action="<?php echo $this->baseUrl ?>">
13
+ <h3><?php _e('Export Settings', 'pmxe_plugin') ?></h3>
14
+ <p>
15
+ <?php printf(__('%s <label for="session_mode_default">Session Mode (default)</label>', 'pmxe_plugin'), '<input type="radio" name="session_mode" id="session_mode_default" value="default" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'default') ? 'checked="checked"' : '') .'/>') ?> <br>
16
+ <?php printf(__('%s <label for="session_mode_files">Session Mode (files)</label>', 'pmxe_plugin'), '<input type="radio" name="session_mode" id="session_mode_files" value="files" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'files') ? 'checked="checked"' : '') .'/>') ?> <br>
17
+ <?php printf(__('%s <label for="session_mode_database">Session Mode (database)</label>', 'pmxe_plugin'), '<input type="radio" name="session_mode" id="session_mode_database" value="database" style="position:relative; top:-2px;" '. (($post['session_mode'] == 'database') ? 'checked="checked"' : '') .'/>') ?>
18
+ </p>
19
+ <p class="submit-buttons">
20
+ <?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
21
+ <input type="hidden" name="is_settings_submitted" value="1" />
22
+ <input type="submit" class="button-primary" value="Save Settings" />
23
+ </p>
24
+
25
+ </form>
views/controller/error.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php foreach ($errors as $msg): ?>
2
+ <div class="error"><p><?php echo $msg ?></p></div>
3
+ <?php endforeach ?>