Timetable and Event Schedule by MotoPress - Version 2.3.13

Version Description

Download this release

Release Info

Developer MotoPress
Plugin Icon 128x128 Timetable and Event Schedule by MotoPress
Version 2.3.13
Comparing to
See all releases

Code changes from version 2.3.12 to 2.3.13

admin/help/index.php CHANGED
@@ -1,70 +1,70 @@
1
- <div class="wrap">
2
- <h1 class="wp-heading-inline">Help</h1>
3
- <p><?php
4
-
5
- $pluginObject = get_plugin_data( MP_TT_PLUGIN_FILE );
6
- $name = $pluginObject[ 'Name' ];
7
-
8
- echo sprintf(
9
- /* translators: 1: Timetable and Event Schedule 2:: five stars rating */
10
- __( 'If you like %1$s please leave us a %2$s rating.', 'mp-timetable' ),
11
- sprintf( '<strong>%s</strong>', esc_html( $name ) ),
12
- '<a href="https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
13
- );
14
- ?></p>
15
- <hr/>
16
- <h2>Quick Start Guide</h2>
17
- <ol>
18
- <li>
19
- <p><strong>Add Columns</strong><br/>
20
- Make sure you created Columns prior to adding Events for the events to be then assigned to the created columns.</p>
21
- </li>
22
- <li>
23
- <p><strong>Add Events</strong><br/>
24
- The events will be displayed in the actual timetable. Event details will be shown on each event’s individual page.</p>
25
- <ol>
26
- <li>
27
- <p><strong>Add Event Category</strong><br/>
28
- Events can be presented under different categories, which can be chosen in the shortcode parameters below.</p>
29
- </li>
30
- </ol>
31
- </li>
32
- <li>
33
- <p><strong>Add Timetable to a Page</strong></p>
34
- <ol>
35
- <li>Find "TimeTable" icon on TinyMCE panel in Classic Editor.</li>
36
- <li>Build Timetable shortcode manually.
37
- <p>Shortcode <code>[mp-timetable ... ]</code> attributes:</p>
38
- <ul>
39
- <li><code>col</code> - comma-separated column IDs.</li>
40
- <li><code>events</code> - comma-separated event IDs.</li>
41
- <li><code>event_categ</code> - comma-separated event category IDs.</li>
42
- <li><code>increment</code> - hour measure; possible values <kbd>1</kbd> - hour (1h), <kbd>0.5</kbd> - half an hour (30min), <kbd>0.25</kbd> - quarter an hour (15min).</li>
43
- <li><code>title</code> - display event title; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
44
- <li><code>time</code> - display event time; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
45
- <li><code>sub-title</code> - display event subtitle; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
46
- <li><code>description</code> - display event description; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
47
- <li><code>user</code> - display event head; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
48
- <li><code>row_height</code> - event block height in pixels; example <kbd>45</kbd></li>
49
- <li><code>font_size</code> - base font size for the table; example <kbd>12px</kbd>, <kbd>2em</kbd>, <kbd>80%</kbd>.</li>
50
- <li><code>view</code> - filter style; possible values <kbd>dropdown_list</kbd> or <kbd>tabs</kbd>.</li>
51
- <li><code>view_sort</code> - order of items in filter; possible values <kbd><i>empty string</i></kbd>, <kbd>menu_order</kbd>, <kbd>post_title</kbd>.</li>
52
- <li><code>label</code> - filter label; default is <kbd>All Events</kbd>.</li>
53
- <li><code>hide_label</code> - display 'All Events' label or not; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
54
- <li><code>hide_hrs</code> - hide first (hours) column; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
55
- <li><code>hide_empty_rows</code> - hide empty rows; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
56
- <li><code>group</code> - merge cells with common events; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
57
- <li><code>disable_event_url</code> - disable event URL; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
58
- <li><code>text_align</code> - horizontal align; possible values <kbd>left</kbd>, <kbd>center</kbd>, <kbd>right</kbd>.</li>
59
- <li><code>text_align_vertical</code> - vertical align ; possible values <kbd>default</kbd>, <kbd>top</kbd>, <kbd>middle</kbd>, <kbd>bottom</kbd>.</li>
60
- <li><code>id</code> - unique ID.</li>
61
- <li><code>custom_class</code> - CSS class.</li>
62
- <li><code>responsive</code> - mobile layout; possible values <kbd>1</kbd> - display as list, <kbd>0</kbd> - display as table.</li>
63
- <li><code>table_layout</code> - table layout; possible values <kbd>auto</kbd>, <kbd>fixed</kbd>.</li>
64
- </ul>
65
- </li>
66
- <li>Use "TimeTable" block in the new Block Editor.</li>
67
- </ol>
68
- </li>
69
- </ol>
70
- </div>
1
+ <div class="wrap">
2
+ <h1 class="wp-heading-inline">Help</h1>
3
+ <p><?php
4
+
5
+ $pluginObject = get_plugin_data( MP_TT_PLUGIN_FILE );
6
+ $name = $pluginObject[ 'Name' ];
7
+
8
+ echo sprintf(
9
+ /* translators: 1: Timetable and Event Schedule 2:: five stars rating */
10
+ __( 'If you like %1$s please leave us a %2$s rating.', 'mp-timetable' ),
11
+ sprintf( '<strong>%s</strong>', esc_html( $name ) ),
12
+ '<a href="https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
13
+ );
14
+ ?></p>
15
+ <hr/>
16
+ <h2>Quick Start Guide</h2>
17
+ <ol>
18
+ <li>
19
+ <p><strong>Add Columns</strong><br/>
20
+ Make sure you created Columns prior to adding Events for the events to be then assigned to the created columns.</p>
21
+ </li>
22
+ <li>
23
+ <p><strong>Add Events</strong><br/>
24
+ The events will be displayed in the actual timetable. Event details will be shown on each event’s individual page.</p>
25
+ <ol>
26
+ <li>
27
+ <p><strong>Add Event Category</strong><br/>
28
+ Events can be presented under different categories, which can be chosen in the shortcode parameters below.</p>
29
+ </li>
30
+ </ol>
31
+ </li>
32
+ <li>
33
+ <p><strong>Add Timetable to a Page</strong></p>
34
+ <ol>
35
+ <li>Find "TimeTable" icon on TinyMCE panel in Classic Editor.</li>
36
+ <li>Build Timetable shortcode manually.
37
+ <p>Shortcode <code>[mp-timetable ... ]</code> attributes:</p>
38
+ <ul>
39
+ <li><code>col</code> - comma-separated column IDs.</li>
40
+ <li><code>events</code> - comma-separated event IDs.</li>
41
+ <li><code>event_categ</code> - comma-separated event category IDs.</li>
42
+ <li><code>increment</code> - hour measure; possible values <kbd>1</kbd> - hour (1h), <kbd>0.5</kbd> - half an hour (30min), <kbd>0.25</kbd> - quarter an hour (15min).</li>
43
+ <li><code>title</code> - display event title; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
44
+ <li><code>time</code> - display event time; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
45
+ <li><code>sub-title</code> - display event subtitle; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
46
+ <li><code>description</code> - display event description; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
47
+ <li><code>user</code> - display event head; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
48
+ <li><code>row_height</code> - event block height in pixels; example <kbd>45</kbd></li>
49
+ <li><code>font_size</code> - base font size for the table; example <kbd>12px</kbd>, <kbd>2em</kbd>, <kbd>80%</kbd>.</li>
50
+ <li><code>view</code> - filter style; possible values <kbd>dropdown_list</kbd> or <kbd>tabs</kbd>.</li>
51
+ <li><code>view_sort</code> - order of items in filter; possible values <kbd><i>empty string</i></kbd>, <kbd>menu_order</kbd>, <kbd>post_title</kbd>.</li>
52
+ <li><code>label</code> - filter label; default is <kbd>All Events</kbd>.</li>
53
+ <li><code>hide_label</code> - display 'All Events' label or not; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
54
+ <li><code>hide_hrs</code> - hide first (hours) column; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
55
+ <li><code>hide_empty_rows</code> - hide empty rows; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
56
+ <li><code>group</code> - merge cells with common events; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
57
+ <li><code>disable_event_url</code> - disable event URL; possible values <kbd>1</kbd> or <kbd>0</kbd>.</li>
58
+ <li><code>text_align</code> - horizontal align; possible values <kbd>left</kbd>, <kbd>center</kbd>, <kbd>right</kbd>.</li>
59
+ <li><code>text_align_vertical</code> - vertical align ; possible values <kbd>default</kbd>, <kbd>top</kbd>, <kbd>middle</kbd>, <kbd>bottom</kbd>.</li>
60
+ <li><code>id</code> - unique ID.</li>
61
+ <li><code>custom_class</code> - CSS class.</li>
62
+ <li><code>responsive</code> - mobile layout; possible values <kbd>1</kbd> - display as list, <kbd>0</kbd> - display as table.</li>
63
+ <li><code>table_layout</code> - column width; possible values <kbd>auto</kbd>, <kbd>fixed</kbd>.</li>
64
+ </ul>
65
+ </li>
66
+ <li>Use "TimeTable" block in the new Block Editor.</li>
67
+ </ol>
68
+ </li>
69
+ </ol>
70
+ </div>
classes/blocks/class-timetable-block.php CHANGED
@@ -1,194 +1,207 @@
1
- <?php
2
-
3
- namespace mp_timetable\classes\blocks;
4
-
5
- use Mp_Time_Table;
6
- use mp_timetable\plugin_core\classes\Core;
7
- use mp_timetable\plugin_core\classes\Shortcode;
8
-
9
- class Timetable_Block {
10
-
11
- public function __construct() {
12
-
13
- // block-js
14
- wp_register_script(
15
- 'mptt-blocks-js',
16
- Mp_Time_Table::get_plugin_url( '/media/js/blocks/dist/index.min.js' ),
17
- array( 'wp-i18n', 'wp-editor', 'wp-element', 'wp-blocks', 'wp-components', 'wp-api', 'wp-api-fetch', 'mptt-functions', 'mptt-event-object'),
18
- Core::get_instance()->get_version()
19
- );
20
-
21
- // style.css
22
- wp_register_style(
23
- 'mptt-blocks',
24
- Mp_Time_Table::get_plugin_url( 'media/css/style.css' ),
25
- array(),
26
- Core::get_instance()->get_version()
27
- );
28
-
29
- // block-editor.css
30
- wp_register_style(
31
- 'mptt-blocks-editor',
32
- Mp_Time_Table::get_plugin_url( '/media/css/block-editor.css' ),
33
- array('mptt-blocks'),
34
- Core::get_instance()->get_version()
35
- );
36
-
37
- // internationalization
38
- wp_set_script_translations( 'mptt-blocks-js', 'mp-timetable', Mp_Time_Table::get_plugin_path() . 'languages' );
39
-
40
- register_block_type(
41
- 'mp-timetable/timetable',
42
- array(
43
- 'attributes' => array(
44
- 'align' => array(
45
- 'type' => 'string',
46
- ),
47
- 'col' => array(
48
- 'type' => 'array',
49
- 'items' => [
50
- 'type' => 'integer',
51
- ],
52
- ),
53
- 'events' => array(
54
- 'type' => 'array',
55
- 'items' => [
56
- 'type' => 'integer',
57
- ],
58
- ),
59
- 'event_categ' => array(
60
- 'type' => 'array',
61
- 'items' => [
62
- 'type' => 'integer',
63
- ],
64
- ),
65
- 'increment' => array(
66
- 'type' => 'string',
67
- 'default' => '1',
68
- ),
69
- 'view' => array(
70
- 'type' => 'string',
71
- 'default' => 'dropdown_list',
72
- ),
73
- 'view_sort' => array(
74
- 'type' => 'string',
75
- 'default' => '',
76
- ),
77
- 'label' => array(
78
- 'type' => 'string',
79
- 'default' => __( "All Events", 'mp-timetable' ),
80
- ),
81
- 'hide_label' => array(
82
- 'type' => 'string',
83
- 'default' => '0',
84
- ),
85
- 'hide_hrs' => array(
86
- 'type' => 'string',
87
- 'default' => '0',
88
- ),
89
- 'hide_empty_rows' => array(
90
- 'type' => 'string',
91
- 'default' => '1',
92
- ),
93
- 'title' => array(
94
- 'type' => 'string',
95
- 'default' => '1',
96
- ),
97
- 'time' => array(
98
- 'type' => 'string',
99
- 'default' => '1',
100
- ),
101
- 'sub_title' => array(
102
- 'type' => 'string',
103
- 'default' => '0',
104
- ),
105
- 'description' => array(
106
- 'type' => 'string',
107
- 'default' => '1',
108
- ),
109
- 'user' => array(
110
- 'type' => 'string',
111
- 'default' => '0',
112
- ),
113
- 'group' => array(
114
- 'type' => 'string',
115
- 'default' => '0',
116
- ),
117
- 'disable_event_url' => array(
118
- 'type' => 'string',
119
- 'default' => '0',
120
- ),
121
- 'text_align' => array(
122
- 'type' => 'string',
123
- 'default' => 'center',
124
- ),
125
- 'id' => array(
126
- 'type' => 'string',
127
- ),
128
- 'row_height' => array(
129
- 'type' => 'string',
130
- 'default' => '45',
131
- ),
132
- 'font_size' => array(
133
- 'type' => 'string',
134
- ),
135
- 'responsive' => array(
136
- 'type' => 'string',
137
- 'default' => '1',
138
- ),
139
- 'text_align_vertical' => array(
140
- 'type' => 'string',
141
- 'default' => 'default',
142
- ),
143
- 'custom_class' => array(
144
- 'type' => 'string',
145
- ),
146
- 'table_layout' => array(
147
- 'type' => 'string'
148
- ),
149
- ),
150
- 'render_callback' => [ $this, 'render_timetable' ],
151
- 'editor_style' => 'mptt-blocks-editor',
152
- 'editor_script' => 'mptt-blocks-js',
153
- )
154
- );
155
- }
156
-
157
- private function show_shortcode($attributes) {
158
- foreach ($attributes as $key => $value) {
159
- // [] -> '1,2,3'
160
- if ( is_array($value) ) {
161
- $attributes[$key] = implode( ',', $value );
162
- }
163
- // 'sub_title' -> 'sub-title'
164
- if ($key == 'sub_title') {
165
- $attributes['sub-title'] = $attributes[$key];
166
- unset( $attributes[$key] );
167
- }
168
- }
169
-
170
- echo Shortcode::get_instance()->show_shortcode($attributes);
171
- }
172
-
173
- public function render_timetable( $attributes ) {
174
-
175
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
176
-
177
- $block_name = 'wp-block-timetable';
178
-
179
- $class = $block_name;
180
- if ( isset( $attributes['align'] ) ) {
181
- $class .= ' align' . $attributes['align'];
182
- }
183
-
184
- ob_start();
185
- ?><div class="<?php echo esc_attr( $class ); ?>"><?php
186
-
187
- $this->show_shortcode($attributes);
188
-
189
- ?></div><?php
190
-
191
- $result = ob_get_clean();
192
- return $result;
193
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  }
1
+ <?php
2
+
3
+ namespace mp_timetable\classes\blocks;
4
+
5
+ use Mp_Time_Table;
6
+ use mp_timetable\plugin_core\classes\Core;
7
+ use mp_timetable\plugin_core\classes\Shortcode;
8
+
9
+ class Timetable_Block {
10
+
11
+ public function __construct() {
12
+
13
+ // block-js
14
+ wp_register_script(
15
+ 'mptt-blocks-js',
16
+ Mp_Time_Table::get_plugin_url( 'media/js/blocks/dist/index.min.js' ),
17
+ array( 'wp-i18n', 'wp-editor', 'wp-element', 'wp-blocks', 'wp-components', 'wp-api', 'wp-api-fetch', 'mptt-functions', 'mptt-event-object'),
18
+ Core::get_instance()->get_version()
19
+ );
20
+
21
+ // style.css
22
+ wp_register_style(
23
+ 'mptt-blocks',
24
+ Mp_Time_Table::get_plugin_url( 'media/css/style.css' ),
25
+ array(),
26
+ Core::get_instance()->get_version()
27
+ );
28
+
29
+ // block-editor.css
30
+ wp_register_style(
31
+ 'mptt-blocks-editor',
32
+ Mp_Time_Table::get_plugin_url( 'media/css/block-editor.css' ),
33
+ array('mptt-blocks'),
34
+ Core::get_instance()->get_version()
35
+ );
36
+
37
+
38
+ // Internationalization
39
+
40
+ /*
41
+ * For custom translations
42
+ * https://developer.wordpress.org/reference/functions/wp_set_script_translations/
43
+ *
44
+ * By default, minified files should still be excluded, and if you want to explicitly include them, you can do so by adding --include=*.min.js to the command.
45
+ * https://github.com/wp-cli/i18n-command/pull/85
46
+ *
47
+ */
48
+ //wp_set_script_translations( 'mptt-blocks-js', 'mp-timetable', Mp_Time_Table::get_plugin_path() . 'languages' );
49
+
50
+
51
+ wp_set_script_translations( 'mptt-blocks-js', 'mp-timetable' );
52
+
53
+ register_block_type(
54
+ 'mp-timetable/timetable',
55
+ array(
56
+ 'attributes' => array(
57
+ 'align' => array(
58
+ 'type' => 'string',
59
+ ),
60
+ 'col' => array(
61
+ 'type' => 'array',
62
+ 'items' => [
63
+ 'type' => 'integer',
64
+ ],
65
+ ),
66
+ 'events' => array(
67
+ 'type' => 'array',
68
+ 'items' => [
69
+ 'type' => 'integer',
70
+ ],
71
+ ),
72
+ 'event_categ' => array(
73
+ 'type' => 'array',
74
+ 'items' => [
75
+ 'type' => 'integer',
76
+ ],
77
+ ),
78
+ 'increment' => array(
79
+ 'type' => 'string',
80
+ 'default' => '1',
81
+ ),
82
+ 'view' => array(
83
+ 'type' => 'string',
84
+ 'default' => 'dropdown_list',
85
+ ),
86
+ 'view_sort' => array(
87
+ 'type' => 'string',
88
+ 'default' => '',
89
+ ),
90
+ 'label' => array(
91
+ 'type' => 'string',
92
+ 'default' => __( "All Events", 'mp-timetable' ),
93
+ ),
94
+ 'hide_label' => array(
95
+ 'type' => 'string',
96
+ 'default' => '0',
97
+ ),
98
+ 'hide_hrs' => array(
99
+ 'type' => 'string',
100
+ 'default' => '0',
101
+ ),
102
+ 'hide_empty_rows' => array(
103
+ 'type' => 'string',
104
+ 'default' => '1',
105
+ ),
106
+ 'title' => array(
107
+ 'type' => 'string',
108
+ 'default' => '1',
109
+ ),
110
+ 'time' => array(
111
+ 'type' => 'string',
112
+ 'default' => '1',
113
+ ),
114
+ 'sub_title' => array(
115
+ 'type' => 'string',
116
+ 'default' => '0',
117
+ ),
118
+ 'description' => array(
119
+ 'type' => 'string',
120
+ 'default' => '1',
121
+ ),
122
+ 'user' => array(
123
+ 'type' => 'string',
124
+ 'default' => '0',
125
+ ),
126
+ 'group' => array(
127
+ 'type' => 'string',
128
+ 'default' => '0',
129
+ ),
130
+ 'disable_event_url' => array(
131
+ 'type' => 'string',
132
+ 'default' => '0',
133
+ ),
134
+ 'text_align' => array(
135
+ 'type' => 'string',
136
+ 'default' => 'center',
137
+ ),
138
+ 'id' => array(
139
+ 'type' => 'string',
140
+ ),
141
+ 'row_height' => array(
142
+ 'type' => 'string',
143
+ 'default' => '45',
144
+ ),
145
+ 'font_size' => array(
146
+ 'type' => 'string',
147
+ ),
148
+ 'responsive' => array(
149
+ 'type' => 'string',
150
+ 'default' => '1',
151
+ ),
152
+ 'text_align_vertical' => array(
153
+ 'type' => 'string',
154
+ 'default' => 'default',
155
+ ),
156
+ 'custom_class' => array(
157
+ 'type' => 'string',
158
+ ),
159
+ 'table_layout' => array(
160
+ 'type' => 'string'
161
+ ),
162
+ ),
163
+ 'render_callback' => [ $this, 'render_timetable' ],
164
+ 'editor_style' => 'mptt-blocks-editor',
165
+ 'editor_script' => 'mptt-blocks-js',
166
+ )
167
+ );
168
+ }
169
+
170
+ private function show_shortcode($attributes) {
171
+ foreach ($attributes as $key => $value) {
172
+ // [] -> '1,2,3'
173
+ if ( is_array($value) ) {
174
+ $attributes[$key] = implode( ',', $value );
175
+ }
176
+ // 'sub_title' -> 'sub-title'
177
+ if ($key == 'sub_title') {
178
+ $attributes['sub-title'] = $attributes[$key];
179
+ unset( $attributes[$key] );
180
+ }
181
+ }
182
+
183
+ echo Shortcode::get_instance()->show_shortcode($attributes);
184
+ }
185
+
186
+ public function render_timetable( $attributes ) {
187
+
188
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
189
+
190
+ $block_name = 'wp-block-timetable';
191
+
192
+ $class = $block_name;
193
+ if ( isset( $attributes['align'] ) ) {
194
+ $class .= ' align' . $attributes['align'];
195
+ }
196
+
197
+ ob_start();
198
+ ?><div class="<?php echo esc_attr( $class ); ?>"><?php
199
+
200
+ $this->show_shortcode($attributes);
201
+
202
+ ?></div><?php
203
+
204
+ $result = ob_get_clean();
205
+ return $result;
206
+ }
207
  }
classes/class-core.php CHANGED
@@ -1,716 +1,717 @@
1
- <?php
2
-
3
- namespace mp_timetable\plugin_core\classes;
4
-
5
- use Mp_Time_Table;
6
- use mp_timetable\classes\models\Column;
7
- use mp_timetable\classes\models\Events;
8
-
9
- /**
10
- * Class main state
11
- */
12
- class Core {
13
-
14
- protected static $instance;
15
-
16
- protected $version;
17
-
18
- /**
19
- * Current state
20
- */
21
- private $state;
22
-
23
- /**
24
- * Core constructor.
25
- */
26
- public function __construct() {
27
-
28
- $this->taxonomy_names = array(
29
- 'mp-event_category',
30
- 'mp-event_tag'
31
- );
32
- $this->post_types = array(
33
- 'mp-event',
34
- 'mp-column'
35
- );
36
- }
37
-
38
- /**
39
- * Check for ajax post
40
- * @return bool
41
- */
42
- static function is_ajax() {
43
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
44
- return true;
45
- } else {
46
- return false;
47
- }
48
- }
49
-
50
- /**
51
- * @return array
52
- */
53
- public function get_post_types() {
54
- return $this->post_types;
55
- }
56
-
57
- /**
58
- * @return array
59
- */
60
- public function get_taxonomy_names() {
61
- return $this->taxonomy_names;
62
- }
63
-
64
- /**
65
- * Init current plugin
66
- *
67
- * @param $name
68
- */
69
- public function init_plugin( $name ) {
70
- load_plugin_textdomain( 'mp-timetable', false, Mp_Time_Table::get_plugin_path() . 'languages/' );
71
-
72
- // include template for function
73
- Core::include_all( Mp_Time_Table::get_plugin_part_path( 'templates-functions' ) );
74
-
75
- // include plugin models files
76
- Model::get_instance()->install();
77
-
78
- // include plugin controllers files
79
- Controller::get_instance()->install();
80
-
81
- // include plugin Preprocessors files
82
- Preprocessor::install();
83
-
84
- // include plugin modules
85
- Module::install();
86
-
87
- // install state
88
- $this->install_state( $name );
89
-
90
- // init all hooks
91
- Hooks::get_instance()->install_hooks();
92
- Hooks::get_instance()->register_template_action();
93
- }
94
-
95
- /**
96
- * Include all files from folder
97
- *
98
- * @param string $folder
99
- * @param boolean $inFolder
100
- */
101
- static function include_all( $folder, $inFolder = true ) {
102
- if ( file_exists( $folder ) ) {
103
- $includeArr = scandir( $folder );
104
- foreach ( $includeArr as $include ) {
105
- if ( ! is_dir( $folder . "/" . $include ) ) {
106
- include_once( $folder . "/" . $include );
107
- } else {
108
- if ( $include != "." && $include != ".." && $inFolder ) {
109
- self::include_all( $folder . "/" . $include );
110
- }
111
- }
112
- }
113
- }
114
- }
115
-
116
- /**
117
- * Install current state
118
- *
119
- * @param $name
120
- */
121
- public function install_state( $name ) {
122
- // include plugin state
123
- Core::get_instance()->set_state( new State_Factory( $name ) );
124
- }
125
-
126
- /**
127
- * @return Core
128
- */
129
- public static function get_instance() {
130
- if ( null === self::$instance ) {
131
- self::$instance = new self();
132
- }
133
-
134
- return self::$instance;
135
- }
136
-
137
- /**
138
- * Include pseudo template
139
- *
140
- * @param $template
141
- *
142
- * @return string
143
- */
144
- public function modify_single_template( $template ) {
145
-
146
- global $post;
147
-
148
- if ( ! empty( $post ) && in_array( $post->post_type, $this->post_types ) ) {
149
- add_action( 'loop_start', array( $this, 'setup_pseudo_template' ) );
150
- }
151
-
152
- return $template;
153
- }
154
-
155
- /**
156
- * Setup pseudo template
157
- *
158
- * @param object $query
159
- */
160
- public function setup_pseudo_template( $query ) {
161
-
162
- global $post;
163
-
164
- if ( $query->is_main_query() ) {
165
- if ( ! empty( $post ) && in_array( $post->post_type, $this->post_types ) ) {
166
- add_filter( 'the_content', array( $this, 'append_post_meta' ) );
167
- }
168
- remove_action( 'loop_start', array( $this, 'setup_pseudo_template' ) );
169
- }
170
- }
171
-
172
- /**
173
- * Append post meta
174
- *
175
- * @param $content
176
- *
177
- * @return string
178
- */
179
- public function append_post_meta( $content ) {
180
- // run only once
181
- remove_filter( 'the_content', array( $this, 'append_post_meta' ) );
182
-
183
- global $post;
184
-
185
- ob_start();
186
- switch ( $post->post_type ) {
187
- case 'mp-event':
188
- Events::get_instance()->render_event_metas();
189
- break;
190
- case 'mp-column':
191
- Column::get_instance()->render_column_metas();
192
- break;
193
- }
194
- $append = ob_get_clean();
195
- $content .= $append;
196
-
197
- return $content;
198
- }
199
-
200
- /**
201
- * Get model instace
202
- *
203
- * @param bool|false $type
204
- *
205
- * @return bool|mixed
206
- */
207
- public function get( $type = false ) {
208
- $state = false;
209
- if ( $type ) {
210
- $state = $this->get_model( $type );
211
- }
212
-
213
- return $state;
214
- }
215
-
216
- /**
217
- * Check and return current state
218
- *
219
- * @param string $type
220
- *
221
- * @return boolean
222
- */
223
- public function get_model( $type = null ) {
224
- return Core::get_instance()->get_state()->get_model( $type );
225
- }
226
-
227
- /**
228
- * Get State
229
- * @return bool
230
- */
231
- public function get_state() {
232
- if ( $this->state ) {
233
- return $this->state;
234
- } else {
235
- return false;
236
- }
237
- }
238
-
239
- /**
240
- * Set state
241
- *
242
- * @param $state
243
- */
244
- public function set_state( $state ) {
245
- $this->state = $state;
246
- }
247
-
248
- /**
249
- * Get version
250
- * @return mixed
251
- */
252
- public function get_version() {
253
- if ( empty( $this->version ) ) {
254
- $this->init_plugin_version();
255
- }
256
-
257
- return $this->version;
258
- }
259
-
260
- /**
261
- * Init plugin version
262
- */
263
- public function init_plugin_version() {
264
-
265
- $filePath = Mp_Time_Table::get_plugin_path() . Mp_Time_Table::get_plugin_name() . '.php';
266
-
267
- if ( ! function_exists( 'get_plugin_data' ) ) {
268
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
269
- }
270
-
271
- $pluginObject = get_plugin_data( $filePath );
272
- $this->version = $pluginObject[ 'Version' ];
273
- }
274
-
275
- /**
276
- * Get controller
277
- *
278
- * @param $type
279
- *
280
- * @return mixed
281
- */
282
- public function get_controller( $type ) {
283
- return Core::get_instance()->get_state()->get_controller( $type );
284
- }
285
-
286
- /**
287
- * Get view
288
- *
289
- * @return View
290
- */
291
- public function get_view() {
292
- return View::get_instance();
293
- }
294
-
295
- /**
296
- * Get preprocessor
297
- *
298
- * @param $type
299
- *
300
- * @return mixed
301
- */
302
- public function get_preprocessor( $type = null ) {
303
- return Core::get_instance()->get_state()->get_preprocessor( $type );
304
- }
305
-
306
- /**
307
- * Route plugin url
308
- */
309
- public function wp_ajax_route_url() {
310
-
311
- $controller = isset( $_REQUEST[ "controller" ] ) ? $_REQUEST[ "controller" ] : null;
312
- $action = isset( $_REQUEST[ "mptt_action" ] ) ? $_REQUEST[ "mptt_action" ] : null;
313
-
314
- if ( ! empty( $action ) && current_user_can('edit_posts') ) {
315
- // call controller
316
- Preprocessor::get_instance()->call_controller( $action, $controller );
317
- wp_die();
318
- }
319
- }
320
-
321
- /**
322
- * Register taxonomies
323
- */
324
- public function register_all_taxonomies() {
325
-
326
- $permalinks = Core::get_instance()->get_permalink_structure();
327
-
328
- do_action( 'mptt_before_register_taxonomies' );
329
-
330
- $event_category_labels = array(
331
- 'name' => __( 'Event categories', 'mp-timetable' ),
332
- 'singular_name' => __( 'Event category', 'mp-timetable' ),
333
- 'add_new' => __( 'Add New Event category', 'mp-timetable' ),
334
- 'add_new_item' => __( 'Add New Event category', 'mp-timetable' ),
335
- 'edit_item' => __( 'Edit Event category', 'mp-timetable' ),
336
- 'new_item' => __( 'New Event category', 'mp-timetable' ),
337
- 'all_items' => __( 'All Event categories', 'mp-timetable' ),
338
- 'view_item' => __( 'View Event category', 'mp-timetable' ),
339
- 'search_items' => __( 'Search Event category', 'mp-timetable' ),
340
- 'not_found' => __( 'No Event categories found', 'mp-timetable' ),
341
- 'not_found_in_trash' => __( 'No Event categories found in Trash', 'mp-timetable' ),
342
- 'menu_name' => __( 'Event categories', 'mp-timetable' )
343
- );
344
-
345
- $event_category_args = array(
346
- 'label' => __( 'Event categories', 'mp-timetable' ),
347
- 'labels' => $event_category_labels,
348
- 'show_in_rest' => true,
349
- 'public' => true,
350
- 'show_in_nav_menus' => true,
351
- 'show_ui' => true,
352
- 'show_in_menu' => false,
353
- 'show_tagcloud' => true,
354
- 'hierarchical' => true,
355
- 'update_count_callback' => '',
356
- 'rewrite' => array(
357
- 'slug' => $permalinks['event_category_base'], //'timetable/category'
358
- 'with_front' => false,
359
- 'hierarchical' => true
360
- ),
361
- 'capabilities' => array(),
362
- 'meta_box_cb' => null,
363
- 'show_admin_column' => false,
364
- '_builtin' => false,
365
- 'show_in_quick_edit' => null,
366
- );
367
-
368
- register_taxonomy(
369
- 'mp-event_category',
370
- apply_filters( 'mptt_taxonomy_objects_event_category', array( 'mp-event' ) ),
371
- apply_filters( 'mptt_taxonomy_args_event_category', $event_category_args)
372
- );
373
-
374
- $event_tag_labels = array(
375
- 'name' => __( 'Event tags', 'mp-timetable' ),
376
- 'singular_name' => __( 'Event tag', 'mp-timetable' ),
377
- 'add_new' => __( 'Add New Event tag', 'mp-timetable' ),
378
- 'add_new_item' => __( 'Add New Event tag', 'mp-timetable' ),
379
- 'edit_item' => __( 'Edit Event tag', 'mp-timetable' ),
380
- 'new_item' => __( 'New Event tag', 'mp-timetable' ),
381
- 'all_items' => __( 'All Event tags', 'mp-timetable' ),
382
- 'view_item' => __( 'View Event tag', 'mp-timetable' ),
383
- 'search_items' => __( 'Search Event tag', 'mp-timetable' ),
384
- 'not_found' => __( 'No Event tags found', 'mp-timetable' ),
385
- 'not_found_in_trash' => __( 'No Event tags found in Trash', 'mp-timetable' ),
386
- 'menu_name' => __( 'Event tags', 'mp-timetable' )
387
- );
388
-
389
- $event_tag_args = array(
390
- 'label' => __( 'Event tags', 'mp-timetable' ),
391
- 'labels' => $event_tag_labels,
392
- 'show_in_rest' => true,
393
- 'public' => true,
394
- 'show_in_nav_menus' => true,
395
- 'show_ui' => true,
396
- 'show_in_menu' => false,
397
- 'show_tagcloud' => true,
398
- 'hierarchical' => false,
399
- 'update_count_callback' => '',
400
- 'rewrite' => array(
401
- 'slug' => $permalinks['event_tag_base'], //'timetable/tag'
402
- 'with_front' => false,
403
- 'hierarchical' => true
404
- ),
405
- 'capabilities' => array(),
406
- 'meta_box_cb' => null,
407
- 'show_admin_column' => false,
408
- '_builtin' => false,
409
- 'show_in_quick_edit' => null,
410
- );
411
-
412
- register_taxonomy(
413
- 'mp-event_tag',
414
- apply_filters( 'mptt_taxonomy_objects_event_tag', array( 'mp-event' ) ),
415
- apply_filters( 'mptt_taxonomy_args_event_tag', $event_tag_args)
416
- );
417
-
418
- do_action( 'mptt_after_register_taxonomies' );
419
- }
420
-
421
- /**
422
- * Register custom post type
423
- */
424
- public function register_all_post_type() {
425
-
426
- $permalinks = Core::get_instance()->get_permalink_structure();
427
-
428
- do_action( 'mptt_before_register_post_types' );
429
-
430
- register_post_type(
431
- 'mp-event',
432
- apply_filters(
433
- 'mptt_register_post_type_event',
434
- array(
435
- 'labels' => array(
436
- 'name' => __( 'Events', 'mp-timetable' ),
437
- 'singular_name' => __( 'Event', 'mp-timetable' ),
438
- 'add_new' => __( 'Add New Event', 'mp-timetable' ),
439
- 'add_new_item' => __( 'Add New Event', 'mp-timetable' ),
440
- 'edit_item' => __( 'Edit Event', 'mp-timetable' ),
441
- 'new_item' => __( 'New Event', 'mp-timetable' ),
442
- 'all_items' => __( 'All Events', 'mp-timetable' ),
443
- 'view_item' => __( 'View Event', 'mp-timetable' ),
444
- 'search_items' => __( 'Search Event', 'mp-timetable' ),
445
- 'not_found' => __( 'No Events found', 'mp-timetable' ),
446
- 'not_found_in_trash' => __( 'No Events found in Trash', 'mp-timetable' ),
447
- 'menu_name' => __( 'Events', 'mp-timetable' )
448
- ),
449
- 'public' => true,
450
- 'show_in_rest' => true,
451
- 'show_ui' => true,
452
- 'show_in_menu' => false,
453
- 'show_in_nav_menus' => true,
454
- 'capability_type' => 'post',
455
- 'menu_position' => 21,
456
- 'hierarchical' => false,
457
- 'has_archive' => true,
458
- 'rewrite' => array(
459
- 'slug' => $permalinks['event_base'], //'timetable/event'
460
- 'with_front' => false,
461
- 'hierarchical' => true
462
- ),
463
- 'supports' => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
464
- 'show_in_admin_bar' => true
465
- )
466
- )
467
- );
468
-
469
- register_post_type(
470
- 'mp-column',
471
- apply_filters(
472
- 'mptt_register_post_type_column',
473
- array(
474
- 'labels' => array(
475
- 'name' => __( 'Columns', 'mp-timetable' ),
476
- 'singular_name' => __( 'Column', 'mp-timetable' ),
477
- 'add_new' => __( 'Add New Column', 'mp-timetable' ),
478
- 'add_new_item' => __( 'Add New Column', 'mp-timetable' ),
479
- 'edit_item' => __( 'Edit Column', 'mp-timetable' ),
480
- 'new_item' => __( 'New Column', 'mp-timetable' ),
481
- 'all_items' => __( 'All Columns', 'mp-timetable' ),
482
- 'view_item' => __( 'View Column', 'mp-timetable' ),
483
- 'search_items' => __( 'Search Column', 'mp-timetable' ),
484
- 'not_found' => __( 'No Columns found', 'mp-timetable' ),
485
- 'not_found_in_trash' => __( 'No Columns found in Trash', 'mp-timetable' ),
486
- 'menu_name' => __( 'Columns', 'mp-timetable' )
487
- ),
488
- 'public' => true,
489
- 'show_in_rest' => true,
490
- 'show_ui' => true,
491
- 'show_in_menu' => false,
492
- 'show_in_nav_menus' => true,
493
- 'capability_type' => 'post',
494
- 'menu_position' => 21,
495
- 'hierarchical' => false,
496
- 'has_archive' => true,
497
- 'rewrite' => array(
498
- 'slug' => $permalinks['column_base'], //'timetable/column'
499
- 'with_front' => false,
500
- 'hierarchical' => true
501
- ),
502
- 'supports' => array( 'title', 'editor', 'page-attributes' ),
503
- 'show_in_admin_bar' => true
504
- )
505
- )
506
- );
507
-
508
- do_action( 'mptt_after_register_post_types' );
509
-
510
- }
511
-
512
- /**
513
- * Create Plugin table if not exists
514
- */
515
- public function create_table() {
516
-
517
- global $wpdb;
518
-
519
- $charset_collate = $wpdb->get_charset_collate();
520
-
521
- $table_name = Mp_Time_Table::get_datatable();
522
-
523
- $sql = "CREATE TABLE IF NOT EXISTS $table_name (
524
- `id` int(11) NOT NULL AUTO_INCREMENT,
525
- `column_id` int(11) NOT NULL,
526
- `event_id` int(11) NOT NULL,
527
- `event_start` time NOT NULL,
528
- `event_end` time NOT NULL,
529
- `user_id` int(11) NOT NULL,
530
- `description` text NOT NULL,
531
- PRIMARY KEY (`id`),
532
- UNIQUE KEY `id` (`id`)
533
- ) $charset_collate";
534
-
535
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
536
- dbDelta( $sql );
537
- }
538
-
539
- /**
540
- * Hook admin_enqueue_scripts
541
- */
542
- public function admin_enqueue_scripts() {
543
- global $current_screen;
544
- $this->current_screen( $current_screen );
545
- }
546
-
547
- /**
548
- * Load script by current screen
549
- *
550
- * @param \WP_Screen $current_screen
551
- */
552
- public function current_screen( \WP_Screen $current_screen = null ) {
553
- wp_register_script( 'mptt-event-object', Mp_Time_Table::get_plugin_url( 'media/js/events/event' . $this->get_prefix() . '.js' ), array( 'jquery' ), $this->version );
554
- wp_localize_script(
555
- 'mptt-event-object',
556
- 'MPTT',
557
- array( 'table_class' => apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) )
558
- );
559
-
560
- wp_enqueue_script( 'underscore' );
561
- wp_enqueue_style( 'mptt-admin-style', Mp_Time_Table::get_plugin_url( 'media/css/admin.css' ), array(), $this->version );
562
-
563
- wp_enqueue_script( 'mptt-functions', Mp_Time_Table::get_plugin_url( 'media/js/mptt-functions' . $this->get_prefix() . '.js' ), array(), $this->version );
564
-
565
- if ( ! empty( $current_screen ) ) {
566
- switch ( $current_screen->id ) {
567
- case 'mp-event':
568
- wp_enqueue_script( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/js/lib/spectrum' . $this->get_prefix() . '.js' ), array( 'jquery' ), '1.8.0' );
569
- wp_enqueue_script( 'mptt-event-object' );
570
- wp_enqueue_script( 'jquery-ui-timepicker', Mp_Time_Table::get_plugin_url( 'media/js/lib/jquery.ui.timepicker' . $this->get_prefix() . '.js' ), '0.3.3' );
571
-
572
- wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
573
- wp_enqueue_style( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/css/spectrum.css' ), array(), '1.8.0' );
574
- wp_enqueue_style( 'jquery-ui-timepicker', Mp_Time_Table::get_plugin_url( 'media/css/jquery.ui.timepicker.css' ), array(), '0.3.3' );
575
- break;
576
-
577
- case 'mp-column':
578
- wp_enqueue_script( 'jquery-ui-datepicker' );
579
- wp_enqueue_script( 'mptt-event-object' );
580
-
581
- wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
582
- break;
583
-
584
- case 'customize':
585
- case 'widgets':
586
- wp_enqueue_script( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/js/lib/spectrum' . $this->get_prefix() . '.js' ), array( 'jquery' ), '1.8.0' );
587
- wp_enqueue_script( 'mptt-event-object' );
588
-
589
- wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
590
- wp_enqueue_style( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/css/spectrum.css' ), array(), '1.8.0' );
591
- break;
592
- }
593
-
594
- switch ( $current_screen->base ) {
595
- case 'post':
596
- case 'page':
597
- wp_enqueue_script( 'jquery-ui-tabs' );
598
- wp_enqueue_script( 'jBox', Mp_Time_Table::get_plugin_url( 'media/js/lib/jBox' . $this->get_prefix() . '.js' ), array( 'jquery' ), '0.2.1' );
599
-
600
- wp_enqueue_style( 'jBox', Mp_Time_Table::get_plugin_url( 'media/css/jbox/jBox.css' ), array(), '1.8.0' );
601
- break;
602
-
603
- case 'options-permalink':
604
- if ( apply_filters('mptt_permalinks_enabled', true) ) {
605
- $permalinks = new Permalinks();
606
- }
607
- break;
608
-
609
- default:
610
- break;
611
- }
612
- }
613
- }
614
-
615
- /**
616
- * Get prefix
617
- *
618
- * @return string
619
- */
620
- public function get_prefix() {
621
- global $is_IE;
622
-
623
- $prefix = ! MP_TT_DEBUG ? '.min' : '';
624
-
625
- if ($is_IE){
626
- $prefix = '';
627
- }
628
-
629
- return $prefix;
630
- }
631
-
632
- /**
633
- * Hook wp_enqueue_scripts
634
- */
635
- public function wp_enqueue_scripts() {
636
- if ( ! empty( $_GET[ 'motopress-ce' ] ) ) {
637
- $this->add_plugin_js( 'shortcode' );
638
- }
639
- }
640
-
641
- /**
642
- * Add plugin js
643
- *
644
- * @param bool $type
645
- */
646
- public function add_plugin_js( $type = false ) {
647
- wp_register_script( 'mptt-event-object', Mp_Time_Table::get_plugin_url( 'media/js/events/event' . $this->get_prefix() . '.js' ), array( 'jquery', 'mptt-functions' ), $this->version );
648
- wp_localize_script(
649
- 'mptt-event-object',
650
- 'MPTT',
651
- array( 'table_class' => apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) )
652
- );
653
-
654
- switch ( $type ) {
655
- case 'shortcode':
656
- case 'widget':
657
- wp_enqueue_script( 'underscore' );
658
- wp_enqueue_script( 'mptt-functions', Mp_Time_Table::get_plugin_url( 'media/js/mptt-functions' . $this->get_prefix() . '.js' ), array( 'jquery' ), $this->version );
659
- wp_enqueue_script( 'mptt-event-object' );
660
- break;
661
- }
662
- }
663
-
664
- /**
665
- * Add plugin css
666
- */
667
- public function add_plugin_css() {
668
- wp_enqueue_style( 'mptt-style', Mp_Time_Table::get_plugin_url( 'media/css/style.css' ), array(), $this->version );
669
- }
670
-
671
- /**
672
- * Fix fatal error for earlier WP versions
673
- *
674
- * @return bool
675
- */
676
- public function is_embed() {
677
- global $wp_version;
678
-
679
- if ( ! function_exists( 'is_embed' ) ) {
680
- return false;
681
- }
682
-
683
- if ( version_compare( $wp_version, '4.4', '<' ) ) {
684
- if ( ! function_exists( 'is_embed' ) ) {
685
- return false;
686
- }
687
- }
688
-
689
- return is_embed();
690
- }
691
-
692
- /**
693
- * Get permalink settings
694
- *
695
- * @return array
696
- */
697
- public function get_permalink_structure() {
698
-
699
- $saved_permalinks = (array) get_option( 'mp_timetable_permalinks', array() );
700
-
701
- $permalinks = wp_parse_args(
702
- array_filter( $saved_permalinks ), array(
703
- 'column_base' => 'timetable/column',
704
- 'event_base' => 'timetable/event',
705
- 'event_category_base' => 'timetable/category',
706
- 'event_tag_base' => 'timetable/tag',
707
- )
708
- );
709
-
710
- if ( $saved_permalinks !== $permalinks ) {
711
- update_option( 'mp_timetable_permalinks', $permalinks );
712
- }
713
-
714
- return $permalinks;
715
- }
 
716
  }
1
+ <?php
2
+
3
+ namespace mp_timetable\plugin_core\classes;
4
+
5
+ use Mp_Time_Table;
6
+ use mp_timetable\classes\models\Column;
7
+ use mp_timetable\classes\models\Events;
8
+
9
+ /**
10
+ * Class main state
11
+ */
12
+ class Core {
13
+
14
+ protected static $instance;
15
+
16
+ protected $version;
17
+
18
+ /**
19
+ * Current state
20
+ */
21
+ private $state;
22
+
23
+ /**
24
+ * Core constructor.
25
+ */
26
+ public function __construct() {
27
+
28
+ $this->taxonomy_names = array(
29
+ 'mp-event_category',
30
+ 'mp-event_tag'
31
+ );
32
+ $this->post_types = array(
33
+ 'mp-event',
34
+ 'mp-column'
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Check for ajax post
40
+ * @return bool
41
+ */
42
+ static function is_ajax() {
43
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
44
+ return true;
45
+ } else {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * @return array
52
+ */
53
+ public function get_post_types() {
54
+ return $this->post_types;
55
+ }
56
+
57
+ /**
58
+ * @return array
59
+ */
60
+ public function get_taxonomy_names() {
61
+ return $this->taxonomy_names;
62
+ }
63
+
64
+ /**
65
+ * Init current plugin
66
+ *
67
+ * @param $name
68
+ */
69
+ public function init_plugin( $name ) {
70
+
71
+ load_plugin_textdomain( 'mp-timetable', false, Mp_Time_Table::get_plugin_name() . '/languages/' );
72
+
73
+ // include template for function
74
+ Core::include_all( Mp_Time_Table::get_plugin_part_path( 'templates-functions' ) );
75
+
76
+ // include plugin models files
77
+ Model::get_instance()->install();
78
+
79
+ // include plugin controllers files
80
+ Controller::get_instance()->install();
81
+
82
+ // include plugin Preprocessors files
83
+ Preprocessor::install();
84
+
85
+ // include plugin modules
86
+ Module::install();
87
+
88
+ // install state
89
+ $this->install_state( $name );
90
+
91
+ // init all hooks
92
+ Hooks::get_instance()->install_hooks();
93
+ Hooks::get_instance()->register_template_action();
94
+ }
95
+
96
+ /**
97
+ * Include all files from folder
98
+ *
99
+ * @param string $folder
100
+ * @param boolean $inFolder
101
+ */
102
+ static function include_all( $folder, $inFolder = true ) {
103
+ if ( file_exists( $folder ) ) {
104
+ $includeArr = scandir( $folder );
105
+ foreach ( $includeArr as $include ) {
106
+ if ( ! is_dir( $folder . "/" . $include ) ) {
107
+ include_once( $folder . "/" . $include );
108
+ } else {
109
+ if ( $include != "." && $include != ".." && $inFolder ) {
110
+ self::include_all( $folder . "/" . $include );
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Install current state
119
+ *
120
+ * @param $name
121
+ */
122
+ public function install_state( $name ) {
123
+ // include plugin state
124
+ Core::get_instance()->set_state( new State_Factory( $name ) );
125
+ }
126
+
127
+ /**
128
+ * @return Core
129
+ */
130
+ public static function get_instance() {
131
+ if ( null === self::$instance ) {
132
+ self::$instance = new self();
133
+ }
134
+
135
+ return self::$instance;
136
+ }
137
+
138
+ /**
139
+ * Include pseudo template
140
+ *
141
+ * @param $template
142
+ *
143
+ * @return string
144
+ */
145
+ public function modify_single_template( $template ) {
146
+
147
+ global $post;
148
+
149
+ if ( ! empty( $post ) && in_array( $post->post_type, $this->post_types ) ) {
150
+ add_action( 'loop_start', array( $this, 'setup_pseudo_template' ) );
151
+ }
152
+
153
+ return $template;
154
+ }
155
+
156
+ /**
157
+ * Setup pseudo template
158
+ *
159
+ * @param object $query
160
+ */
161
+ public function setup_pseudo_template( $query ) {
162
+
163
+ global $post;
164
+
165
+ if ( $query->is_main_query() ) {
166
+ if ( ! empty( $post ) && in_array( $post->post_type, $this->post_types ) ) {
167
+ add_filter( 'the_content', array( $this, 'append_post_meta' ) );
168
+ }
169
+ remove_action( 'loop_start', array( $this, 'setup_pseudo_template' ) );
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Append post meta
175
+ *
176
+ * @param $content
177
+ *
178
+ * @return string
179
+ */
180
+ public function append_post_meta( $content ) {
181
+ // run only once
182
+ remove_filter( 'the_content', array( $this, 'append_post_meta' ) );
183
+
184
+ global $post;
185
+
186
+ ob_start();
187
+ switch ( $post->post_type ) {
188
+ case 'mp-event':
189
+ Events::get_instance()->render_event_metas();
190
+ break;
191
+ case 'mp-column':
192
+ Column::get_instance()->render_column_metas();
193
+ break;
194
+ }
195
+ $append = ob_get_clean();
196
+ $content .= $append;
197
+
198
+ return $content;
199
+ }
200
+
201
+ /**
202
+ * Get model instace
203
+ *
204
+ * @param bool|false $type
205
+ *
206
+ * @return bool|mixed
207
+ */
208
+ public function get( $type = false ) {
209
+ $state = false;
210
+ if ( $type ) {
211
+ $state = $this->get_model( $type );
212
+ }
213
+
214
+ return $state;
215
+ }
216
+
217
+ /**
218
+ * Check and return current state
219
+ *
220
+ * @param string $type
221
+ *
222
+ * @return boolean
223
+ */
224
+ public function get_model( $type = null ) {
225
+ return Core::get_instance()->get_state()->get_model( $type );
226
+ }
227
+
228
+ /**
229
+ * Get State
230
+ * @return bool
231
+ */
232
+ public function get_state() {
233
+ if ( $this->state ) {
234
+ return $this->state;
235
+ } else {
236
+ return false;
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Set state
242
+ *
243
+ * @param $state
244
+ */
245
+ public function set_state( $state ) {
246
+ $this->state = $state;
247
+ }
248
+
249
+ /**
250
+ * Get version
251
+ * @return mixed
252
+ */
253
+ public function get_version() {
254
+ if ( empty( $this->version ) ) {
255
+ $this->init_plugin_version();
256
+ }
257
+
258
+ return $this->version;
259
+ }
260
+
261
+ /**
262
+ * Init plugin version
263
+ */
264
+ public function init_plugin_version() {
265
+
266
+ $filePath = Mp_Time_Table::get_plugin_path() . Mp_Time_Table::get_plugin_name() . '.php';
267
+
268
+ if ( ! function_exists( 'get_plugin_data' ) ) {
269
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
270
+ }
271
+
272
+ $pluginObject = get_plugin_data( $filePath );
273
+ $this->version = $pluginObject[ 'Version' ];
274
+ }
275
+
276
+ /**
277
+ * Get controller
278
+ *
279
+ * @param $type
280
+ *
281
+ * @return mixed
282
+ */
283
+ public function get_controller( $type ) {
284
+ return Core::get_instance()->get_state()->get_controller( $type );
285
+ }
286
+
287
+ /**
288
+ * Get view
289
+ *
290
+ * @return View
291
+ */
292
+ public function get_view() {
293
+ return View::get_instance();
294
+ }
295
+
296
+ /**
297
+ * Get preprocessor
298
+ *
299
+ * @param $type
300
+ *
301
+ * @return mixed
302
+ */
303
+ public function get_preprocessor( $type = null ) {
304
+ return Core::get_instance()->get_state()->get_preprocessor( $type );
305
+ }
306
+
307
+ /**
308
+ * Route plugin url
309
+ */
310
+ public function wp_ajax_route_url() {
311
+
312
+ $controller = isset( $_REQUEST[ "controller" ] ) ? $_REQUEST[ "controller" ] : null;
313
+ $action = isset( $_REQUEST[ "mptt_action" ] ) ? $_REQUEST[ "mptt_action" ] : null;
314
+
315
+ if ( ! empty( $action ) && current_user_can('edit_posts') ) {
316
+ // call controller
317
+ Preprocessor::get_instance()->call_controller( $action, $controller );
318
+ wp_die();
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Register taxonomies
324
+ */
325
+ public function register_all_taxonomies() {
326
+
327
+ $permalinks = Core::get_instance()->get_permalink_structure();
328
+
329
+ do_action( 'mptt_before_register_taxonomies' );
330
+
331
+ $event_category_labels = array(
332
+ 'name' => __( 'Event categories', 'mp-timetable' ),
333
+ 'singular_name' => __( 'Event category', 'mp-timetable' ),
334
+ 'add_new' => __( 'Add New Event category', 'mp-timetable' ),
335
+ 'add_new_item' => __( 'Add New Event category', 'mp-timetable' ),
336
+ 'edit_item' => __( 'Edit Event category', 'mp-timetable' ),
337
+ 'new_item' => __( 'New Event category', 'mp-timetable' ),
338
+ 'all_items' => __( 'All Event categories', 'mp-timetable' ),
339
+ 'view_item' => __( 'View Event category', 'mp-timetable' ),
340
+ 'search_items' => __( 'Search Event category', 'mp-timetable' ),
341
+ 'not_found' => __( 'No Event categories found', 'mp-timetable' ),
342
+ 'not_found_in_trash' => __( 'No Event categories found in Trash', 'mp-timetable' ),
343
+ 'menu_name' => __( 'Event categories', 'mp-timetable' )
344
+ );
345
+
346
+ $event_category_args = array(
347
+ 'label' => __( 'Event categories', 'mp-timetable' ),
348
+ 'labels' => $event_category_labels,
349
+ 'show_in_rest' => true,
350
+ 'public' => true,
351
+ 'show_in_nav_menus' => true,
352
+ 'show_ui' => true,
353
+ 'show_in_menu' => false,
354
+ 'show_tagcloud' => true,
355
+ 'hierarchical' => true,
356
+ 'update_count_callback' => '',
357
+ 'rewrite' => array(
358
+ 'slug' => $permalinks['event_category_base'], //'timetable/category'
359
+ 'with_front' => false,
360
+ 'hierarchical' => true
361
+ ),
362
+ 'capabilities' => array(),
363
+ 'meta_box_cb' => null,
364
+ 'show_admin_column' => false,
365
+ '_builtin' => false,
366
+ 'show_in_quick_edit' => null,
367
+ );
368
+
369
+ register_taxonomy(
370
+ 'mp-event_category',
371
+ apply_filters( 'mptt_taxonomy_objects_event_category', array( 'mp-event' ) ),
372
+ apply_filters( 'mptt_taxonomy_args_event_category', $event_category_args)
373
+ );
374
+
375
+ $event_tag_labels = array(
376
+ 'name' => __( 'Event tags', 'mp-timetable' ),
377
+ 'singular_name' => __( 'Event tag', 'mp-timetable' ),
378
+ 'add_new' => __( 'Add New Event tag', 'mp-timetable' ),
379
+ 'add_new_item' => __( 'Add New Event tag', 'mp-timetable' ),
380
+ 'edit_item' => __( 'Edit Event tag', 'mp-timetable' ),
381
+ 'new_item' => __( 'New Event tag', 'mp-timetable' ),
382
+ 'all_items' => __( 'All Event tags', 'mp-timetable' ),
383
+ 'view_item' => __( 'View Event tag', 'mp-timetable' ),
384
+ 'search_items' => __( 'Search Event tag', 'mp-timetable' ),
385
+ 'not_found' => __( 'No Event tags found', 'mp-timetable' ),
386
+ 'not_found_in_trash' => __( 'No Event tags found in Trash', 'mp-timetable' ),
387
+ 'menu_name' => __( 'Event tags', 'mp-timetable' )
388
+ );
389
+
390
+ $event_tag_args = array(
391
+ 'label' => __( 'Event tags', 'mp-timetable' ),
392
+ 'labels' => $event_tag_labels,
393
+ 'show_in_rest' => true,
394
+ 'public' => true,
395
+ 'show_in_nav_menus' => true,
396
+ 'show_ui' => true,
397
+ 'show_in_menu' => false,
398
+ 'show_tagcloud' => true,
399
+ 'hierarchical' => false,
400
+ 'update_count_callback' => '',
401
+ 'rewrite' => array(
402
+ 'slug' => $permalinks['event_tag_base'], //'timetable/tag'
403
+ 'with_front' => false,
404
+ 'hierarchical' => true
405
+ ),
406
+ 'capabilities' => array(),
407
+ 'meta_box_cb' => null,
408
+ 'show_admin_column' => false,
409
+ '_builtin' => false,
410
+ 'show_in_quick_edit' => null,
411
+ );
412
+
413
+ register_taxonomy(
414
+ 'mp-event_tag',
415
+ apply_filters( 'mptt_taxonomy_objects_event_tag', array( 'mp-event' ) ),
416
+ apply_filters( 'mptt_taxonomy_args_event_tag', $event_tag_args)
417
+ );
418
+
419
+ do_action( 'mptt_after_register_taxonomies' );
420
+ }
421
+
422
+ /**
423
+ * Register custom post type
424
+ */
425
+ public function register_all_post_type() {
426
+
427
+ $permalinks = Core::get_instance()->get_permalink_structure();
428
+
429
+ do_action( 'mptt_before_register_post_types' );
430
+
431
+ register_post_type(
432
+ 'mp-event',
433
+ apply_filters(
434
+ 'mptt_register_post_type_event',
435
+ array(
436
+ 'labels' => array(
437
+ 'name' => __( 'Events', 'mp-timetable' ),
438
+ 'singular_name' => __( 'Event', 'mp-timetable' ),
439
+ 'add_new' => __( 'Add New Event', 'mp-timetable' ),
440
+ 'add_new_item' => __( 'Add New Event', 'mp-timetable' ),
441
+ 'edit_item' => __( 'Edit Event', 'mp-timetable' ),
442
+ 'new_item' => __( 'New Event', 'mp-timetable' ),
443
+ 'all_items' => __( 'All Events', 'mp-timetable' ),
444
+ 'view_item' => __( 'View Event', 'mp-timetable' ),
445
+ 'search_items' => __( 'Search Event', 'mp-timetable' ),
446
+ 'not_found' => __( 'No Events found', 'mp-timetable' ),
447
+ 'not_found_in_trash' => __( 'No Events found in Trash', 'mp-timetable' ),
448
+ 'menu_name' => __( 'Events', 'mp-timetable' )
449
+ ),
450
+ 'public' => true,
451
+ 'show_in_rest' => true,
452
+ 'show_ui' => true,
453
+ 'show_in_menu' => false,
454
+ 'show_in_nav_menus' => true,
455
+ 'capability_type' => 'post',
456
+ 'menu_position' => 21,
457
+ 'hierarchical' => false,
458
+ 'has_archive' => true,
459
+ 'rewrite' => array(
460
+ 'slug' => $permalinks['event_base'], //'timetable/event'
461
+ 'with_front' => false,
462
+ 'hierarchical' => true
463
+ ),
464
+ 'supports' => array( 'title', 'editor', 'comments', 'excerpt', 'author', 'thumbnail', 'page-attributes' ),
465
+ 'show_in_admin_bar' => true
466
+ )
467
+ )
468
+ );
469
+
470
+ register_post_type(
471
+ 'mp-column',
472
+ apply_filters(
473
+ 'mptt_register_post_type_column',
474
+ array(
475
+ 'labels' => array(
476
+ 'name' => __( 'Columns', 'mp-timetable' ),
477
+ 'singular_name' => __( 'Column', 'mp-timetable' ),
478
+ 'add_new' => __( 'Add New Column', 'mp-timetable' ),
479
+ 'add_new_item' => __( 'Add New Column', 'mp-timetable' ),
480
+ 'edit_item' => __( 'Edit Column', 'mp-timetable' ),
481
+ 'new_item' => __( 'New Column', 'mp-timetable' ),
482
+ 'all_items' => __( 'All Columns', 'mp-timetable' ),
483
+ 'view_item' => __( 'View Column', 'mp-timetable' ),
484
+ 'search_items' => __( 'Search Column', 'mp-timetable' ),
485
+ 'not_found' => __( 'No Columns found', 'mp-timetable' ),
486
+ 'not_found_in_trash' => __( 'No Columns found in Trash', 'mp-timetable' ),
487
+ 'menu_name' => __( 'Columns', 'mp-timetable' )
488
+ ),
489
+ 'public' => true,
490
+ 'show_in_rest' => true,
491
+ 'show_ui' => true,
492
+ 'show_in_menu' => false,
493
+ 'show_in_nav_menus' => true,
494
+ 'capability_type' => 'post',
495
+ 'menu_position' => 21,
496
+ 'hierarchical' => false,
497
+ 'has_archive' => true,
498
+ 'rewrite' => array(
499
+ 'slug' => $permalinks['column_base'], //'timetable/column'
500
+ 'with_front' => false,
501
+ 'hierarchical' => true
502
+ ),
503
+ 'supports' => array( 'title', 'editor', 'page-attributes' ),
504
+ 'show_in_admin_bar' => true
505
+ )
506
+ )
507
+ );
508
+
509
+ do_action( 'mptt_after_register_post_types' );
510
+
511
+ }
512
+
513
+ /**
514
+ * Create Plugin table if not exists
515
+ */
516
+ public function create_table() {
517
+
518
+ global $wpdb;
519
+
520
+ $charset_collate = $wpdb->get_charset_collate();
521
+
522
+ $table_name = Mp_Time_Table::get_datatable();
523
+
524
+ $sql = "CREATE TABLE IF NOT EXISTS $table_name (
525
+ `id` int(11) NOT NULL AUTO_INCREMENT,
526
+ `column_id` int(11) NOT NULL,
527
+ `event_id` int(11) NOT NULL,
528
+ `event_start` time NOT NULL,
529
+ `event_end` time NOT NULL,
530
+ `user_id` int(11) NOT NULL,
531
+ `description` text NOT NULL,
532
+ PRIMARY KEY (`id`),
533
+ UNIQUE KEY `id` (`id`)
534
+ ) $charset_collate";
535
+
536
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
537
+ dbDelta( $sql );
538
+ }
539
+
540
+ /**
541
+ * Hook admin_enqueue_scripts
542
+ */
543
+ public function admin_enqueue_scripts() {
544
+ global $current_screen;
545
+ $this->current_screen( $current_screen );
546
+ }
547
+
548
+ /**
549
+ * Load script by current screen
550
+ *
551
+ * @param \WP_Screen $current_screen
552
+ */
553
+ public function current_screen( \WP_Screen $current_screen = null ) {
554
+ wp_register_script( 'mptt-event-object', Mp_Time_Table::get_plugin_url( 'media/js/events/event' . $this->get_prefix() . '.js' ), array( 'jquery' ), $this->version );
555
+ wp_localize_script(
556
+ 'mptt-event-object',
557
+ 'MPTT',
558
+ array( 'table_class' => apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) )
559
+ );
560
+
561
+ wp_enqueue_script( 'underscore' );
562
+ wp_enqueue_style( 'mptt-admin-style', Mp_Time_Table::get_plugin_url( 'media/css/admin.css' ), array(), $this->version );
563
+
564
+ wp_enqueue_script( 'mptt-functions', Mp_Time_Table::get_plugin_url( 'media/js/mptt-functions' . $this->get_prefix() . '.js' ), array(), $this->version );
565
+
566
+ if ( ! empty( $current_screen ) ) {
567
+ switch ( $current_screen->id ) {
568
+ case 'mp-event':
569
+ wp_enqueue_script( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/js/lib/spectrum' . $this->get_prefix() . '.js' ), array( 'jquery' ), '1.8.0' );
570
+ wp_enqueue_script( 'mptt-event-object' );
571
+ wp_enqueue_script( 'jquery-ui-timepicker', Mp_Time_Table::get_plugin_url( 'media/js/lib/jquery.ui.timepicker' . $this->get_prefix() . '.js' ), '0.3.3' );
572
+
573
+ wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
574
+ wp_enqueue_style( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/css/spectrum.css' ), array(), '1.8.0' );
575
+ wp_enqueue_style( 'jquery-ui-timepicker', Mp_Time_Table::get_plugin_url( 'media/css/jquery.ui.timepicker.css' ), array(), '0.3.3' );
576
+ break;
577
+
578
+ case 'mp-column':
579
+ wp_enqueue_script( 'jquery-ui-datepicker' );
580
+ wp_enqueue_script( 'mptt-event-object' );
581
+
582
+ wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
583
+ break;
584
+
585
+ case 'customize':
586
+ case 'widgets':
587
+ wp_enqueue_script( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/js/lib/spectrum' . $this->get_prefix() . '.js' ), array( 'jquery' ), '1.8.0' );
588
+ wp_enqueue_script( 'mptt-event-object' );
589
+
590
+ wp_enqueue_style( 'jquery-ui-core', Mp_Time_Table::get_plugin_url( 'media/css/jquery-ui-1.10.0.custom.min.css' ), array(), '1.10.0' );
591
+ wp_enqueue_style( 'spectrum', Mp_Time_Table::get_plugin_url( 'media/css/spectrum.css' ), array(), '1.8.0' );
592
+ break;
593
+ }
594
+
595
+ switch ( $current_screen->base ) {
596
+ case 'post':
597
+ case 'page':
598
+ wp_enqueue_script( 'jquery-ui-tabs' );
599
+ wp_enqueue_script( 'jBox', Mp_Time_Table::get_plugin_url( 'media/js/lib/jBox' . $this->get_prefix() . '.js' ), array( 'jquery' ), '0.2.1' );
600
+
601
+ wp_enqueue_style( 'jBox', Mp_Time_Table::get_plugin_url( 'media/css/jbox/jBox.css' ), array(), '1.8.0' );
602
+ break;
603
+
604
+ case 'options-permalink':
605
+ if ( apply_filters('mptt_permalinks_enabled', true) ) {
606
+ $permalinks = new Permalinks();
607
+ }
608
+ break;
609
+
610
+ default:
611
+ break;
612
+ }
613
+ }
614
+ }
615
+
616
+ /**
617
+ * Get prefix
618
+ *
619
+ * @return string
620
+ */
621
+ public function get_prefix() {
622
+ global $is_IE;
623
+
624
+ $prefix = ! MP_TT_DEBUG ? '.min' : '';
625
+
626
+ if ($is_IE){
627
+ $prefix = '';
628
+ }
629
+
630
+ return $prefix;
631
+ }
632
+
633
+ /**
634
+ * Hook wp_enqueue_scripts
635
+ */
636
+ public function wp_enqueue_scripts() {
637
+ if ( ! empty( $_GET[ 'motopress-ce' ] ) ) {
638
+ $this->add_plugin_js( 'shortcode' );
639
+ }
640
+ }
641
+
642
+ /**
643
+ * Add plugin js
644
+ *
645
+ * @param bool $type
646
+ */
647
+ public function add_plugin_js( $type = false ) {
648
+ wp_register_script( 'mptt-event-object', Mp_Time_Table::get_plugin_url( 'media/js/events/event' . $this->get_prefix() . '.js' ), array( 'jquery', 'mptt-functions' ), $this->version );
649
+ wp_localize_script(
650
+ 'mptt-event-object',
651
+ 'MPTT',
652
+ array( 'table_class' => apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) )
653
+ );
654
+
655
+ switch ( $type ) {
656
+ case 'shortcode':
657
+ case 'widget':
658
+ wp_enqueue_script( 'underscore' );
659
+ wp_enqueue_script( 'mptt-functions', Mp_Time_Table::get_plugin_url( 'media/js/mptt-functions' . $this->get_prefix() . '.js' ), array( 'jquery' ), $this->version );
660
+ wp_enqueue_script( 'mptt-event-object' );
661
+ break;
662
+ }
663
+ }
664
+
665
+ /**
666
+ * Add plugin css
667
+ */
668
+ public function add_plugin_css() {
669
+ wp_enqueue_style( 'mptt-style', Mp_Time_Table::get_plugin_url( 'media/css/style.css' ), array(), $this->version );
670
+ }
671
+
672
+ /**
673
+ * Fix fatal error for earlier WP versions
674
+ *
675
+ * @return bool
676
+ */
677
+ public function is_embed() {
678
+ global $wp_version;
679
+
680
+ if ( ! function_exists( 'is_embed' ) ) {
681
+ return false;
682
+ }
683
+
684
+ if ( version_compare( $wp_version, '4.4', '<' ) ) {
685
+ if ( ! function_exists( 'is_embed' ) ) {
686
+ return false;
687
+ }
688
+ }
689
+
690
+ return is_embed();
691
+ }
692
+
693
+ /**
694
+ * Get permalink settings
695
+ *
696
+ * @return array
697
+ */
698
+ public function get_permalink_structure() {
699
+
700
+ $saved_permalinks = (array) get_option( 'mp_timetable_permalinks', array() );
701
+
702
+ $permalinks = wp_parse_args(
703
+ array_filter( $saved_permalinks ), array(
704
+ 'column_base' => 'timetable/column',
705
+ 'event_base' => 'timetable/event',
706
+ 'event_category_base' => 'timetable/category',
707
+ 'event_tag_base' => 'timetable/tag',
708
+ )
709
+ );
710
+
711
+ if ( $saved_permalinks !== $permalinks ) {
712
+ update_option( 'mp_timetable_permalinks', $permalinks );
713
+ }
714
+
715
+ return $permalinks;
716
+ }
717
  }
classes/class-hooks.php CHANGED
@@ -1,298 +1,298 @@
1
- <?php
2
-
3
- namespace mp_timetable\plugin_core\classes;
4
-
5
- use Mp_Time_Table;
6
- use mp_timetable\classes\models\Import;
7
- use mp_timetable\classes\models\Settings;
8
- use mp_timetable\plugin_core\classes\modules\Post;
9
- use mp_timetable\classes\blocks\Timetable_Block;
10
-
11
- /**
12
- * Class Hooks
13
- * @package mp_timetable\plugin_core\classes
14
- */
15
- class Hooks extends Core {
16
-
17
- protected static $instance;
18
-
19
- /**
20
- * @return Hooks
21
- */
22
- public static function get_instance() {
23
- if ( null === self::$instance ) {
24
- self::$instance = new self();
25
- }
26
-
27
- return self::$instance;
28
- }
29
-
30
- /**
31
- * Install hooks
32
- */
33
- public function install_hooks() {
34
-
35
- // register custom post type and taxonomies
36
- add_action( 'init', array( $this, 'init' ) );
37
- add_action( 'wp_enqueue_scripts', array( Core::get_instance(), 'add_plugin_css' ) );
38
- add_action( 'wp_head', array( $this, 'set_html_js_class' ) );
39
-
40
- add_action( 'admin_init', array( $this->get_controller( 'settings' ), 'action_save' ) );
41
- add_action( 'admin_init', array( $this, 'admin_init' ) );
42
- add_action( 'admin_menu', array( $this, 'admin_menu' ) );
43
- add_action( 'manage_posts_custom_column', array( $this->get( 'events' ), 'get_event_taxonomy' ) );
44
- add_action( 'manage_posts_custom_column', array( $this->get( 'column' ), 'get_column_columns' ) );
45
- add_action( 'current_screen', array( Core::get_instance(), 'current_screen' ) );
46
- add_action( 'pre_get_posts', array( $this->get( 'column' ), 'clientarea_default_order' ), 9 );
47
-
48
- //add media in frontend WP
49
- add_action( 'wp_enqueue_scripts', array( Core::get_instance(), 'wp_enqueue_scripts' ) );
50
-
51
- //add media in admin WP
52
- add_action( 'admin_enqueue_scripts', array( Core::get_instance(), 'admin_enqueue_scripts' ) );
53
- add_action( 'widgets_init', array( $this, 'register_widgets' ) );
54
-
55
- // Manage event/column columns
56
- add_filter( 'manage_edit-mp-event_columns', array( $this->get( 'events' ), 'set_event_columns' ) );
57
- add_filter( 'manage_edit-mp-column_columns', array( $this->get( 'column' ), 'set_column_columns' ) );
58
-
59
- // Duplicate Event
60
- add_filter( 'post_row_actions', array( $this->get( 'events' ), 'post_row_actions' ), 999, 2 );
61
- add_action( 'post_action_mptt_duplicate_event', array( $this->get( 'events' ), 'post_action_mptt_duplicate_event' ) );
62
-
63
- // post_class filter
64
- add_filter( 'post_class', 'mptt_post_class', 15, 3 );
65
-
66
- // to display events with other posts on author page
67
- add_filter( 'pre_get_posts', array( Post::get_instance(), 'pre_get_posts' ), 9 );
68
- add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 );
69
- }
70
-
71
- /**
72
- * Register widgets and sidebar
73
- */
74
- public function register_widgets() {
75
- $template = get_option( 'template' );
76
- if ( $template != 'twentyfourteen' && Settings::get_instance()->is_plugin_template_mode() ) {
77
- register_sidebar( array(
78
- 'name' => __( 'Timetable Sidebar', 'mp-timetable' ),
79
- 'id' => "mptt-sidebar",
80
- 'description' => __( 'Timetable', 'mp-timetable' ),
81
- 'class' => 'sidebar-container',
82
- 'before_widget' => '<li id="%1$s" class="widget %2$s">',
83
- 'after_widget' => "</li>\n",
84
- 'before_title' => '<h2 class="widget-title">',
85
- 'after_title' => "</h2>\n"
86
- ) );
87
- }
88
- register_widget( 'timetable\classes\widgets\Timetable_widget' );
89
- }
90
-
91
- /**
92
- * Register template_action
93
- */
94
- public function register_template_action() {
95
- add_action( 'mptt_sidebar', 'mptt_sidebar', 10 );
96
- add_filter( 'mptt_widget_settings', 'mptt_widget_settings', 10, 1 );
97
- add_action( 'mptt-single-mp-column-before-wrapper', 'mptt_theme_wrapper_before' );
98
- add_action( 'mptt-single-mp-column-after-wrapper', 'mptt_theme_wrapper_after' );
99
- add_action( 'mptt-single-mp-event-before-wrapper', 'mptt_theme_wrapper_before' );
100
- add_action( 'mptt-single-mp-event-after-wrapper', 'mptt_theme_wrapper_after' );
101
-
102
- // Event template action
103
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_title', 10 );
104
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_thumbnail', 20 );
105
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_post_content', 30 );
106
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_time_title', 40 );
107
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_time_list', 50 );
108
- add_action( 'mptt_event_item_content', 'mptt_event_template_content_comments', 60 );
109
-
110
- // Column template action
111
- add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_title', 10 );
112
- add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_post_content', 20 );
113
- add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_events_list', 30 );
114
-
115
- //Shortcode template action
116
- add_action( 'mptt_shortcode_template_before_content', 'mptt_shortcode_template_before_content', 10 );
117
- add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_filter', 10 );
118
- add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_static_table', 20 );
119
- add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_responsive_table', 30 );
120
- add_action( 'mptt_shortcode_template_after_content', 'mptt_shortcode_template_after_content', 10 );
121
-
122
- // Widget actions
123
- add_action( 'mptt_widget_template_before_content', 'mptt_widget_template_before_content', 10 );
124
- add_action( 'mptt_widget_template_content', 'mptt_widget_template_content', 10 );
125
- add_action( 'mptt_widget_template_after_content', 'mptt_widget_template_after_content', 10 );
126
-
127
- }
128
-
129
- /**
130
- * Init hook
131
- */
132
- public function init() {
133
-
134
- // Init sort codes
135
- Shortcode::get_instance()->init();
136
- // Register post type
137
- Core::get_instance()->register_all_post_type();
138
- // Register taxonomy all
139
- Core::get_instance()->register_all_taxonomies();
140
- // route url
141
- Core::get_instance()->wp_ajax_route_url();
142
-
143
- if ( Settings::get_instance()->is_plugin_template_mode() ) {
144
- // plugin mode
145
- add_filter( 'template_include', array( View::get_instance(), 'template_loader' ), 99 );
146
- } else {
147
- //theme mode
148
- add_filter( 'single_template', array( Core::get_instance(), 'modify_single_template' ), 99 );
149
- }
150
-
151
- add_action( 'mp_library', array( Shortcode::get_instance(), 'integration_motopress' ), 20, 1 );
152
-
153
- Core::get_instance()->init_plugin_version();
154
-
155
- add_filter( 'body_class', array( $this, 'browser_body_class' ) );
156
- add_filter( 'the_tags', array( $this->get( 'events' ), 'the_tags' ), 10, 5 );
157
- add_filter( 'the_category', array( $this->get( 'events' ), 'the_category' ), 10, 3 );
158
-
159
- if ( function_exists('register_block_type') ) {
160
- new Timetable_Block();
161
- }
162
- }
163
-
164
- /**
165
- * Hooks for admin panel
166
- */
167
- public function admin_init() {
168
- //add buttons to mce
169
- add_filter( "mce_external_plugins", array( $this, "mce_external_plugins" ) );
170
- add_filter( 'mce_buttons', array( $this, "mce_buttons" ) );
171
-
172
- Core::get_instance()->init_plugin_version();
173
-
174
- add_action( 'before_delete_post', array( Post::get_instance(), 'before_delete_custom_post' ) );
175
- add_action( 'add_meta_boxes', array( Post::get_instance(), 'add_meta_boxes' ) );
176
- add_action( 'save_post', array( Post::get_instance(), 'save_custom_post' ), 40, 2 );
177
- add_action( 'wp_ajax_route_url', array( Core::get_instance(), "wp_ajax_route_url" ) );
178
-
179
- register_importer( 'mptt-importer', 'Timetable', __( 'Import Timetable events, categories, tags and images.' ), array( Import::get_instance(), 'import' ) );
180
- }
181
-
182
- /**
183
- * Registered page in admin wp
184
- */
185
- public function admin_menu() {
186
-
187
- //Timetable
188
- add_menu_page( __( 'Timetable', 'mp-timetable' ), __( 'Timetable', 'mp-timetable' ),
189
- 'edit_posts', 'edit.php?post_type=mp-event', '', 'dashicons-calendar', '59.51' );
190
-
191
- //Events
192
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Events', 'mp-timetable' ), __( 'Events', 'mp-timetable' ),
193
- 'edit_posts', 'edit.php?post_type=mp-event' );
194
-
195
- //Add Event
196
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Add Event', 'mp-timetable' ), __( 'Add Event', 'mp-timetable' ),
197
- 'edit_posts', 'post-new.php?post_type=mp-event' );
198
-
199
- //Columns
200
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Columns', 'mp-timetable' ), __( 'Columns', 'mp-timetable' ),
201
- 'edit_posts', 'edit.php?post_type=mp-column' );
202
-
203
- //Add Column
204
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Add Column', 'mp-timetable' ), __( 'Add Column', 'mp-timetable' ),
205
- 'edit_posts', 'post-new.php?post_type=mp-column' );
206
-
207
- //Event Categories
208
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Event Categories', 'mp-timetable' ), __( 'Event Categories', 'mp-timetable' ),
209
- 'manage_categories', 'edit-tags.php?taxonomy=mp-event_category&amp;post_type=mp-event' );
210
-
211
- //Event Tags
212
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Event Tags', 'mp-timetable' ), __( 'Event Tags', 'mp-timetable' ),
213
- 'manage_categories', 'edit-tags.php?taxonomy=mp-event_tag&amp;post_type=mp-event' );
214
-
215
- //Settings
216
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Settings', 'mp-timetable' ), __( 'Settings', 'mp-timetable' ),
217
- 'manage_options', 'mptt-settings', array( $this->get_controller( 'settings' ), 'action_content' ) );
218
-
219
- //Export / Import
220
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Export / Import', 'mp-timetable' ), __( 'Export / Import', 'mp-timetable' ),
221
- 'import', 'mptt-import', array( $this->get_controller( 'import' ), 'action_content' ) );
222
-
223
- //Help
224
- add_submenu_page( 'edit.php?post_type=mp-event', __( 'Help & Shortcode', 'mp-timetable' ), __( 'Help & Shortcode', 'mp-timetable' ),
225
- 'edit_posts', 'mptt-help', array( $this->get_controller( 'help' ), 'action_content' ) );
226
- }
227
-
228
- /**
229
- * Connect js for MCE editor
230
- *
231
- * @param $plugin_array
232
- *
233
- * @return mixed
234
- */
235
- public function mce_external_plugins( $plugin_array ) {
236
- $path = Mp_Time_Table::get_plugin_url( 'media/js/mce-timeTable-buttons' . $this->get_prefix() . '.js' );
237
- $plugin_array[ 'mp_timetable' ] = $path;
238
-
239
- return $plugin_array;
240
- }
241
-
242
- /**
243
- * Add button in MCE editor
244
- *
245
- * @param $buttons
246
- *
247
- * @return mixed
248
- */
249
- public function mce_buttons( $buttons ) {
250
- array_push( $buttons, 'addTimeTableButton' );
251
-
252
- return $buttons;
253
- }
254
-
255
- /**
256
- * Browser body class
257
- *
258
- * @param $classes
259
- *
260
- * @return array
261
- */
262
- public function browser_body_class( $classes ) {
263
- global $is_IE;
264
-
265
- if ( $is_IE ) {
266
- $classes[] = 'mprm_ie_browser';
267
- }
268
-
269
- return $classes;
270
- }
271
-
272
- /**
273
- * Set js
274
- */
275
- public function set_html_js_class() {
276
- echo View::get_instance()->get_template_html('events/no-script');
277
- }
278
-
279
- /**
280
- * Show row meta on the plugin screen.
281
- *
282
- * @return array
283
- */
284
- public static function plugin_row_meta( $links, $file ) {
285
-
286
- if ( MP_TT_PLUGIN_BASENAME === $file ) {
287
- $row_meta = array(
288
- 'help' => '<a href="' . esc_url( admin_url('edit.php?post_type=mp-event&page=mptt-help') ) . '" aria-label="' . esc_attr__( 'Quick Start Guide', 'mp-timetable' ) . '">' .
289
- esc_html__( 'Help', 'mp-timetable' ) . '</a>',
290
- 'review' => '<a href="' . esc_url( 'https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post' ) . '" aria-label="' . esc_attr__( 'Leave a Review', 'mp-timetable' ) . '" target="_blank">' . esc_html__( 'Leave a Review', 'mp-timetable' ) . '</a>',
291
- );
292
-
293
- return array_merge( $links, $row_meta );
294
- }
295
-
296
- return (array) $links;
297
- }
298
- }
1
+ <?php
2
+
3
+ namespace mp_timetable\plugin_core\classes;
4
+
5
+ use Mp_Time_Table;
6
+ use mp_timetable\classes\models\Import;
7
+ use mp_timetable\classes\models\Settings;
8
+ use mp_timetable\plugin_core\classes\modules\Post;
9
+ use mp_timetable\classes\blocks\Timetable_Block;
10
+
11
+ /**
12
+ * Class Hooks
13
+ * @package mp_timetable\plugin_core\classes
14
+ */
15
+ class Hooks extends Core {
16
+
17
+ protected static $instance;
18
+
19
+ /**
20
+ * @return Hooks
21
+ */
22
+ public static function get_instance() {
23
+ if ( null === self::$instance ) {
24
+ self::$instance = new self();
25
+ }
26
+
27
+ return self::$instance;
28
+ }
29
+
30
+ /**
31
+ * Install hooks
32
+ */
33
+ public function install_hooks() {
34
+
35
+ // register custom post type and taxonomies
36
+ add_action( 'init', array( $this, 'init' ) );
37
+ add_action( 'wp_enqueue_scripts', array( Core::get_instance(), 'add_plugin_css' ) );
38
+ add_action( 'wp_head', array( $this, 'set_html_js_class' ) );
39
+
40
+ add_action( 'admin_init', array( $this->get_controller( 'settings' ), 'action_save' ) );
41
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
42
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
43
+ add_action( 'manage_posts_custom_column', array( $this->get( 'events' ), 'get_event_taxonomy' ) );
44
+ add_action( 'manage_posts_custom_column', array( $this->get( 'column' ), 'get_column_columns' ) );
45
+ add_action( 'current_screen', array( Core::get_instance(), 'current_screen' ) );
46
+ add_action( 'pre_get_posts', array( $this->get( 'column' ), 'clientarea_default_order' ), 9 );
47
+
48
+ //add media in frontend WP
49
+ add_action( 'wp_enqueue_scripts', array( Core::get_instance(), 'wp_enqueue_scripts' ) );
50
+
51
+ //add media in admin WP
52
+ add_action( 'admin_enqueue_scripts', array( Core::get_instance(), 'admin_enqueue_scripts' ) );
53
+ add_action( 'widgets_init', array( $this, 'register_widgets' ) );
54
+
55
+ // Manage event/column columns
56
+ add_filter( 'manage_edit-mp-event_columns', array( $this->get( 'events' ), 'set_event_columns' ) );
57
+ add_filter( 'manage_edit-mp-column_columns', array( $this->get( 'column' ), 'set_column_columns' ) );
58
+
59
+ // Duplicate Event
60
+ add_filter( 'post_row_actions', array( $this->get( 'events' ), 'post_row_actions' ), 999, 2 );
61
+ add_action( 'post_action_mptt_duplicate_event', array( $this->get( 'events' ), 'post_action_mptt_duplicate_event' ) );
62
+
63
+ // post_class filter
64
+ add_filter( 'post_class', 'mptt_post_class', 15, 3 );
65
+
66
+ // to display events with other posts on author page
67
+ add_filter( 'pre_get_posts', array( Post::get_instance(), 'pre_get_posts' ), 9 );
68
+ add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_row_meta' ), 10, 2 );
69
+ }
70
+
71
+ /**
72
+ * Register widgets and sidebar
73
+ */
74
+ public function register_widgets() {
75
+ $template = get_option( 'template' );
76
+ if ( $template != 'twentyfourteen' && Settings::get_instance()->is_plugin_template_mode() ) {
77
+ register_sidebar( array(
78
+ 'name' => __( 'Timetable Sidebar', 'mp-timetable' ),
79
+ 'id' => "mptt-sidebar",
80
+ 'description' => __( 'Timetable', 'mp-timetable' ),
81
+ 'class' => 'sidebar-container',
82
+ 'before_widget' => '<li id="%1$s" class="widget %2$s">',
83
+ 'after_widget' => "</li>\n",
84
+ 'before_title' => '<h2 class="widget-title">',
85
+ 'after_title' => "</h2>\n"
86
+ ) );
87
+ }
88
+ register_widget( 'timetable\classes\widgets\Timetable_widget' );
89
+ }
90
+
91
+ /**
92
+ * Register template_action
93
+ */
94
+ public function register_template_action() {
95
+ add_action( 'mptt_sidebar', 'mptt_sidebar', 10 );
96
+ add_filter( 'mptt_widget_settings', 'mptt_widget_settings', 10, 1 );
97
+ add_action( 'mptt-single-mp-column-before-wrapper', 'mptt_theme_wrapper_before' );
98
+ add_action( 'mptt-single-mp-column-after-wrapper', 'mptt_theme_wrapper_after' );
99
+ add_action( 'mptt-single-mp-event-before-wrapper', 'mptt_theme_wrapper_before' );
100
+ add_action( 'mptt-single-mp-event-after-wrapper', 'mptt_theme_wrapper_after' );
101
+
102
+ // Event template action
103
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_title', 10 );
104
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_thumbnail', 20 );
105
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_post_content', 30 );
106
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_time_title', 40 );
107
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_time_list', 50 );
108
+ add_action( 'mptt_event_item_content', 'mptt_event_template_content_comments', 60 );
109
+
110
+ // Column template action
111
+ add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_title', 10 );
112
+ add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_post_content', 20 );
113
+ add_action( 'mptt_single_column_template_content', 'mptt_column_template_content_events_list', 30 );
114
+
115
+ //Shortcode template action
116
+ add_action( 'mptt_shortcode_template_before_content', 'mptt_shortcode_template_before_content', 10 );
117
+ add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_filter', 10 );
118
+ add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_static_table', 20 );
119
+ add_action( 'mptt_shortcode_template_content', 'mptt_shortcode_template_content_responsive_table', 30 );
120
+ add_action( 'mptt_shortcode_template_after_content', 'mptt_shortcode_template_after_content', 10 );
121
+
122
+ // Widget actions
123
+ add_action( 'mptt_widget_template_before_content', 'mptt_widget_template_before_content', 10 );
124
+ add_action( 'mptt_widget_template_content', 'mptt_widget_template_content', 10 );
125
+ add_action( 'mptt_widget_template_after_content', 'mptt_widget_template_after_content', 10 );
126
+
127
+ }
128
+
129
+ /**
130
+ * Init hook
131
+ */
132
+ public function init() {
133
+
134
+ // Init sort codes
135
+ Shortcode::get_instance()->init();
136
+ // Register post type
137
+ Core::get_instance()->register_all_post_type();
138
+ // Register taxonomy all
139
+ Core::get_instance()->register_all_taxonomies();
140
+ // route url
141
+ Core::get_instance()->wp_ajax_route_url();
142
+
143
+ if ( Settings::get_instance()->is_plugin_template_mode() ) {
144
+ // plugin mode
145
+ add_filter( 'template_include', array( View::get_instance(), 'template_loader' ), 99 );
146
+ } else {
147
+ //theme mode
148
+ add_filter( 'single_template', array( Core::get_instance(), 'modify_single_template' ), 99 );
149
+ }
150
+
151
+ add_action( 'mp_library', array( Shortcode::get_instance(), 'integration_motopress' ), 20, 1 );
152
+
153
+ Core::get_instance()->init_plugin_version();
154
+
155
+ add_filter( 'body_class', array( $this, 'browser_body_class' ) );
156
+ add_filter( 'the_tags', array( $this->get( 'events' ), 'the_tags' ), 10, 5 );
157
+ add_filter( 'the_category', array( $this->get( 'events' ), 'the_category' ), 10, 3 );
158
+
159
+ if ( function_exists('register_block_type') ) {
160
+ new Timetable_Block();
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Hooks for admin panel
166
+ */
167
+ public function admin_init() {
168
+ //add buttons to mce
169
+ add_filter( "mce_external_plugins", array( $this, "mce_external_plugins" ) );
170
+ add_filter( 'mce_buttons', array( $this, "mce_buttons" ) );
171
+
172
+ Core::get_instance()->init_plugin_version();
173
+
174
+ add_action( 'before_delete_post', array( Post::get_instance(), 'before_delete_custom_post' ) );
175
+ add_action( 'add_meta_boxes', array( Post::get_instance(), 'add_meta_boxes' ) );
176
+ add_action( 'save_post', array( Post::get_instance(), 'save_custom_post' ), 40, 2 );
177
+ add_action( 'wp_ajax_route_url', array( Core::get_instance(), "wp_ajax_route_url" ) );
178
+
179
+ register_importer( 'mptt-importer', 'Timetable', __( 'Import Timetable events, categories, tags and images.', 'mp-timetable' ), array( Import::get_instance(), 'import' ) );
180
+ }
181
+
182
+ /**
183
+ * Registered page in admin wp
184
+ */
185
+ public function admin_menu() {
186
+
187
+ //Timetable
188
+ add_menu_page( __( 'Timetable', 'mp-timetable' ), __( 'Timetable', 'mp-timetable' ),
189
+ 'edit_posts', 'edit.php?post_type=mp-event', '', 'dashicons-calendar', '59.51' );
190
+
191
+ //Events
192
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Events', 'mp-timetable' ), __( 'Events', 'mp-timetable' ),
193
+ 'edit_posts', 'edit.php?post_type=mp-event' );
194
+
195
+ //Add Event
196
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Add Event', 'mp-timetable' ), __( 'Add Event', 'mp-timetable' ),
197
+ 'edit_posts', 'post-new.php?post_type=mp-event' );
198
+
199
+ //Columns
200
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Columns', 'mp-timetable' ), __( 'Columns', 'mp-timetable' ),
201
+ 'edit_posts', 'edit.php?post_type=mp-column' );
202
+
203
+ //Add Column
204
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Add Column', 'mp-timetable' ), __( 'Add Column', 'mp-timetable' ),
205
+ 'edit_posts', 'post-new.php?post_type=mp-column' );
206
+
207
+ //Event Categories
208
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Event Categories', 'mp-timetable' ), __( 'Event Categories', 'mp-timetable' ),
209
+ 'manage_categories', 'edit-tags.php?taxonomy=mp-event_category&amp;post_type=mp-event' );
210
+
211
+ //Event Tags
212
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Event Tags', 'mp-timetable' ), __( 'Event Tags', 'mp-timetable' ),
213
+ 'manage_categories', 'edit-tags.php?taxonomy=mp-event_tag&amp;post_type=mp-event' );
214
+
215
+ //Settings
216
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Settings', 'mp-timetable' ), __( 'Settings', 'mp-timetable' ),
217
+ 'manage_options', 'mptt-settings', array( $this->get_controller( 'settings' ), 'action_content' ) );
218
+
219
+ //Export / Import
220
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Export / Import', 'mp-timetable' ), __( 'Export / Import', 'mp-timetable' ),
221
+ 'import', 'mptt-import', array( $this->get_controller( 'import' ), 'action_content' ) );
222
+
223
+ //Help
224
+ add_submenu_page( 'edit.php?post_type=mp-event', __( 'Help & Shortcode', 'mp-timetable' ), __( 'Help & Shortcode', 'mp-timetable' ),
225
+ 'edit_posts', 'mptt-help', array( $this->get_controller( 'help' ), 'action_content' ) );
226
+ }
227
+
228
+ /**
229
+ * Connect js for MCE editor
230
+ *
231
+ * @param $plugin_array
232
+ *
233
+ * @return mixed
234
+ */
235
+ public function mce_external_plugins( $plugin_array ) {
236
+ $path = Mp_Time_Table::get_plugin_url( 'media/js/mce-timeTable-buttons' . $this->get_prefix() . '.js' );
237
+ $plugin_array[ 'mp_timetable' ] = $path;
238
+
239
+ return $plugin_array;
240
+ }
241
+
242
+ /**
243
+ * Add button in MCE editor
244
+ *
245
+ * @param $buttons
246
+ *
247
+ * @return mixed
248
+ */
249
+ public function mce_buttons( $buttons ) {
250
+ array_push( $buttons, 'addTimeTableButton' );
251
+
252
+ return $buttons;
253
+ }
254
+
255
+ /**
256
+ * Browser body class
257
+ *
258
+ * @param $classes
259
+ *
260
+ * @return array
261
+ */
262
+ public function browser_body_class( $classes ) {
263
+ global $is_IE;
264
+
265
+ if ( $is_IE ) {
266
+ $classes[] = 'mprm_ie_browser';
267
+ }
268
+
269
+ return $classes;
270
+ }
271
+
272
+ /**
273
+ * Set js
274
+ */
275
+ public function set_html_js_class() {
276
+ echo View::get_instance()->get_template_html('events/no-script');
277
+ }
278
+
279
+ /**
280
+ * Show row meta on the plugin screen.
281
+ *
282
+ * @return array
283
+ */
284
+ public static function plugin_row_meta( $links, $file ) {
285
+
286
+ if ( MP_TT_PLUGIN_BASENAME === $file ) {
287
+ $row_meta = array(
288
+ 'help' => '<a href="' . esc_url( admin_url('edit.php?post_type=mp-event&page=mptt-help') ) . '" aria-label="' . esc_attr__( 'Quick Start Guide', 'mp-timetable' ) . '">' .
289
+ esc_html__( 'Help', 'mp-timetable' ) . '</a>',
290
+ 'review' => '<a href="' . esc_url( 'https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post' ) . '" aria-label="' . esc_attr__( 'Leave a Review', 'mp-timetable' ) . '" target="_blank">' . esc_html__( 'Leave a Review', 'mp-timetable' ) . '</a>',
291
+ );
292
+
293
+ return array_merge( $links, $row_meta );
294
+ }
295
+
296
+ return (array) $links;
297
+ }
298
+ }
classes/class-shortcode.php CHANGED
@@ -1,400 +1,400 @@
1
- <?php
2
-
3
- namespace mp_timetable\plugin_core\classes;
4
-
5
- use mp_timetable\classes\models\Column;
6
- use mp_timetable\classes\models\Events;
7
-
8
- /**
9
- * Class Shortcode
10
- *
11
- * @package mp_timetable\plugin_core\classes
12
- */
13
- class Shortcode extends Core {
14
-
15
- protected static $instance;
16
-
17
- /**
18
- * Shortcode constructor.
19
- */
20
- public function __construct() {
21
- $this->init_plugin_version();
22
- parent::__construct();
23
- }
24
-
25
- /**
26
- * Return instance
27
- *
28
- * @return Shortcode
29
- */
30
- public static function get_instance() {
31
- if ( null === self::$instance ) {
32
- self::$instance = new self();
33
- }
34
-
35
- return self::$instance;
36
- }
37
-
38
- /**
39
- * Init
40
- */
41
- public function init() {
42
- add_shortcode( 'mp-timetable', array( $this, "show_shortcode" ) );
43
- }
44
-
45
- /**
46
- * Show shortcode
47
- *
48
- * @param $params
49
- *
50
- * @return mixed
51
- */
52
- public function show_shortcode( $params ) {
53
- global $mptt_shortcode_data;
54
-
55
- $this->add_plugin_js( 'shortcode' );
56
-
57
- if ( empty( $params ) ) {
58
- $params = array();
59
- }
60
-
61
- $mptt_shortcode_data = array();
62
-
63
- $mptt_shortcode_data[ 'params' ] = $params = shortcode_atts( array(
64
- 'events' => "",
65
- 'event_categ' => "",
66
- 'col' => "",
67
- 'increment' => "1", // 1 | 0.5 | 0.25
68
- 'view' => "dropdown_list", // dropdown_list | tabs
69
- 'view_sort' => "", // '' | menu_order || post_title
70
- 'label' => __( "All Events", 'mp-timetable' ),
71
- 'hide_label' => "0",
72
- 'title' => "0",
73
- 'time' => "0",
74
- 'group' => "0",
75
- 'sub-title' => "0",
76
- 'description' => "0",
77
- 'user' => "0",
78
- 'hide_hrs' => "0",
79
- 'hide_empty_rows' => "1",
80
- 'text_align_vertical' => "default", // default | top | middle | bottom
81
- 'row_height' => "45",
82
- 'font_size' => "",
83
- 'disable_event_url' => "0",
84
- 'text_align' => "center", // left | center | right
85
- 'id' => "",
86
- 'custom_class' => "",
87
- 'responsive' => "1",
88
- 'table_layout' => "" // default | auto | fixed
89
- ), $params );
90
-
91
- $mptt_shortcode_data[ 'events_data' ] = $this->get_shortcode_events( $params );
92
-
93
- if ( ! empty( $mptt_shortcode_data[ 'events_data' ] ) ) {
94
- if ( isset($mptt_shortcode_data[ 'events_data' ][ 'unique_events' ]) ) {
95
- $mptt_shortcode_data[ 'unique_events' ] = $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ];
96
- }
97
- if ( isset( $mptt_shortcode_data[ 'events_data' ][ 'events' ] ) ) {
98
- unset( $mptt_shortcode_data[ 'events_data' ][ 'events' ] );
99
- }
100
- }
101
-
102
- if ( empty( $mptt_shortcode_data[ 'events_data' ][ 'events' ] ) && empty( $mptt_shortcode_data[ 'events_data' ][ 'column' ] ) ) {
103
- return $this->get_view()->get_template_html( 'shortcodes/empty-search-events', array() );
104
- } else {
105
- return $this->get_view()->get_template_html( 'shortcodes/index-timetable', array() );
106
- }
107
- }
108
-
109
- /**
110
- * Get shortcode events
111
- *
112
- * @param $params
113
- *
114
- * @return array
115
- */
116
- public function get_shortcode_events( $params ) {
117
- $columns_ids = $events_categ = $events = array();
118
-
119
- $step = $params[ 'increment' ] === '1' ? 60 : ( 60 * $params[ 'increment' ] );
120
-
121
- $events_data = array( 'events' => array(), 'column' => array() );
122
-
123
- //get event by id
124
- if ( ! empty( $params[ 'events' ] ) && empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) ) {
125
- $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
126
- }
127
-
128
- // get event by category
129
- if ( ! empty( $params[ 'event_categ' ] ) ) {
130
- $events_categ = $this->get( 'events' )->get_events_data_by_category( $params[ 'event_categ' ] );
131
- }
132
-
133
- // get event by column
134
- if ( ! empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) && empty( $params[ 'events' ] ) ) {
135
- $events = $this->get( 'events' )->get_events_data( array( 'column' => 'column_id', 'list' => $params[ 'col' ] ) );
136
- }
137
-
138
- //Columns + events
139
- if ( ! empty( $params[ 'events' ] ) && ! empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) ) {
140
- $events = $this->get( 'events' )->get_events_data( array( 'column' => array( 'column_id', 'event_id' ), 'list' => array( 'column_id' => $params[ 'col' ], 'event_id' => $params[ 'events' ] ) ) );
141
- }
142
-
143
- //Events + Categories
144
- if ( ! empty( $params[ 'events' ] ) && ! empty( $params[ 'event_categ' ] ) && empty( $params[ 'col' ] ) ) {
145
- $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
146
- }
147
-
148
- //if all params empty
149
- if ( empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) && empty( $params[ 'events' ] ) ) {
150
- $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'all' => true ) );
151
- $events_categ = $this->get( 'events' )->get_events_data_by_category( '' );
152
- }
153
- // select all event option
154
- if ( ! empty( $params[ 'col' ] ) && ! empty( $params[ 'event_categ' ] ) && ! empty( $params[ 'events' ] ) ) {
155
- $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
156
- }
157
-
158
- $events_data[ 'events' ] = array_merge( $events_data[ 'events' ], $events_categ, $events );
159
-
160
- //Create column array;
161
- if ( empty( $params[ 'col' ] ) ) {
162
- foreach ( $events_data[ 'events' ] as $event ) {
163
- $columns_ids[] = $event->column_id;
164
- }
165
- $columns_ids = array_unique( $columns_ids );
166
- } else {
167
- $columns_ids = explode( ',', $params[ 'col' ] );
168
- }
169
-
170
- //Sort column by menu order
171
- $events_data[ 'column' ] = $this->get( 'column' )->get_all_column( array( 'post__in' => $columns_ids ) );
172
-
173
- if ( ! empty( $events_data[ 'column' ] ) ) {
174
- foreach ( $events_data[ 'column' ] as $key => $column ) {
175
- $column_events = array();
176
- // add to column events
177
-
178
- foreach ( $events_data[ 'events' ] as $event_key => $event ) {
179
- if ( $column->ID == $event->column_id ) {
180
- $start_index = $this->get_event_index( $params[ 'increment' ], $event->event_start, $step, 'start' );
181
- $end_index = $this->get_event_index( $params[ 'increment' ], $event->event_end, $step, 'end' );
182
- $event->output = false;
183
- $event->start_index = $start_index;
184
- $event->end_index = ( $end_index < $start_index ) ? $this->get_event_index( $params[ 'increment' ], '23:59', $step, 'end' ) : $end_index;
185
- $column_events[ $event->id ] = $event;
186
- $events_data[ 'unique_events' ][ $event->event_id ] = $event;
187
- }
188
- }
189
-
190
- //sort by start date
191
- $column_events = $this->get_model( 'events' )->sort_by_param( $column_events );
192
-
193
- $events_data[ 'column_events' ][ $column->ID ] = $column_events;
194
- }
195
- } else {
196
- $events_data[ 'events' ] = array();
197
- }
198
-
199
- return $events_data;
200
- }
201
-
202
- /**
203
- * @param $increment
204
- * @param $time
205
- * @param $step
206
- * @param $type
207
- *
208
- * @return float|int
209
- */
210
- protected function get_event_index( $increment, $time, $step, $type ) {
211
- if ( $type == 'start' ) {
212
- $index = date( 'G', strtotime( $time ) ) / $increment + floor( date( 'i', strtotime( $time ) ) / $step );
213
- } else {
214
- $index = date( 'G', strtotime( $time ) ) / $increment + ceil( date( 'i', strtotime( $time ) ) / $step );
215
- }
216
-
217
- return $index;
218
- }
219
-
220
- /**
221
- * Get events Id
222
- *
223
- * @param array $data
224
- *
225
- * @return string
226
- */
227
- public function get_event_ids( array $data = array() ) {
228
- $ids_list = array();
229
- if ( empty( $data ) ) {
230
- return '';
231
- } else {
232
- foreach ( $data as $event ) {
233
- $ids_list[] = $event->id;
234
- }
235
-
236
- return implode( ',', $ids_list );
237
- }
238
- }
239
-
240
- /**
241
- * Integration in motopress
242
- *
243
- * @param $motopressCELibrary
244
- */
245
- public function integration_motopress( $motopressCELibrary ) {
246
- $columns = $this->create_list_motopress( Column::get_instance()->get_all_column() );
247
- $events = $this->create_list_motopress( Events::get_instance()->get_all_events() );
248
-
249
- $categories = get_terms( 'mp-event_category', 'orderby=count&hide_empty=0' );
250
- $categories = $this->create_list_motopress( $categories, 'term' );
251
-
252
- $attributes = array(
253
- 'col' => array(
254
- 'type' => 'select-multiple',
255
- 'label' => __( 'Column', 'mp-timetable' ),
256
- 'list' => $columns
257
- ),
258
- 'events' => array(
259
- 'type' => 'select-multiple',
260
- 'label' => __( 'Events', 'mp-timetable' ),
261
- 'list' => $events
262
- ),
263
- 'event_categ' => array(
264
- 'type' => 'select-multiple',
265
- 'label' => __( 'Event categories', 'mp-timetable' ),
266
- 'list' => $categories
267
- ),
268
- 'increment' => array(
269
- 'type' => 'select',
270
- 'label' => __( 'Hour measure', 'mp-timetable' ),
271
- 'list' => array( '1' => __( 'Hour (1h)', 'mp-timetable' ), '0.5' => __( 'Half hour (30min)', 'mp-timetable' ), '0.25' => __( 'Quarter hour (15min)', 'mp-timetable' ) )
272
- ),
273
- 'view' => array(
274
- 'type' => 'select',
275
- 'label' => __( 'Filter style', 'mp-timetable' ),
276
- 'list' => array( 'dropdown_list' => __( 'Dropdown list', 'mp-timetable' ), 'tabs' => __( 'Tabs', 'mp-timetable' ) )
277
- ),
278
- 'view_sort' => array(
279
- 'type' => 'select',
280
- 'label' => __( 'Order of items in filter', 'mp-timetable' ),
281
- 'list' => array( '' => __( 'Default', 'mp-timetable' ), 'menu_order' => __( 'Menu Order', 'mp-timetable' ), 'post_title' => __( 'Title', 'mp-timetable' ) )
282
- ),
283
- 'label' => array(
284
- 'type' => 'text',
285
- 'label' => __( 'Filter label', 'mp-timetable' ),
286
- 'default' => __( 'All Events', 'mp-timetable' )
287
- ),
288
- 'hide_label' => array(
289
- 'type' => 'select',
290
- 'label' => __( "Hide 'All Events' view", 'mp-timetable' ),
291
- 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
292
- ),
293
- 'hide_hrs' => array(
294
- 'type' => 'select',
295
- 'label' => __( 'Hide first (hours) column', 'mp-timetable' ),
296
- 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
297
- ),
298
- 'hide_empty_rows' => array(
299
- 'type' => 'select',
300
- 'label' => __( 'Hide empty rows', 'mp-timetable' ),
301
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
302
- 'default' => 1
303
- ),
304
- 'title' => array(
305
- 'type' => 'radio-buttons',
306
- 'label' => __( 'Title', 'mp-timetable' ),
307
- 'default' => 1,
308
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
309
- ),
310
- 'time' => array(
311
- 'type' => 'radio-buttons',
312
- 'label' => __( 'Time', 'mp-timetable' ),
313
- 'default' => 1,
314
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
315
- ),
316
- 'sub-title' => array(
317
- 'type' => 'radio-buttons',
318
- 'label' => __( 'Subtitle', 'mp-timetable' ),
319
- 'default' => 1,
320
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
321
- ),
322
- 'description' => array(
323
- 'type' => 'radio-buttons',
324
- 'label' => __( 'Description', 'mp-timetable' ),
325
- 'default' => 0,
326
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
327
- ),
328
- 'user' => array(
329
- 'type' => 'radio-buttons',
330
- 'label' => __( 'User', 'mp-timetable' ),
331
- 'default' => 0,
332
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
333
- ),
334
- 'disable_event_url' => array(
335
- 'type' => 'select',
336
- 'label' => __( 'Disable event URL', 'mp-timetable' ),
337
- 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
338
- ),
339
- 'text_align' => array(
340
- 'type' => 'select',
341
- 'label' => __( 'Text align', 'mp-timetable' ),
342
- 'list' => array( 'center' => __( 'center', 'mp-timetable' ), 'left' => __( 'left', 'mp-timetable' ), 'right' => __( 'right', 'mp-timetable' ) )
343
- ),
344
- 'id' => array(
345
- 'type' => 'text',
346
- 'label' => __( 'Id', 'mp-timetable' )
347
- ),
348
- 'row_height' => array(
349
- 'type' => 'text',
350
- 'label' => __( 'Row height (in px)', 'mp-timetable' ),
351
- 'default' => 45
352
- ),
353
- 'font_size' => array(
354
- 'type' => 'text',
355
- 'label' => __( 'Base Font Size', 'mp-timetable' ),
356
- 'default' => ''
357
- ),
358
- 'responsive' => array(
359
- 'type' => 'select',
360
- 'label' => __( 'Responsive', 'mp-timetable' ),
361
- 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
362
- 'default' => 1,
363
- ),
364
- 'table_layout' => array(
365
- 'type' => 'select',
366
- 'label' => __( 'Table layout', 'mp-timetable' ),
367
- 'list' => array( '' => __( 'Default', 'mp-timetable' ), 'auto' => __( 'Auto', 'mp-timetable' ), 'fixed' => __( 'Fixed', 'mp-timetable' ) )
368
- ),
369
- );
370
- $mp_timetable = new \MPCEObject( 'mp-timetable', __( 'Timetable', 'mp-timetable' ), '', $attributes );
371
-
372
- $motopressCELibrary->addObject( $mp_timetable, 'other' );
373
- }
374
-
375
- /**
376
- * @param array $data_array
377
- * @param string $type
378
- *
379
- * @return array
380
- */
381
- public function create_list_motopress( $data_array = array(), $type = 'post' ) {
382
- $list_array = array();
383
- switch ( $type ) {
384
- case "post":
385
- foreach ( $data_array as $item ) {
386
- $list_array[ $item->ID ] = $item->post_title;
387
- }
388
- break;
389
- case "term":
390
- foreach ( $data_array as $item ) {
391
- $list_array[ $item->term_id ] = $item->name;
392
- }
393
- break;
394
- default:
395
- break;
396
- }
397
-
398
- return $list_array;
399
- }
400
  }
1
+ <?php
2
+
3
+ namespace mp_timetable\plugin_core\classes;
4
+
5
+ use mp_timetable\classes\models\Column;
6
+ use mp_timetable\classes\models\Events;
7
+
8
+ /**
9
+ * Class Shortcode
10
+ *
11
+ * @package mp_timetable\plugin_core\classes
12
+ */
13
+ class Shortcode extends Core {
14
+
15
+ protected static $instance;
16
+
17
+ /**
18
+ * Shortcode constructor.
19
+ */
20
+ public function __construct() {
21
+ $this->init_plugin_version();
22
+ parent::__construct();
23
+ }
24
+
25
+ /**
26
+ * Return instance
27
+ *
28
+ * @return Shortcode
29
+ */
30
+ public static function get_instance() {
31
+ if ( null === self::$instance ) {
32
+ self::$instance = new self();
33
+ }
34
+
35
+ return self::$instance;
36
+ }
37
+
38
+ /**
39
+ * Init
40
+ */
41
+ public function init() {
42
+ add_shortcode( 'mp-timetable', array( $this, "show_shortcode" ) );
43
+ }
44
+
45
+ /**
46
+ * Show shortcode
47
+ *
48
+ * @param $params
49
+ *
50
+ * @return mixed
51
+ */
52
+ public function show_shortcode( $params ) {
53
+ global $mptt_shortcode_data;
54
+
55
+ $this->add_plugin_js( 'shortcode' );
56
+
57
+ if ( empty( $params ) ) {
58
+ $params = array();
59
+ }
60
+
61
+ $mptt_shortcode_data = array();
62
+
63
+ $mptt_shortcode_data[ 'params' ] = $params = shortcode_atts( array(
64
+ 'events' => "",
65
+ 'event_categ' => "",
66
+ 'col' => "",
67
+ 'increment' => "1", // 1 | 0.5 | 0.25
68
+ 'view' => "dropdown_list", // dropdown_list | tabs
69
+ 'view_sort' => "", // '' | menu_order || post_title
70
+ 'label' => __( "All Events", 'mp-timetable' ),
71
+ 'hide_label' => "0",
72
+ 'title' => "0",
73
+ 'time' => "0",
74
+ 'group' => "0",
75
+ 'sub-title' => "0",
76
+ 'description' => "0",
77
+ 'user' => "0",
78
+ 'hide_hrs' => "0",
79
+ 'hide_empty_rows' => "1",
80
+ 'text_align_vertical' => "default", // default | top | middle | bottom
81
+ 'row_height' => "45",
82
+ 'font_size' => "",
83
+ 'disable_event_url' => "0",
84
+ 'text_align' => "center", // left | center | right
85
+ 'id' => "",
86
+ 'custom_class' => "",
87
+ 'responsive' => "1",
88
+ 'table_layout' => "" // default | auto | fixed
89
+ ), $params );
90
+
91
+ $mptt_shortcode_data[ 'events_data' ] = $this->get_shortcode_events( $params );
92
+
93
+ if ( ! empty( $mptt_shortcode_data[ 'events_data' ] ) ) {
94
+ if ( isset($mptt_shortcode_data[ 'events_data' ][ 'unique_events' ]) ) {
95
+ $mptt_shortcode_data[ 'unique_events' ] = $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ];
96
+ }
97
+ if ( isset( $mptt_shortcode_data[ 'events_data' ][ 'events' ] ) ) {
98
+ unset( $mptt_shortcode_data[ 'events_data' ][ 'events' ] );
99
+ }
100
+ }
101
+
102
+ if ( empty( $mptt_shortcode_data[ 'events_data' ][ 'events' ] ) && empty( $mptt_shortcode_data[ 'events_data' ][ 'column' ] ) ) {
103
+ return $this->get_view()->get_template_html( 'shortcodes/empty-search-events', array() );
104
+ } else {
105
+ return $this->get_view()->get_template_html( 'shortcodes/index-timetable', array() );
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Get shortcode events
111
+ *
112
+ * @param $params
113
+ *
114
+ * @return array
115
+ */
116
+ public function get_shortcode_events( $params ) {
117
+ $columns_ids = $events_categ = $events = array();
118
+
119
+ $step = $params[ 'increment' ] === '1' ? 60 : ( 60 * $params[ 'increment' ] );
120
+
121
+ $events_data = array( 'events' => array(), 'column' => array() );
122
+
123
+ //get event by id
124
+ if ( ! empty( $params[ 'events' ] ) && empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) ) {
125
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
126
+ }
127
+
128
+ // get event by category
129
+ if ( ! empty( $params[ 'event_categ' ] ) ) {
130
+ $events_categ = $this->get( 'events' )->get_events_data_by_category( $params[ 'event_categ' ] );
131
+ }
132
+
133
+ // get event by column
134
+ if ( ! empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) && empty( $params[ 'events' ] ) ) {
135
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => 'column_id', 'list' => $params[ 'col' ] ) );
136
+ }
137
+
138
+ //Columns + events
139
+ if ( ! empty( $params[ 'events' ] ) && ! empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) ) {
140
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => array( 'column_id', 'event_id' ), 'list' => array( 'column_id' => $params[ 'col' ], 'event_id' => $params[ 'events' ] ) ) );
141
+ }
142
+
143
+ //Events + Categories
144
+ if ( ! empty( $params[ 'events' ] ) && ! empty( $params[ 'event_categ' ] ) && empty( $params[ 'col' ] ) ) {
145
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
146
+ }
147
+
148
+ //if all params empty
149
+ if ( empty( $params[ 'col' ] ) && empty( $params[ 'event_categ' ] ) && empty( $params[ 'events' ] ) ) {
150
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'all' => true ) );
151
+ $events_categ = $this->get( 'events' )->get_events_data_by_category( '' );
152
+ }
153
+ // select all event option
154
+ if ( ! empty( $params[ 'col' ] ) && ! empty( $params[ 'event_categ' ] ) && ! empty( $params[ 'events' ] ) ) {
155
+ $events = $this->get( 'events' )->get_events_data( array( 'column' => 'event_id', 'list' => $params[ 'events' ] ) );
156
+ }
157
+
158
+ $events_data[ 'events' ] = array_merge( $events_data[ 'events' ], $events_categ, $events );
159
+
160
+ //Create column array;
161
+ if ( empty( $params[ 'col' ] ) ) {
162
+ foreach ( $events_data[ 'events' ] as $event ) {
163
+ $columns_ids[] = $event->column_id;
164
+ }
165
+ $columns_ids = array_unique( $columns_ids );
166
+ } else {
167
+ $columns_ids = explode( ',', $params[ 'col' ] );
168
+ }
169
+
170
+ //Sort column by menu order
171
+ $events_data[ 'column' ] = $this->get( 'column' )->get_all_column( array( 'post__in' => $columns_ids ) );
172
+
173
+ if ( ! empty( $events_data[ 'column' ] ) ) {
174
+ foreach ( $events_data[ 'column' ] as $key => $column ) {
175
+ $column_events = array();
176
+ // add to column events
177
+
178
+ foreach ( $events_data[ 'events' ] as $event_key => $event ) {
179
+ if ( $column->ID == $event->column_id ) {
180
+ $start_index = $this->get_event_index( $params[ 'increment' ], $event->event_start, $step, 'start' );
181
+ $end_index = $this->get_event_index( $params[ 'increment' ], $event->event_end, $step, 'end' );
182
+ $event->output = false;
183
+ $event->start_index = $start_index;
184
+ $event->end_index = ( $end_index < $start_index ) ? $this->get_event_index( $params[ 'increment' ], '23:59', $step, 'end' ) : $end_index;
185
+ $column_events[ $event->id ] = $event;
186
+ $events_data[ 'unique_events' ][ $event->event_id ] = $event;
187
+ }
188
+ }
189
+
190
+ //sort by start date
191
+ $column_events = $this->get_model( 'events' )->sort_by_param( $column_events );
192
+
193
+ $events_data[ 'column_events' ][ $column->ID ] = $column_events;
194
+ }
195
+ } else {
196
+ $events_data[ 'events' ] = array();
197
+ }
198
+
199
+ return $events_data;
200
+ }
201
+
202
+ /**
203
+ * @param $increment
204
+ * @param $time
205
+ * @param $step
206
+ * @param $type
207
+ *
208
+ * @return float|int
209
+ */
210
+ protected function get_event_index( $increment, $time, $step, $type ) {
211
+ if ( $type == 'start' ) {
212
+ $index = date( 'G', strtotime( $time ) ) / $increment + floor( date( 'i', strtotime( $time ) ) / $step );
213
+ } else {
214
+ $index = date( 'G', strtotime( $time ) ) / $increment + ceil( date( 'i', strtotime( $time ) ) / $step );
215
+ }
216
+
217
+ return $index;
218
+ }
219
+
220
+ /**
221
+ * Get events Id
222
+ *
223
+ * @param array $data
224
+ *
225
+ * @return string
226
+ */
227
+ public function get_event_ids( array $data = array() ) {
228
+ $ids_list = array();
229
+ if ( empty( $data ) ) {
230
+ return '';
231
+ } else {
232
+ foreach ( $data as $event ) {
233
+ $ids_list[] = $event->id;
234
+ }
235
+
236
+ return implode( ',', $ids_list );
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Integration in motopress
242
+ *
243
+ * @param $motopressCELibrary
244
+ */
245
+ public function integration_motopress( $motopressCELibrary ) {
246
+ $columns = $this->create_list_motopress( Column::get_instance()->get_all_column() );
247
+ $events = $this->create_list_motopress( Events::get_instance()->get_all_events() );
248
+
249
+ $categories = get_terms( 'mp-event_category', 'orderby=count&hide_empty=0' );
250
+ $categories = $this->create_list_motopress( $categories, 'term' );
251
+
252
+ $attributes = array(
253
+ 'col' => array(
254
+ 'type' => 'select-multiple',
255
+ 'label' => __( 'Column', 'mp-timetable' ),
256
+ 'list' => $columns
257
+ ),
258
+ 'events' => array(
259
+ 'type' => 'select-multiple',
260
+ 'label' => __( 'Events', 'mp-timetable' ),
261
+ 'list' => $events
262
+ ),
263
+ 'event_categ' => array(
264
+ 'type' => 'select-multiple',
265
+ 'label' => __( 'Event categories', 'mp-timetable' ),
266
+ 'list' => $categories
267
+ ),
268
+ 'increment' => array(
269
+ 'type' => 'select',
270
+ 'label' => __( 'Hour measure', 'mp-timetable' ),
271
+ 'list' => array( '1' => __( 'Hour (1h)', 'mp-timetable' ), '0.5' => __( 'Half hour (30min)', 'mp-timetable' ), '0.25' => __( 'Quarter hour (15min)', 'mp-timetable' ) )
272
+ ),
273
+ 'view' => array(
274
+ 'type' => 'select',
275
+ 'label' => __( 'Filter style', 'mp-timetable' ),
276
+ 'list' => array( 'dropdown_list' => __( 'Dropdown list', 'mp-timetable' ), 'tabs' => __( 'Tabs', 'mp-timetable' ) )
277
+ ),
278
+ 'view_sort' => array(
279
+ 'type' => 'select',
280
+ 'label' => __( 'Order of items in filter', 'mp-timetable' ),
281
+ 'list' => array( '' => __( 'Default', 'mp-timetable' ), 'menu_order' => __( 'Menu Order', 'mp-timetable' ), 'post_title' => __( 'Title', 'mp-timetable' ) )
282
+ ),
283
+ 'label' => array(
284
+ 'type' => 'text',
285
+ 'label' => __( 'Filter label', 'mp-timetable' ),
286
+ 'default' => __( 'All Events', 'mp-timetable' )
287
+ ),
288
+ 'hide_label' => array(
289
+ 'type' => 'select',
290
+ 'label' => __( "Hide 'All Events' view", 'mp-timetable' ),
291
+ 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
292
+ ),
293
+ 'hide_hrs' => array(
294
+ 'type' => 'select',
295
+ 'label' => __( 'Hide first (hours) column', 'mp-timetable' ),
296
+ 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
297
+ ),
298
+ 'hide_empty_rows' => array(
299
+ 'type' => 'select',
300
+ 'label' => __( 'Hide empty rows', 'mp-timetable' ),
301
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
302
+ 'default' => 1
303
+ ),
304
+ 'title' => array(
305
+ 'type' => 'radio-buttons',
306
+ 'label' => __( 'Title', 'mp-timetable' ),
307
+ 'default' => 1,
308
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
309
+ ),
310
+ 'time' => array(
311
+ 'type' => 'radio-buttons',
312
+ 'label' => __( 'Time', 'mp-timetable' ),
313
+ 'default' => 1,
314
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
315
+ ),
316
+ 'sub-title' => array(
317
+ 'type' => 'radio-buttons',
318
+ 'label' => __( 'Subtitle', 'mp-timetable' ),
319
+ 'default' => 1,
320
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
321
+ ),
322
+ 'description' => array(
323
+ 'type' => 'radio-buttons',
324
+ 'label' => __( 'Description', 'mp-timetable' ),
325
+ 'default' => 0,
326
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
327
+ ),
328
+ 'user' => array(
329
+ 'type' => 'radio-buttons',
330
+ 'label' => __( 'User', 'mp-timetable' ),
331
+ 'default' => 0,
332
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
333
+ ),
334
+ 'disable_event_url' => array(
335
+ 'type' => 'select',
336
+ 'label' => __( 'Disable event URL', 'mp-timetable' ),
337
+ 'list' => array( '0' => __( 'No', 'mp-timetable' ), '1' => __( 'Yes', 'mp-timetable' ) )
338
+ ),
339
+ 'text_align' => array(
340
+ 'type' => 'select',
341
+ 'label' => __( 'Text align', 'mp-timetable' ),
342
+ 'list' => array( 'center' => __( 'center', 'mp-timetable' ), 'left' => __( 'left', 'mp-timetable' ), 'right' => __( 'right', 'mp-timetable' ) )
343
+ ),
344
+ 'id' => array(
345
+ 'type' => 'text',
346
+ 'label' => __( 'Id', 'mp-timetable' )
347
+ ),
348
+ 'row_height' => array(
349
+ 'type' => 'text',
350
+ 'label' => __( 'Row height (in px)', 'mp-timetable' ),
351
+ 'default' => 45
352
+ ),
353
+ 'font_size' => array(
354
+ 'type' => 'text',
355
+ 'label' => __( 'Base Font Size', 'mp-timetable' ),
356
+ 'default' => ''
357
+ ),
358
+ 'responsive' => array(
359
+ 'type' => 'select',
360
+ 'label' => __( 'Responsive', 'mp-timetable' ),
361
+ 'list' => array( '1' => __( 'Yes', 'mp-timetable' ), '0' => __( 'No', 'mp-timetable' ) ),
362
+ 'default' => 1,
363
+ ),
364
+ 'table_layout' => array(
365
+ 'type' => 'select',
366
+ 'label' => __( 'Column width', 'mp-timetable' ),
367
+ 'list' => array( '' => __( 'Default', 'mp-timetable' ), 'auto' => __( 'Auto', 'mp-timetable' ), 'fixed' => __( 'Fixed', 'mp-timetable' ) )
368
+ ),
369
+ );
370
+ $mp_timetable = new \MPCEObject( 'mp-timetable', __( 'Timetable', 'mp-timetable' ), '', $attributes );
371
+
372
+ $motopressCELibrary->addObject( $mp_timetable, 'other' );
373
+ }
374
+
375
+ /**
376
+ * @param array $data_array
377
+ * @param string $type
378
+ *
379
+ * @return array
380
+ */
381
+ public function create_list_motopress( $data_array = array(), $type = 'post' ) {
382
+ $list_array = array();
383
+ switch ( $type ) {
384
+ case "post":
385
+ foreach ( $data_array as $item ) {
386
+ $list_array[ $item->ID ] = $item->post_title;
387
+ }
388
+ break;
389
+ case "term":
390
+ foreach ( $data_array as $item ) {
391
+ $list_array[ $item->term_id ] = $item->name;
392
+ }
393
+ break;
394
+ default:
395
+ break;
396
+ }
397
+
398
+ return $list_array;
399
+ }
400
  }
classes/libs/parsers.php CHANGED
@@ -1,789 +1,789 @@
1
- <?php
2
- namespace mp_timetable\classes\libs;
3
- /**
4
- * WordPress eXtended RSS file parser implementations
5
- *
6
- * @package WordPress
7
- * @subpackage Importer
8
- */
9
-
10
- /**
11
- * WordPress Importer class for managing parsing of WXR files.
12
- */
13
- class WXR_Parser {
14
- function parse($file) {
15
-
16
- // Attempt to use proper XML parsers first
17
- if (extension_loaded('simplexml')) {
18
- $parser = new WXR_Parser_SimpleXML;
19
- $result = $parser->parse($file);
20
-
21
- // If SimpleXML succeeds or this is an invalid WXR file then return the results
22
- if (!is_wp_error($result) || 'SimpleXML_parse_error' != $result->get_error_code())
23
- return $result;
24
- } else if (extension_loaded('xml')) {
25
- $parser = new WXR_Parser_XML;
26
- $result = $parser->parse($file);
27
-
28
- // If XMLParser succeeds or this is an invalid WXR file then return the results
29
- if (!is_wp_error($result) || 'XML_parse_error' != $result->get_error_code())
30
- return $result;
31
- }
32
-
33
- // We have a malformed XML file, so display the error and fallthrough to regex
34
- if (isset($result) && defined('IMPORT_DEBUG') && IMPORT_DEBUG) {
35
- echo '<pre>';
36
- if ('SimpleXML_parse_error' == $result->get_error_code()) {
37
- foreach ($result->get_error_data() as $error)
38
- echo $error->line . ':' . $error->column . ' ' . esc_html($error->message) . "\n";
39
- } else if ('XML_parse_error' == $result->get_error_code()) {
40
- $error = $result->get_error_data();
41
- echo $error[0] . ':' . $error[1] . ' ' . esc_html($error[2]);
42
- }
43
- echo '</pre>';
44
- echo '<p><strong>' . __('There was an error when reading this WXR file', 'wordpress-importer') . '</strong><br />';
45
- echo __('Details are shown above. The importer will now try again with a different parser...', 'wordpress-importer') . '</p>';
46
- }
47
-
48
- // use regular expressions if nothing else available or this is bad XML
49
- $parser = new WXR_Parser_Regex;
50
- return $parser->parse($file);
51
- }
52
- }
53
-
54
- /**
55
- * WXR Parser that makes use of the SimpleXML PHP extension.
56
- */
57
- class WXR_Parser_SimpleXML {
58
- function parse($file) {
59
- $authors = $posts = $categories = $tags = $time_slots = $terms = array();
60
-
61
- $internal_errors = libxml_use_internal_errors(true);
62
-
63
- $dom = new \DOMDocument;
64
- $old_value = null;
65
- if (function_exists('libxml_disable_entity_loader')) {
66
- $old_value = libxml_disable_entity_loader(true);
67
- }
68
- $success = $dom->loadXML(file_get_contents($file));
69
- if (!is_null($old_value)) {
70
- libxml_disable_entity_loader($old_value);
71
- }
72
-
73
- if (!$success || isset($dom->doctype)) {
74
- return new \WP_Error('SimpleXML_parse_error', __('There was an error when reading this WXR file', 'wordpress-importer'), libxml_get_errors());
75
- }
76
-
77
- $xml = simplexml_import_dom($dom);
78
- unset($dom);
79
-
80
- // halt if loading produces an error
81
- if (!$xml)
82
- return new \WP_Error('SimpleXML_parse_error', __('There was an error when reading this WXR file', 'wordpress-importer'), libxml_get_errors());
83
-
84
- $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
85
- if (!$wxr_version)
86
- return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer'));
87
-
88
- $wxr_version = (string)trim($wxr_version[0]);
89
- // confirm that we are dealing with the correct file format
90
- if (!preg_match('/^\d+\.\d+$/', $wxr_version))
91
- return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer'));
92
-
93
- $base_url = $xml->xpath('/rss/channel/wp:base_site_url');
94
- $base_url = (string)trim($base_url[0]);
95
-
96
- $namespaces = $xml->getDocNamespaces();
97
- if (!isset($namespaces['wp']))
98
- $namespaces['wp'] = 'http://wordpress.org/export/1.1/';
99
- if (!isset($namespaces['excerpt']))
100
- $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
101
-
102
- // grab authors
103
- foreach ($xml->xpath('/rss/channel/wp:author') as $author_arr) {
104
- $a = $author_arr->children($namespaces['wp']);
105
- $login = (string)$a->author_login;
106
- $authors[$login] = array(
107
- 'author_id' => (int)$a->author_id,
108
- 'author_login' => $login,
109
- 'author_email' => (string)$a->author_email,
110
- 'author_display_name' => (string)$a->author_display_name,
111
- 'author_first_name' => (string)$a->author_first_name,
112
- 'author_last_name' => (string)$a->author_last_name
113
- );
114
- }
115
-
116
- // grab cats, tags and terms
117
- foreach ($xml->xpath('/rss/channel/wp:category') as $term_arr) {
118
- $t = $term_arr->children($namespaces['wp']);
119
- $categories[] = array(
120
- 'term_id' => (int)$t->term_id,
121
- 'category_nicename' => (string)$t->category_nicename,
122
- 'category_parent' => (string)$t->category_parent,
123
- 'cat_name' => (string)$t->cat_name,
124
- 'category_description' => (string)$t->category_description
125
- );
126
- }
127
-
128
- foreach ($xml->xpath('/rss/channel/wp:tag') as $term_arr) {
129
- $t = $term_arr->children($namespaces['wp']);
130
- $tags[] = array(
131
- 'term_id' => (int)$t->term_id,
132
- 'tag_slug' => (string)$t->tag_slug,
133
- 'tag_name' => (string)$t->tag_name,
134
- 'tag_description' => (string)$t->tag_description
135
- );
136
- }
137
-
138
- foreach ($xml->xpath('/rss/channel/wp:term') as $term_arr) {
139
- $t = $term_arr->children($namespaces['wp']);
140
- $terms[] = array(
141
- 'term_id' => (int)$t->term_id,
142
- 'term_taxonomy' => (string)$t->term_taxonomy,
143
- 'slug' => (string)$t->term_slug,
144
- 'term_parent' => (string)$t->term_parent,
145
- 'term_name' => (string)$t->term_name,
146
- 'term_description' => (string)$t->term_description
147
- );
148
- }
149
-
150
- // grab posts
151
- foreach ($xml->channel->item as $item) {
152
- $post = array(
153
- 'post_title' => (string)$item->title,
154
- 'guid' => (string)$item->guid,
155
- );
156
-
157
- $dc = $item->children('http://purl.org/dc/elements/1.1/');
158
- $post['post_author'] = (string)$dc->creator;
159
-
160
- $content = $item->children('http://purl.org/rss/1.0/modules/content/');
161
- $excerpt = $item->children($namespaces['excerpt']);
162
- $post['post_content'] = (string)$content->encoded;
163
- $post['post_excerpt'] = (string)$excerpt->encoded;
164
-
165
- $wp = $item->children($namespaces['wp']);
166
- $post['post_id'] = (int)$wp->post_id;
167
- $post['post_date'] = (string)$wp->post_date;
168
- $post['post_date_gmt'] = (string)$wp->post_date_gmt;
169
- $post['comment_status'] = (string)$wp->comment_status;
170
- $post['ping_status'] = (string)$wp->ping_status;
171
- $post['post_name'] = (string)$wp->post_name;
172
- $post['status'] = (string)$wp->status;
173
- $post['post_parent'] = (int)$wp->post_parent;
174
- $post['menu_order'] = (int)$wp->menu_order;
175
- $post['post_type'] = (string)$wp->post_type;
176
- $post['post_password'] = (string)$wp->post_password;
177
- $post['is_sticky'] = (int)$wp->is_sticky;
178
-
179
- if (isset($wp->attachment_url))
180
- $post['attachment_url'] = (string)$wp->attachment_url;
181
-
182
- foreach ($item->category as $c) {
183
- $att = $c->attributes();
184
- if (isset($att['nicename']))
185
- $post['terms'][] = array(
186
- 'name' => (string)$c,
187
- 'slug' => (string)$att['nicename'],
188
- 'domain' => (string)$att['domain']
189
- );
190
- }
191
-
192
- foreach ($wp->postmeta as $meta) {
193
- $post['postmeta'][] = array(
194
- 'key' => (string)$meta->meta_key,
195
- 'value' => (string)$meta->meta_value
196
- );
197
- }
198
-
199
- foreach ($wp->timeslot as $time) {
200
- $post['timeslot'][] = array(
201
- 'column' => (string)$time->column,
202
- 'event' => (string)$time->event,
203
- 'event_start' => (string)$time->event_start,
204
- 'event_end' => (string)$time->event_end,
205
- 'user_id' => (string)$time->user_id,
206
- 'description' => (string)$time->description,
207
- );
208
- }
209
-
210
-
211
- foreach ($wp->comment as $comment) {
212
- $meta = array();
213
- if (isset($comment->commentmeta)) {
214
- foreach ($comment->commentmeta as $m) {
215
- $meta[] = array(
216
- 'key' => (string)$m->meta_key,
217
- 'value' => (string)$m->meta_value
218
- );
219
- }
220
- }
221
-
222
- $post['comments'][] = array(
223
- 'comment_id' => (int)$comment->comment_id,
224
- 'comment_author' => (string)$comment->comment_author,
225
- 'comment_author_email' => (string)$comment->comment_author_email,
226
- 'comment_author_IP' => (string)$comment->comment_author_IP,
227
- 'comment_author_url' => (string)$comment->comment_author_url,
228
- 'comment_date' => (string)$comment->comment_date,
229
- 'comment_date_gmt' => (string)$comment->comment_date_gmt,
230
- 'comment_content' => (string)$comment->comment_content,
231
- 'comment_approved' => (string)$comment->comment_approved,
232
- 'comment_type' => (string)$comment->comment_type,
233
- 'comment_parent' => (string)$comment->comment_parent,
234
- 'comment_user_id' => (int)$comment->comment_user_id,
235
- 'commentmeta' => $meta,
236
- );
237
- }
238
-
239
- $posts[] = $post;
240
- }
241
- // grab time_slots
242
- foreach ($xml->channel->timeslot as $time) {
243
- $time_slots[] = array(
244
- 'column' => (int)$time->column,
245
- 'event' => (int)$time->event,
246
- 'event_start' => (string)$time->event_start,
247
- 'event_end' => (string)$time->event_end,
248
- 'user_id' => (int)$time->user_id,
249
- 'description' => (string)$time->description,
250
- );
251
- }
252
- return array(
253
- 'authors' => $authors,
254
- 'posts' => $posts,
255
- 'categories' => $categories,
256
- 'tags' => $tags,
257
- 'terms' => $terms,
258
- 'time_slots' => $time_slots,
259
- 'base_url' => $base_url,
260
- 'version' => $wxr_version
261
- );
262
- }
263
- }
264
-
265
- /**
266
- * WXR Parser that makes use of the XML Parser PHP extension.
267
- */
268
- class WXR_Parser_XML {
269
- var $wp_tags = array(
270
- 'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url',
271
- 'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password',
272
- 'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description',
273
- 'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent',
274
- 'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name',
275
- 'wp:author_first_name', 'wp:author_last_name',
276
- );
277
- var $wp_sub_tags = array(
278
- 'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url',
279
- 'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content',
280
- 'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id',
281
- );
282
-
283
- function parse($file) {
284
- $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false;
285
- $this->authors = $this->posts = $this->term = $this->category = $this->tag = $this->time_slots = array();
286
-
287
- $xml = xml_parser_create('UTF-8');
288
- xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
289
- xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
290
- xml_set_object($xml, $this);
291
- xml_set_character_data_handler($xml, 'cdata');
292
- xml_set_element_handler($xml, 'tag_open', 'tag_close');
293
-
294
- if (!xml_parse($xml, file_get_contents($file), true)) {
295
- $current_line = xml_get_current_line_number($xml);
296
- $current_column = xml_get_current_column_number($xml);
297
- $error_code = xml_get_error_code($xml);
298
- $error_string = xml_error_string($error_code);
299
- return new \WP_Error('XML_parse_error', 'There was an error when reading this WXR file', array($current_line, $current_column, $error_string));
300
- }
301
- xml_parser_free($xml);
302
-
303
- if (!preg_match('/^\d+\.\d+$/', $this->wxr_version))
304
- return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer'));
305
-
306
- return array(
307
- 'authors' => $this->authors,
308
- 'posts' => $this->posts,
309
- 'categories' => $this->category,
310
- 'tags' => $this->tag,
311
- 'terms' => $this->term,
312
- 'base_url' => $this->base_url,
313
- 'version' => $this->wxr_version,
314
- 'time_slots' => $this->time_slots
315
- );
316
- }
317
-
318
- function tag_open($parse, $tag, $attr) {
319
- if (in_array($tag, $this->wp_tags)) {
320
- $this->in_tag = substr($tag, 3);
321
- return;
322
- }
323
-
324
- if (in_array($tag, $this->wp_sub_tags)) {
325
- $this->in_sub_tag = substr($tag, 3);
326
- return;
327
- }
328
-
329
- switch ($tag) {
330
- case 'category':
331
- if (isset($attr['domain'], $attr['nicename'])) {
332
- $this->sub_data['domain'] = $attr['domain'];
333
- $this->sub_data['slug'] = $attr['nicename'];
334
- }
335
- break;
336
- case 'item':
337
- $this->in_post = true;
338
- case 'title':
339
- if ($this->in_post) $this->in_tag = 'post_title';
340
- break;
341
- case 'timeslot':
342
- break;
343
- case 'column':
344
- $this->in_tag = 'column';
345
- break;
346
- case 'event':
347
- $this->in_tag = 'event';
348
- break;
349
- case 'event_start':
350
- $this->in_tag = 'event_start';
351
- break;
352
- case 'event_end':
353
- $this->in_tag = 'event_end';
354
- break;
355
- case 'user_id':
356
- $this->in_tag = 'user_id';
357
- break;
358
- case 'description':
359
- $this->in_tag = 'description';
360
- break;
361
- case 'guid':
362
- $this->in_tag = 'guid';
363
- break;
364
- case 'dc:creator':
365
- $this->in_tag = 'post_author';
366
- break;
367
- case 'content:encoded':
368
- $this->in_tag = 'post_content';
369
- break;
370
- case 'excerpt:encoded':
371
- $this->in_tag = 'post_excerpt';
372
- break;
373
- case 'wp:term_slug':
374
- $this->in_tag = 'slug';
375
- break;
376
- case 'wp:meta_key':
377
- $this->in_sub_tag = 'key';
378
- break;
379
- case 'wp:meta_value':
380
- $this->in_sub_tag = 'value';
381
- break;
382
- }
383
- }
384
-
385
- function cdata($parser, $cdata) {
386
- if (!trim($cdata))
387
- return;
388
-
389
- $this->cdata .= trim($cdata);
390
- }
391
-
392
- function tag_close($parser, $tag) {
393
- switch ($tag) {
394
- case 'wp:comment':
395
- unset($this->sub_data['key'], $this->sub_data['value']); // remove meta sub_data
396
- if (!empty($this->sub_data))
397
- $this->data['comments'][] = $this->sub_data;
398
- $this->sub_data = false;
399
- break;
400
- case 'wp:commentmeta':
401
- $this->sub_data['commentmeta'][] = array(
402
- 'key' => $this->sub_data['key'],
403
- 'value' => $this->sub_data['value']
404
- );
405
- break;
406
- case 'category':
407
- if (!empty($this->sub_data)) {
408
- $this->sub_data['name'] = $this->cdata;
409
- $this->data['terms'][] = $this->sub_data;
410
- }
411
- $this->sub_data = false;
412
- break;
413
- case 'wp:postmeta':
414
- if (!empty($this->sub_data))
415
- $this->data['postmeta'][] = $this->sub_data;
416
- $this->sub_data = false;
417
- break;
418
- case 'timeslot':
419
- $this->time_slots[] = $this->data;
420
- $this->data = false;
421
- break;
422
- case 'item':
423
- $this->posts[] = $this->data;
424
- $this->data = false;
425
- break;
426
- case 'wp:category':
427
- case 'wp:tag':
428
- case 'wp:term':
429
- $n = substr($tag, 3);
430
- array_push($this->$n, $this->data);
431
- $this->data = false;
432
- break;
433
- case 'wp:author':
434
- if (!empty($this->data['author_login']))
435
- $this->authors[$this->data['author_login']] = $this->data;
436
- $this->data = false;
437
- break;
438
- case 'wp:base_site_url':
439
- $this->base_url = $this->cdata;
440
- break;
441
- case 'wp:wxr_version':
442
- $this->wxr_version = $this->cdata;
443
- break;
444
-
445
- default:
446
- if ($this->in_sub_tag) {
447
- $this->sub_data[$this->in_sub_tag] = !empty($this->cdata) ? $this->cdata : '';
448
- $this->in_sub_tag = false;
449
- } else if ($this->in_tag) {
450
- $this->data[$this->in_tag] = !empty($this->cdata) ? $this->cdata : '';
451
- $this->in_tag = false;
452
- }
453
- }
454
-
455
- $this->cdata = false;
456
- }
457
- }
458
-
459
- /**
460
- * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
461
- */
462
- class WXR_Parser_Regex {
463
- var $authors = array();
464
- var $posts = array();
465
- var $categories = array();
466
- var $tags = array();
467
- var $terms = array();
468
- var $time_slots = array();
469
- var $base_url = '';
470
-
471
- function __construct() {
472
- $this->has_gzip = is_callable('gzopen');
473
- }
474
-
475
- function parse($file) {
476
- $wxr_version = $in_post = $in_tag = false;
477
- $post = $tag = '';
478
- $fp = $this->fopen($file, 'r');
479
- if ($fp) {
480
- while (!$this->feof($fp)) {
481
- $importline = rtrim($this->fgets($fp));
482
-
483
- if (!$wxr_version && preg_match('|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version))
484
- $wxr_version = $version[1];
485
-
486
- if (false !== strpos($importline, '<wp:base_site_url>')) {
487
- preg_match('|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url);
488
- $this->base_url = $url[1];
489
- continue;
490
- }
491
- if (false !== strpos($importline, '<wp:category>')) {
492
- preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
493
- $this->categories[] = $this->process_category($category[1]);
494
- continue;
495
- }
496
- if (false !== strpos($importline, '<wp:tag>')) {
497
- preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
498
- $this->tags[] = $this->process_tag($tag[1]);
499
- continue;
500
- }
501
- if (false !== strpos($importline, '<wp:term>')) {
502
- preg_match('|<wp:term>(.*?)</wp:term>|is', $importline, $term);
503
- if (!empty($term)) {
504
- $this->terms[] = $this->process_term($term[1]);
505
- } else {
506
- $in_tag = true;
507
- }
508
- continue;
509
- }
510
-
511
- if (false !== strpos($importline, '</wp:term>')) {
512
- $tag .= $importline . "\n";
513
- $this->terms[] = $this->process_term($tag);
514
- $tag = '';
515
- $in_tag = false;
516
- continue;
517
- }
518
-
519
- if (false !== strpos($importline, '<timeslot>')) {
520
- preg_match('|<timeslot>(.*?)</timeslot>|is', $importline, $time_slot);
521
- if (!empty($time_slot)) {
522
- $this->time_slots[] = $this->process_time_slot($time_slot[1]);
523
- } else {
524
- $in_tag = true;
525
- }
526
- continue;
527
- }
528
- if (false !== strpos($importline, '</timeslot>')) {
529
- $tag .= $importline . "\n";
530
- $this->time_slots[] = $this->process_time_slot($tag);
531
- $tag = '';
532
- $in_tag = false;
533
- continue;
534
- }
535
-
536
-
537
- if (false !== strpos($importline, '<wp:author>')) {
538
- preg_match('|<wp:author>(.*?)</wp:author>|is', $importline, $author);
539
- $a = $this->process_author($author[1]);
540
- $this->authors[$a['author_login']] = $a;
541
- continue;
542
- }
543
- if (false !== strpos($importline, '<item>')) {
544
- $in_post = true;
545
- continue;
546
- }
547
- if (false !== strpos($importline, '</item>')) {
548
- $in_post = false;
549
- $this->posts[] = $this->process_post($post);
550
- continue;
551
- }
552
- if ($in_post) {
553
- $post .= $importline . "\n";
554
- }
555
-
556
- if ($in_tag) {
557
- $tag .= $importline . "\n";
558
- }
559
- }
560
-
561
- $this->fclose($fp);
562
- }
563
-
564
- if (!$wxr_version)
565
- return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'wordpress-importer'));
566
-
567
- return array(
568
- 'authors' => $this->authors,
569
- 'posts' => $this->posts,
570
- 'categories' => $this->categories,
571
- 'tags' => $this->tags,
572
- 'terms' => $this->terms,
573
- 'base_url' => $this->base_url,
574
- 'version' => $wxr_version,
575
- 'time_slots' => $this->time_slots
576
- );
577
- }
578
-
579
- function get_tag($string, $tag) {
580
- preg_match("|<$tag.*?>(.*?)</$tag>|is", $string, $return);
581
- if (isset($return[1])) {
582
- if (substr($return[1], 0, 9) == '<![CDATA[') {
583
- if (strpos($return[1], ']]]]><![CDATA[>') !== false) {
584
- preg_match_all('|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches);
585
- $return = '';
586
- foreach ($matches[1] as $match)
587
- $return .= $match;
588
- } else {
589
- $return = preg_replace('|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1]);
590
- }
591
- } else {
592
- $return = $return[1];
593
- }
594
- } else {
595
- $return = '';
596
- }
597
- return $return;
598
- }
599
-
600
- function process_category($c) {
601
- return array(
602
- 'term_id' => $this->get_tag($c, 'wp:term_id'),
603
- 'cat_name' => $this->get_tag($c, 'wp:cat_name'),
604
- 'category_nicename' => $this->get_tag($c, 'wp:category_nicename'),
605
- 'category_parent' => $this->get_tag($c, 'wp:category_parent'),
606
- 'category_description' => $this->get_tag($c, 'wp:category_description'),
607
- );
608
- }
609
-
610
- function process_tag($t) {
611
- return array(
612
- 'term_id' => $this->get_tag($t, 'wp:term_id'),
613
- 'tag_name' => $this->get_tag($t, 'wp:tag_name'),
614
- 'tag_slug' => $this->get_tag($t, 'wp:tag_slug'),
615
- 'tag_description' => $this->get_tag($t, 'wp:tag_description'),
616
- );
617
- }
618
-
619
- function process_term($t) {
620
- return array(
621
- 'term_id' => $this->get_tag($t, 'wp:term_id'),
622
- 'term_taxonomy' => $this->get_tag($t, 'wp:term_taxonomy'),
623
- 'slug' => $this->get_tag($t, 'wp:term_slug'),
624
- 'term_parent' => $this->get_tag($t, 'wp:term_parent'),
625
- 'term_name' => $this->get_tag($t, 'wp:term_name'),
626
- 'term_description' => $this->get_tag($t, 'wp:term_description'),
627
- );
628
- }
629
-
630
- function process_time_slot($t) {
631
- return array(
632
- 'column' => $this->get_tag($t, 'column'),
633
- 'event' => $this->get_tag($t, 'event'),
634
- 'event_start' => $this->get_tag($t, 'event_start'),
635
- 'event_end' => $this->get_tag($t, 'event_end'),
636
- 'user_id' => $this->get_tag($t, 'user_id'),
637
- 'description' => $this->get_tag($t, 'description'),
638
- );
639
- }
640
-
641
- function process_author($a) {
642
- return array(
643
- 'author_id' => $this->get_tag($a, 'wp:author_id'),
644
- 'author_login' => $this->get_tag($a, 'wp:author_login'),
645
- 'author_email' => $this->get_tag($a, 'wp:author_email'),
646
- 'author_display_name' => $this->get_tag($a, 'wp:author_display_name'),
647
- 'author_first_name' => $this->get_tag($a, 'wp:author_first_name'),
648
- 'author_last_name' => $this->get_tag($a, 'wp:author_last_name'),
649
- );
650
- }
651
-
652
- function process_post($post) {
653
- $post_id = $this->get_tag($post, 'wp:post_id');
654
- $post_title = $this->get_tag($post, 'title');
655
- $post_date = $this->get_tag($post, 'wp:post_date');
656
- $post_date_gmt = $this->get_tag($post, 'wp:post_date_gmt');
657
- $comment_status = $this->get_tag($post, 'wp:comment_status');
658
- $ping_status = $this->get_tag($post, 'wp:ping_status');
659
- $status = $this->get_tag($post, 'wp:status');
660
- $post_name = $this->get_tag($post, 'wp:post_name');
661
- $post_parent = $this->get_tag($post, 'wp:post_parent');
662
- $menu_order = $this->get_tag($post, 'wp:menu_order');
663
- $post_type = $this->get_tag($post, 'wp:post_type');
664
- $post_password = $this->get_tag($post, 'wp:post_password');
665
- $is_sticky = $this->get_tag($post, 'wp:is_sticky');
666
- $guid = $this->get_tag($post, 'guid');
667
- $post_author = $this->get_tag($post, 'dc:creator');
668
-
669
- $post_excerpt = $this->get_tag($post, 'excerpt:encoded');
670
- $post_excerpt = preg_replace_callback('|<(/?[A-Z]+)|', array(&$this, '_normalize_tag'), $post_excerpt);
671
- $post_excerpt = str_replace('<br>', '<br />', $post_excerpt);
672
- $post_excerpt = str_replace('<hr>', '<hr />', $post_excerpt);
673
-
674
- $post_content = $this->get_tag($post, 'content:encoded');
675
- $post_content = preg_replace_callback('|<(/?[A-Z]+)|', array(&$this, '_normalize_tag'), $post_content);
676
- $post_content = str_replace('<br>', '<br />', $post_content);
677
- $post_content = str_replace('<hr>', '<hr />', $post_content);
678
-
679
- $postdata = compact('post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt',
680
- 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent',
681
- 'menu_order', 'post_type', 'post_password', 'is_sticky'
682
- );
683
-
684
- $attachment_url = $this->get_tag($post, 'wp:attachment_url');
685
- if ($attachment_url)
686
- $postdata['attachment_url'] = $attachment_url;
687
-
688
- preg_match_all('|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER);
689
- foreach ($terms as $t) {
690
- $post_terms[] = array(
691
- 'slug' => $t[2],
692
- 'domain' => $t[1],
693
- 'name' => str_replace(array('<![CDATA[', ']]>'), '', $t[3]),
694
- );
695
- }
696
- if (!empty($post_terms)) $postdata['terms'] = $post_terms;
697
-
698
- preg_match_all('|<wp:comment>(.+?)</wp:comment>|is', $post, $comments);
699
- $comments = $comments[1];
700
- if ($comments) {
701
- foreach ($comments as $comment) {
702
- preg_match_all('|<wp:commentmeta>(.+?)</wp:commentmeta>|is', $comment, $commentmeta);
703
- $commentmeta = $commentmeta[1];
704
- $c_meta = array();
705
- foreach ($commentmeta as $m) {
706
- $c_meta[] = array(
707
- 'key' => $this->get_tag($m, 'wp:meta_key'),
708
- 'value' => $this->get_tag($m, 'wp:meta_value'),
709
- );
710
- }
711
-
712
- $post_comments[] = array(
713
- 'comment_id' => $this->get_tag($comment, 'wp:comment_id'),
714
- 'comment_author' => $this->get_tag($comment, 'wp:comment_author'),
715
- 'comment_author_email' => $this->get_tag($comment, 'wp:comment_author_email'),
716
- 'comment_author_IP' => $this->get_tag($comment, 'wp:comment_author_IP'),
717
- 'comment_author_url' => $this->get_tag($comment, 'wp:comment_author_url'),
718
- 'comment_date' => $this->get_tag($comment, 'wp:comment_date'),
719
- 'comment_date_gmt' => $this->get_tag($comment, 'wp:comment_date_gmt'),
720
- 'comment_content' => $this->get_tag($comment, 'wp:comment_content'),
721
- 'comment_approved' => $this->get_tag($comment, 'wp:comment_approved'),
722
- 'comment_type' => $this->get_tag($comment, 'wp:comment_type'),
723
- 'comment_parent' => $this->get_tag($comment, 'wp:comment_parent'),
724
- 'comment_user_id' => $this->get_tag($comment, 'wp:comment_user_id'),
725
- 'commentmeta' => $c_meta,
726
- );
727
- }
728
- }
729
- if (!empty($post_comments)) $postdata['comments'] = $post_comments;
730
-
731
- preg_match_all('|<wp:postmeta>(.+?)</wp:postmeta>|is', $post, $postmeta);
732
- $postmeta = $postmeta[1];
733
- if ($postmeta) {
734
- foreach ($postmeta as $p) {
735
- $post_postmeta[] = array(
736
- 'key' => $this->get_tag($p, 'wp:meta_key'),
737
- 'value' => $this->get_tag($p, 'wp:meta_value'),
738
- );
739
- }
740
- }
741
- if (!empty($post_postmeta)) $postdata['postmeta'] = $post_postmeta;
742
-
743
- preg_match_all('|<wp:timeslot>(.+?)</wp:timeslot>|is', $post, $timeslot);
744
- $timeslot = $timeslot[1];
745
- if ($timeslot) {
746
- foreach ($timeslot as $p) {
747
- $post_ptimeslot[] = array(
748
- 'column' => $this->get_tag($p, 'wp:column'),
749
- 'event' => $this->get_tag($p, 'wp:event'),
750
- 'event_start' => $this->get_tag($p, 'wp:event_start'),
751
- 'event_end' => $this->get_tag($p, 'wp:event_end'),
752
- 'user_id' => $this->get_tag($p, 'wp:user_id'),
753
- 'description' => $this->get_tag($p, 'wp:description')
754
- );
755
- }
756
- }
757
- if (!empty($post_timeslot)) $postdata['timeslot'] = $post_timeslot;
758
-
759
- return $postdata;
760
- }
761
-
762
- function _normalize_tag($matches) {
763
- return '<' . strtolower($matches[1]);
764
- }
765
-
766
- function fopen($filename, $mode = 'r') {
767
- if ($this->has_gzip)
768
- return gzopen($filename, $mode);
769
- return fopen($filename, $mode);
770
- }
771
-
772
- function feof($fp) {
773
- if ($this->has_gzip)
774
- return gzeof($fp);
775
- return feof($fp);
776
- }
777
-
778
- function fgets($fp, $len = 8192) {
779
- if ($this->has_gzip)
780
- return gzgets($fp, $len);
781
- return fgets($fp, $len);
782
- }
783
-
784
- function fclose($fp) {
785
- if ($this->has_gzip)
786
- return gzclose($fp);
787
- return fclose($fp);
788
- }
789
- }
1
+ <?php
2
+ namespace mp_timetable\classes\libs;
3
+ /**
4
+ * WordPress eXtended RSS file parser implementations
5
+ *
6
+ * @package WordPress
7
+ * @subpackage Importer
8
+ */
9
+
10
+ /**
11
+ * WordPress Importer class for managing parsing of WXR files.
12
+ */
13
+ class WXR_Parser {
14
+ function parse($file) {
15
+
16
+ // Attempt to use proper XML parsers first
17
+ if (extension_loaded('simplexml')) {
18
+ $parser = new WXR_Parser_SimpleXML;
19
+ $result = $parser->parse($file);
20
+
21
+ // If SimpleXML succeeds or this is an invalid WXR file then return the results
22
+ if (!is_wp_error($result) || 'SimpleXML_parse_error' != $result->get_error_code())
23
+ return $result;
24
+ } else if (extension_loaded('xml')) {
25
+ $parser = new WXR_Parser_XML;
26
+ $result = $parser->parse($file);
27
+
28
+ // If XMLParser succeeds or this is an invalid WXR file then return the results
29
+ if (!is_wp_error($result) || 'XML_parse_error' != $result->get_error_code())
30
+ return $result;
31
+ }
32
+
33
+ // We have a malformed XML file, so display the error and fallthrough to regex
34
+ if (isset($result) && defined('IMPORT_DEBUG') && IMPORT_DEBUG) {
35
+ echo '<pre>';
36
+ if ('SimpleXML_parse_error' == $result->get_error_code()) {
37
+ foreach ($result->get_error_data() as $error)
38
+ echo $error->line . ':' . $error->column . ' ' . esc_html($error->message) . "\n";
39
+ } else if ('XML_parse_error' == $result->get_error_code()) {
40
+ $error = $result->get_error_data();
41
+ echo $error[0] . ':' . $error[1] . ' ' . esc_html($error[2]);
42
+ }
43
+ echo '</pre>';
44
+ echo '<p><strong>' . __('There was an error when reading this WXR file', 'mp-timetable') . '</strong><br />';
45
+ echo __('Details are shown above. The importer will now try again with a different parser...', 'mp-timetable') . '</p>';
46
+ }
47
+
48
+ // use regular expressions if nothing else available or this is bad XML
49
+ $parser = new WXR_Parser_Regex;
50
+ return $parser->parse($file);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * WXR Parser that makes use of the SimpleXML PHP extension.
56
+ */
57
+ class WXR_Parser_SimpleXML {
58
+ function parse($file) {
59
+ $authors = $posts = $categories = $tags = $time_slots = $terms = array();
60
+
61
+ $internal_errors = libxml_use_internal_errors(true);
62
+
63
+ $dom = new \DOMDocument;
64
+ $old_value = null;
65
+ if (function_exists('libxml_disable_entity_loader')) {
66
+ $old_value = libxml_disable_entity_loader(true);
67
+ }
68
+ $success = $dom->loadXML(file_get_contents($file));
69
+ if (!is_null($old_value)) {
70
+ libxml_disable_entity_loader($old_value);
71
+ }
72
+
73
+ if (!$success || isset($dom->doctype)) {
74
+ return new \WP_Error('SimpleXML_parse_error', __('There was an error when reading this WXR file', 'mp-timetable'), libxml_get_errors());
75
+ }
76
+
77
+ $xml = simplexml_import_dom($dom);
78
+ unset($dom);
79
+
80
+ // halt if loading produces an error
81
+ if (!$xml)
82
+ return new \WP_Error('SimpleXML_parse_error', __('There was an error when reading this WXR file', 'mp-timetable'), libxml_get_errors());
83
+
84
+ $wxr_version = $xml->xpath('/rss/channel/wp:wxr_version');
85
+ if (!$wxr_version)
86
+ return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'mp-timetable'));
87
+
88
+ $wxr_version = (string)trim($wxr_version[0]);
89
+ // confirm that we are dealing with the correct file format
90
+ if (!preg_match('/^\d+\.\d+$/', $wxr_version))
91
+ return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'mp-timetable'));
92
+
93
+ $base_url = $xml->xpath('/rss/channel/wp:base_site_url');
94
+ $base_url = (string)trim($base_url[0]);
95
+
96
+ $namespaces = $xml->getDocNamespaces();
97
+ if (!isset($namespaces['wp']))
98
+ $namespaces['wp'] = 'http://wordpress.org/export/1.1/';
99
+ if (!isset($namespaces['excerpt']))
100
+ $namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
101
+
102
+ // grab authors
103
+ foreach ($xml->xpath('/rss/channel/wp:author') as $author_arr) {
104
+ $a = $author_arr->children($namespaces['wp']);
105
+ $login = (string)$a->author_login;
106
+ $authors[$login] = array(
107
+ 'author_id' => (int)$a->author_id,
108
+ 'author_login' => $login,
109
+ 'author_email' => (string)$a->author_email,
110
+ 'author_display_name' => (string)$a->author_display_name,
111
+ 'author_first_name' => (string)$a->author_first_name,
112
+ 'author_last_name' => (string)$a->author_last_name
113
+ );
114
+ }
115
+
116
+ // grab cats, tags and terms
117
+ foreach ($xml->xpath('/rss/channel/wp:category') as $term_arr) {
118
+ $t = $term_arr->children($namespaces['wp']);
119
+ $categories[] = array(
120
+ 'term_id' => (int)$t->term_id,
121
+ 'category_nicename' => (string)$t->category_nicename,
122
+ 'category_parent' => (string)$t->category_parent,
123
+ 'cat_name' => (string)$t->cat_name,
124
+ 'category_description' => (string)$t->category_description
125
+ );
126
+ }
127
+
128
+ foreach ($xml->xpath('/rss/channel/wp:tag') as $term_arr) {
129
+ $t = $term_arr->children($namespaces['wp']);
130
+ $tags[] = array(
131
+ 'term_id' => (int)$t->term_id,
132
+ 'tag_slug' => (string)$t->tag_slug,
133
+ 'tag_name' => (string)$t->tag_name,
134
+ 'tag_description' => (string)$t->tag_description
135
+ );
136
+ }
137
+
138
+ foreach ($xml->xpath('/rss/channel/wp:term') as $term_arr) {
139
+ $t = $term_arr->children($namespaces['wp']);
140
+ $terms[] = array(
141
+ 'term_id' => (int)$t->term_id,
142
+ 'term_taxonomy' => (string)$t->term_taxonomy,
143
+ 'slug' => (string)$t->term_slug,
144
+ 'term_parent' => (string)$t->term_parent,
145
+ 'term_name' => (string)$t->term_name,
146
+ 'term_description' => (string)$t->term_description
147
+ );
148
+ }
149
+
150
+ // grab posts
151
+ foreach ($xml->channel->item as $item) {
152
+ $post = array(
153
+ 'post_title' => (string)$item->title,
154
+ 'guid' => (string)$item->guid,
155
+ );
156
+
157
+ $dc = $item->children('http://purl.org/dc/elements/1.1/');
158
+ $post['post_author'] = (string)$dc->creator;
159
+
160
+ $content = $item->children('http://purl.org/rss/1.0/modules/content/');
161
+ $excerpt = $item->children($namespaces['excerpt']);
162
+ $post['post_content'] = (string)$content->encoded;
163
+ $post['post_excerpt'] = (string)$excerpt->encoded;
164
+
165
+ $wp = $item->children($namespaces['wp']);
166
+ $post['post_id'] = (int)$wp->post_id;
167
+ $post['post_date'] = (string)$wp->post_date;
168
+ $post['post_date_gmt'] = (string)$wp->post_date_gmt;
169
+ $post['comment_status'] = (string)$wp->comment_status;
170
+ $post['ping_status'] = (string)$wp->ping_status;
171
+ $post['post_name'] = (string)$wp->post_name;
172
+ $post['status'] = (string)$wp->status;
173
+ $post['post_parent'] = (int)$wp->post_parent;
174
+ $post['menu_order'] = (int)$wp->menu_order;
175
+ $post['post_type'] = (string)$wp->post_type;
176
+ $post['post_password'] = (string)$wp->post_password;
177
+ $post['is_sticky'] = (int)$wp->is_sticky;
178
+
179
+ if (isset($wp->attachment_url))
180
+ $post['attachment_url'] = (string)$wp->attachment_url;
181
+
182
+ foreach ($item->category as $c) {
183
+ $att = $c->attributes();
184
+ if (isset($att['nicename']))
185
+ $post['terms'][] = array(
186
+ 'name' => (string)$c,
187
+ 'slug' => (string)$att['nicename'],
188
+ 'domain' => (string)$att['domain']
189
+ );
190
+ }
191
+
192
+ foreach ($wp->postmeta as $meta) {
193
+ $post['postmeta'][] = array(
194
+ 'key' => (string)$meta->meta_key,
195
+ 'value' => (string)$meta->meta_value
196
+ );
197
+ }
198
+
199
+ foreach ($wp->timeslot as $time) {
200
+ $post['timeslot'][] = array(
201
+ 'column' => (string)$time->column,
202
+ 'event' => (string)$time->event,
203
+ 'event_start' => (string)$time->event_start,
204
+ 'event_end' => (string)$time->event_end,
205
+ 'user_id' => (string)$time->user_id,
206
+ 'description' => (string)$time->description,
207
+ );
208
+ }
209
+
210
+
211
+ foreach ($wp->comment as $comment) {
212
+ $meta = array();
213
+ if (isset($comment->commentmeta)) {
214
+ foreach ($comment->commentmeta as $m) {
215
+ $meta[] = array(
216
+ 'key' => (string)$m->meta_key,
217
+ 'value' => (string)$m->meta_value
218
+ );
219
+ }
220
+ }
221
+
222
+ $post['comments'][] = array(
223
+ 'comment_id' => (int)$comment->comment_id,
224
+ 'comment_author' => (string)$comment->comment_author,
225
+ 'comment_author_email' => (string)$comment->comment_author_email,
226
+ 'comment_author_IP' => (string)$comment->comment_author_IP,
227
+ 'comment_author_url' => (string)$comment->comment_author_url,
228
+ 'comment_date' => (string)$comment->comment_date,
229
+ 'comment_date_gmt' => (string)$comment->comment_date_gmt,
230
+ 'comment_content' => (string)$comment->comment_content,
231
+ 'comment_approved' => (string)$comment->comment_approved,
232
+ 'comment_type' => (string)$comment->comment_type,
233
+ 'comment_parent' => (string)$comment->comment_parent,
234
+ 'comment_user_id' => (int)$comment->comment_user_id,
235
+ 'commentmeta' => $meta,
236
+ );
237
+ }
238
+
239
+ $posts[] = $post;
240
+ }
241
+ // grab time_slots
242
+ foreach ($xml->channel->timeslot as $time) {
243
+ $time_slots[] = array(
244
+ 'column' => (int)$time->column,
245
+ 'event' => (int)$time->event,
246
+ 'event_start' => (string)$time->event_start,
247
+ 'event_end' => (string)$time->event_end,
248
+ 'user_id' => (int)$time->user_id,
249
+ 'description' => (string)$time->description,
250
+ );
251
+ }
252
+ return array(
253
+ 'authors' => $authors,
254
+ 'posts' => $posts,
255
+ 'categories' => $categories,
256
+ 'tags' => $tags,
257
+ 'terms' => $terms,
258
+ 'time_slots' => $time_slots,
259
+ 'base_url' => $base_url,
260
+ 'version' => $wxr_version
261
+ );
262
+ }
263
+ }
264
+
265
+ /**
266
+ * WXR Parser that makes use of the XML Parser PHP extension.
267
+ */
268
+ class WXR_Parser_XML {
269
+ var $wp_tags = array(
270
+ 'wp:post_id', 'wp:post_date', 'wp:post_date_gmt', 'wp:comment_status', 'wp:ping_status', 'wp:attachment_url',
271
+ 'wp:status', 'wp:post_name', 'wp:post_parent', 'wp:menu_order', 'wp:post_type', 'wp:post_password',
272
+ 'wp:is_sticky', 'wp:term_id', 'wp:category_nicename', 'wp:category_parent', 'wp:cat_name', 'wp:category_description',
273
+ 'wp:tag_slug', 'wp:tag_name', 'wp:tag_description', 'wp:term_taxonomy', 'wp:term_parent',
274
+ 'wp:term_name', 'wp:term_description', 'wp:author_id', 'wp:author_login', 'wp:author_email', 'wp:author_display_name',
275
+ 'wp:author_first_name', 'wp:author_last_name',
276
+ );
277
+ var $wp_sub_tags = array(
278
+ 'wp:comment_id', 'wp:comment_author', 'wp:comment_author_email', 'wp:comment_author_url',
279
+ 'wp:comment_author_IP', 'wp:comment_date', 'wp:comment_date_gmt', 'wp:comment_content',
280
+ 'wp:comment_approved', 'wp:comment_type', 'wp:comment_parent', 'wp:comment_user_id',
281
+ );
282
+
283
+ function parse($file) {
284
+ $this->wxr_version = $this->in_post = $this->cdata = $this->data = $this->sub_data = $this->in_tag = $this->in_sub_tag = false;
285
+ $this->authors = $this->posts = $this->term = $this->category = $this->tag = $this->time_slots = array();
286
+
287
+ $xml = xml_parser_create('UTF-8');
288
+ xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
289
+ xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
290
+ xml_set_object($xml, $this);
291
+ xml_set_character_data_handler($xml, 'cdata');
292
+ xml_set_element_handler($xml, 'tag_open', 'tag_close');
293
+
294
+ if (!xml_parse($xml, file_get_contents($file), true)) {
295
+ $current_line = xml_get_current_line_number($xml);
296
+ $current_column = xml_get_current_column_number($xml);
297
+ $error_code = xml_get_error_code($xml);
298
+ $error_string = xml_error_string($error_code);
299
+ return new \WP_Error('XML_parse_error', 'There was an error when reading this WXR file', array($current_line, $current_column, $error_string));
300
+ }
301
+ xml_parser_free($xml);
302
+
303
+ if (!preg_match('/^\d+\.\d+$/', $this->wxr_version))
304
+ return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'mp-timetable'));
305
+
306
+ return array(
307
+ 'authors' => $this->authors,
308
+ 'posts' => $this->posts,
309
+ 'categories' => $this->category,
310
+ 'tags' => $this->tag,
311
+ 'terms' => $this->term,
312
+ 'base_url' => $this->base_url,
313
+ 'version' => $this->wxr_version,
314
+ 'time_slots' => $this->time_slots
315
+ );
316
+ }
317
+
318
+ function tag_open($parse, $tag, $attr) {
319
+ if (in_array($tag, $this->wp_tags)) {
320
+ $this->in_tag = substr($tag, 3);
321
+ return;
322
+ }
323
+
324
+ if (in_array($tag, $this->wp_sub_tags)) {
325
+ $this->in_sub_tag = substr($tag, 3);
326
+ return;
327
+ }
328
+
329
+ switch ($tag) {
330
+ case 'category':
331
+ if (isset($attr['domain'], $attr['nicename'])) {
332
+ $this->sub_data['domain'] = $attr['domain'];
333
+ $this->sub_data['slug'] = $attr['nicename'];
334
+ }
335
+ break;
336
+ case 'item':
337
+ $this->in_post = true;
338
+ case 'title':
339
+ if ($this->in_post) $this->in_tag = 'post_title';
340
+ break;
341
+ case 'timeslot':
342
+ break;
343
+ case 'column':
344
+ $this->in_tag = 'column';
345
+ break;
346
+ case 'event':
347
+ $this->in_tag = 'event';
348
+ break;
349
+ case 'event_start':
350
+ $this->in_tag = 'event_start';
351
+ break;
352
+ case 'event_end':
353
+ $this->in_tag = 'event_end';
354
+ break;
355
+ case 'user_id':
356
+ $this->in_tag = 'user_id';
357
+ break;
358
+ case 'description':
359
+ $this->in_tag = 'description';
360
+ break;
361
+ case 'guid':
362
+ $this->in_tag = 'guid';
363
+ break;
364
+ case 'dc:creator':
365
+ $this->in_tag = 'post_author';
366
+ break;
367
+ case 'content:encoded':
368
+ $this->in_tag = 'post_content';
369
+ break;
370
+ case 'excerpt:encoded':
371
+ $this->in_tag = 'post_excerpt';
372
+ break;
373
+ case 'wp:term_slug':
374
+ $this->in_tag = 'slug';
375
+ break;
376
+ case 'wp:meta_key':
377
+ $this->in_sub_tag = 'key';
378
+ break;
379
+ case 'wp:meta_value':
380
+ $this->in_sub_tag = 'value';
381
+ break;
382
+ }
383
+ }
384
+
385
+ function cdata($parser, $cdata) {
386
+ if (!trim($cdata))
387
+ return;
388
+
389
+ $this->cdata .= trim($cdata);
390
+ }
391
+
392
+ function tag_close($parser, $tag) {
393
+ switch ($tag) {
394
+ case 'wp:comment':
395
+ unset($this->sub_data['key'], $this->sub_data['value']); // remove meta sub_data
396
+ if (!empty($this->sub_data))
397
+ $this->data['comments'][] = $this->sub_data;
398
+ $this->sub_data = false;
399
+ break;
400
+ case 'wp:commentmeta':
401
+ $this->sub_data['commentmeta'][] = array(
402
+ 'key' => $this->sub_data['key'],
403
+ 'value' => $this->sub_data['value']
404
+ );
405
+ break;
406
+ case 'category':
407
+ if (!empty($this->sub_data)) {
408
+ $this->sub_data['name'] = $this->cdata;
409
+ $this->data['terms'][] = $this->sub_data;
410
+ }
411
+ $this->sub_data = false;
412
+ break;
413
+ case 'wp:postmeta':
414
+ if (!empty($this->sub_data))
415
+ $this->data['postmeta'][] = $this->sub_data;
416
+ $this->sub_data = false;
417
+ break;
418
+ case 'timeslot':
419
+ $this->time_slots[] = $this->data;
420
+ $this->data = false;
421
+ break;
422
+ case 'item':
423
+ $this->posts[] = $this->data;
424
+ $this->data = false;
425
+ break;
426
+ case 'wp:category':
427
+ case 'wp:tag':
428
+ case 'wp:term':
429
+ $n = substr($tag, 3);
430
+ array_push($this->$n, $this->data);
431
+ $this->data = false;
432
+ break;
433
+ case 'wp:author':
434
+ if (!empty($this->data['author_login']))
435
+ $this->authors[$this->data['author_login']] = $this->data;
436
+ $this->data = false;
437
+ break;
438
+ case 'wp:base_site_url':
439
+ $this->base_url = $this->cdata;
440
+ break;
441
+ case 'wp:wxr_version':
442
+ $this->wxr_version = $this->cdata;
443
+ break;
444
+
445
+ default:
446
+ if ($this->in_sub_tag) {
447
+ $this->sub_data[$this->in_sub_tag] = !empty($this->cdata) ? $this->cdata : '';
448
+ $this->in_sub_tag = false;
449
+ } else if ($this->in_tag) {
450
+ $this->data[$this->in_tag] = !empty($this->cdata) ? $this->cdata : '';
451
+ $this->in_tag = false;
452
+ }
453
+ }
454
+
455
+ $this->cdata = false;
456
+ }
457
+ }
458
+
459
+ /**
460
+ * WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
461
+ */
462
+ class WXR_Parser_Regex {
463
+ var $authors = array();
464
+ var $posts = array();
465
+ var $categories = array();
466
+ var $tags = array();
467
+ var $terms = array();
468
+ var $time_slots = array();
469
+ var $base_url = '';
470
+
471
+ function __construct() {
472
+ $this->has_gzip = is_callable('gzopen');
473
+ }
474
+
475
+ function parse($file) {
476
+ $wxr_version = $in_post = $in_tag = false;
477
+ $post = $tag = '';
478
+ $fp = $this->fopen($file, 'r');
479
+ if ($fp) {
480
+ while (!$this->feof($fp)) {
481
+ $importline = rtrim($this->fgets($fp));
482
+
483
+ if (!$wxr_version && preg_match('|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version))
484
+ $wxr_version = $version[1];
485
+
486
+ if (false !== strpos($importline, '<wp:base_site_url>')) {
487
+ preg_match('|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url);
488
+ $this->base_url = $url[1];
489
+ continue;
490
+ }
491
+ if (false !== strpos($importline, '<wp:category>')) {
492
+ preg_match('|<wp:category>(.*?)</wp:category>|is', $importline, $category);
493
+ $this->categories[] = $this->process_category($category[1]);
494
+ continue;
495
+ }
496
+ if (false !== strpos($importline, '<wp:tag>')) {
497
+ preg_match('|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag);
498
+ $this->tags[] = $this->process_tag($tag[1]);
499
+ continue;
500
+ }
501
+ if (false !== strpos($importline, '<wp:term>')) {
502
+ preg_match('|<wp:term>(.*?)</wp:term>|is', $importline, $term);
503
+ if (!empty($term)) {
504
+ $this->terms[] = $this->process_term($term[1]);
505
+ } else {
506
+ $in_tag = true;
507
+ }
508
+ continue;
509
+ }
510
+
511
+ if (false !== strpos($importline, '</wp:term>')) {
512
+ $tag .= $importline . "\n";
513
+ $this->terms[] = $this->process_term($tag);
514
+ $tag = '';
515
+ $in_tag = false;
516
+ continue;
517
+ }
518
+
519
+ if (false !== strpos($importline, '<timeslot>')) {
520
+ preg_match('|<timeslot>(.*?)</timeslot>|is', $importline, $time_slot);
521
+ if (!empty($time_slot)) {
522
+ $this->time_slots[] = $this->process_time_slot($time_slot[1]);
523
+ } else {
524
+ $in_tag = true;
525
+ }
526
+ continue;
527
+ }
528
+ if (false !== strpos($importline, '</timeslot>')) {
529
+ $tag .= $importline . "\n";
530
+ $this->time_slots[] = $this->process_time_slot($tag);
531
+ $tag = '';
532
+ $in_tag = false;
533
+ continue;
534
+ }
535
+
536
+
537
+ if (false !== strpos($importline, '<wp:author>')) {
538
+ preg_match('|<wp:author>(.*?)</wp:author>|is', $importline, $author);
539
+ $a = $this->process_author($author[1]);
540
+ $this->authors[$a['author_login']] = $a;
541
+ continue;
542
+ }
543
+ if (false !== strpos($importline, '<item>')) {
544
+ $in_post = true;
545
+ continue;
546
+ }
547
+ if (false !== strpos($importline, '</item>')) {
548
+ $in_post = false;
549
+ $this->posts[] = $this->process_post($post);
550
+ continue;
551
+ }
552
+ if ($in_post) {
553
+ $post .= $importline . "\n";
554
+ }
555
+
556
+ if ($in_tag) {
557
+ $tag .= $importline . "\n";
558
+ }
559
+ }
560
+
561
+ $this->fclose($fp);
562
+ }
563
+
564
+ if (!$wxr_version)
565
+ return new \WP_Error('WXR_parse_error', __('This does not appear to be a WXR file, missing/invalid WXR version number', 'mp-timetable'));
566
+
567
+ return array(
568
+ 'authors' => $this->authors,
569
+ 'posts' => $this->posts,
570
+ 'categories' => $this->categories,
571
+ 'tags' => $this->tags,
572
+ 'terms' => $this->terms,
573
+ 'base_url' => $this->base_url,
574
+ 'version' => $wxr_version,
575
+ 'time_slots' => $this->time_slots
576
+ );
577
+ }
578
+
579
+ function get_tag($string, $tag) {
580
+ preg_match("|<$tag.*?>(.*?)</$tag>|is", $string, $return);
581
+ if (isset($return[1])) {
582
+ if (substr($return[1], 0, 9) == '<![CDATA[') {
583
+ if (strpos($return[1], ']]]]><![CDATA[>') !== false) {
584
+ preg_match_all('|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches);
585
+ $return = '';
586
+ foreach ($matches[1] as $match)
587
+ $return .= $match;
588
+ } else {
589
+ $return = preg_replace('|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1]);
590
+ }
591
+ } else {
592
+ $return = $return[1];
593
+ }
594
+ } else {
595
+ $return = '';
596
+ }
597
+ return $return;
598
+ }
599
+
600
+ function process_category($c) {
601
+ return array(
602
+ 'term_id' => $this->get_tag($c, 'wp:term_id'),
603
+ 'cat_name' => $this->get_tag($c, 'wp:cat_name'),
604
+ 'category_nicename' => $this->get_tag($c, 'wp:category_nicename'),
605
+ 'category_parent' => $this->get_tag($c, 'wp:category_parent'),
606
+ 'category_description' => $this->get_tag($c, 'wp:category_description'),
607
+ );
608
+ }
609
+
610
+ function process_tag($t) {
611
+ return array(
612
+ 'term_id' => $this->get_tag($t, 'wp:term_id'),
613
+ 'tag_name' => $this->get_tag($t, 'wp:tag_name'),
614
+ 'tag_slug' => $this->get_tag($t, 'wp:tag_slug'),
615
+ 'tag_description' => $this->get_tag($t, 'wp:tag_description'),
616
+ );
617
+ }
618
+
619
+ function process_term($t) {
620
+ return array(
621
+ 'term_id' => $this->get_tag($t, 'wp:term_id'),
622
+ 'term_taxonomy' => $this->get_tag($t, 'wp:term_taxonomy'),
623
+ 'slug' => $this->get_tag($t, 'wp:term_slug'),
624
+ 'term_parent' => $this->get_tag($t, 'wp:term_parent'),
625
+ 'term_name' => $this->get_tag($t, 'wp:term_name'),
626
+ 'term_description' => $this->get_tag($t, 'wp:term_description'),
627
+ );
628
+ }
629
+
630
+ function process_time_slot($t) {
631
+ return array(
632
+ 'column' => $this->get_tag($t, 'column'),
633
+ 'event' => $this->get_tag($t, 'event'),
634
+ 'event_start' => $this->get_tag($t, 'event_start'),
635
+ 'event_end' => $this->get_tag($t, 'event_end'),
636
+ 'user_id' => $this->get_tag($t, 'user_id'),
637
+ 'description' => $this->get_tag($t, 'description'),
638
+ );
639
+ }
640
+
641
+ function process_author($a) {
642
+ return array(
643
+ 'author_id' => $this->get_tag($a, 'wp:author_id'),
644
+ 'author_login' => $this->get_tag($a, 'wp:author_login'),
645
+ 'author_email' => $this->get_tag($a, 'wp:author_email'),
646
+ 'author_display_name' => $this->get_tag($a, 'wp:author_display_name'),
647
+ 'author_first_name' => $this->get_tag($a, 'wp:author_first_name'),
648
+ 'author_last_name' => $this->get_tag($a, 'wp:author_last_name'),
649
+ );
650
+ }
651
+
652
+ function process_post($post) {
653
+ $post_id = $this->get_tag($post, 'wp:post_id');
654
+ $post_title = $this->get_tag($post, 'title');
655
+ $post_date = $this->get_tag($post, 'wp:post_date');
656
+ $post_date_gmt = $this->get_tag($post, 'wp:post_date_gmt');
657
+ $comment_status = $this->get_tag($post, 'wp:comment_status');
658
+ $ping_status = $this->get_tag($post, 'wp:ping_status');
659
+ $status = $this->get_tag($post, 'wp:status');
660
+ $post_name = $this->get_tag($post, 'wp:post_name');
661
+ $post_parent = $this->get_tag($post, 'wp:post_parent');
662
+ $menu_order = $this->get_tag($post, 'wp:menu_order');
663
+ $post_type = $this->get_tag($post, 'wp:post_type');
664
+ $post_password = $this->get_tag($post, 'wp:post_password');
665
+ $is_sticky = $this->get_tag($post, 'wp:is_sticky');
666
+ $guid = $this->get_tag($post, 'guid');
667
+ $post_author = $this->get_tag($post, 'dc:creator');
668
+
669
+ $post_excerpt = $this->get_tag($post, 'excerpt:encoded');
670
+ $post_excerpt = preg_replace_callback('|<(/?[A-Z]+)|', array(&$this, '_normalize_tag'), $post_excerpt);
671
+ $post_excerpt = str_replace('<br>', '<br />', $post_excerpt);
672
+ $post_excerpt = str_replace('<hr>', '<hr />', $post_excerpt);
673
+
674
+ $post_content = $this->get_tag($post, 'content:encoded');
675
+ $post_content = preg_replace_callback('|<(/?[A-Z]+)|', array(&$this, '_normalize_tag'), $post_content);
676
+ $post_content = str_replace('<br>', '<br />', $post_content);
677
+ $post_content = str_replace('<hr>', '<hr />', $post_content);
678
+
679
+ $postdata = compact('post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt',
680
+ 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent',
681
+ 'menu_order', 'post_type', 'post_password', 'is_sticky'
682
+ );
683
+
684
+ $attachment_url = $this->get_tag($post, 'wp:attachment_url');
685
+ if ($attachment_url)
686
+ $postdata['attachment_url'] = $attachment_url;
687
+
688
+ preg_match_all('|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER);
689
+ foreach ($terms as $t) {
690
+ $post_terms[] = array(
691
+ 'slug' => $t[2],
692
+ 'domain' => $t[1],
693
+ 'name' => str_replace(array('<![CDATA[', ']]>'), '', $t[3]),
694
+ );
695
+ }
696
+ if (!empty($post_terms)) $postdata['terms'] = $post_terms;
697
+
698
+ preg_match_all('|<wp:comment>(.+?)</wp:comment>|is', $post, $comments);
699
+ $comments = $comments[1];
700
+ if ($comments) {
701
+ foreach ($comments as $comment) {
702
+ preg_match_all('|<wp:commentmeta>(.+?)</wp:commentmeta>|is', $comment, $commentmeta);
703
+ $commentmeta = $commentmeta[1];
704
+ $c_meta = array();
705
+ foreach ($commentmeta as $m) {
706
+ $c_meta[] = array(
707
+ 'key' => $this->get_tag($m, 'wp:meta_key'),
708
+ 'value' => $this->get_tag($m, 'wp:meta_value'),
709
+ );
710
+ }
711
+
712
+ $post_comments[] = array(
713
+ 'comment_id' => $this->get_tag($comment, 'wp:comment_id'),
714
+ 'comment_author' => $this->get_tag($comment, 'wp:comment_author'),
715
+ 'comment_author_email' => $this->get_tag($comment, 'wp:comment_author_email'),
716
+ 'comment_author_IP' => $this->get_tag($comment, 'wp:comment_author_IP'),
717
+ 'comment_author_url' => $this->get_tag($comment, 'wp:comment_author_url'),
718
+ 'comment_date' => $this->get_tag($comment, 'wp:comment_date'),
719
+ 'comment_date_gmt' => $this->get_tag($comment, 'wp:comment_date_gmt'),
720
+ 'comment_content' => $this->get_tag($comment, 'wp:comment_content'),
721
+ 'comment_approved' => $this->get_tag($comment, 'wp:comment_approved'),
722
+ 'comment_type' => $this->get_tag($comment, 'wp:comment_type'),
723
+ 'comment_parent' => $this->get_tag($comment, 'wp:comment_parent'),
724
+ 'comment_user_id' => $this->get_tag($comment, 'wp:comment_user_id'),
725
+ 'commentmeta' => $c_meta,
726
+ );
727
+ }
728
+ }
729
+ if (!empty($post_comments)) $postdata['comments'] = $post_comments;
730
+
731
+ preg_match_all('|<wp:postmeta>(.+?)</wp:postmeta>|is', $post, $postmeta);
732
+ $postmeta = $postmeta[1];
733
+ if ($postmeta) {
734
+ foreach ($postmeta as $p) {
735
+ $post_postmeta[] = array(
736
+ 'key' => $this->get_tag($p, 'wp:meta_key'),
737
+ 'value' => $this->get_tag($p, 'wp:meta_value'),
738
+ );
739
+ }
740
+ }
741
+ if (!empty($post_postmeta)) $postdata['postmeta'] = $post_postmeta;
742
+
743
+ preg_match_all('|<wp:timeslot>(.+?)</wp:timeslot>|is', $post, $timeslot);
744
+ $timeslot = $timeslot[1];
745
+ if ($timeslot) {
746
+ foreach ($timeslot as $p) {
747
+ $post_ptimeslot[] = array(
748
+ 'column' => $this->get_tag($p, 'wp:column'),
749
+ 'event' => $this->get_tag($p, 'wp:event'),
750
+ 'event_start' => $this->get_tag($p, 'wp:event_start'),
751
+ 'event_end' => $this->get_tag($p, 'wp:event_end'),
752
+ 'user_id' => $this->get_tag($p, 'wp:user_id'),
753
+ 'description' => $this->get_tag($p, 'wp:description')
754
+ );
755
+ }
756
+ }
757
+ if (!empty($post_timeslot)) $postdata['timeslot'] = $post_timeslot;
758
+
759
+ return $postdata;
760
+ }
761
+
762
+ function _normalize_tag($matches) {
763
+ return '<' . strtolower($matches[1]);
764
+ }
765
+
766
+ function fopen($filename, $mode = 'r') {
767
+ if ($this->has_gzip)
768
+ return gzopen($filename, $mode);
769
+ return fopen($filename, $mode);
770
+ }
771
+
772
+ function feof($fp) {
773
+ if ($this->has_gzip)
774
+ return gzeof($fp);
775
+ return feof($fp);
776
+ }
777
+
778
+ function fgets($fp, $len = 8192) {
779
+ if ($this->has_gzip)
780
+ return gzgets($fp, $len);
781
+ return fgets($fp, $len);
782
+ }
783
+
784
+ function fclose($fp) {
785
+ if ($this->has_gzip)
786
+ return gzclose($fp);
787
+ return fclose($fp);
788
+ }
789
+ }
classes/models/class-events.php CHANGED
@@ -1,897 +1,897 @@
1
- <?php
2
-
3
- namespace mp_timetable\classes\models;
4
-
5
- use mp_timetable\plugin_core\classes\Model as Model;
6
- use mp_timetable\plugin_core\classes\modules\Taxonomy;
7
-
8
-
9
- /**
10
- * Model Events
11
- */
12
- class Events extends Model {
13
-
14
- protected static $instance;
15
- protected $wpdb;
16
- protected $table_name;
17
- protected $post_type;
18
-
19
- /**
20
- * Events constructor.
21
- */
22
- function __construct() {
23
- parent::__construct();
24
- global $wpdb;
25
- $this->wpdb = $wpdb;
26
- $this->post_type = 'mp-event';
27
- $this->taxonomy_names = array(
28
- 'tag' => 'mp-event_tag',
29
- 'cat' => 'mp-event_category',
30
- );
31
- $this->table_name = $wpdb->prefix . "mp_timetable_data";
32
- }
33
-
34
- /**
35
- * @return Events
36
- */
37
- public static function get_instance() {
38
- if ( null === self::$instance ) {
39
- self::$instance = new self();
40
- }
41
-
42
- return self::$instance;
43
- }
44
-
45
- /**
46
- * Getter
47
- *
48
- * @param $property
49
- *
50
- * @return mixed
51
- */
52
- function __get( $property ) {
53
- return $this->{$property};
54
- }
55
-
56
- /**
57
- * Setter
58
- *
59
- * @param $property
60
- * @param $value
61
- *
62
- * @return mixed
63
- */
64
- function __set( $property, $value ) {
65
- return $this->{$property} = $value;
66
- }
67
-
68
- /**
69
- * Render event metabox
70
- *
71
- * @param $post
72
- * @param $metabox
73
- */
74
- public function render_event_data( $post, $metabox ) {
75
-
76
- $time_format = get_option( 'time_format' );
77
- if ( $time_format === 'H:i' ) {
78
- $time_format_array = array( 'hours' => '0,23', 'am_pm' => false );
79
- } elseif ( $time_format === 'g:i A' ) {
80
- $time_format_array = array( 'hours' => '1,12', 'am_pm' => true );
81
- } else {
82
- $time_format_array = array( 'hours' => '0,23', 'am_pm' => false );
83
- }
84
-
85
- $data[ 'columns' ] = $this->get( 'column' )->get_all_column();
86
- $event_data = $this->get_event_data( array( 'field' => 'event_id', 'id' => $post->ID ), 'event_start', false );
87
-
88
- $this->get_view()->render_html( "events/metabox-event-data", array( 'event_data' => $event_data, 'args' => $metabox[ 'args' ],
89
- 'columns' => $data[ 'columns' ], 'date' => array( 'time_format' => $time_format_array ) ), true );
90
- }
91
-
92
- /**
93
- *
94
- * Get single event data by id
95
- *
96
- * @param $params
97
- * @param string $order_by
98
- * @param bool $publish
99
- *
100
- * @return array|null|object
101
- */
102
- public function get_event_data( $params, $order_by = 'event_start', $publish = true ) {
103
- $publish_query_part = $publish ? " AND `post_status` = 'publish'" : '';
104
- $table_posts = $this->wpdb->prefix . 'posts';
105
-
106
- $event_data = $this->wpdb->get_results(
107
- "SELECT t.*"
108
- . " FROM $this->table_name t INNER JOIN"
109
- . " ("
110
- . " SELECT * FROM {$table_posts}"
111
- . " WHERE `post_type` = 'mp-column' AND `post_status` = 'publish'"
112
- . " ) p ON t.`column_id` = p.`ID`"
113
- . " INNER JOIN ("
114
- . " SELECT * FROM {$table_posts}"
115
- . " WHERE `post_type` = '{$this->post_type}'{$publish_query_part}"
116
- . " ) e ON t.`event_id` = e.`ID`"
117
- . " WHERE t.`{$params["field"]}` = {$params['id']} "
118
- . " ORDER BY p.`menu_order`, t.`{$order_by}`"
119
- );
120
-
121
- foreach ( $event_data as $key => $event ) {
122
- $event_data[ $key ]->event_start = date( 'H:i', strtotime( $event_data[ $key ]->event_start ) );
123
- $event_data[ $key ]->event_end = date( 'H:i', strtotime( $event_data[ $key ]->event_end ) );
124
- $event_data[ $key ]->user = get_user_by( 'id', $event_data[ $key ]->user_id );
125
- $event_data[ $key ]->post = get_post( $event_data[ $key ]->event_id );
126
- $event_data[ $key ]->description = stripcslashes( $event_data[ $key ]->description );
127
- }
128
-
129
- return $event_data;
130
- }
131
-
132
- /**
133
- * Render meta data
134
- */
135
- public function render_event_metas() {
136
- $this->append_time_slots();
137
- }
138
-
139
- /**
140
- * Render Timeslots by $post
141
- */
142
- public function append_time_slots() {
143
- global $post;
144
-
145
- $show_public_only = ( ( get_post_status( $post->ID ) == 'draft' ) && is_preview() ) ? false : true;
146
-
147
- $data = $this->get_event_data( array( 'field' => 'event_id', 'id' => $post->ID ), 'event_start', $show_public_only );
148
- $event_data = ( ! empty( $data ) ) ? $data : array();
149
- $count = count( $event_data );
150
-
151
- $this->get_view()->get_template( "theme/event-timeslots", array( 'events' => $event_data, 'count' => $count ) );
152
- }
153
-
154
- /**
155
- * Render event options
156
- *
157
- * @param $post
158
- */
159
- public function render_event_options( $post ) {
160
- $this->get_view()->render_html( "events/metabox-event-options", array( 'post' => $post ), true );
161
- }
162
-
163
- /**
164
- * Add column
165
- *
166
- * @param $columns
167
- *
168
- * @return array
169
- */
170
- public function set_event_columns( $columns ) {
171
- $columns = array_slice( $columns, 0, 2, true ) + array( $this->taxonomy_names[ 'tag' ] => __( 'Tags', 'mp-timetable' ) ) + array_slice( $columns, 2, count( $columns ) - 1, true );
172
- $columns = array_slice( $columns, 0, 2, true ) + array( $this->taxonomy_names[ 'cat' ] => __( 'Categories', 'mp-timetable' ) ) + array_slice( $columns, 2, count( $columns ) - 1, true );
173
-
174
- return $columns;
175
- }
176
-
177
- /**
178
- * Create event category admin link
179
- *
180
- * @param $column
181
- */
182
- public function get_event_taxonomy( $column ) {
183
- global $post;
184
- if ( $column === $this->taxonomy_names[ 'cat' ] ) {
185
- echo Taxonomy::get_instance()->get_the_term_filter_list( $post, $this->taxonomy_names[ 'cat' ] );
186
- }
187
- if ( $column === $this->taxonomy_names[ 'tag' ] ) {
188
- echo Taxonomy::get_instance()->get_the_term_filter_list( $post, $this->taxonomy_names[ 'tag' ] );
189
- }
190
- }
191
-
192
- /**
193
- * Output category post
194
- *
195
- * @param string $the_list
196
- * @param string $separator
197
- * @param string $parents
198
- *
199
- * @return mixed
200
- */
201
- public function the_category( $the_list = '', $separator = '', $parents = '' ) {
202
- global $post;
203
-
204
- if ( $post && $post->post_type === $this->post_type && ! is_admin() ) {
205
- $categories = wp_get_post_terms( $post->ID, $this->taxonomy_names[ 'cat' ] );
206
- $the_list .= $this->generate_event_tags( $categories, $separator, $parents );
207
- }
208
-
209
- /**
210
- * Filter the category or list of Timetable categories.
211
- *
212
- * @param array $thelist List of categories for the current post.
213
- * @param string $separator Separator used between the categories.
214
- * @param string $parents How to display the category parents. Accepts 'multiple',
215
- * 'single', or empty.
216
- */
217
- return apply_filters( 'mptt_the_category', $the_list, $separator, $parents );
218
- }
219
-
220
- /**
221
- * Generate HTML of the post tags
222
- *
223
- * @param $categories
224
- * @param $separator
225
- * @param $parents
226
- *
227
- * @return string
228
- */
229
- public function generate_event_tags( $categories, $separator, $parents ) {
230
- global $wp_rewrite;
231
- $the_list = '';
232
- $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
233
-
234
- if ( '' == $separator ) {
235
- $the_list .= '<ul class="post-categories">';
236
- foreach ( $categories as $category ) {
237
- $the_list .= "\n\t<li>";
238
- switch ( strtolower( $parents ) ) {
239
- case 'multiple':
240
- if ( $category->parent ) {
241
- $the_list .= get_category_parents( $category->parent, true, $separator );
242
- }
243
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
244
- break;
245
- case 'single':
246
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
247
- if ( $category->parent ) {
248
- $the_list .= get_category_parents( $category->parent, false, $separator );
249
- }
250
- $the_list .= $category->name . '</a></li>';
251
- break;
252
- case '':
253
- default:
254
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
255
- }
256
- }
257
- $the_list .= '</ul>';
258
- } else {
259
- $i = 0;
260
- foreach ( $categories as $category ) {
261
- if ( 0 < $i ) {
262
- $the_list .= $separator;
263
- }
264
- switch ( strtolower( $parents ) ) {
265
- case 'multiple':
266
- if ( $category->parent ) {
267
- $the_list .= get_category_parents( $category->parent, true, $separator );
268
- }
269
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
270
- break;
271
- case 'single':
272
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
273
- if ( $category->parent ) {
274
- $the_list .= get_category_parents( $category->parent, false, $separator );
275
- }
276
- $the_list .= "$category->name</a>";
277
- break;
278
- case '':
279
- default:
280
- $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
281
- }
282
- ++ $i;
283
- }
284
- }
285
-
286
- return $the_list;
287
- }
288
-
289
- /**
290
- * Returns a formatted tags.
291
- *
292
- * @param $tags
293
- * @param string $before
294
- * @param string $sep
295
- * @param string $after
296
- * @param int $id
297
- *
298
- * @return mixed
299
- */
300
- public function the_tags( $tags, $before = '', $sep = '', $after = '', $id = 0 ) {
301
- global $post;
302
-
303
- if ( $post && $post->post_type === $this->post_type ) {
304
- $id = ( $id === 0 ) ? $post->id : $id;
305
- $events_tags = get_the_term_list( $id, $this->taxonomy_names[ 'tag' ], $before, $sep, $after );
306
- $tags = apply_filters( 'mptt_the_tags', $events_tags, $tags );
307
- }
308
-
309
- return $tags;
310
- }
311
-
312
- /**
313
- * Save(insert) event data
314
- *
315
- * @param array $params
316
- *
317
- * @return array
318
- */
319
- public function save_event_data( array $params ) {
320
-
321
- $rows_affected = array();
322
-
323
- if ( ! empty( $params[ 'event_data' ] ) ) {
324
- foreach ( $params[ 'event_data' ] as $key => $event ) {
325
- if ( is_array( $event[ 'event_start' ] ) && ! empty( $event[ 'event_start' ] ) ) {
326
-
327
- for ( $i = 0; $i < count( $event[ 'event_start' ] ); $i ++ ) {
328
- $rows_affected[] = $this->wpdb->insert( $this->table_name, array(
329
- 'column_id' => $key,
330
- 'event_id' => $params[ 'post' ]->ID,
331
- 'event_start' => date( 'H:i', strtotime( $event[ 'event_start' ][ $i ] ) ),
332
- 'event_end' => date( 'H:i', strtotime( $event[ 'event_end' ][ $i ] ) ),
333
- 'user_id' => $event[ 'user_id' ][ $i ],
334
- 'description' => $event[ 'description' ][ $i ]
335
- )
336
- );
337
- }
338
- }
339
- }
340
- }
341
- if ( ! empty( $params[ 'event_meta' ] ) ) {
342
- foreach ( $params[ 'event_meta' ] as $meta_key => $meta ) {
343
- update_post_meta( $params[ 'post' ]->ID, $meta_key, $meta );
344
- }
345
- }
346
-
347
- return $rows_affected;
348
- }
349
-
350
- /**
351
- * Delete event timeslot
352
- *
353
- * @param $id
354
- *
355
- * @return false|int
356
- */
357
- public function delete_event( $id ) {
358
- return $this->wpdb->delete( $this->table_name, array( 'id' => $id ), array( '%d' ) );
359
- }
360
-
361
- /**
362
- * Delete event data
363
- *
364
- * @param $post_id
365
- *
366
- * @return false|int
367
- */
368
- public function before_delete_event( $post_id ) {
369
- $meta_keys = array( 'event_id', 'event_start', 'event_end', 'user_id', 'description' );
370
-
371
- foreach ( $meta_keys as $meta_key ) {
372
- delete_post_meta( $post_id, $meta_key );
373
- }
374
-
375
- return $this->wpdb->delete( $this->table_name, array( 'event_id' => $post_id ), array( '%d' ) );
376
- }
377
-
378
- /**
379
- * Get widget events
380
- *
381
- * @param $instance
382
- *
383
- * @return array
384
- */
385
- public function get_widget_events( $instance ) {
386
- $events = array();
387
- $current_local_time = current_time( 'timestamp' );
388
-
389
- $weekday = strtolower( date( 'l', $current_local_time ) );
390
- $current_date = date( 'd/m/Y', $current_local_time );
391
-
392
- // 24.09.2019 seconds added
393
- $curent_time = date( 'H:i:s', $current_local_time );
394
-
395
- if ( ! empty( $instance[ 'mp_categories' ] ) ) {
396
- $category_columns_ids = $this->get( 'column' )->get_columns_by_event_category( $instance[ 'mp_categories' ] );
397
- }
398
-
399
- $args = array(
400
- 'post_type' => 'mp-column',
401
- 'post_status' => 'publish',
402
- 'fields' => 'ids',
403
- 'post__in' => ! empty( $category_columns_ids ) ? $category_columns_ids : '',
404
- 'orderby' => 'menu_order',
405
- 'meta_query' => array(
406
- 'relation' => 'OR',
407
- array(
408
- 'key' => 'weekday',
409
- 'value' => $weekday
410
- ),
411
- array(
412
- 'key' => 'option_day',
413
- 'value' => $current_date
414
- )
415
- )
416
- );
417
-
418
- switch ( $instance[ 'view_settings' ] ) {
419
- case'today':
420
- case 'current':
421
- $column_post_ids = get_posts( $args );
422
- if ( ! empty( $column_post_ids ) ) {
423
- $events = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
424
- }
425
- $events = $this->filter_events( array( 'events' => $events, 'view_settings' => $instance[ 'view_settings' ], 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
426
- break;
427
- case 'all':
428
-
429
- if ( ! empty( $instance[ 'next_days' ] ) && $instance[ 'next_days' ] > 0 ) {
430
- $events_array = array();
431
- for ( $i = 0; $i <= $instance[ 'next_days' ]; $i ++ ) {
432
-
433
- // set new day week
434
- $time = strtotime( "+$i days", $current_local_time );
435
- $day = strtolower( date( 'l', $time ) );
436
- $date = date( 'd/m/Y', $time );
437
-
438
- //set week day
439
- $args[ 'meta_query' ][ 0 ][ 'value' ] = $day;
440
- //set new date
441
- $args[ 'meta_query' ][ 1 ][ 'value' ] = $date;
442
-
443
- $column_post_ids = get_posts( $args );
444
-
445
- if ( ! empty( $column_post_ids ) ) {
446
- $events_array[ $i ] = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
447
- } else {
448
- $events_array[ $i ] = array();
449
- }
450
-
451
- // Filter by time and categories for current day
452
- if ( $i === 0 && ! empty( $instance[ 'mp_categories' ] ) && ! empty( $events_array[ $i ] ) ) {
453
- $events_array[ $i ] = $events_array[ $i ] = $this->filter_events( array( 'events' => $events_array[ $i ], 'view_settings' => 'today', 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
454
- } elseif ( ! empty( $instance[ 'mp_categories' ] ) && ! empty( $events_array[ $i ] ) ) {
455
- //Filter by categories for next days
456
- $events_array[ $i ] = $this->filter_events_by_categories( $events_array[ $i ], $instance[ 'mp_categories' ] );
457
- }
458
-
459
- }
460
-
461
- foreach ( $events_array as $day_events ) {
462
- $events = array_merge( $events, $day_events );
463
- }
464
-
465
- }
466
-
467
- break;
468
-
469
- default:
470
- $column_post_ids = get_posts( $args );
471
- if ( ! empty( $column_post_ids ) ) {
472
- $events = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
473
- }
474
- $events = $this->filter_events( array( 'events' => $events, 'view_settings' => 'today', 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
475
-
476
- break;
477
- }
478
- if ( $instance[ 'limit' ] > 0 ) {
479
- $events = array_slice( $events, 0, $instance[ 'limit' ] );
480
- }
481
-
482
- return $events;
483
- }
484
-
485
- /**
486
- * Get event data by post
487
- *
488
- * @param array $params
489
- *
490
- * @return array
491
- */
492
- public function get_events_data( array $params ) {
493
- $events = array();
494
- $sql_request = "SELECT * FROM " . $this->table_name;
495
-
496
- if ( ( ! empty( $params[ 'all' ] ) && $params[ 'all' ] ) || empty( $params[ 'list' ] ) ) {
497
-
498
- } elseif ( ! is_array( $params[ 'column' ] ) ) {
499
-
500
- if ( isset( $params[ 'list' ] ) && is_array( $params[ 'list' ] ) ) {
501
- $params[ 'list' ] = implode( ',', $params[ 'list' ] );
502
- }
503
-
504
- $sql_request .= " WHERE " . $params[ 'column' ] . " IN (" . $params[ 'list' ] . ")";
505
-
506
- } elseif ( is_array( $params[ 'column' ] ) && is_array( $params[ 'list' ] ) ) {
507
-
508
- $sql_request .= " WHERE ";
509
-
510
- $last_key = key( array_slice( $params[ 'column' ], - 1, 1, true ) );
511
-
512
- foreach ( $params[ 'column' ] as $key => $column ) {
513
- if ( isset( $params[ 'list' ][ $column ] ) && is_array( $params[ 'list' ][ $column ] ) ) {
514
- $params[ 'list' ][ $column ] = implode( ',', $params[ 'list' ][ $column ] );
515
- }
516
- $sql_request .= $column . " IN (" . $params[ 'list' ][ $column ] . ")";
517
- $sql_request .= ( $last_key != $key ) ? ' AND ' : '';
518
- }
519
-
520
- }
521
-
522
- $sql_request .= ' ORDER BY `event_start`';
523
-
524
- $events_data = $this->wpdb->get_results( $sql_request );
525
-
526
- if ( is_array( $events_data ) ) {
527
-
528
- foreach ( $events_data as $event ) {
529
- $post = get_post( $event->event_id );
530
-
531
- if ( $post && ( $post->post_type == $this->post_type ) && ( $post->post_status == 'publish' ) ) {
532
- $event->post = $post;
533
- $event->event_start = date( 'H:i', strtotime( $event->event_start ) );
534
- $event->event_end = date( 'H:i', strtotime( $event->event_end ) );
535
- $events[] = $event;
536
- }
537
- }
538
- }
539
-
540
- return $events;
541
- }
542
-
543
- /**
544
- * Filtered events by view settings
545
- *
546
- * @param $params
547
- *
548
- * @return array
549
- */
550
- protected function filter_events( $params ) {
551
-
552
- $events = array();
553
- $events = $this->filter_by_time_period( $params, $events );
554
-
555
- if ( ! empty( $params[ 'mp_categories' ] ) ) {
556
- $events = $this->filter_events_by_categories( $events, $params[ 'mp_categories' ] );
557
- }
558
-
559
- return $events;
560
- }
561
-
562
- /**
563
- * Filter by time period
564
- *
565
- * @param $params
566
- * @param $events
567
- *
568
- * @return array
569
- */
570
- protected function filter_by_time_period( $params, $events ) {
571
- if ( ! empty( $params[ 'events' ] ) ) {
572
-
573
- $time = strtotime( $params[ 'time' ] );
574
-
575
- foreach ( $params[ 'events' ] as $key => $event ) {
576
-
577
- $event_end = strtotime( $event->event_end );
578
- $event_start = strtotime( $event->event_start );
579
-
580
- if ( $params[ 'view_settings' ] === 'today' || $params[ 'view_settings' ] === 'all' ) {
581
- if ( $event_end <= $time ) {
582
- continue;
583
- }
584
- } elseif ( $params[ 'view_settings' ] === 'current' ) {
585
- if ( $event_start >= $time || $event_end <= $time ) {
586
- continue;
587
- }
588
- }
589
- $events[ $key ] = $event;
590
- }
591
- }
592
-
593
- return $events;
594
- }
595
-
596
- /**
597
- * Filter find events by select categories;
598
- *
599
- * @param array $events
600
- * @param array $categories
601
- *
602
- * @return array
603
- */
604
- public function filter_events_by_categories( array $events, array $categories ) {
605
- $temp_events = array();
606
- $taxonomy = $this->taxonomy_names[ 'cat' ];
607
-
608
- foreach ( $events as $event ) {
609
- if ( @has_term( $categories, $taxonomy, $event->post->ID ) ) {
610
- $temp_events[] = $event;
611
- }
612
- }
613
-
614
- return $temp_events;
615
- }
616
-
617
- /**
618
- * Sort by params
619
- *
620
- * @param $events
621
- *
622
- * @return mixed
623
- */
624
-
625
- public function sort_by_param( $events ) {
626
-
627
- usort( $events, function ( $a, $b ) {
628
- if ( strtotime( $a->event_start ) == strtotime( $b->event_start ) ) {
629
- return 0;
630
- }
631
-
632
- return ( strtotime( $a->event_start ) < strtotime( $b->event_start ) ) ? - 1 : 1;
633
- } );
634
-
635
-
636
- return $events;
637
- }
638
-
639
- /**
640
- * @param array /string $event_category
641
- *
642
- * @return array|null|object
643
- */
644
- public function get_events_data_by_category( $event_categories ) {
645
- if ( ! is_array( $event_categories ) ) {
646
- $terms = explode( ',', $event_categories );
647
- } else {
648
- $terms = $event_categories;
649
- }
650
-
651
- $posts_array = get_posts(
652
- array(
653
- 'fields' => 'ids',
654
- 'posts_per_page' => - 1,
655
- 'post_type' => $this->post_type,
656
- 'post_status' => 'publish',
657
- 'tax_query' => array(
658
- array(
659
- 'taxonomy' => 'mp-event_category',
660
- 'field' => 'term_id',
661
- 'terms' => $terms,
662
- )
663
- )
664
- )
665
- );
666
-
667
- $ids = implode( ',', $posts_array );
668
- $event_data = $this->get_events_data( array( 'column' => 'event_id', 'list' => $ids ) );
669
-
670
- return $event_data;
671
- }
672
-
673
- /**
674
- * Update event data
675
- *
676
- * @param $data
677
- *
678
- * @return false|int
679
- */
680
- public function update_event_data( $data ) {
681
- $result = $this->wpdb->update(
682
- $this->table_name,
683
- array(
684
- 'event_start' => date( 'H:i', strtotime( $data[ 'event_start' ] ) ),
685
- 'event_end' => date( 'H:i', strtotime( $data[ 'event_end' ] ) ),
686
- 'description' => $data[ 'description' ],
687
- 'column_id' => $data[ 'weekday_ids' ],
688
- 'user_id' => $data[ 'user_id' ],
689
- ),
690
- array( 'id' => $data[ 'id' ] ),
691
- array(
692
- '%s',
693
- '%s',
694
- '%s',
695
- '%d',
696
- '%d',
697
- ),
698
- array( '%d' )
699
- );
700
-
701
- return $result;
702
- }
703
-
704
- /**
705
- * Get all events
706
- * @return array
707
- */
708
- public function get_all_events() {
709
- $args = array(
710
- 'post_type' => $this->post_type,
711
- 'post_status' => 'publish',
712
- 'order' => 'ASC',
713
- 'orderby' => 'title',
714
- 'posts_per_page' => - 1
715
- );
716
-
717
- return get_posts( $args );
718
- }
719
-
720
- /**
721
- * Choose color widget or event
722
- *
723
- * @param $params
724
- *
725
- * @return string
726
- */
727
-
728
- public function choose_event_color( $params ) {
729
- if ( ! empty( $params[ 'widget_color' ] ) ) {
730
- return $params[ 'widget_color' ];
731
- } elseif ( ! empty( $params[ 'event_color' ] ) ) {
732
- return $params[ 'event_color' ];
733
- } else {
734
- return '';
735
- }
736
- }
737
-
738
- /**
739
- * Filtered events by Event Head
740
- *
741
- * @param $params
742
- *
743
- * @return array
744
- */
745
- protected function filter_events_by_field( $params ) {
746
- $events = array();
747
- if ( ! empty( $params[ 'events' ] ) ) {
748
- foreach ( $params[ 'events' ] as $key => $event ) {
749
- if ( $event->$params[ 'field' ] != $params[ 'value' ] ) {
750
- continue;
751
- }
752
-
753
- $events[ $key ] = $event;
754
- }
755
- }
756
-
757
- return $events;
758
- }
759
-
760
- public function post_row_actions( $actions, $post ) {
761
-
762
- if ( $post->post_type == $this->post_type && current_user_can('edit_posts') ) {
763
-
764
- $action_url = add_query_arg(
765
- array(
766
- 'post' => $post->ID,
767
- 'action' => 'mptt_duplicate_event',
768
- '_wpnonce' => wp_create_nonce( 'mptt_duplicate_event' )
769
- ),
770
- admin_url( 'post.php' )
771
- );
772
-
773
- $actions['duplicate'] = '<a href="' . $action_url . '" aria-label="' .
774
- __('Duplicate', 'mp-timetable') . '" rel="permalink">' . __('Duplicate', 'mp-timetable') . '</a>';
775
- }
776
-
777
- return $actions;
778
- }
779
-
780
- public function post_action_mptt_duplicate_event( $post_id ) {
781
-
782
- global $wpdb;
783
-
784
- $post_type = '';
785
-
786
- if ( $post_id ) {
787
- $post = get_post( $post_id );
788
- }
789
-
790
- if ( $post ) {
791
- $post_type = $post->post_type;
792
- }
793
-
794
- if ( $post_type !== $this->post_type ) {
795
- wp_die( __( 'A post type mismatch has been detected.' ), __( 'Sorry, you are not allowed to edit this item.' ), 400 );
796
- }
797
-
798
- $nonce = $_REQUEST['_wpnonce'];
799
-
800
- if ( wp_verify_nonce( $nonce, 'mptt_duplicate_event' ) && current_user_can('edit_posts') ) {
801
-
802
- $current_user = wp_get_current_user();
803
- $new_post_author = $current_user->ID;
804
-
805
- /*
806
- * new post data array
807
- */
808
- $args = array(
809
- 'comment_status' => $post->comment_status,
810
- 'ping_status' => $post->ping_status,
811
- 'post_author' => $new_post_author,
812
- 'post_content' => $post->post_content,
813
- 'post_excerpt' => $post->post_excerpt,
814
- 'post_name' => $post->post_name,
815
- 'post_parent' => $post->post_parent,
816
- 'post_password' => $post->post_password,
817
- 'post_status' => 'draft',
818
- // translators: New post title of the duplicated post
819
- 'post_title' => sprintf( __('%s - Copy', 'mp-timetable'), $post->post_title ),
820
- 'post_type' => $post->post_type,
821
- 'to_ping' => $post->to_ping,
822
- 'menu_order' => $post->menu_order
823
- );
824
-
825
- /*
826
- * insert the post by wp_insert_post() function
827
- */
828
- $new_post_id = wp_insert_post( $args );
829
-
830
- if( is_wp_error($new_post_id) ) {
831
- wp_die( $post_id->get_error_message() );
832
- }
833
-
834
- /*
835
- * get all current post terms and set them to the new post draft
836
- */
837
- $taxonomies = get_object_taxonomies($post->post_type);
838
- foreach ($taxonomies as $taxonomy) {
839
- $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
840
- wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
841
- }
842
-
843
- /*
844
- * duplicate all post meta
845
- */
846
- $post_meta = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
847
-
848
- if ( !empty($post_meta) ) {
849
-
850
- $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
851
-
852
- foreach ($post_meta as $meta_info) {
853
- $meta_key = $meta_info->meta_key;
854
- if ( $meta_key == '_wp_old_slug' ) continue;
855
- $meta_value = addslashes($meta_info->meta_value);
856
- $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
857
- }
858
-
859
- $sql_query .= implode( " UNION ALL ", $sql_query_sel );
860
-
861
- $wpdb->query( $sql_query );
862
- }
863
-
864
- /*
865
- * duplicate timeslots in custom BD
866
- */
867
- $timeslots = $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE event_id = " . $post_id, OBJECT );
868
-
869
- if ( !empty($timeslots) ) {
870
-
871
- foreach ( $timeslots as $timeslot ) {
872
- $wpdb->insert(
873
- $this->table_name,
874
- array(
875
- 'column_id' => $timeslot->column_id,
876
- 'event_id' => $new_post_id,
877
- 'event_start' => date( 'H:i', strtotime( $timeslot->event_start ) ),
878
- 'event_end' => date( 'H:i', strtotime( $timeslot->event_end ) ),
879
- 'user_id' => $timeslot->user_id,
880
- 'description' => $timeslot->description
881
- )
882
- );
883
- }
884
- }
885
-
886
- /*
887
- * redirect to the edit post screen for the new draft
888
- */
889
- wp_safe_redirect( get_edit_post_link( $new_post_id, '' ) );
890
- exit();
891
-
892
- } else {
893
- wp_die( __( 'Sorry, you are not allowed to edit this item.' ) );
894
- }
895
- }
896
-
897
- }
1
+ <?php
2
+
3
+ namespace mp_timetable\classes\models;
4
+
5
+ use mp_timetable\plugin_core\classes\Model as Model;
6
+ use mp_timetable\plugin_core\classes\modules\Taxonomy;
7
+
8
+
9
+ /**
10
+ * Model Events
11
+ */
12
+ class Events extends Model {
13
+
14
+ protected static $instance;
15
+ protected $wpdb;
16
+ protected $table_name;
17
+ protected $post_type;
18
+
19
+ /**
20
+ * Events constructor.
21
+ */
22
+ function __construct() {
23
+ parent::__construct();
24
+ global $wpdb;
25
+ $this->wpdb = $wpdb;
26
+ $this->post_type = 'mp-event';
27
+ $this->taxonomy_names = array(
28
+ 'tag' => 'mp-event_tag',
29
+ 'cat' => 'mp-event_category',
30
+ );
31
+ $this->table_name = $wpdb->prefix . "mp_timetable_data";
32
+ }
33
+
34
+ /**
35
+ * @return Events
36
+ */
37
+ public static function get_instance() {
38
+ if ( null === self::$instance ) {
39
+ self::$instance = new self();
40
+ }
41
+
42
+ return self::$instance;
43
+ }
44
+
45
+ /**
46
+ * Getter
47
+ *
48
+ * @param $property
49
+ *
50
+ * @return mixed
51
+ */
52
+ function __get( $property ) {
53
+ return $this->{$property};
54
+ }
55
+
56
+ /**
57
+ * Setter
58
+ *
59
+ * @param $property
60
+ * @param $value
61
+ *
62
+ * @return mixed
63
+ */
64
+ function __set( $property, $value ) {
65
+ return $this->{$property} = $value;
66
+ }
67
+
68
+ /**
69
+ * Render event metabox
70
+ *
71
+ * @param $post
72
+ * @param $metabox
73
+ */
74
+ public function render_event_data( $post, $metabox ) {
75
+
76
+ $time_format = get_option( 'time_format' );
77
+ if ( $time_format === 'H:i' ) {
78
+ $time_format_array = array( 'hours' => '0,23', 'am_pm' => false );
79
+ } elseif ( $time_format === 'g:i A' ) {
80
+ $time_format_array = array( 'hours' => '1,12', 'am_pm' => true );
81
+ } else {
82
+ $time_format_array = array( 'hours' => '0,23', 'am_pm' => false );
83
+ }
84
+
85
+ $data[ 'columns' ] = $this->get( 'column' )->get_all_column();
86
+ $event_data = $this->get_event_data( array( 'field' => 'event_id', 'id' => $post->ID ), 'event_start', false );
87
+
88
+ $this->get_view()->render_html( "events/metabox-event-data", array( 'event_data' => $event_data, 'args' => $metabox[ 'args' ],
89
+ 'columns' => $data[ 'columns' ], 'date' => array( 'time_format' => $time_format_array ) ), true );
90
+ }
91
+
92
+ /**
93
+ *
94
+ * Get single event data by id
95
+ *
96
+ * @param $params
97
+ * @param string $order_by
98
+ * @param bool $publish
99
+ *
100
+ * @return array|null|object
101
+ */
102
+ public function get_event_data( $params, $order_by = 'event_start', $publish = true ) {
103
+ $publish_query_part = $publish ? " AND `post_status` = 'publish'" : '';
104
+ $table_posts = $this->wpdb->prefix . 'posts';
105
+
106
+ $event_data = $this->wpdb->get_results(
107
+ "SELECT t.*"
108
+ . " FROM $this->table_name t INNER JOIN"
109
+ . " ("
110
+ . " SELECT * FROM {$table_posts}"
111
+ . " WHERE `post_type` = 'mp-column' AND `post_status` = 'publish'"
112
+ . " ) p ON t.`column_id` = p.`ID`"
113
+ . " INNER JOIN ("
114
+ . " SELECT * FROM {$table_posts}"
115
+ . " WHERE `post_type` = '{$this->post_type}'{$publish_query_part}"
116
+ . " ) e ON t.`event_id` = e.`ID`"
117
+ . " WHERE t.`{$params["field"]}` = {$params['id']} "
118
+ . " ORDER BY p.`menu_order`, t.`{$order_by}`"
119
+ );
120
+
121
+ foreach ( $event_data as $key => $event ) {
122
+ $event_data[ $key ]->event_start = date( 'H:i', strtotime( $event_data[ $key ]->event_start ) );
123
+ $event_data[ $key ]->event_end = date( 'H:i', strtotime( $event_data[ $key ]->event_end ) );
124
+ $event_data[ $key ]->user = get_user_by( 'id', $event_data[ $key ]->user_id );
125
+ $event_data[ $key ]->post = get_post( $event_data[ $key ]->event_id );
126
+ $event_data[ $key ]->description = stripcslashes( $event_data[ $key ]->description );
127
+ }
128
+
129
+ return $event_data;
130
+ }
131
+
132
+ /**
133
+ * Render meta data
134
+ */
135
+ public function render_event_metas() {
136
+ $this->append_time_slots();
137
+ }
138
+
139
+ /**
140
+ * Render Timeslots by $post
141
+ */
142
+ public function append_time_slots() {
143
+ global $post;
144
+
145
+ $show_public_only = ( ( get_post_status( $post->ID ) == 'draft' ) && is_preview() ) ? false : true;
146
+
147
+ $data = $this->get_event_data( array( 'field' => 'event_id', 'id' => $post->ID ), 'event_start', $show_public_only );
148
+ $event_data = ( ! empty( $data ) ) ? $data : array();
149
+ $count = count( $event_data );
150
+
151
+ $this->get_view()->get_template( "theme/event-timeslots", array( 'events' => $event_data, 'count' => $count ) );
152
+ }
153
+
154
+ /**
155
+ * Render event options
156
+ *
157
+ * @param $post
158
+ */
159
+ public function render_event_options( $post ) {
160
+ $this->get_view()->render_html( "events/metabox-event-options", array( 'post' => $post ), true );
161
+ }
162
+
163
+ /**
164
+ * Add column
165
+ *
166
+ * @param $columns
167
+ *
168
+ * @return array
169
+ */
170
+ public function set_event_columns( $columns ) {
171
+ $columns = array_slice( $columns, 0, 2, true ) + array( $this->taxonomy_names[ 'tag' ] => __( 'Tags', 'mp-timetable' ) ) + array_slice( $columns, 2, count( $columns ) - 1, true );
172
+ $columns = array_slice( $columns, 0, 2, true ) + array( $this->taxonomy_names[ 'cat' ] => __( 'Categories', 'mp-timetable' ) ) + array_slice( $columns, 2, count( $columns ) - 1, true );
173
+
174
+ return $columns;
175
+ }
176
+
177
+ /**
178
+ * Create event category admin link
179
+ *
180
+ * @param $column
181
+ */
182
+ public function get_event_taxonomy( $column ) {
183
+ global $post;
184
+ if ( $column === $this->taxonomy_names[ 'cat' ] ) {
185
+ echo Taxonomy::get_instance()->get_the_term_filter_list( $post, $this->taxonomy_names[ 'cat' ] );
186
+ }
187
+ if ( $column === $this->taxonomy_names[ 'tag' ] ) {
188
+ echo Taxonomy::get_instance()->get_the_term_filter_list( $post, $this->taxonomy_names[ 'tag' ] );
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Output category post
194
+ *
195
+ * @param string $the_list
196
+ * @param string $separator
197
+ * @param string $parents
198
+ *
199
+ * @return mixed
200
+ */
201
+ public function the_category( $the_list = '', $separator = '', $parents = '' ) {
202
+ global $post;
203
+
204
+ if ( $post && $post->post_type === $this->post_type && ! is_admin() ) {
205
+ $categories = wp_get_post_terms( $post->ID, $this->taxonomy_names[ 'cat' ] );
206
+ $the_list .= $this->generate_event_tags( $categories, $separator, $parents );
207
+ }
208
+
209
+ /**
210
+ * Filter the category or list of Timetable categories.
211
+ *
212
+ * @param array $thelist List of categories for the current post.
213
+ * @param string $separator Separator used between the categories.
214
+ * @param string $parents How to display the category parents. Accepts 'multiple',
215
+ * 'single', or empty.
216
+ */
217
+ return apply_filters( 'mptt_the_category', $the_list, $separator, $parents );
218
+ }
219
+
220
+ /**
221
+ * Generate HTML of the post tags
222
+ *
223
+ * @param $categories
224
+ * @param $separator
225
+ * @param $parents
226
+ *
227
+ * @return string
228
+ */
229
+ public function generate_event_tags( $categories, $separator, $parents ) {
230
+ global $wp_rewrite;
231
+ $the_list = '';
232
+ $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
233
+
234
+ if ( '' == $separator ) {
235
+ $the_list .= '<ul class="post-categories">';
236
+ foreach ( $categories as $category ) {
237
+ $the_list .= "\n\t<li>";
238
+ switch ( strtolower( $parents ) ) {
239
+ case 'multiple':
240
+ if ( $category->parent ) {
241
+ $the_list .= get_category_parents( $category->parent, true, $separator );
242
+ }
243
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
244
+ break;
245
+ case 'single':
246
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
247
+ if ( $category->parent ) {
248
+ $the_list .= get_category_parents( $category->parent, false, $separator );
249
+ }
250
+ $the_list .= $category->name . '</a></li>';
251
+ break;
252
+ case '':
253
+ default:
254
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a></li>';
255
+ }
256
+ }
257
+ $the_list .= '</ul>';
258
+ } else {
259
+ $i = 0;
260
+ foreach ( $categories as $category ) {
261
+ if ( 0 < $i ) {
262
+ $the_list .= $separator;
263
+ }
264
+ switch ( strtolower( $parents ) ) {
265
+ case 'multiple':
266
+ if ( $category->parent ) {
267
+ $the_list .= get_category_parents( $category->parent, true, $separator );
268
+ }
269
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
270
+ break;
271
+ case 'single':
272
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>';
273
+ if ( $category->parent ) {
274
+ $the_list .= get_category_parents( $category->parent, false, $separator );
275
+ }
276
+ $the_list .= "$category->name</a>";
277
+ break;
278
+ case '':
279
+ default:
280
+ $the_list .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '" ' . $rel . '>' . $category->name . '</a>';
281
+ }
282
+ ++ $i;
283
+ }
284
+ }
285
+
286
+ return $the_list;
287
+ }
288
+
289
+ /**
290
+ * Returns a formatted tags.
291
+ *
292
+ * @param $tags
293
+ * @param string $before
294
+ * @param string $sep
295
+ * @param string $after
296
+ * @param int $id
297
+ *
298
+ * @return mixed
299
+ */
300
+ public function the_tags( $tags, $before = '', $sep = '', $after = '', $id = 0 ) {
301
+ global $post;
302
+
303
+ if ( $post && $post->post_type === $this->post_type ) {
304
+ $id = ( $id === 0 ) ? $post->id : $id;
305
+ $events_tags = get_the_term_list( $id, $this->taxonomy_names[ 'tag' ], $before, $sep, $after );
306
+ $tags = apply_filters( 'mptt_the_tags', $events_tags, $tags );
307
+ }
308
+
309
+ return $tags;
310
+ }
311
+
312
+ /**
313
+ * Save(insert) event data
314
+ *
315
+ * @param array $params
316
+ *
317
+ * @return array
318
+ */
319
+ public function save_event_data( array $params ) {
320
+
321
+ $rows_affected = array();
322
+
323
+ if ( ! empty( $params[ 'event_data' ] ) ) {
324
+ foreach ( $params[ 'event_data' ] as $key => $event ) {
325
+ if ( is_array( $event[ 'event_start' ] ) && ! empty( $event[ 'event_start' ] ) ) {
326
+
327
+ for ( $i = 0; $i < count( $event[ 'event_start' ] ); $i ++ ) {
328
+ $rows_affected[] = $this->wpdb->insert( $this->table_name, array(
329
+ 'column_id' => $key,
330
+ 'event_id' => $params[ 'post' ]->ID,
331
+ 'event_start' => date( 'H:i', strtotime( $event[ 'event_start' ][ $i ] ) ),
332
+ 'event_end' => date( 'H:i', strtotime( $event[ 'event_end' ][ $i ] ) ),
333
+ 'user_id' => $event[ 'user_id' ][ $i ],
334
+ 'description' => $event[ 'description' ][ $i ]
335
+ )
336
+ );
337
+ }
338
+ }
339
+ }
340
+ }
341
+ if ( ! empty( $params[ 'event_meta' ] ) ) {
342
+ foreach ( $params[ 'event_meta' ] as $meta_key => $meta ) {
343
+ update_post_meta( $params[ 'post' ]->ID, $meta_key, $meta );
344
+ }
345
+ }
346
+
347
+ return $rows_affected;
348
+ }
349
+
350
+ /**
351
+ * Delete event timeslot
352
+ *
353
+ * @param $id
354
+ *
355
+ * @return false|int
356
+ */
357
+ public function delete_event( $id ) {
358
+ return $this->wpdb->delete( $this->table_name, array( 'id' => $id ), array( '%d' ) );
359
+ }
360
+
361
+ /**
362
+ * Delete event data
363
+ *
364
+ * @param $post_id
365
+ *
366
+ * @return false|int
367
+ */
368
+ public function before_delete_event( $post_id ) {
369
+ $meta_keys = array( 'event_id', 'event_start', 'event_end', 'user_id', 'description' );
370
+
371
+ foreach ( $meta_keys as $meta_key ) {
372
+ delete_post_meta( $post_id, $meta_key );
373
+ }
374
+
375
+ return $this->wpdb->delete( $this->table_name, array( 'event_id' => $post_id ), array( '%d' ) );
376
+ }
377
+
378
+ /**
379
+ * Get widget events
380
+ *
381
+ * @param $instance
382
+ *
383
+ * @return array
384
+ */
385
+ public function get_widget_events( $instance ) {
386
+ $events = array();
387
+ $current_local_time = current_time( 'timestamp' );
388
+
389
+ $weekday = strtolower( date( 'l', $current_local_time ) );
390
+ $current_date = date( 'd/m/Y', $current_local_time );
391
+
392
+ // 24.09.2019 seconds added
393
+ $curent_time = date( 'H:i:s', $current_local_time );
394
+
395
+ if ( ! empty( $instance[ 'mp_categories' ] ) ) {
396
+ $category_columns_ids = $this->get( 'column' )->get_columns_by_event_category( $instance[ 'mp_categories' ] );
397
+ }
398
+
399
+ $args = array(
400
+ 'post_type' => 'mp-column',
401
+ 'post_status' => 'publish',
402
+ 'fields' => 'ids',
403
+ 'post__in' => ! empty( $category_columns_ids ) ? $category_columns_ids : '',
404
+ 'orderby' => 'menu_order',
405
+ 'meta_query' => array(
406
+ 'relation' => 'OR',
407
+ array(
408
+ 'key' => 'weekday',
409
+ 'value' => $weekday
410
+ ),
411
+ array(
412
+ 'key' => 'option_day',
413
+ 'value' => $current_date
414
+ )
415
+ )
416
+ );
417
+
418
+ switch ( $instance[ 'view_settings' ] ) {
419
+ case'today':
420
+ case 'current':
421
+ $column_post_ids = get_posts( $args );
422
+ if ( ! empty( $column_post_ids ) ) {
423
+ $events = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
424
+ }
425
+ $events = $this->filter_events( array( 'events' => $events, 'view_settings' => $instance[ 'view_settings' ], 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
426
+ break;
427
+ case 'all':
428
+
429
+ if ( ! empty( $instance[ 'next_days' ] ) && $instance[ 'next_days' ] > 0 ) {
430
+ $events_array = array();
431
+ for ( $i = 0; $i <= $instance[ 'next_days' ]; $i ++ ) {
432
+
433
+ // set new day week
434
+ $time = strtotime( "+$i days", $current_local_time );
435
+ $day = strtolower( date( 'l', $time ) );
436
+ $date = date( 'd/m/Y', $time );
437
+
438
+ //set week day
439
+ $args[ 'meta_query' ][ 0 ][ 'value' ] = $day;
440
+ //set new date
441
+ $args[ 'meta_query' ][ 1 ][ 'value' ] = $date;
442
+
443
+ $column_post_ids = get_posts( $args );
444
+
445
+ if ( ! empty( $column_post_ids ) ) {
446
+ $events_array[ $i ] = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
447
+ } else {
448
+ $events_array[ $i ] = array();
449
+ }
450
+
451
+ // Filter by time and categories for current day
452
+ if ( $i === 0 && ! empty( $instance[ 'mp_categories' ] ) && ! empty( $events_array[ $i ] ) ) {
453
+ $events_array[ $i ] = $events_array[ $i ] = $this->filter_events( array( 'events' => $events_array[ $i ], 'view_settings' => 'today', 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
454
+ } elseif ( ! empty( $instance[ 'mp_categories' ] ) && ! empty( $events_array[ $i ] ) ) {
455
+ //Filter by categories for next days
456
+ $events_array[ $i ] = $this->filter_events_by_categories( $events_array[ $i ], $instance[ 'mp_categories' ] );
457
+ }
458
+
459
+ }
460
+
461
+ foreach ( $events_array as $day_events ) {
462
+ $events = array_merge( $events, $day_events );
463
+ }
464
+
465
+ }
466
+
467
+ break;
468
+
469
+ default:
470
+ $column_post_ids = get_posts( $args );
471
+ if ( ! empty( $column_post_ids ) ) {
472
+ $events = $this->get_events_data( array( 'column' => 'column_id', 'list' => $column_post_ids ) );
473
+ }
474
+ $events = $this->filter_events( array( 'events' => $events, 'view_settings' => 'today', 'time' => $curent_time, 'mp_categories' => $instance[ 'mp_categories' ] ) );
475
+
476
+ break;
477
+ }
478
+ if ( $instance[ 'limit' ] > 0 ) {
479
+ $events = array_slice( $events, 0, $instance[ 'limit' ] );
480
+ }
481
+
482
+ return $events;
483
+ }
484
+
485
+ /**
486
+ * Get event data by post
487
+ *
488
+ * @param array $params
489
+ *
490
+ * @return array
491
+ */
492
+ public function get_events_data( array $params ) {
493
+ $events = array();
494
+ $sql_request = "SELECT * FROM " . $this->table_name;
495
+
496
+ if ( ( ! empty( $params[ 'all' ] ) && $params[ 'all' ] ) || empty( $params[ 'list' ] ) ) {
497
+
498
+ } elseif ( ! is_array( $params[ 'column' ] ) ) {
499
+
500
+ if ( isset( $params[ 'list' ] ) && is_array( $params[ 'list' ] ) ) {
501
+ $params[ 'list' ] = implode( ',', $params[ 'list' ] );
502
+ }
503
+
504
+ $sql_request .= " WHERE " . $params[ 'column' ] . " IN (" . $params[ 'list' ] . ")";
505
+
506
+ } elseif ( is_array( $params[ 'column' ] ) && is_array( $params[ 'list' ] ) ) {
507
+
508
+ $sql_request .= " WHERE ";
509
+
510
+ $last_key = key( array_slice( $params[ 'column' ], - 1, 1, true ) );
511
+
512
+ foreach ( $params[ 'column' ] as $key => $column ) {
513
+ if ( isset( $params[ 'list' ][ $column ] ) && is_array( $params[ 'list' ][ $column ] ) ) {
514
+ $params[ 'list' ][ $column ] = implode( ',', $params[ 'list' ][ $column ] );
515
+ }
516
+ $sql_request .= $column . " IN (" . $params[ 'list' ][ $column ] . ")";
517
+ $sql_request .= ( $last_key != $key ) ? ' AND ' : '';
518
+ }
519
+
520
+ }
521
+
522
+ $sql_request .= ' ORDER BY `event_start`';
523
+
524
+ $events_data = $this->wpdb->get_results( $sql_request );
525
+
526
+ if ( is_array( $events_data ) ) {
527
+
528
+ foreach ( $events_data as $event ) {
529
+ $post = get_post( $event->event_id );
530
+
531
+ if ( $post && ( $post->post_type == $this->post_type ) && ( $post->post_status == 'publish' ) ) {
532
+ $event->post = $post;
533
+ $event->event_start = date( 'H:i', strtotime( $event->event_start ) );
534
+ $event->event_end = date( 'H:i', strtotime( $event->event_end ) );
535
+ $events[] = $event;
536
+ }
537
+ }
538
+ }
539
+
540
+ return $events;
541
+ }
542
+
543
+ /**
544
+ * Filtered events by view settings
545
+ *
546
+ * @param $params
547
+ *
548
+ * @return array
549
+ */
550
+ protected function filter_events( $params ) {
551
+
552
+ $events = array();
553
+ $events = $this->filter_by_time_period( $params, $events );
554
+
555
+ if ( ! empty( $params[ 'mp_categories' ] ) ) {
556
+ $events = $this->filter_events_by_categories( $events, $params[ 'mp_categories' ] );
557
+ }
558
+
559
+ return $events;
560
+ }
561
+
562
+ /**
563
+ * Filter by time period
564
+ *
565
+ * @param $params
566
+ * @param $events
567
+ *
568
+ * @return array
569
+ */
570
+ protected function filter_by_time_period( $params, $events ) {
571
+ if ( ! empty( $params[ 'events' ] ) ) {
572
+
573
+ $time = strtotime( $params[ 'time' ] );
574
+
575
+ foreach ( $params[ 'events' ] as $key => $event ) {
576
+
577
+ $event_end = strtotime( $event->event_end );
578
+ $event_start = strtotime( $event->event_start );
579
+
580
+ if ( $params[ 'view_settings' ] === 'today' || $params[ 'view_settings' ] === 'all' ) {
581
+ if ( $event_end <= $time ) {
582
+ continue;
583
+ }
584
+ } elseif ( $params[ 'view_settings' ] === 'current' ) {
585
+ if ( $event_start >= $time || $event_end <= $time ) {
586
+ continue;
587
+ }
588
+ }
589
+ $events[ $key ] = $event;
590
+ }
591
+ }
592
+
593
+ return $events;
594
+ }
595
+
596
+ /**
597
+ * Filter find events by select categories;
598
+ *
599
+ * @param array $events
600
+ * @param array $categories
601
+ *
602
+ * @return array
603
+ */
604
+ public function filter_events_by_categories( array $events, array $categories ) {
605
+ $temp_events = array();
606
+ $taxonomy = $this->taxonomy_names[ 'cat' ];
607
+
608
+ foreach ( $events as $event ) {
609
+ if ( @has_term( $categories, $taxonomy, $event->post->ID ) ) {
610
+ $temp_events[] = $event;
611
+ }
612
+ }
613
+
614
+ return $temp_events;
615
+ }
616
+
617
+ /**
618
+ * Sort by params
619
+ *
620
+ * @param $events
621
+ *
622
+ * @return mixed
623
+ */
624
+
625
+ public function sort_by_param( $events ) {
626
+
627
+ usort( $events, function ( $a, $b ) {
628
+ if ( strtotime( $a->event_start ) == strtotime( $b->event_start ) ) {
629
+ return 0;
630
+ }
631
+
632
+ return ( strtotime( $a->event_start ) < strtotime( $b->event_start ) ) ? - 1 : 1;
633
+ } );
634
+
635
+
636
+ return $events;
637
+ }
638
+
639
+ /**
640
+ * @param array /string $event_category
641
+ *
642
+ * @return array|null|object
643
+ */
644
+ public function get_events_data_by_category( $event_categories ) {
645
+ if ( ! is_array( $event_categories ) ) {
646
+ $terms = explode( ',', $event_categories );
647
+ } else {
648
+ $terms = $event_categories;
649
+ }
650
+
651
+ $posts_array = get_posts(
652
+ array(
653
+ 'fields' => 'ids',
654
+ 'posts_per_page' => - 1,
655
+ 'post_type' => $this->post_type,
656
+ 'post_status' => 'publish',
657
+ 'tax_query' => array(
658
+ array(
659
+ 'taxonomy' => 'mp-event_category',
660
+ 'field' => 'term_id',
661
+ 'terms' => $terms,
662
+ )
663
+ )
664
+ )
665
+ );
666
+
667
+ $ids = implode( ',', $posts_array );
668
+ $event_data = $this->get_events_data( array( 'column' => 'event_id', 'list' => $ids ) );
669
+
670
+ return $event_data;
671
+ }
672
+
673
+ /**
674
+ * Update event data
675
+ *
676
+ * @param $data
677
+ *
678
+ * @return false|int
679
+ */
680
+ public function update_event_data( $data ) {
681
+ $result = $this->wpdb->update(
682
+ $this->table_name,
683
+ array(
684
+ 'event_start' => date( 'H:i', strtotime( $data[ 'event_start' ] ) ),
685
+ 'event_end' => date( 'H:i', strtotime( $data[ 'event_end' ] ) ),
686
+ 'description' => $data[ 'description' ],
687
+ 'column_id' => $data[ 'weekday_ids' ],
688
+ 'user_id' => $data[ 'user_id' ],
689
+ ),
690
+ array( 'id' => $data[ 'id' ] ),
691
+ array(
692
+ '%s',
693
+ '%s',
694
+ '%s',
695
+ '%d',
696
+ '%d',
697
+ ),
698
+ array( '%d' )
699
+ );
700
+
701
+ return $result;
702
+ }
703
+
704
+ /**
705
+ * Get all events
706
+ * @return array
707
+ */
708
+ public function get_all_events() {
709
+ $args = array(
710
+ 'post_type' => $this->post_type,
711
+ 'post_status' => 'publish',
712
+ 'order' => 'ASC',
713
+ 'orderby' => 'title',
714
+ 'posts_per_page' => - 1
715
+ );
716
+
717
+ return get_posts( $args );
718
+ }
719
+
720
+ /**
721
+ * Choose color widget or event
722
+ *
723
+ * @param $params
724
+ *
725
+ * @return string
726
+ */
727
+
728
+ public function choose_event_color( $params ) {
729
+ if ( ! empty( $params[ 'widget_color' ] ) ) {
730
+ return $params[ 'widget_color' ];
731
+ } elseif ( ! empty( $params[ 'event_color' ] ) ) {
732
+ return $params[ 'event_color' ];
733
+ } else {
734
+ return '';
735
+ }
736
+ }
737
+
738
+ /**
739
+ * Filtered events by Event Head
740
+ *
741
+ * @param $params
742
+ *
743
+ * @return array
744
+ */
745
+ protected function filter_events_by_field( $params ) {
746
+ $events = array();
747
+ if ( ! empty( $params[ 'events' ] ) ) {
748
+ foreach ( $params[ 'events' ] as $key => $event ) {
749
+ if ( $event->$params[ 'field' ] != $params[ 'value' ] ) {
750
+ continue;
751
+ }
752
+
753
+ $events[ $key ] = $event;
754
+ }
755
+ }
756
+
757
+ return $events;
758
+ }
759
+
760
+ public function post_row_actions( $actions, $post ) {
761
+
762
+ if ( $post->post_type == $this->post_type && current_user_can('edit_posts') ) {
763
+
764
+ $action_url = add_query_arg(
765
+ array(
766
+ 'post' => $post->ID,
767
+ 'action' => 'mptt_duplicate_event',
768
+ '_wpnonce' => wp_create_nonce( 'mptt_duplicate_event' )
769
+ ),
770
+ admin_url( 'post.php' )
771
+ );
772
+
773
+ $actions['duplicate'] = '<a href="' . $action_url . '" aria-label="' .
774
+ __('Duplicate', 'mp-timetable') . '" rel="permalink">' . __('Duplicate', 'mp-timetable') . '</a>';
775
+ }
776
+
777
+ return $actions;
778
+ }
779
+
780
+ public function post_action_mptt_duplicate_event( $post_id ) {
781
+
782
+ global $wpdb;
783
+
784
+ $post_type = '';
785
+
786
+ if ( $post_id ) {
787
+ $post = get_post( $post_id );
788
+ }
789
+
790
+ if ( $post ) {
791
+ $post_type = $post->post_type;
792
+ }
793
+
794
+ if ( $post_type !== $this->post_type ) {
795
+ wp_die( __( 'A post type mismatch has been detected.', 'mp-timetable' ), __( 'Sorry, you are not allowed to edit this item.', 'mp-timetable' ), 400 );
796
+ }
797
+
798
+ $nonce = $_REQUEST['_wpnonce'];
799
+
800
+ if ( wp_verify_nonce( $nonce, 'mptt_duplicate_event' ) && current_user_can('edit_posts') ) {
801
+
802
+ $current_user = wp_get_current_user();
803
+ $new_post_author = $current_user->ID;
804
+
805
+ /*
806
+ * new post data array
807
+ */
808
+ $args = array(
809
+ 'comment_status' => $post->comment_status,
810
+ 'ping_status' => $post->ping_status,
811
+ 'post_author' => $new_post_author,
812
+ 'post_content' => $post->post_content,
813
+ 'post_excerpt' => $post->post_excerpt,
814
+ 'post_name' => $post->post_name,
815
+ 'post_parent' => $post->post_parent,
816
+ 'post_password' => $post->post_password,
817
+ 'post_status' => 'draft',
818
+ // translators: New post title of the duplicated post
819
+ 'post_title' => sprintf( __('%s - Copy', 'mp-timetable'), $post->post_title ),
820
+ 'post_type' => $post->post_type,
821
+ 'to_ping' => $post->to_ping,
822
+ 'menu_order' => $post->menu_order
823
+ );
824
+
825
+ /*
826
+ * insert the post by wp_insert_post() function
827
+ */
828
+ $new_post_id = wp_insert_post( $args );
829
+
830
+ if( is_wp_error($new_post_id) ) {
831
+ wp_die( $post_id->get_error_message() );
832
+ }
833
+
834
+ /*
835
+ * get all current post terms and set them to the new post draft
836
+ */
837
+ $taxonomies = get_object_taxonomies($post->post_type);
838
+ foreach ($taxonomies as $taxonomy) {
839
+ $post_terms = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'slugs'));
840
+ wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
841
+ }
842
+
843
+ /*
844
+ * duplicate all post meta
845
+ */
846
+ $post_meta = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id");
847
+
848
+ if ( !empty($post_meta) ) {
849
+
850
+ $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
851
+
852
+ foreach ($post_meta as $meta_info) {
853
+ $meta_key = $meta_info->meta_key;
854
+ if ( $meta_key == '_wp_old_slug' ) continue;
855
+ $meta_value = addslashes($meta_info->meta_value);
856
+ $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";
857
+ }
858
+
859
+ $sql_query .= implode( " UNION ALL ", $sql_query_sel );
860
+
861
+ $wpdb->query( $sql_query );
862
+ }
863
+
864
+ /*
865
+ * duplicate timeslots in custom BD
866
+ */
867
+ $timeslots = $wpdb->get_results( "SELECT * FROM {$this->table_name} WHERE event_id = " . $post_id, OBJECT );
868
+
869
+ if ( !empty($timeslots) ) {
870
+
871
+ foreach ( $timeslots as $timeslot ) {
872
+ $wpdb->insert(
873
+ $this->table_name,
874
+ array(
875
+ 'column_id' => $timeslot->column_id,
876
+ 'event_id' => $new_post_id,
877
+ 'event_start' => date( 'H:i', strtotime( $timeslot->event_start ) ),
878
+ 'event_end' => date( 'H:i', strtotime( $timeslot->event_end ) ),
879
+ 'user_id' => $timeslot->user_id,
880
+ 'description' => $timeslot->description
881
+ )
882
+ );
883
+ }
884
+ }
885
+
886
+ /*
887
+ * redirect to the edit post screen for the new draft
888
+ */
889
+ wp_safe_redirect( get_edit_post_link( $new_post_id, '' ) );
890
+ exit();
891
+
892
+ } else {
893
+ wp_die( __( 'Sorry, you are not allowed to edit this item.' ) );
894
+ }
895
+ }
896
+
897
+ }
languages/mp-timetable-fa_IR.po CHANGED
@@ -1,962 +1,962 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: Timetable and Event Schedule Plugin\n"
4
- "POT-Creation-Date: 2018-05-18 09:58+0430\n"
5
- "PO-Revision-Date: \n"
6
- "Last-Translator: \n"
7
- "Language-Team: Alireza Rastegar<alireza.mine@gmail.com>\n"
8
- "Language: fa_IR\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "Plural-Forms: nplurals=1; plural=0;\n"
13
- "X-Generator: Poedit 2.0.1\n"
14
- "X-Poedit-SourceCharset: UTF-8\n"
15
- "X-Poedit-KeywordsList: esc_attr__;esc_html__;esc_attr_e;__;_e;_n;_x\n"
16
- "X-Poedit-Basepath: ..\n"
17
- "X-Poedit-SearchPath-0: .\n"
18
- "X-Poedit-SearchPathExcluded-0: classes/libs\n"
19
- "X-Poedit-SearchPathExcluded-1: media\n"
20
-
21
- #: admin/import/export.php:1 admin/import/export.php:5
22
- msgid "Export"
23
- msgstr "برونریزی"
24
-
25
- #: admin/import/greet.php:2
26
- msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
27
- msgstr ""
28
- "یک فایل WXR (.xml) را برای آپلود انتخاب کنید، سپس روی آپلود فایل و وارد کردن "
29
- "کلیک کنید."
30
-
31
- #: admin/import/header.php:2
32
- msgid "Import / Export Timetable Plugin Data"
33
- msgstr "درون ریزی / برون ریزی داده افزونه جدول زمانی"
34
-
35
- #: admin/import/import.php:1
36
- msgid "Import"
37
- msgstr "درون ریزی"
38
-
39
- #: classes/class-core.php:317 classes/class-core.php:329
40
- #: classes/class-core.php:333 classes/class-shortcode.php:261
41
- msgid "Event categories"
42
- msgstr "دسته های رویداد"
43
-
44
- #: classes/class-core.php:318
45
- msgid "Event category"
46
- msgstr "دسته بندی رویداد"
47
-
48
- #: classes/class-core.php:319 classes/class-core.php:320
49
- msgid "Add New Event category"
50
- msgstr "افزودن دسته بندی رویداد"
51
-
52
- #: classes/class-core.php:321
53
- msgid "Edit Event category"
54
- msgstr "ویرایش دسته بندی رویداد"
55
-
56
- #: classes/class-core.php:322
57
- msgid "New Event category"
58
- msgstr "دسته رویداد جدید"
59
-
60
- #: classes/class-core.php:323
61
- msgid "All Event categories"
62
- msgstr "همه دسته های رویداد"
63
-
64
- #: classes/class-core.php:324
65
- msgid "View Event category"
66
- msgstr "نمایش دسته رویداد"
67
-
68
- #: classes/class-core.php:325
69
- msgid "Search Event category"
70
- msgstr "جستجوی دسته رویداد"
71
-
72
- #: classes/class-core.php:326
73
- msgid "No Event categories found"
74
- msgstr "دسته رویدادی پیدا نشد"
75
-
76
- #: classes/class-core.php:327
77
- msgid "No Event categories found in Trash"
78
- msgstr "هیچ دسته رویدادی در «حذف شده ها» یافت نشد"
79
-
80
- #: classes/class-core.php:356 classes/class-core.php:368
81
- #: classes/class-core.php:372
82
- msgid "Event tags"
83
- msgstr "برچسب های رویداد"
84
-
85
- #: classes/class-core.php:357
86
- msgid "Event tag"
87
- msgstr "برچسب رویداد"
88
-
89
- #: classes/class-core.php:358 classes/class-core.php:359
90
- msgid "Add New Event tag"
91
- msgstr "افزودن برچسب جدید رویداد"
92
-
93
- #: classes/class-core.php:360
94
- msgid "Edit Event tag"
95
- msgstr "ویرایش برچسب رویداد"
96
-
97
- #: classes/class-core.php:361
98
- msgid "New Event tag"
99
- msgstr "برچسب جدید رویداد"
100
-
101
- #: classes/class-core.php:362
102
- msgid "All Event tags"
103
- msgstr "همه برچسب های رویداد"
104
-
105
- #: classes/class-core.php:363
106
- msgid "View Event tag"
107
- msgstr "نمایش برچسب رویداد"
108
-
109
- #: classes/class-core.php:364
110
- msgid "Search Event tag"
111
- msgstr "جستجوی برچسب رویداد"
112
-
113
- #: classes/class-core.php:365
114
- msgid "No Event tags found"
115
- msgstr "برچسب رویداد یافت نشد"
116
-
117
- #: classes/class-core.php:366
118
- msgid "No Event tags found in Trash"
119
- msgstr "هیچ برچسب رویدادی در «حذف شده ها» یافت نشد"
120
-
121
- #: classes/class-core.php:404 classes/class-core.php:416
122
- #: classes/class-hooks.php:171 classes/class-shortcode.php:256
123
- msgid "Events"
124
- msgstr "رویدادها"
125
-
126
- #: classes/class-core.php:405
127
- msgid "Event"
128
- msgstr "رویداد"
129
-
130
- #: classes/class-core.php:406 classes/class-core.php:407
131
- msgid "Add New Event"
132
- msgstr "افزودن رویداد جدید"
133
-
134
- #: classes/class-core.php:408
135
- msgid "Edit Event"
136
- msgstr "ویرایش رویداد"
137
-
138
- #: classes/class-core.php:409
139
- msgid "New Event"
140
- msgstr "رویداد جدید"
141
-
142
- #: classes/class-core.php:410 classes/class-shortcode.php:69
143
- #: classes/class-shortcode.php:277
144
- #: templates-functions/action-shortcode-functions.php:39
145
- #: templates-functions/action-shortcode-functions.php:52
146
- #: templates-functions/action-shortcode-functions.php:53
147
- msgid "All Events"
148
- msgstr "همه رویدادها"
149
-
150
- #: classes/class-core.php:411
151
- msgid "View Event"
152
- msgstr "نمایش رویداد"
153
-
154
- #: classes/class-core.php:412
155
- msgid "Search Event"
156
- msgstr "جستجوی رویداد"
157
-
158
- #: classes/class-core.php:413
159
- msgid "No Events found"
160
- msgstr "رویدادی یافت نشد"
161
-
162
- #: classes/class-core.php:414
163
- msgid "No Events found in Trash"
164
- msgstr "هیچ رویدادی در «حذف شده ها» یافت نشد"
165
-
166
- #: classes/class-core.php:438 classes/class-core.php:450
167
- #: classes/class-hooks.php:173
168
- msgid "Columns"
169
- msgstr "ستون ها"
170
-
171
- #: classes/class-core.php:439 classes/class-shortcode.php:251
172
- #: templates/events/event-data.php:4
173
- msgid "Column"
174
- msgstr "ستون"
175
-
176
- #: classes/class-core.php:440 classes/class-core.php:441
177
- msgid "Add New Column"
178
- msgstr "افزودن ستون جدید"
179
-
180
- #: classes/class-core.php:442
181
- msgid "Edit Column"
182
- msgstr "ویرایش ستون"
183
-
184
- #: classes/class-core.php:443
185
- msgid "New Column"
186
- msgstr "ستون جدید"
187
-
188
- #: classes/class-core.php:444
189
- msgid "All Columns"
190
- msgstr "همه ستون ها"
191
-
192
- #: classes/class-core.php:445
193
- msgid "View Column"
194
- msgstr "نمایش ستون"
195
-
196
- #: classes/class-core.php:446
197
- msgid "Search Column"
198
- msgstr "جستجوی ستون"
199
-
200
- #: classes/class-core.php:447
201
- msgid "No Columns found"
202
- msgstr "هیچ ستونی یافت نشد"
203
-
204
- #: classes/class-core.php:448
205
- msgid "No Columns found in Trash"
206
- msgstr "هیچ ستونی در «حذف شده ها» یافت نشد"
207
-
208
- #: classes/class-hooks.php:66
209
- msgid "Timetable Sidebar"
210
- msgstr "ابزارک جدول زمانی"
211
-
212
- #: classes/class-hooks.php:68 classes/class-hooks.php:170
213
- #: classes/class-shortcode.php:356
214
- msgid "Timetable"
215
- msgstr "جدول زمانی"
216
-
217
- #: classes/class-hooks.php:163
218
- msgid "Import Timetable events, categories, tags and images."
219
- msgstr "درون ریزی رویدادهای جدول زمانی، دسته بندی ها، برچسب ها و عکس ها"
220
-
221
- #: classes/class-hooks.php:172
222
- msgid "Add Event"
223
- msgstr "افزودن رویداد"
224
-
225
- #: classes/class-hooks.php:174
226
- msgid "Add Column"
227
- msgstr "افزودن ستون"
228
-
229
- #: classes/class-hooks.php:175
230
- msgid "Event Categories"
231
- msgstr "دسته های رویداد"
232
-
233
- #: classes/class-hooks.php:176
234
- msgid "Event Tags"
235
- msgstr "برچسب های رویداد"
236
-
237
- #: classes/class-hooks.php:177 classes/modules/class-post.php:41
238
- msgid "Settings"
239
- msgstr "تنظیمات"
240
-
241
- #: classes/class-hooks.php:178
242
- msgid "Export / Import"
243
- msgstr "درون ریزی/برون ریزی"
244
-
245
- #: classes/class-shortcode.php:266
246
- msgid "Hour measure"
247
- msgstr "اندازه گیری ساعت"
248
-
249
- #: classes/class-shortcode.php:267 templates/popup/index.php:66
250
- msgid "Hour (1h)"
251
- msgstr "ساعت (1 ساعت)"
252
-
253
- #: classes/class-shortcode.php:267 templates/popup/index.php:67
254
- msgid "Half hour (30min)"
255
- msgstr "نیم ساعت (30 دقیقه)"
256
-
257
- #: classes/class-shortcode.php:267 templates/popup/index.php:68
258
- msgid "Quarter hour (15min)"
259
- msgstr "ربع ساعت (15 دقیقه)"
260
-
261
- #: classes/class-shortcode.php:271
262
- msgid "Filter style"
263
- msgstr "سبک فیلتر"
264
-
265
- #: classes/class-shortcode.php:272
266
- msgid "Dropdown list"
267
- msgstr "لیست بازشو"
268
-
269
- #: classes/class-shortcode.php:272 templates/popup/index.php:77
270
- msgid "Tabs"
271
- msgstr "تب ها"
272
-
273
- #: classes/class-shortcode.php:276
274
- msgid "Filter label"
275
- msgstr "برچسب فیلتر"
276
-
277
- #: classes/class-shortcode.php:281
278
- msgid "Hide 'All Events' view"
279
- msgstr "نمایش ندادن همه رویدادها"
280
-
281
- #: classes/class-shortcode.php:282 classes/class-shortcode.php:287
282
- #: classes/class-shortcode.php:292 classes/class-shortcode.php:299
283
- #: classes/class-shortcode.php:305 classes/class-shortcode.php:311
284
- #: classes/class-shortcode.php:317 classes/class-shortcode.php:323
285
- #: classes/class-shortcode.php:328 classes/class-shortcode.php:352
286
- #: templates/events/metabox-event-options.php:45 templates/popup/index.php:93
287
- #: templates/popup/index.php:102 templates/popup/index.php:112
288
- #: templates/popup/index.php:120 templates/popup/index.php:129
289
- #: templates/widgets/gallery-list.php:60
290
- msgid "No"
291
- msgstr "خیر"
292
-
293
- #: classes/class-shortcode.php:282 classes/class-shortcode.php:287
294
- #: classes/class-shortcode.php:292 classes/class-shortcode.php:299
295
- #: classes/class-shortcode.php:305 classes/class-shortcode.php:311
296
- #: classes/class-shortcode.php:317 classes/class-shortcode.php:323
297
- #: classes/class-shortcode.php:328 classes/class-shortcode.php:352
298
- #: templates/events/metabox-event-options.php:46 templates/popup/index.php:94
299
- #: templates/popup/index.php:103 templates/popup/index.php:111
300
- #: templates/popup/index.php:121 templates/popup/index.php:130
301
- #: templates/widgets/gallery-list.php:62
302
- msgid "Yes"
303
- msgstr "بله"
304
-
305
- #: classes/class-shortcode.php:286
306
- msgid "Hide first (hours) column"
307
- msgstr "پنهان کردن ستون اول (ساعت)"
308
-
309
- #: classes/class-shortcode.php:291
310
- msgid "Hide empty rows"
311
- msgstr "پنهان کردن سطرهای خالی"
312
-
313
- #: classes/class-shortcode.php:297 templates/popup/index.php:40
314
- #: templates/widgets/gallery-list.php:3
315
- msgid "Title"
316
- msgstr "عنوان"
317
-
318
- #: classes/class-shortcode.php:303 templates/popup/index.php:41
319
- msgid "Time"
320
- msgstr "زمان"
321
-
322
- #: classes/class-shortcode.php:309 templates/popup/index.php:42
323
- msgid "Subtitle"
324
- msgstr "عنوان فرعی"
325
-
326
- #: classes/class-shortcode.php:315 templates/events/event-data.php:7
327
- #: templates/popup/index.php:43
328
- msgid "Description"
329
- msgstr "توضیحات"
330
-
331
- #: classes/class-shortcode.php:321
332
- msgid "User"
333
- msgstr "کاربر"
334
-
335
- #: classes/class-shortcode.php:327
336
- msgid "Disable event URL"
337
- msgstr "URL رویداد را غیرفعال کنید"
338
-
339
- #: classes/class-shortcode.php:332
340
- msgid "Text align"
341
- msgstr "چیدمان متن"
342
-
343
- #: classes/class-shortcode.php:333 templates/popup/index.php:137
344
- msgid "center"
345
- msgstr "وسط"
346
-
347
- #: classes/class-shortcode.php:333 templates/popup/index.php:138
348
- msgid "left"
349
- msgstr "چپ"
350
-
351
- #: classes/class-shortcode.php:333 templates/popup/index.php:139
352
- msgid "right"
353
- msgstr "راست"
354
-
355
- #: classes/class-shortcode.php:337
356
- msgid "Id"
357
- msgstr "ID"
358
-
359
- #: classes/class-shortcode.php:341
360
- msgid "Row height (in px)"
361
- msgstr "ارتفاع ردیف (در پیکسل)"
362
-
363
- #: classes/class-shortcode.php:346
364
- msgid "Base Font Size"
365
- msgstr "اندازه فونت پایه"
366
-
367
- #: classes/class-shortcode.php:351
368
- msgid "Responsive"
369
- msgstr "واکنش گرایی"
370
-
371
- #: classes/controllers/class-controller-settings.php:53
372
- msgid "Settings saved."
373
- msgstr "تنظیمات ذخیره شد."
374
-
375
- #: classes/models/class-column.php:42 classes/modules/class-post.php:40
376
- msgid "Timeslots"
377
- msgstr "فاصله زمانی"
378
-
379
- #: classes/models/class-events.php:167
380
- msgid "Tags"
381
- msgstr "تگ ها"
382
-
383
- #: classes/models/class-events.php:168
384
- msgid "Categories"
385
- msgstr "دسته ها"
386
-
387
- #: classes/models/class-import.php:125
388
- msgid "Assign Authors"
389
- msgstr "اختصاص دادن نویسندگان"
390
-
391
- #: classes/models/class-import.php:126
392
- msgid ""
393
- "To make it easier for you to edit and save the imported content, you may "
394
- "want to reassign the author of the imported item to an existing user of this "
395
- "site. For example, you may want to import all the entries as <code>admin</"
396
- "code>s entries."
397
- msgstr ""
398
- "برای اینکه بتوانید محتوای وارد شده را ویرایش و ذخیره کنید، ممکن است بخواهید "
399
- "نویسنده اثر وارد شده را به یک کاربر فعلی این سایت مجددا اختصاص دهید.به عنوان "
400
- "مثال، شما ممکن است بخواهید تمام ورودی ها را به عنوان ورودی <code> مدیر </"
401
- "code> وارد کنید."
402
-
403
- #: classes/models/class-import.php:128
404
- #, php-format
405
- msgid ""
406
- "If a new user is created by WordPress, a new password will be randomly "
407
- "generated and the new user&#8217;s role will be set as %s. Manually changing "
408
- "the new user&#8217;s details will be necessary."
409
- msgstr ""
410
- "اگر یک کاربر جدید توسط وردپرس ایجاد شده باشد، یک رمز عبور جدید به صورت "
411
- "تصادفی ایجاد خواهد شد و نقش کاربر جدید user&#8217;s به عنوان %s تنظیم خواهد "
412
- "شد. تغییر دستی اطلاعات جدید کاربر user&#8217;s ضروری است."
413
-
414
- #: classes/models/class-import.php:138
415
- msgid "Import Attachments"
416
- msgstr "درون ریزی پیوست ها"
417
-
418
- #: classes/models/class-import.php:141
419
- msgid "Download and import file attachments"
420
- msgstr "دریافت و درون ریزی فایل های پیوست"
421
-
422
- #: classes/models/class-import.php:145
423
- msgid "Submit"
424
- msgstr "ارسال"
425
-
426
- #: classes/models/class-import.php:158
427
- msgid "Import author:"
428
- msgstr "درون ریزی نویسنده:"
429
-
430
- #: classes/models/class-import.php:169
431
- msgid "or create new user with login name:"
432
- msgstr "یا ایجاد کاربر جدید با نام کاربری:"
433
-
434
- #: classes/models/class-import.php:172
435
- msgid "as a new user:"
436
- msgstr "به عنوان یک کاربر جدید:"
437
-
438
- #: classes/models/class-import.php:180
439
- msgid "assign posts to an existing user:"
440
- msgstr "اختصاص دادن پست به یک کاربر موجود:"
441
-
442
- #: classes/models/class-import.php:182
443
- msgid "or assign posts to an existing user:"
444
- msgstr "یا اختصاص دادن پست به یک کاربر موجود:"
445
-
446
- #: classes/models/class-import.php:183
447
- #: templates/column/metabox-column-options.php:18
448
- msgid "- Select -"
449
- msgstr "- انتخاب -"
450
-
451
- #: classes/models/class-import.php:269
452
- msgid "All done."
453
- msgstr "همه انجام شد."
454
-
455
- #: classes/models/class-import.php:269
456
- msgid "Have fun!"
457
- msgstr "خوش بگذره!"
458
-
459
- #: classes/models/class-import.php:270
460
- msgid "Remember to update the passwords and roles of imported users."
461
- msgstr ""
462
- "به خاطر داشته باشید که کلمه عبور و نقش کاربران وارد شده را به روز کنید."
463
-
464
- #: classes/models/class-import.php:286
465
- msgid "Fetching attachments is not enabled"
466
- msgstr "پیوست های دریافتی فعال نیستند"
467
-
468
- #: classes/models/class-import.php:299
469
- msgid "Invalid file type"
470
- msgstr "نوع فایل نامعتبر است"
471
-
472
- #: classes/models/class-import.php:379
473
- msgid "Remote server did not respond"
474
- msgstr "سرور از راه دور جواب نمی دهد"
475
-
476
- #: classes/models/class-import.php:385
477
- #, php-format
478
- msgid "Remote server returned error response %1$d %2$s"
479
- msgstr "سرور راه دور پاسخ خطا %1$d %2$s را دریافت کرد"
480
-
481
- #: classes/models/class-import.php:394
482
- msgid "Remote file is incorrect size"
483
- msgstr "سایز فایل ارسالی سرور رته دور نادرست است"
484
-
485
- #: classes/models/class-import.php:399
486
- msgid "Zero size file downloaded"
487
- msgstr "سایز فایل دانلود شده صفر می باشد"
488
-
489
- #: classes/models/class-import.php:405
490
- #, php-format
491
- msgid "Remote file is too large, limit is %s"
492
- msgstr "سایز فایل از راه دور بسیار بزرگ است، سایز به %s محدود شده"
493
-
494
- #: classes/models/class-import.php:422 classes/models/class-import.php:426
495
- #: classes/models/class-import.php:436
496
- msgid "Sorry, there has been an error."
497
- msgstr "با عرض پوزش، یک خطا وجود دارد."
498
-
499
- #: classes/models/class-import.php:427
500
- #, php-format
501
- msgid ""
502
- "The export file could not be found at <code>%s</code>. It is likely that "
503
- "this was caused by a permissions problem."
504
- msgstr ""
505
- "فایل درون ریزی در <code>%s</code> یافت نمی شود. احتمالا این مسئله توسط یک "
506
- "مشکل مجوز ایجاد شده است."
507
-
508
- #: classes/models/class-import.php:444
509
- #, php-format
510
- msgid ""
511
- "This WXR file (version %s) may not be supported by this version of the "
512
- "importer. Please consider updating."
513
- msgstr ""
514
- "این فایل WXR (نسخه %s) ممکن است توسط این نسخه از وارد کننده پشتیبانی نشود. "
515
- "لطفا به روزرسانی کنید."
516
-
517
- #: classes/models/class-import.php:501
518
- #, php-format
519
- msgid ""
520
- "Failed to import author %s. Their posts will be attributed to the current "
521
- "user."
522
- msgstr ""
523
- "وارد کردن نویسنده %s امکان پذیر نبود. پست های آن به کاربر فعلی نسبت داده می "
524
- "شود."
525
-
526
- #: classes/models/class-import.php:558
527
- #, php-format
528
- msgid ""
529
- "Failed to create new user for %s. Their posts will be attributed to the "
530
- "current user."
531
- msgstr ""
532
- "امکان ایجاد کاربر جدید برای %s نبود. پست های آن به کاربر فعلی نسبت داده می "
533
- "شود."
534
-
535
- #: classes/models/class-import.php:609 classes/models/class-import.php:766
536
- #, php-format
537
- msgid "Failed to import %s %s"
538
- msgstr "درون ریزی نا موفق بود %s %s"
539
-
540
- #: classes/models/class-import.php:656
541
- #, php-format
542
- msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
543
- msgstr "وارد کردن &#8220;%s&#8221;: ناموفق بود. نوع پست %s نامعتبر است"
544
-
545
- #: classes/models/class-import.php:673
546
- #, php-format
547
- msgid "%s &#8220;%s&#8221; already exists."
548
- msgstr "%s &#8220;%s&#8221; درحال حاضر وجود دارد."
549
-
550
- #: classes/models/class-import.php:732
551
- #, php-format
552
- msgid "Failed to import %s &#8220;%s&#8221;"
553
- msgstr "%s &#8220;%s&#8221; وارد کردن نشد"
554
-
555
- #: classes/modules/class-post.php:42
556
- msgid "Column Type"
557
- msgstr "نوع ستون"
558
-
559
- #: classes/widgets/class-mp-timetable-widget.php:22
560
- msgid "Display upcoming events."
561
- msgstr "نمایش رویدادهای آینده"
562
-
563
- #: classes/widgets/class-mp-timetable-widget.php:24
564
- msgid "Timetable Events"
565
- msgstr "جدول زمانی رویدادها"
566
-
567
- #: templates-functions/actions-mp-event-functions.php:27
568
- #: templates/theme/event-timeslots.php:7
569
- #, php-format
570
- msgid "Event Timeslots (%s)"
571
- msgstr "فاصله زمانی رویداد (%s)"
572
-
573
- #: templates/column/metabox-column-options.php:9
574
- msgid "Simple Column"
575
- msgstr "ستون ساده"
576
-
577
- #: templates/column/metabox-column-options.php:15
578
- msgid "Day"
579
- msgstr "روز"
580
-
581
- #: templates/column/metabox-column-options.php:19
582
- msgid "Sunday"
583
- msgstr "یک شنبه"
584
-
585
- #: templates/column/metabox-column-options.php:20
586
- msgid "Monday"
587
- msgstr "دوشنبه"
588
-
589
- #: templates/column/metabox-column-options.php:21
590
- msgid "Tuesday"
591
- msgstr "سه شنبه"
592
-
593
- #: templates/column/metabox-column-options.php:22
594
- msgid "Wednesday"
595
- msgstr "چهارشنبه"
596
-
597
- #: templates/column/metabox-column-options.php:23
598
- msgid "Thursday"
599
- msgstr "پنج شنبه"
600
-
601
- #: templates/column/metabox-column-options.php:24
602
- msgid "Friday"
603
- msgstr "جمعه"
604
-
605
- #: templates/column/metabox-column-options.php:25
606
- msgid "Saturday"
607
- msgstr "شنبه"
608
-
609
- #: templates/column/metabox-column-options.php:32
610
- msgid "Date"
611
- msgstr "تاریخ"
612
-
613
- #: templates/events/event-data.php:5
614
- msgid "Start"
615
- msgstr "شروع"
616
-
617
- #: templates/events/event-data.php:6
618
- msgid "End"
619
- msgstr "پایان"
620
-
621
- #: templates/events/event-data.php:8
622
- msgid "Head"
623
- msgstr "مسئول"
624
-
625
- #: templates/events/event-data.php:9
626
- msgid "Actions"
627
- msgstr "اقدامات"
628
-
629
- #: templates/events/event-data.php:32
630
- msgid "Edit event in the form below"
631
- msgstr "رویداد را در فرم زیر ویرایش کنید"
632
-
633
- #: templates/events/event-data.php:33
634
- msgid "Delete"
635
- msgstr "حذف"
636
-
637
- #: templates/events/metabox-event-data.php:10
638
- msgid "Column:"
639
- msgstr "ستون:"
640
-
641
- #: templates/events/metabox-event-data.php:18
642
- #, php-format
643
- msgid "Select column or <a target=\"_blank\" href=\"%s\">Add New</a>."
644
- msgstr "انتخاب یک ستون<a target=\"_blank\" href=\"%s\">افزودن ستون جدید</a>."
645
-
646
- #: templates/events/metabox-event-data.php:20
647
- #, php-format
648
- msgid "No columns found. <a href=\"%s\">Create at least one column first.</a>"
649
- msgstr "ستون یافت نشد. <a href=\"%s\">ابتدا حداقل یک ستون ایجاد کنید.</a>"
650
-
651
- #: templates/events/metabox-event-data.php:26
652
- msgid "Start Time:"
653
- msgstr "زمان شروع:"
654
-
655
- #: templates/events/metabox-event-data.php:29
656
- #: templates/events/metabox-event-data.php:36
657
- msgid "hh:mm"
658
- msgstr "hh:mm"
659
-
660
- #: templates/events/metabox-event-data.php:33
661
- msgid "End Time:"
662
- msgstr "زمان اتمام:"
663
-
664
- #: templates/events/metabox-event-data.php:40
665
- msgid "Description:"
666
- msgstr "توضیحات:"
667
-
668
- #: templates/events/metabox-event-data.php:44
669
- msgid "Event Head:"
670
- msgstr "مسئول رویداد:"
671
-
672
- #: templates/events/metabox-event-data.php:52
673
- msgid "none"
674
- msgstr "هیچکدام (خالی)"
675
-
676
- #: templates/events/metabox-event-data.php:75
677
- msgid "Add New"
678
- msgstr "مورد جدیدی اضافه کنید"
679
-
680
- #: templates/events/metabox-event-options.php:4
681
- msgid "Event Subtitle:"
682
- msgstr "عنوان فرعی رویداد:"
683
-
684
- #: templates/events/metabox-event-options.php:8
685
- msgid "Background Color:"
686
- msgstr "رنگ پس زمینه:"
687
-
688
- #: templates/events/metabox-event-options.php:15
689
- msgid "Background Hover Color:"
690
- msgstr "رنگ دور پس زمینه:"
691
-
692
- #: templates/events/metabox-event-options.php:22
693
- msgid "Text Color:"
694
- msgstr "رنگ متن:"
695
-
696
- #: templates/events/metabox-event-options.php:29
697
- msgid "Text Hover Color:"
698
- msgstr "رنگ سایه متن:"
699
-
700
- #: templates/events/metabox-event-options.php:36
701
- msgid "Custom Event URL:"
702
- msgstr "سفارشی کردن URL رویداد:"
703
-
704
- #: templates/events/metabox-event-options.php:42
705
- msgid "Disable link to this event:"
706
- msgstr "غیر فعال کردن لینک به این رویداد:"
707
-
708
- #: templates/popup/index.php:5
709
- msgid "<b>Columns</b> (required)"
710
- msgstr "<b>ستون</b> (ضروری)"
711
-
712
- #: templates/popup/index.php:12 templates/popup/index.php:23
713
- #: templates/popup/index.php:34
714
- msgid "In order to display multiple points hold ctrl/cmd button."
715
- msgstr "برای نمایش چندین نقطه دکمه ctrl / cmd را نگه دارید."
716
-
717
- #: templates/popup/index.php:16
718
- msgid "Specific <b>events</b>"
719
- msgstr "<b>رویدادهای</b> ویژه"
720
-
721
- #: templates/popup/index.php:27
722
- msgid "Event <b>categories</b>"
723
- msgstr "<b>دسته های</b> رویداد"
724
-
725
- #: templates/popup/index.php:38
726
- msgid "Fields to display:"
727
- msgstr "زمینه نمایش:"
728
-
729
- #: templates/popup/index.php:44
730
- msgid "Event Head"
731
- msgstr "مسئول رویداد"
732
-
733
- #: templates/popup/index.php:45
734
- msgid "Check the event parameter(s) to be displayed in the timetable."
735
- msgstr "پارامترهای رویداد را در جدول زمانبندی نمایش دهید."
736
-
737
- #: templates/popup/index.php:49
738
- msgid "Block height in pixels"
739
- msgstr "ارتفاع بلوک به صورت پیکسل"
740
-
741
- #: templates/popup/index.php:52
742
- msgid "Set height of the block"
743
- msgstr "ارتفاع بلوک را تنظیم کنید"
744
-
745
- #: templates/popup/index.php:56
746
- msgid "Base font size"
747
- msgstr "اندازه فونت پایه"
748
-
749
- #: templates/popup/index.php:59
750
- msgid "Base font size for the table. Example 12px, 2em, 80%."
751
- msgstr "اندازه فونت پایه برای جدول. مثال 12px، 2em، 80٪."
752
-
753
- #: templates/popup/index.php:63
754
- msgid "Time frame for event"
755
- msgstr "نحوه نمایش زمان برای رویداد"
756
-
757
- #: templates/popup/index.php:73
758
- msgid "Filter events style"
759
- msgstr "سبک فیلتر رویدادها"
760
-
761
- #: templates/popup/index.php:76
762
- msgid "Dropdown"
763
- msgstr "کشویی"
764
-
765
- #: templates/popup/index.php:78
766
- msgid "None"
767
- msgstr "هیچکدام"
768
-
769
- #: templates/popup/index.php:83
770
- msgid "Filter title to display all events"
771
- msgstr "عنوان فیلتر برای نمایش همه رویدادها"
772
-
773
- #: templates/popup/index.php:89
774
- msgid "Hide 'All Events' option"
775
- msgstr "پنهان کردن گزینه \"همه رویدادها\""
776
-
777
- #: templates/popup/index.php:99
778
- msgid "Hide column with hours"
779
- msgstr "پنهان کردن ستون با ساعت"
780
-
781
- #: templates/popup/index.php:108
782
- msgid "Do not display empty rows"
783
- msgstr "ردیف های خالی را نمایش ندهید"
784
-
785
- #: templates/popup/index.php:117
786
- msgid "Merge cells with common events"
787
- msgstr "ادغام سلول ها با رویدادهای مشترک"
788
-
789
- #: templates/popup/index.php:126 templates/widgets/gallery-list.php:56
790
- msgid "Disable event link"
791
- msgstr "پیوند رویداد را غیرفعال کنید"
792
-
793
- #: templates/popup/index.php:135
794
- msgid "Horizontal align"
795
- msgstr "تراز چیدمان افقی"
796
-
797
- #: templates/popup/index.php:144
798
- msgid "Vertical align"
799
- msgstr "تراز چیدمان عمودی"
800
-
801
- #: templates/popup/index.php:146
802
- msgid "default"
803
- msgstr "پیشفرض"
804
-
805
- #: templates/popup/index.php:147
806
- msgid "top"
807
- msgstr "بالا"
808
-
809
- #: templates/popup/index.php:148
810
- msgid "middle"
811
- msgstr "وسط"
812
-
813
- #: templates/popup/index.php:149
814
- msgid "bottom"
815
- msgstr "پایین"
816
-
817
- #: templates/popup/index.php:154
818
- msgid "Unique ID"
819
- msgstr "شناسه منحصر به فرد"
820
-
821
- #: templates/popup/index.php:157
822
- msgid ""
823
- "If you use more than one table on a page specify the unique ID for a "
824
- "timetable. It is usually all lowercase and contains only letters, numbers, "
825
- "and hyphens."
826
- msgstr ""
827
- "اگر بیش از یک جدول در یک صفحه استفاده کنید، شناسه منحصر به فرد برای یک جدول "
828
- "زمانی را مشخص کنید. شناسه منحصر به فرد به صورت حروف کوچک است و فقط شامل "
829
- "حروف، اعداد و خطوط است."
830
-
831
- #: templates/popup/index.php:161
832
- msgid "CSS class"
833
- msgstr "کلاس CSS"
834
-
835
- #: templates/popup/index.php:167
836
- msgid "Mobile behavior"
837
- msgstr "نحوه نمایش در موبایل"
838
-
839
- #: templates/popup/index.php:170
840
- msgid "List"
841
- msgstr "لیست"
842
-
843
- #: templates/popup/index.php:171
844
- msgid "Table"
845
- msgstr "جدول"
846
-
847
- #: templates/popup/index.php:173
848
- msgid ""
849
- "Tick \"List\" to display events in a list view on mobile devices. Tick "
850
- "\"Table\" to display events in a table."
851
- msgstr ""
852
- "با کلیک بر روی \"لیست\" رویدادها به صورت لیست زیر هم در موبایل به نمایش در "
853
- "می آید. و با انتخاب \"جدول\" رویدادها در یک جدول به نمایش گذاشته می شود.."
854
-
855
- #: templates/popup/index.php:179
856
- msgid "Add Timetable"
857
- msgstr "افزودن جدول زمانی"
858
-
859
- #: templates/settings/general.php:1
860
- msgid "General Settings"
861
- msgstr "تنظیمات عمومی"
862
-
863
- #: templates/settings/general.php:8
864
- msgid "Template Mode"
865
- msgstr "حالت الگو"
866
-
867
- #: templates/settings/general.php:12
868
- msgid "Theme Mode"
869
- msgstr "حالت قالب"
870
-
871
- #: templates/settings/general.php:13
872
- msgid "Developer Mode"
873
- msgstr "حالت توسعه دهنده"
874
-
875
- #: templates/settings/general.php:15
876
- msgid ""
877
- "Choose Theme Mode to display the content with the styles of your theme. "
878
- "Choose Developer Mode to control appearance of the content with custom page "
879
- "templates, actions and filters."
880
- msgstr ""
881
- "اگر میخواهید تا محتوا به سبک قالب فعلی به نمایش گذاشته شود \"حالت قالب\" را "
882
- "انتخاب کنید. اگر حالت توسعه دهنده را انتخاب کنید نحوه نمایش را کاملا می "
883
- "توانید سفارشی کنید."
884
-
885
- #: templates/settings/general.php:15
886
- msgid ""
887
- "This option can't be changed if your theme is initially integrated with the "
888
- "plugin."
889
- msgstr ""
890
- "این گزینه را نمی توان تغییر داد اگر موضوع شما در ابتدا با افزونه ادغام شود."
891
-
892
- #: templates/settings/general.php:20
893
- msgid "Save"
894
- msgstr "ذخیره"
895
-
896
- #: templates/shortcodes/empty-search-events.php:1
897
- #: templates/theme/widget-upcoming-view.php:54
898
- #: templates/widgets/widget-view.php:91
899
- msgid "no events found"
900
- msgstr "رویدادی یافت نشد"
901
-
902
- #: templates/templates-actions/action-sidebar.php:8
903
- #: templates/widgets/gallery-list.php:14
904
- msgid "Today upcoming events"
905
- msgstr "رویدادهای آینده در این روز"
906
-
907
- #: templates/templates-actions/action-sidebar.php:13
908
- #: templates/widgets/gallery-list.php:16
909
- msgid "All upcoming events"
910
- msgstr "همه رویدادهای آینده"
911
-
912
- #: templates/widgets/gallery-list.php:10
913
- msgid "Events to display"
914
- msgstr "رویدادهای برای نمایش"
915
-
916
- #: templates/widgets/gallery-list.php:18
917
- msgid "Ongoing events"
918
- msgstr "رویدادهای پیش رو"
919
-
920
- #: templates/widgets/gallery-list.php:23
921
- msgid "Input number of days"
922
- msgstr "تعداد ورودی ها در روز"
923
-
924
- #: templates/widgets/gallery-list.php:28
925
- msgid "day"
926
- msgstr "روز"
927
-
928
- #: templates/widgets/gallery-list.php:32
929
- msgid "Event categories. Leave blank to display all."
930
- msgstr "دسته های رویداد، برای نمایش همه خالی بگذارید"
931
-
932
- #: templates/widgets/gallery-list.php:49
933
- msgid "Number of events to display"
934
- msgstr "تعداد رویداد قایل نمایش"
935
-
936
- #: templates/widgets/gallery-list.php:67
937
- msgid "Custom link for events"
938
- msgstr "آدرس سفارشی برای رویداد"
939
-
940
- #: templates/widgets/gallery-list.php:75
941
- msgid "Event background color"
942
- msgstr "رنگ پشت زمینه رویداد"
943
-
944
- #: templates/widgets/gallery-list.php:85
945
- msgid "Event background color on hover"
946
- msgstr "رنگ سایه پشت زمینه رویداد"
947
-
948
- #: templates/widgets/gallery-list.php:95
949
- msgid "Event text color"
950
- msgstr "رنگ متن رویداد"
951
-
952
- #: templates/widgets/gallery-list.php:105
953
- msgid "Event text color on hover"
954
- msgstr "رنگ سایه متن رویداد"
955
-
956
- #: templates/widgets/gallery-list.php:115
957
- msgid "Event border color"
958
- msgstr "رنگ کادر دور رویداد"
959
-
960
- #: templates/widgets/gallery-list.php:125
961
- msgid "Event border color on hover"
962
- msgstr "رنگ سایه کادر دور رویداد"
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Timetable and Event Schedule Plugin\n"
4
+ "POT-Creation-Date: 2018-05-18 09:58+0430\n"
5
+ "PO-Revision-Date: \n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Alireza Rastegar<alireza.mine@gmail.com>\n"
8
+ "Language: fa_IR\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=1; plural=0;\n"
13
+ "X-Generator: Poedit 2.0.1\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-KeywordsList: esc_attr__;esc_html__;esc_attr_e;__;_e;_n;_x\n"
16
+ "X-Poedit-Basepath: ..\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+ "X-Poedit-SearchPathExcluded-0: classes/libs\n"
19
+ "X-Poedit-SearchPathExcluded-1: media\n"
20
+
21
+ #: admin/import/export.php:1 admin/import/export.php:5
22
+ msgid "Export"
23
+ msgstr "برونریزی"
24
+
25
+ #: admin/import/greet.php:2
26
+ msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
27
+ msgstr ""
28
+ "یک فایل WXR (.xml) را برای آپلود انتخاب کنید، سپس روی آپلود فایل و وارد کردن "
29
+ "کلیک کنید."
30
+
31
+ #: admin/import/header.php:2
32
+ msgid "Import / Export Timetable Plugin Data"
33
+ msgstr "درون ریزی / برون ریزی داده افزونه جدول زمانی"
34
+
35
+ #: admin/import/import.php:1
36
+ msgid "Import"
37
+ msgstr "درون ریزی"
38
+
39
+ #: classes/class-core.php:317 classes/class-core.php:329
40
+ #: classes/class-core.php:333 classes/class-shortcode.php:261
41
+ msgid "Event categories"
42
+ msgstr "دسته های رویداد"
43
+
44
+ #: classes/class-core.php:318
45
+ msgid "Event category"
46
+ msgstr "دسته بندی رویداد"
47
+
48
+ #: classes/class-core.php:319 classes/class-core.php:320
49
+ msgid "Add New Event category"
50
+ msgstr "افزودن دسته بندی رویداد"
51
+
52
+ #: classes/class-core.php:321
53
+ msgid "Edit Event category"
54
+ msgstr "ویرایش دسته بندی رویداد"
55
+
56
+ #: classes/class-core.php:322
57
+ msgid "New Event category"
58
+ msgstr "دسته رویداد جدید"
59
+
60
+ #: classes/class-core.php:323
61
+ msgid "All Event categories"
62
+ msgstr "همه دسته های رویداد"
63
+
64
+ #: classes/class-core.php:324
65
+ msgid "View Event category"
66
+ msgstr "نمایش دسته رویداد"
67
+
68
+ #: classes/class-core.php:325
69
+ msgid "Search Event category"
70
+ msgstr "جستجوی دسته رویداد"
71
+
72
+ #: classes/class-core.php:326
73
+ msgid "No Event categories found"
74
+ msgstr "دسته رویدادی پیدا نشد"
75
+
76
+ #: classes/class-core.php:327
77
+ msgid "No Event categories found in Trash"
78
+ msgstr "هیچ دسته رویدادی در «حذف شده ها» یافت نشد"
79
+
80
+ #: classes/class-core.php:356 classes/class-core.php:368
81
+ #: classes/class-core.php:372
82
+ msgid "Event tags"
83
+ msgstr "برچسب های رویداد"
84
+
85
+ #: classes/class-core.php:357
86
+ msgid "Event tag"
87
+ msgstr "برچسب رویداد"
88
+
89
+ #: classes/class-core.php:358 classes/class-core.php:359
90
+ msgid "Add New Event tag"
91
+ msgstr "افزودن برچسب جدید رویداد"
92
+
93
+ #: classes/class-core.php:360
94
+ msgid "Edit Event tag"
95
+ msgstr "ویرایش برچسب رویداد"
96
+
97
+ #: classes/class-core.php:361
98
+ msgid "New Event tag"
99
+ msgstr "برچسب جدید رویداد"
100
+
101
+ #: classes/class-core.php:362
102
+ msgid "All Event tags"
103
+ msgstr "همه برچسب های رویداد"
104
+
105
+ #: classes/class-core.php:363
106
+ msgid "View Event tag"
107
+ msgstr "نمایش برچسب رویداد"
108
+
109
+ #: classes/class-core.php:364
110
+ msgid "Search Event tag"
111
+ msgstr "جستجوی برچسب رویداد"
112
+
113
+ #: classes/class-core.php:365
114
+ msgid "No Event tags found"
115
+ msgstr "برچسب رویداد یافت نشد"
116
+
117
+ #: classes/class-core.php:366
118
+ msgid "No Event tags found in Trash"
119
+ msgstr "هیچ برچسب رویدادی در «حذف شده ها» یافت نشد"
120
+
121
+ #: classes/class-core.php:404 classes/class-core.php:416
122
+ #: classes/class-hooks.php:171 classes/class-shortcode.php:256
123
+ msgid "Events"
124
+ msgstr "رویدادها"
125
+
126
+ #: classes/class-core.php:405
127
+ msgid "Event"
128
+ msgstr "رویداد"
129
+
130
+ #: classes/class-core.php:406 classes/class-core.php:407
131
+ msgid "Add New Event"
132
+ msgstr "افزودن رویداد جدید"
133
+
134
+ #: classes/class-core.php:408
135
+ msgid "Edit Event"
136
+ msgstr "ویرایش رویداد"
137
+
138
+ #: classes/class-core.php:409
139
+ msgid "New Event"
140
+ msgstr "رویداد جدید"
141
+
142
+ #: classes/class-core.php:410 classes/class-shortcode.php:69
143
+ #: classes/class-shortcode.php:277
144
+ #: templates-functions/action-shortcode-functions.php:39
145
+ #: templates-functions/action-shortcode-functions.php:52
146
+ #: templates-functions/action-shortcode-functions.php:53
147
+ msgid "All Events"
148
+ msgstr "همه رویدادها"
149
+
150
+ #: classes/class-core.php:411
151
+ msgid "View Event"
152
+ msgstr "نمایش رویداد"
153
+
154
+ #: classes/class-core.php:412
155
+ msgid "Search Event"
156
+ msgstr "جستجوی رویداد"
157
+
158
+ #: classes/class-core.php:413
159
+ msgid "No Events found"
160
+ msgstr "رویدادی یافت نشد"
161
+
162
+ #: classes/class-core.php:414
163
+ msgid "No Events found in Trash"
164
+ msgstr "هیچ رویدادی در «حذف شده ها» یافت نشد"
165
+
166
+ #: classes/class-core.php:438 classes/class-core.php:450
167
+ #: classes/class-hooks.php:173
168
+ msgid "Columns"
169
+ msgstr "ستون ها"
170
+
171
+ #: classes/class-core.php:439 classes/class-shortcode.php:251
172
+ #: templates/events/event-data.php:4
173
+ msgid "Column"
174
+ msgstr "ستون"
175
+
176
+ #: classes/class-core.php:440 classes/class-core.php:441
177
+ msgid "Add New Column"
178
+ msgstr "افزودن ستون جدید"
179
+
180
+ #: classes/class-core.php:442
181
+ msgid "Edit Column"
182
+ msgstr "ویرایش ستون"
183
+
184
+ #: classes/class-core.php:443
185
+ msgid "New Column"
186
+ msgstr "ستون جدید"
187
+
188
+ #: classes/class-core.php:444
189
+ msgid "All Columns"
190
+ msgstr "همه ستون ها"
191
+
192
+ #: classes/class-core.php:445
193
+ msgid "View Column"
194
+ msgstr "نمایش ستون"
195
+
196
+ #: classes/class-core.php:446
197
+ msgid "Search Column"
198
+ msgstr "جستجوی ستون"
199
+
200
+ #: classes/class-core.php:447
201
+ msgid "No Columns found"
202
+ msgstr "هیچ ستونی یافت نشد"
203
+
204
+ #: classes/class-core.php:448
205
+ msgid "No Columns found in Trash"
206
+ msgstr "هیچ ستونی در «حذف شده ها» یافت نشد"
207
+
208
+ #: classes/class-hooks.php:66
209
+ msgid "Timetable Sidebar"
210
+ msgstr "ابزارک جدول زمانی"
211
+
212
+ #: classes/class-hooks.php:68 classes/class-hooks.php:170
213
+ #: classes/class-shortcode.php:356
214
+ msgid "Timetable"
215
+ msgstr "جدول زمانی"
216
+
217
+ #: classes/class-hooks.php:163
218
+ msgid "Import Timetable events, categories, tags and images."
219
+ msgstr "درون ریزی رویدادهای جدول زمانی، دسته بندی ها، برچسب ها و عکس ها"
220
+
221
+ #: classes/class-hooks.php:172
222
+ msgid "Add Event"
223
+ msgstr "افزودن رویداد"
224
+
225
+ #: classes/class-hooks.php:174
226
+ msgid "Add Column"
227
+ msgstr "افزودن ستون"
228
+
229
+ #: classes/class-hooks.php:175
230
+ msgid "Event Categories"
231
+ msgstr "دسته های رویداد"
232
+
233
+ #: classes/class-hooks.php:176
234
+ msgid "Event Tags"
235
+ msgstr "برچسب های رویداد"
236
+
237
+ #: classes/class-hooks.php:177 classes/modules/class-post.php:41
238
+ msgid "Settings"
239
+ msgstr "تنظیمات"
240
+
241
+ #: classes/class-hooks.php:178
242
+ msgid "Export / Import"
243
+ msgstr "درون ریزی/برون ریزی"
244
+
245
+ #: classes/class-shortcode.php:266
246
+ msgid "Hour measure"
247
+ msgstr "اندازه گیری ساعت"
248
+
249
+ #: classes/class-shortcode.php:267 templates/popup/index.php:66
250
+ msgid "Hour (1h)"
251
+ msgstr "ساعت (1 ساعت)"
252
+
253
+ #: classes/class-shortcode.php:267 templates/popup/index.php:67
254
+ msgid "Half hour (30min)"
255
+ msgstr "نیم ساعت (30 دقیقه)"
256
+
257
+ #: classes/class-shortcode.php:267 templates/popup/index.php:68
258
+ msgid "Quarter hour (15min)"
259
+ msgstr "ربع ساعت (15 دقیقه)"
260
+
261
+ #: classes/class-shortcode.php:271
262
+ msgid "Filter style"
263
+ msgstr "سبک فیلتر"
264
+
265
+ #: classes/class-shortcode.php:272
266
+ msgid "Dropdown list"
267
+ msgstr "لیست بازشو"
268
+
269
+ #: classes/class-shortcode.php:272 templates/popup/index.php:77
270
+ msgid "Tabs"
271
+ msgstr "تب ها"
272
+
273
+ #: classes/class-shortcode.php:276
274
+ msgid "Filter label"
275
+ msgstr "برچسب فیلتر"
276
+
277
+ #: classes/class-shortcode.php:281
278
+ msgid "Hide 'All Events' view"
279
+ msgstr "نمایش ندادن همه رویدادها"
280
+
281
+ #: classes/class-shortcode.php:282 classes/class-shortcode.php:287
282
+ #: classes/class-shortcode.php:292 classes/class-shortcode.php:299
283
+ #: classes/class-shortcode.php:305 classes/class-shortcode.php:311
284
+ #: classes/class-shortcode.php:317 classes/class-shortcode.php:323
285
+ #: classes/class-shortcode.php:328 classes/class-shortcode.php:352
286
+ #: templates/events/metabox-event-options.php:45 templates/popup/index.php:93
287
+ #: templates/popup/index.php:102 templates/popup/index.php:112
288
+ #: templates/popup/index.php:120 templates/popup/index.php:129
289
+ #: templates/widgets/gallery-list.php:60
290
+ msgid "No"
291
+ msgstr "خیر"
292
+
293
+ #: classes/class-shortcode.php:282 classes/class-shortcode.php:287
294
+ #: classes/class-shortcode.php:292 classes/class-shortcode.php:299
295
+ #: classes/class-shortcode.php:305 classes/class-shortcode.php:311
296
+ #: classes/class-shortcode.php:317 classes/class-shortcode.php:323
297
+ #: classes/class-shortcode.php:328 classes/class-shortcode.php:352
298
+ #: templates/events/metabox-event-options.php:46 templates/popup/index.php:94
299
+ #: templates/popup/index.php:103 templates/popup/index.php:111
300
+ #: templates/popup/index.php:121 templates/popup/index.php:130
301
+ #: templates/widgets/gallery-list.php:62
302
+ msgid "Yes"
303
+ msgstr "بله"
304
+
305
+ #: classes/class-shortcode.php:286
306
+ msgid "Hide first (hours) column"
307
+ msgstr "پنهان کردن ستون اول (ساعت)"
308
+
309
+ #: classes/class-shortcode.php:291
310
+ msgid "Hide empty rows"
311
+ msgstr "پنهان کردن سطرهای خالی"
312
+
313
+ #: classes/class-shortcode.php:297 templates/popup/index.php:40
314
+ #: templates/widgets/gallery-list.php:3
315
+ msgid "Title"
316
+ msgstr "عنوان"
317
+
318
+ #: classes/class-shortcode.php:303 templates/popup/index.php:41
319
+ msgid "Time"
320
+ msgstr "زمان"
321
+
322
+ #: classes/class-shortcode.php:309 templates/popup/index.php:42
323
+ msgid "Subtitle"
324
+ msgstr "عنوان فرعی"
325
+
326
+ #: classes/class-shortcode.php:315 templates/events/event-data.php:7
327
+ #: templates/popup/index.php:43
328
+ msgid "Description"
329
+ msgstr "توضیحات"
330
+
331
+ #: classes/class-shortcode.php:321
332
+ msgid "User"
333
+ msgstr "کاربر"
334
+
335
+ #: classes/class-shortcode.php:327
336
+ msgid "Disable event URL"
337
+ msgstr "URL رویداد را غیرفعال کنید"
338
+
339
+ #: classes/class-shortcode.php:332
340
+ msgid "Text align"
341
+ msgstr "چیدمان متن"
342
+
343
+ #: classes/class-shortcode.php:333 templates/popup/index.php:137
344
+ msgid "center"
345
+ msgstr "وسط"
346
+
347
+ #: classes/class-shortcode.php:333 templates/popup/index.php:138
348
+ msgid "left"
349
+ msgstr "چپ"
350
+
351
+ #: classes/class-shortcode.php:333 templates/popup/index.php:139
352
+ msgid "right"
353
+ msgstr "راست"
354
+
355
+ #: classes/class-shortcode.php:337
356
+ msgid "Id"
357
+ msgstr "ID"
358
+
359
+ #: classes/class-shortcode.php:341
360
+ msgid "Row height (in px)"
361
+ msgstr "ارتفاع ردیف (در پیکسل)"
362
+
363
+ #: classes/class-shortcode.php:346
364
+ msgid "Base Font Size"
365
+ msgstr "اندازه فونت پایه"
366
+
367
+ #: classes/class-shortcode.php:351
368
+ msgid "Responsive"
369
+ msgstr "واکنش گرایی"
370
+
371
+ #: classes/controllers/class-controller-settings.php:53
372
+ msgid "Settings saved."
373
+ msgstr "تنظیمات ذخیره شد."
374
+
375
+ #: classes/models/class-column.php:42 classes/modules/class-post.php:40
376
+ msgid "Timeslots"
377
+ msgstr "فاصله زمانی"
378
+
379
+ #: classes/models/class-events.php:167
380
+ msgid "Tags"
381
+ msgstr "تگ ها"
382
+
383
+ #: classes/models/class-events.php:168
384
+ msgid "Categories"
385
+ msgstr "دسته ها"
386
+
387
+ #: classes/models/class-import.php:125
388
+ msgid "Assign Authors"
389
+ msgstr "اختصاص دادن نویسندگان"
390
+
391
+ #: classes/models/class-import.php:126
392
+ msgid ""
393
+ "To make it easier for you to edit and save the imported content, you may "
394
+ "want to reassign the author of the imported item to an existing user of this "
395
+ "site. For example, you may want to import all the entries as <code>admin</"
396
+ "code>s entries."
397
+ msgstr ""
398
+ "برای اینکه بتوانید محتوای وارد شده را ویرایش و ذخیره کنید، ممکن است بخواهید "
399
+ "نویسنده اثر وارد شده را به یک کاربر فعلی این سایت مجددا اختصاص دهید.به عنوان "
400
+ "مثال، شما ممکن است بخواهید تمام ورودی ها را به عنوان ورودی <code> مدیر </"
401
+ "code> وارد کنید."
402
+
403
+ #: classes/models/class-import.php:128
404
+ #, php-format
405
+ msgid ""
406
+ "If a new user is created by WordPress, a new password will be randomly "
407
+ "generated and the new user&#8217;s role will be set as %s. Manually changing "
408
+ "the new user&#8217;s details will be necessary."
409
+ msgstr ""
410
+ "اگر یک کاربر جدید توسط وردپرس ایجاد شده باشد، یک رمز عبور جدید به صورت "
411
+ "تصادفی ایجاد خواهد شد و نقش کاربر جدید user&#8217;s به عنوان %s تنظیم خواهد "
412
+ "شد. تغییر دستی اطلاعات جدید کاربر user&#8217;s ضروری است."
413
+
414
+ #: classes/models/class-import.php:138
415
+ msgid "Import Attachments"
416
+ msgstr "درون ریزی پیوست ها"
417
+
418
+ #: classes/models/class-import.php:141
419
+ msgid "Download and import file attachments"
420
+ msgstr "دریافت و درون ریزی فایل های پیوست"
421
+
422
+ #: classes/models/class-import.php:145
423
+ msgid "Submit"
424
+ msgstr "ارسال"
425
+
426
+ #: classes/models/class-import.php:158
427
+ msgid "Import author:"
428
+ msgstr "درون ریزی نویسنده:"
429
+
430
+ #: classes/models/class-import.php:169
431
+ msgid "or create new user with login name:"
432
+ msgstr "یا ایجاد کاربر جدید با نام کاربری:"
433
+
434
+ #: classes/models/class-import.php:172
435
+ msgid "as a new user:"
436
+ msgstr "به عنوان یک کاربر جدید:"
437
+
438
+ #: classes/models/class-import.php:180
439
+ msgid "assign posts to an existing user:"
440
+ msgstr "اختصاص دادن پست به یک کاربر موجود:"
441
+
442
+ #: classes/models/class-import.php:182
443
+ msgid "or assign posts to an existing user:"
444
+ msgstr "یا اختصاص دادن پست به یک کاربر موجود:"
445
+
446
+ #: classes/models/class-import.php:183
447
+ #: templates/column/metabox-column-options.php:18
448
+ msgid "- Select -"
449
+ msgstr "- انتخاب -"
450
+
451
+ #: classes/models/class-import.php:269
452
+ msgid "All done."
453
+ msgstr "همه انجام شد."
454
+
455
+ #: classes/models/class-import.php:269
456
+ msgid "Have fun!"
457
+ msgstr "خوش بگذره!"
458
+
459
+ #: classes/models/class-import.php:270
460
+ msgid "Remember to update the passwords and roles of imported users."
461
+ msgstr ""
462
+ "به خاطر داشته باشید که کلمه عبور و نقش کاربران وارد شده را به روز کنید."
463
+
464
+ #: classes/models/class-import.php:286
465
+ msgid "Fetching attachments is not enabled"
466
+ msgstr "پیوست های دریافتی فعال نیستند"
467
+
468
+ #: classes/models/class-import.php:299
469
+ msgid "Invalid file type"
470
+ msgstr "نوع فایل نامعتبر است"
471
+
472
+ #: classes/models/class-import.php:379
473
+ msgid "Remote server did not respond"
474
+ msgstr "سرور از راه دور جواب نمی دهد"
475
+
476
+ #: classes/models/class-import.php:385
477
+ #, php-format
478
+ msgid "Remote server returned error response %1$d %2$s"
479
+ msgstr "سرور راه دور پاسخ خطا %1$d %2$s را دریافت کرد"
480
+
481
+ #: classes/models/class-import.php:394
482
+ msgid "Remote file is incorrect size"
483
+ msgstr "سایز فایل ارسالی سرور رته دور نادرست است"
484
+
485
+ #: classes/models/class-import.php:399
486
+ msgid "Zero size file downloaded"
487
+ msgstr "سایز فایل دانلود شده صفر می باشد"
488
+
489
+ #: classes/models/class-import.php:405
490
+ #, php-format
491
+ msgid "Remote file is too large, limit is %s"
492
+ msgstr "سایز فایل از راه دور بسیار بزرگ است، سایز به %s محدود شده"
493
+
494
+ #: classes/models/class-import.php:422 classes/models/class-import.php:426
495
+ #: classes/models/class-import.php:436
496
+ msgid "Sorry, there has been an error."
497
+ msgstr "با عرض پوزش، یک خطا وجود دارد."
498
+
499
+ #: classes/models/class-import.php:427
500
+ #, php-format
501
+ msgid ""
502
+ "The export file could not be found at <code>%s</code>. It is likely that "
503
+ "this was caused by a permissions problem."
504
+ msgstr ""
505
+ "فایل درون ریزی در <code>%s</code> یافت نمی شود. احتمالا این مسئله توسط یک "
506
+ "مشکل مجوز ایجاد شده است."
507
+
508
+ #: classes/models/class-import.php:444
509
+ #, php-format
510
+ msgid ""
511
+ "This WXR file (version %s) may not be supported by this version of the "
512
+ "importer. Please consider updating."
513
+ msgstr ""
514
+ "این فایل WXR (نسخه %s) ممکن است توسط این نسخه از وارد کننده پشتیبانی نشود. "
515
+ "لطفا به روزرسانی کنید."
516
+
517
+ #: classes/models/class-import.php:501
518
+ #, php-format
519
+ msgid ""
520
+ "Failed to import author %s. Their posts will be attributed to the current "
521
+ "user."
522
+ msgstr ""
523
+ "وارد کردن نویسنده %s امکان پذیر نبود. پست های آن به کاربر فعلی نسبت داده می "
524
+ "شود."
525
+
526
+ #: classes/models/class-import.php:558
527
+ #, php-format
528
+ msgid ""
529
+ "Failed to create new user for %s. Their posts will be attributed to the "
530
+ "current user."
531
+ msgstr ""
532
+ "امکان ایجاد کاربر جدید برای %s نبود. پست های آن به کاربر فعلی نسبت داده می "
533
+ "شود."
534
+
535
+ #: classes/models/class-import.php:609 classes/models/class-import.php:766
536
+ #, php-format
537
+ msgid "Failed to import %s %s"
538
+ msgstr "درون ریزی نا موفق بود %s %s"
539
+
540
+ #: classes/models/class-import.php:656
541
+ #, php-format
542
+ msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
543
+ msgstr "وارد کردن &#8220;%s&#8221;: ناموفق بود. نوع پست %s نامعتبر است"
544
+
545
+ #: classes/models/class-import.php:673
546
+ #, php-format
547
+ msgid "%s &#8220;%s&#8221; already exists."
548
+ msgstr "%s &#8220;%s&#8221; درحال حاضر وجود دارد."
549
+
550
+ #: classes/models/class-import.php:732
551
+ #, php-format
552
+ msgid "Failed to import %s &#8220;%s&#8221;"
553
+ msgstr "%s &#8220;%s&#8221; وارد کردن نشد"
554
+
555
+ #: classes/modules/class-post.php:42
556
+ msgid "Column Type"
557
+ msgstr "نوع ستون"
558
+
559
+ #: classes/widgets/class-mp-timetable-widget.php:22
560
+ msgid "Display upcoming events."
561
+ msgstr "نمایش رویدادهای آینده"
562
+
563
+ #: classes/widgets/class-mp-timetable-widget.php:24
564
+ msgid "Timetable Events"
565
+ msgstr "جدول زمانی رویدادها"
566
+
567
+ #: templates-functions/actions-mp-event-functions.php:27
568
+ #: templates/theme/event-timeslots.php:7
569
+ #, php-format
570
+ msgid "Event Timeslots (%s)"
571
+ msgstr "فاصله زمانی رویداد (%s)"
572
+
573
+ #: templates/column/metabox-column-options.php:9
574
+ msgid "Simple Column"
575
+ msgstr "ستون ساده"
576
+
577
+ #: templates/column/metabox-column-options.php:15
578
+ msgid "Day"
579
+ msgstr "روز"
580
+
581
+ #: templates/column/metabox-column-options.php:19
582
+ msgid "Sunday"
583
+ msgstr "یک شنبه"
584
+
585
+ #: templates/column/metabox-column-options.php:20
586
+ msgid "Monday"
587
+ msgstr "دوشنبه"
588
+
589
+ #: templates/column/metabox-column-options.php:21
590
+ msgid "Tuesday"
591
+ msgstr "سه شنبه"
592
+
593
+ #: templates/column/metabox-column-options.php:22
594
+ msgid "Wednesday"
595
+ msgstr "چهارشنبه"
596
+
597
+ #: templates/column/metabox-column-options.php:23
598
+ msgid "Thursday"
599
+ msgstr "پنج شنبه"
600
+
601
+ #: templates/column/metabox-column-options.php:24
602
+ msgid "Friday"
603
+ msgstr "جمعه"
604
+
605
+ #: templates/column/metabox-column-options.php:25
606
+ msgid "Saturday"
607
+ msgstr "شنبه"
608
+
609
+ #: templates/column/metabox-column-options.php:32
610
+ msgid "Date"
611
+ msgstr "تاریخ"
612
+
613
+ #: templates/events/event-data.php:5
614
+ msgid "Start"
615
+ msgstr "شروع"
616
+
617
+ #: templates/events/event-data.php:6
618
+ msgid "End"
619
+ msgstr "پایان"
620
+
621
+ #: templates/events/event-data.php:8
622
+ msgid "Head"
623
+ msgstr "مسئول"
624
+
625
+ #: templates/events/event-data.php:9
626
+ msgid "Actions"
627
+ msgstr "اقدامات"
628
+
629
+ #: templates/events/event-data.php:32
630
+ msgid "Edit event in the form below"
631
+ msgstr "رویداد را در فرم زیر ویرایش کنید"
632
+
633
+ #: templates/events/event-data.php:33
634
+ msgid "Delete"
635
+ msgstr "حذف"
636
+
637
+ #: templates/events/metabox-event-data.php:10
638
+ msgid "Column:"
639
+ msgstr "ستون:"
640
+
641
+ #: templates/events/metabox-event-data.php:18
642
+ #, php-format
643
+ msgid "Select column or <a target=\"_blank\" href=\"%s\">Add New</a>."
644
+ msgstr "انتخاب یک ستون<a target=\"_blank\" href=\"%s\">افزودن ستون جدید</a>."
645
+
646
+ #: templates/events/metabox-event-data.php:20
647
+ #, php-format
648
+ msgid "No columns found. <a href=\"%s\">Create at least one column first.</a>"
649
+ msgstr "ستون یافت نشد. <a href=\"%s\">ابتدا حداقل یک ستون ایجاد کنید.</a>"
650
+
651
+ #: templates/events/metabox-event-data.php:26
652
+ msgid "Start Time:"
653
+ msgstr "زمان شروع:"
654
+
655
+ #: templates/events/metabox-event-data.php:29
656
+ #: templates/events/metabox-event-data.php:36
657
+ msgid "hh:mm"
658
+ msgstr "hh:mm"
659
+
660
+ #: templates/events/metabox-event-data.php:33
661
+ msgid "End Time:"
662
+ msgstr "زمان اتمام:"
663
+
664
+ #: templates/events/metabox-event-data.php:40
665
+ msgid "Description:"
666
+ msgstr "توضیحات:"
667
+
668
+ #: templates/events/metabox-event-data.php:44
669
+ msgid "Event Head:"
670
+ msgstr "مسئول رویداد:"
671
+
672
+ #: templates/events/metabox-event-data.php:52
673
+ msgid "none"
674
+ msgstr "هیچکدام (خالی)"
675
+
676
+ #: templates/events/metabox-event-data.php:75
677
+ msgid "Add New"
678
+ msgstr "مورد جدیدی اضافه کنید"
679
+
680
+ #: templates/events/metabox-event-options.php:4
681
+ msgid "Event Subtitle:"
682
+ msgstr "عنوان فرعی رویداد:"
683
+
684
+ #: templates/events/metabox-event-options.php:8
685
+ msgid "Background Color:"
686
+ msgstr "رنگ پس زمینه:"
687
+
688
+ #: templates/events/metabox-event-options.php:15
689
+ msgid "Background Hover Color:"
690
+ msgstr "رنگ دور پس زمینه:"
691
+
692
+ #: templates/events/metabox-event-options.php:22
693
+ msgid "Text Color:"
694
+ msgstr "رنگ متن:"
695
+
696
+ #: templates/events/metabox-event-options.php:29
697
+ msgid "Text Hover Color:"
698
+ msgstr "رنگ سایه متن:"
699
+
700
+ #: templates/events/metabox-event-options.php:36
701
+ msgid "Custom Event URL:"
702
+ msgstr "سفارشی کردن URL رویداد:"
703
+
704
+ #: templates/events/metabox-event-options.php:42
705
+ msgid "Disable link to this event:"
706
+ msgstr "غیر فعال کردن لینک به این رویداد:"
707
+
708
+ #: templates/popup/index.php:5
709
+ msgid "<b>Columns</b> (required)"
710
+ msgstr "<b>ستون</b> (ضروری)"
711
+
712
+ #: templates/popup/index.php:12 templates/popup/index.php:23
713
+ #: templates/popup/index.php:34
714
+ msgid "In order to display multiple points hold ctrl/cmd button."
715
+ msgstr "برای نمایش چندین نقطه دکمه ctrl / cmd را نگه دارید."
716
+
717
+ #: templates/popup/index.php:16
718
+ msgid "Specific <b>events</b>"
719
+ msgstr "<b>رویدادهای</b> ویژه"
720
+
721
+ #: templates/popup/index.php:27
722
+ msgid "Event <b>categories</b>"
723
+ msgstr "<b>دسته های</b> رویداد"
724
+
725
+ #: templates/popup/index.php:38
726
+ msgid "Fields to display:"
727
+ msgstr "زمینه نمایش:"
728
+
729
+ #: templates/popup/index.php:44
730
+ msgid "Event Head"
731
+ msgstr "مسئول رویداد"
732
+
733
+ #: templates/popup/index.php:45
734
+ msgid "Check the event parameter(s) to be displayed in the timetable."
735
+ msgstr "پارامترهای رویداد را در جدول زمانبندی نمایش دهید."
736
+
737
+ #: templates/popup/index.php:49
738
+ msgid "Block height in pixels"
739
+ msgstr "ارتفاع بلوک به صورت پیکسل"
740
+
741
+ #: templates/popup/index.php:52
742
+ msgid "Set height of the block"
743
+ msgstr "ارتفاع بلوک را تنظیم کنید"
744
+
745
+ #: templates/popup/index.php:56
746
+ msgid "Base font size"
747
+ msgstr "اندازه فونت پایه"
748
+
749
+ #: templates/popup/index.php:59
750
+ msgid "Base font size for the table. Example 12px, 2em, 80%."
751
+ msgstr "اندازه فونت پایه برای جدول. مثال 12px، 2em، 80٪."
752
+
753
+ #: templates/popup/index.php:63
754
+ msgid "Time frame for event"
755
+ msgstr "نحوه نمایش زمان برای رویداد"
756
+
757
+ #: templates/popup/index.php:73
758
+ msgid "Filter events style"
759
+ msgstr "سبک فیلتر رویدادها"
760
+
761
+ #: templates/popup/index.php:76
762
+ msgid "Dropdown"
763
+ msgstr "کشویی"
764
+
765
+ #: templates/popup/index.php:78
766
+ msgid "None"
767
+ msgstr "هیچکدام"
768
+
769
+ #: templates/popup/index.php:83
770
+ msgid "Filter title to display all events"
771
+ msgstr "عنوان فیلتر برای نمایش همه رویدادها"
772
+
773
+ #: templates/popup/index.php:89
774
+ msgid "Hide 'All Events' option"
775
+ msgstr "پنهان کردن گزینه \"همه رویدادها\""
776
+
777
+ #: templates/popup/index.php:99
778
+ msgid "Hide column with hours"
779
+ msgstr "پنهان کردن ستون با ساعت"
780
+
781
+ #: templates/popup/index.php:108
782
+ msgid "Do not display empty rows"
783
+ msgstr "ردیف های خالی را نمایش ندهید"
784
+
785
+ #: templates/popup/index.php:117
786
+ msgid "Merge cells with common events"
787
+ msgstr "ادغام سلول ها با رویدادهای مشترک"
788
+
789
+ #: templates/popup/index.php:126 templates/widgets/gallery-list.php:56
790
+ msgid "Disable event link"
791
+ msgstr "پیوند رویداد را غیرفعال کنید"
792
+
793
+ #: templates/popup/index.php:135
794
+ msgid "Horizontal align"
795
+ msgstr "تراز چیدمان افقی"
796
+
797
+ #: templates/popup/index.php:144
798
+ msgid "Vertical align"
799
+ msgstr "تراز چیدمان عمودی"
800
+
801
+ #: templates/popup/index.php:146
802
+ msgid "default"
803
+ msgstr "پیشفرض"
804
+
805
+ #: templates/popup/index.php:147
806
+ msgid "top"
807
+ msgstr "بالا"
808
+
809
+ #: templates/popup/index.php:148
810
+ msgid "middle"
811
+ msgstr "وسط"
812
+
813
+ #: templates/popup/index.php:149
814
+ msgid "bottom"
815
+ msgstr "پایین"
816
+
817
+ #: templates/popup/index.php:154
818
+ msgid "Unique ID"
819
+ msgstr "شناسه منحصر به فرد"
820
+
821
+ #: templates/popup/index.php:157
822
+ msgid ""
823
+ "If you use more than one table on a page specify the unique ID for a "
824
+ "timetable. It is usually all lowercase and contains only letters, numbers, "
825
+ "and hyphens."
826
+ msgstr ""
827
+ "اگر بیش از یک جدول در یک صفحه استفاده کنید، شناسه منحصر به فرد برای یک جدول "
828
+ "زمانی را مشخص کنید. شناسه منحصر به فرد به صورت حروف کوچک است و فقط شامل "
829
+ "حروف، اعداد و خطوط است."
830
+
831
+ #: templates/popup/index.php:161
832
+ msgid "CSS class"
833
+ msgstr "کلاس CSS"
834
+
835
+ #: templates/popup/index.php:167
836
+ msgid "Mobile behavior"
837
+ msgstr "نحوه نمایش در موبایل"
838
+
839
+ #: templates/popup/index.php:170
840
+ msgid "List"
841
+ msgstr "لیست"
842
+
843
+ #: templates/popup/index.php:171
844
+ msgid "Table"
845
+ msgstr "جدول"
846
+
847
+ #: templates/popup/index.php:173
848
+ msgid ""
849
+ "Tick \"List\" to display events in a list view on mobile devices. Tick "
850
+ "\"Table\" to display events in a table."
851
+ msgstr ""
852
+ "با کلیک بر روی \"لیست\" رویدادها به صورت لیست زیر هم در موبایل به نمایش در "
853
+ "می آید. و با انتخاب \"جدول\" رویدادها در یک جدول به نمایش گذاشته می شود.."
854
+
855
+ #: templates/popup/index.php:179
856
+ msgid "Add Timetable"
857
+ msgstr "افزودن جدول زمانی"
858
+
859
+ #: templates/settings/general.php:1
860
+ msgid "General Settings"
861
+ msgstr "تنظیمات عمومی"
862
+
863
+ #: templates/settings/general.php:8
864
+ msgid "Template Mode"
865
+ msgstr "حالت الگو"
866
+
867
+ #: templates/settings/general.php:12
868
+ msgid "Theme Mode"
869
+ msgstr "حالت قالب"
870
+
871
+ #: templates/settings/general.php:13
872
+ msgid "Developer Mode"
873
+ msgstr "حالت توسعه دهنده"
874
+
875
+ #: templates/settings/general.php:15
876
+ msgid ""
877
+ "Choose Theme Mode to display the content with the styles of your theme. "
878
+ "Choose Developer Mode to control appearance of the content with custom page "
879
+ "templates, actions and filters."
880
+ msgstr ""
881
+ "اگر میخواهید تا محتوا به سبک قالب فعلی به نمایش گذاشته شود \"حالت قالب\" را "
882
+ "انتخاب کنید. اگر حالت توسعه دهنده را انتخاب کنید نحوه نمایش را کاملا می "
883
+ "توانید سفارشی کنید."
884
+
885
+ #: templates/settings/general.php:15
886
+ msgid ""
887
+ "This option can't be changed if your theme is initially integrated with the "
888
+ "plugin."
889
+ msgstr ""
890
+ "این گزینه را نمی توان تغییر داد اگر موضوع شما در ابتدا با افزونه ادغام شود."
891
+
892
+ #: templates/settings/general.php:20
893
+ msgid "Save"
894
+ msgstr "ذخیره"
895
+
896
+ #: templates/shortcodes/empty-search-events.php:1
897
+ #: templates/theme/widget-upcoming-view.php:54
898
+ #: templates/widgets/widget-view.php:91
899
+ msgid "no events found"
900
+ msgstr "رویدادی یافت نشد"
901
+
902
+ #: templates/templates-actions/action-sidebar.php:8
903
+ #: templates/widgets/gallery-list.php:14
904
+ msgid "Today upcoming events"
905
+ msgstr "رویدادهای آینده در این روز"
906
+
907
+ #: templates/templates-actions/action-sidebar.php:13
908
+ #: templates/widgets/gallery-list.php:16
909
+ msgid "All upcoming events"
910
+ msgstr "همه رویدادهای آینده"
911
+
912
+ #: templates/widgets/gallery-list.php:10
913
+ msgid "Events to display"
914
+ msgstr "رویدادهای برای نمایش"
915
+
916
+ #: templates/widgets/gallery-list.php:18
917
+ msgid "Ongoing events"
918
+ msgstr "رویدادهای پیش رو"
919
+
920
+ #: templates/widgets/gallery-list.php:23
921
+ msgid "Input number of days"
922
+ msgstr "تعداد ورودی ها در روز"
923
+
924
+ #: templates/widgets/gallery-list.php:28
925
+ msgid "day"
926
+ msgstr "روز"
927
+
928
+ #: templates/widgets/gallery-list.php:32
929
+ msgid "Event categories. Leave blank to display all."
930
+ msgstr "دسته های رویداد، برای نمایش همه خالی بگذارید"
931
+
932
+ #: templates/widgets/gallery-list.php:49
933
+ msgid "Number of events to display"
934
+ msgstr "تعداد رویداد قایل نمایش"
935
+
936
+ #: templates/widgets/gallery-list.php:67
937
+ msgid "Custom link for events"
938
+ msgstr "آدرس سفارشی برای رویداد"
939
+
940
+ #: templates/widgets/gallery-list.php:75
941
+ msgid "Event background color"
942
+ msgstr "رنگ پشت زمینه رویداد"
943
+
944
+ #: templates/widgets/gallery-list.php:85
945
+ msgid "Event background color on hover"
946
+ msgstr "رنگ سایه پشت زمینه رویداد"
947
+
948
+ #: templates/widgets/gallery-list.php:95
949
+ msgid "Event text color"
950
+ msgstr "رنگ متن رویداد"
951
+
952
+ #: templates/widgets/gallery-list.php:105
953
+ msgid "Event text color on hover"
954
+ msgstr "رنگ سایه متن رویداد"
955
+
956
+ #: templates/widgets/gallery-list.php:115
957
+ msgid "Event border color"
958
+ msgstr "رنگ کادر دور رویداد"
959
+
960
+ #: templates/widgets/gallery-list.php:125
961
+ msgid "Event border color on hover"
962
+ msgstr "رنگ سایه کادر دور رویداد"
languages/mp-timetable-ru_RU-1350249ca68bb46ac81f10c0007fcc6d.json ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "translation-revision-date": "2021-02-03 21:20+0200",
3
+ "generator": "WP-CLI\/2.4.0",
4
+ "source": "media\/js\/blocks\/dist\/index.js",
5
+ "domain": "messages",
6
+ "locale_data": {
7
+ "messages": {
8
+ "": {
9
+ "domain": "messages",
10
+ "lang": "ru",
11
+ "plural-forms": "nplurals=3; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : ((n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : 2);"
12
+ },
13
+ "Event categories": [
14
+ "\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439"
15
+ ],
16
+ "Columns": [
17
+ "\u0421\u0442\u043e\u043b\u0431\u0446\u044b"
18
+ ],
19
+ "Timetable": [
20
+ "\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435"
21
+ ],
22
+ "Settings": [
23
+ "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438"
24
+ ],
25
+ "Hour (1h)": [
26
+ "\u0427\u0430\u0441 (1 \u0447)"
27
+ ],
28
+ "Half hour (30min)": [
29
+ "\u041f\u043e\u043b\u0447\u0430\u0441\u0430 (30 \u043c\u0438\u043d)"
30
+ ],
31
+ "Quarter hour (15min)": [
32
+ "\u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044c \u0447\u0430\u0441\u0430 (15 \u043c\u0438\u043d)"
33
+ ],
34
+ "Dropdown list": [
35
+ "\u0412\u044b\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a"
36
+ ],
37
+ "Tabs": [
38
+ "\u0412\u043a\u043b\u0430\u0434\u043a\u0438"
39
+ ],
40
+ "Order of items in filter": [
41
+ "\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0444\u0438\u043b\u044c\u0442\u0440\u0435"
42
+ ],
43
+ "Default": [
44
+ "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e"
45
+ ],
46
+ "Menu Order": [
47
+ "\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043c\u0435\u043d\u044e"
48
+ ],
49
+ "Title": [
50
+ "\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a"
51
+ ],
52
+ "No": [
53
+ "\u041d\u0435\u0442"
54
+ ],
55
+ "Yes": [
56
+ "\u0414\u0430"
57
+ ],
58
+ "Time": [
59
+ "\u0412\u0440\u0435\u043c\u044f"
60
+ ],
61
+ "Subtitle": [
62
+ "\u041f\u043e\u0434\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a"
63
+ ],
64
+ "Description": [
65
+ "\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435"
66
+ ],
67
+ "center": [
68
+ "\u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443"
69
+ ],
70
+ "left": [
71
+ "\u0441\u043b\u0435\u0432\u0430"
72
+ ],
73
+ "right": [
74
+ "\u0441\u043f\u0440\u0430\u0432\u0430"
75
+ ],
76
+ "Column width": [
77
+ "\u0428\u0438\u0440\u0438\u043d\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u0430"
78
+ ],
79
+ "Auto": [
80
+ "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438"
81
+ ],
82
+ "Fixed": [
83
+ "\u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435"
84
+ ],
85
+ "Hold the Ctrl or Command key to select\/deselect multiple options.": [
86
+ "\u0423\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0443 Ctrl \u0438\u043b\u0438 Command, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \/ \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432."
87
+ ],
88
+ "Specific events": [
89
+ "\u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f"
90
+ ],
91
+ "Event Head": [
92
+ "\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f"
93
+ ],
94
+ "Block height in pixels": [
95
+ "\u0412\u044b\u0441\u043e\u0442\u0430 \u0431\u043b\u043e\u043a\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445"
96
+ ],
97
+ "Base font size": [
98
+ "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0448\u0440\u0438\u0444\u0442\u0430"
99
+ ],
100
+ "Base font size for the table. Example 12px, 2em, 80%.": [
101
+ "\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0448\u0440\u0438\u0444\u0442\u0430 \u0434\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 12px, 2em, 80%."
102
+ ],
103
+ "Time frame for event": [
104
+ "\u041f\u0435\u0440\u0438\u043e\u0434 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f"
105
+ ],
106
+ "Filter events style": [
107
+ "\u0421\u0442\u0438\u043b\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439"
108
+ ],
109
+ "Filter title to display all events": [
110
+ "\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439"
111
+ ],
112
+ "Hide 'All Events' option": [
113
+ "\u0421\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u043e\u043f\u0446\u0438\u044e \"\u0412\u0441\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\""
114
+ ],
115
+ "Hide column with hours": [
116
+ "\u041f\u0440\u044f\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u0441 \u0447\u0430\u0441\u0430\u043c\u0438"
117
+ ],
118
+ "Do not display empty rows": [
119
+ "\u041d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438"
120
+ ],
121
+ "Merge cells with common events": [
122
+ "\u041e\u0431\u044c\u0435\u0434\u0435\u043d\u0438\u0442\u044c \u044f\u0447\u0435\u0439\u043a\u0438 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438"
123
+ ],
124
+ "Disable event link": [
125
+ "\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u044f"
126
+ ],
127
+ "Horizontal align": [
128
+ "\u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435"
129
+ ],
130
+ "Vertical align": [
131
+ "\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435"
132
+ ],
133
+ "top": [
134
+ "\u0441\u0432\u0435\u0440\u0445\u0443"
135
+ ],
136
+ "middle": [
137
+ "\u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435"
138
+ ],
139
+ "bottom": [
140
+ "\u0441\u043d\u0438\u0437\u0443"
141
+ ],
142
+ "Unique ID": [
143
+ "\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ID"
144
+ ],
145
+ "If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.": [
146
+ "\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044f. \u041e\u043d, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b \u0432 \u043d\u0438\u0436\u043d\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435, \u0446\u0438\u0444\u0440\u044b \u0438 \u0434\u0435\u0444\u0438\u0441."
147
+ ],
148
+ "CSS class": [
149
+ "CSS \u043a\u043b\u0430\u0441\u0441"
150
+ ],
151
+ "Mobile behavior": [
152
+ "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u043c"
153
+ ],
154
+ "List": [
155
+ "\u0421\u043f\u0438\u0441\u043e\u043a"
156
+ ],
157
+ "Table": [
158
+ "\u0422\u0430\u0431\u043b\u0438\u0446\u0430"
159
+ ]
160
+ }
161
+ }
162
+ }
languages/mp-timetable-ru_RU.mo ADDED
Binary file
languages/mp-timetable-ru_RU.po ADDED
@@ -0,0 +1,1109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Plugins - Timetable and Event Schedule by MotoPress - "
4
+ "Development (trunk)\n"
5
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/mp-timetable\n"
6
+ "POT-Creation-Date: 2021-02-03T19:20:41+00:00\n"
7
+ "PO-Revision-Date: 2021-02-03 21:20+0200\n"
8
+ "Last-Translator: \n"
9
+ "Language-Team: \n"
10
+ "Language: ru\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "Plural-Forms: nplurals=3; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : ((n % "
15
+ "10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14)) ? 1 : 2);\n"
16
+ "X-Generator: Poedit 2.2.1\n"
17
+
18
+ #. Plugin Name of the plugin
19
+ msgid "Timetable and Event Schedule"
20
+ msgstr "Timetable and Event Schedule"
21
+
22
+ #. Plugin URI of the plugin
23
+ msgid "https://motopress.com/products/timetable-event-schedule/"
24
+ msgstr "https://motopress.com/products/timetable-event-schedule/"
25
+
26
+ #. Description of the plugin
27
+ msgid ""
28
+ "Smart time-management tool with a clean minimalist design for featuring your "
29
+ "timetables and upcoming events."
30
+ msgstr ""
31
+ "Смарт инструмент для тайм-менеджмента с простым и минималистичным дизайном "
32
+ "для отображения расписаний и предстоящих событий."
33
+
34
+ #. Author of the plugin
35
+ msgid "MotoPress"
36
+ msgstr "MotoPress"
37
+
38
+ #. Author URI of the plugin
39
+ msgid "https://motopress.com"
40
+ msgstr "https://motopress.com"
41
+
42
+ #. translators: 1: Timetable and Event Schedule 2:: five stars rating
43
+ #: admin/help/index.php:10 templates/settings/general.php:41
44
+ msgid "If you like %1$s please leave us a %2$s rating."
45
+ msgstr "Если вам нравится %1$s, поставьте нам %2$s оценку."
46
+
47
+ #: admin/import/export.php:1 admin/import/export.php:5
48
+ msgid "Export"
49
+ msgstr "Экспортировать"
50
+
51
+ #: admin/import/greet.php:2
52
+ msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
53
+ msgstr "Выберите WXR файл (с расширением XML), и нажмите кноку Загрузить."
54
+
55
+ #: admin/import/header.php:2
56
+ msgid "Import / Export Timetable Plugin Data"
57
+ msgstr "Импорт / Экспорт данных плагина"
58
+
59
+ #: admin/import/import.php:4
60
+ msgid "Import"
61
+ msgstr "Импортировать"
62
+
63
+ #: classes/blocks/class-timetable-block.php:92 classes/class-core.php:443
64
+ #: classes/class-shortcode.php:70 classes/class-shortcode.php:286
65
+ #: templates-functions/action-shortcode-functions.php:57
66
+ #: templates-functions/action-shortcode-functions.php:71
67
+ #: templates-functions/action-shortcode-functions.php:72
68
+ msgid "All Events"
69
+ msgstr "Все события"
70
+
71
+ #: classes/class-core.php:332 classes/class-core.php:343
72
+ #: classes/class-core.php:347 classes/class-shortcode.php:265
73
+ #: templates/popup/index.php:27 media/js/blocks/dist/index.min.js:1
74
+ msgid "Event categories"
75
+ msgstr "Категории событий"
76
+
77
+ #: classes/class-core.php:333
78
+ msgid "Event category"
79
+ msgstr "Категория события"
80
+
81
+ #: classes/class-core.php:334 classes/class-core.php:335
82
+ msgid "Add New Event category"
83
+ msgstr "Добавить новую категорию события"
84
+
85
+ #: classes/class-core.php:336
86
+ msgid "Edit Event category"
87
+ msgstr "Редактировать категорию события"
88
+
89
+ #: classes/class-core.php:337
90
+ msgid "New Event category"
91
+ msgstr "Новая категория события"
92
+
93
+ #: classes/class-core.php:338
94
+ msgid "All Event categories"
95
+ msgstr "Все категории событий"
96
+
97
+ #: classes/class-core.php:339
98
+ msgid "View Event category"
99
+ msgstr "Просмотр категории события"
100
+
101
+ #: classes/class-core.php:340
102
+ msgid "Search Event category"
103
+ msgstr "Поиск категорий события"
104
+
105
+ #: classes/class-core.php:341
106
+ msgid "No Event categories found"
107
+ msgstr "Категории событий не найдены"
108
+
109
+ #: classes/class-core.php:342
110
+ msgid "No Event categories found in Trash"
111
+ msgstr "Категории событий в корзине не найдены"
112
+
113
+ #: classes/class-core.php:376 classes/class-core.php:387
114
+ #: classes/class-core.php:391
115
+ msgid "Event tags"
116
+ msgstr "Ярлыки событий"
117
+
118
+ #: classes/class-core.php:377
119
+ msgid "Event tag"
120
+ msgstr "Ярлык события"
121
+
122
+ #: classes/class-core.php:378 classes/class-core.php:379
123
+ msgid "Add New Event tag"
124
+ msgstr "Добавить новый ярлык события"
125
+
126
+ #: classes/class-core.php:380
127
+ msgid "Edit Event tag"
128
+ msgstr "Редактировать ярлык события"
129
+
130
+ #: classes/class-core.php:381
131
+ msgid "New Event tag"
132
+ msgstr "Новый ярлык события"
133
+
134
+ #: classes/class-core.php:382
135
+ msgid "All Event tags"
136
+ msgstr "Все ярлыки событий"
137
+
138
+ #: classes/class-core.php:383
139
+ msgid "View Event tag"
140
+ msgstr "Просмотр ярлыков события"
141
+
142
+ #: classes/class-core.php:384
143
+ msgid "Search Event tag"
144
+ msgstr "Поиск ярлыка события"
145
+
146
+ #: classes/class-core.php:385
147
+ msgid "No Event tags found"
148
+ msgstr "Ярлыки событий не найдены"
149
+
150
+ #: classes/class-core.php:386
151
+ msgid "No Event tags found in Trash"
152
+ msgstr "Ярлыков событий в корзине не найдено"
153
+
154
+ #: classes/class-core.php:437 classes/class-core.php:448
155
+ #: classes/class-hooks.php:192 classes/class-shortcode.php:260
156
+ msgid "Events"
157
+ msgstr "События"
158
+
159
+ #: classes/class-core.php:438
160
+ msgid "Event"
161
+ msgstr "Событие"
162
+
163
+ #: classes/class-core.php:439 classes/class-core.php:440
164
+ msgid "Add New Event"
165
+ msgstr "Добавить новое событе"
166
+
167
+ #: classes/class-core.php:441
168
+ msgid "Edit Event"
169
+ msgstr "Редактировать событие"
170
+
171
+ #: classes/class-core.php:442
172
+ msgid "New Event"
173
+ msgstr "Новое событие"
174
+
175
+ #: classes/class-core.php:444
176
+ msgid "View Event"
177
+ msgstr "Просмотреть событие"
178
+
179
+ #: classes/class-core.php:445
180
+ msgid "Search Event"
181
+ msgstr "Поиск событий"
182
+
183
+ #: classes/class-core.php:446
184
+ msgid "No Events found"
185
+ msgstr "События не найдены"
186
+
187
+ #: classes/class-core.php:447
188
+ msgid "No Events found in Trash"
189
+ msgstr "События не найдены в корзине"
190
+
191
+ #: classes/class-core.php:476 classes/class-core.php:487
192
+ #: classes/class-hooks.php:200 templates/popup/index.php:5
193
+ #: media/js/blocks/dist/index.min.js:1
194
+ msgid "Columns"
195
+ msgstr "Столбцы"
196
+
197
+ #: classes/class-core.php:477 classes/class-shortcode.php:255
198
+ #: templates/events/event-data.php:4
199
+ msgid "Column"
200
+ msgstr "Столбец"
201
+
202
+ #: classes/class-core.php:478 classes/class-core.php:479
203
+ msgid "Add New Column"
204
+ msgstr "Добавить новый столбец"
205
+
206
+ #: classes/class-core.php:480
207
+ msgid "Edit Column"
208
+ msgstr "Редактировать столбец"
209
+
210
+ #: classes/class-core.php:481
211
+ msgid "New Column"
212
+ msgstr "Новый столбец"
213
+
214
+ #: classes/class-core.php:482
215
+ msgid "All Columns"
216
+ msgstr "Все столбцы"
217
+
218
+ #: classes/class-core.php:483
219
+ msgid "View Column"
220
+ msgstr "Просмотр столбцов"
221
+
222
+ #: classes/class-core.php:484
223
+ msgid "Search Column"
224
+ msgstr "Поиск столбцов"
225
+
226
+ #: classes/class-core.php:485
227
+ msgid "No Columns found"
228
+ msgstr "Столбцы не найдены"
229
+
230
+ #: classes/class-core.php:486
231
+ msgid "No Columns found in Trash"
232
+ msgstr "Столбцов в корзине не найдено"
233
+
234
+ #: classes/class-hooks.php:78
235
+ msgid "Timetable Sidebar"
236
+ msgstr "Расписание в боковой панели"
237
+
238
+ #: classes/class-hooks.php:80 classes/class-hooks.php:188
239
+ #: classes/class-shortcode.php:370 media/js/blocks/dist/index.min.js:1
240
+ msgid "Timetable"
241
+ msgstr "Расписание"
242
+
243
+ #: classes/class-hooks.php:179
244
+ msgid "Import Timetable events, categories, tags and images."
245
+ msgstr "Импортировать события, категории, ярлыки и изображения."
246
+
247
+ #: classes/class-hooks.php:196
248
+ msgid "Add Event"
249
+ msgstr "Добавить событие"
250
+
251
+ #: classes/class-hooks.php:204
252
+ msgid "Add Column"
253
+ msgstr "Добавить столбец"
254
+
255
+ #: classes/class-hooks.php:208
256
+ msgid "Event Categories"
257
+ msgstr "Категории событий"
258
+
259
+ #: classes/class-hooks.php:212
260
+ msgid "Event Tags"
261
+ msgstr "Ярлыки событий"
262
+
263
+ #: classes/class-hooks.php:216 classes/modules/class-post.php:41
264
+ #: media/js/blocks/dist/index.min.js:1
265
+ msgid "Settings"
266
+ msgstr "Настройки"
267
+
268
+ #: classes/class-hooks.php:220
269
+ msgid "Export / Import"
270
+ msgstr "Экспорт / Импорт"
271
+
272
+ #: classes/class-hooks.php:224
273
+ msgid "Help & Shortcode"
274
+ msgstr "Помощь и шорткоды"
275
+
276
+ #: classes/class-hooks.php:288
277
+ msgid "Quick Start Guide"
278
+ msgstr "Краткое руководство пользователя"
279
+
280
+ #: classes/class-hooks.php:289
281
+ msgid "Help"
282
+ msgstr "Помощь"
283
+
284
+ #: classes/class-hooks.php:290
285
+ msgid "Leave a Review"
286
+ msgstr "Оставьте отзыв"
287
+
288
+ #: classes/class-permalinks.php:26
289
+ msgid "Timetable Permalinks"
290
+ msgstr "Ссылки расписания"
291
+
292
+ #: classes/class-permalinks.php:30
293
+ msgid "Column base"
294
+ msgstr "Префикс для столбцов"
295
+
296
+ #: classes/class-permalinks.php:37
297
+ msgid "Event base"
298
+ msgstr "Префикс для событий"
299
+
300
+ #: classes/class-permalinks.php:44
301
+ msgid "Event Category base"
302
+ msgstr "Префикс для рубрик событий"
303
+
304
+ #: classes/class-permalinks.php:51
305
+ msgid "Event Tag base"
306
+ msgstr "Префикс для меток событий"
307
+
308
+ #: classes/class-shortcode.php:270
309
+ msgid "Hour measure"
310
+ msgstr "Мера часа"
311
+
312
+ #: classes/class-shortcode.php:271 templates/popup/index.php:71
313
+ #: media/js/blocks/dist/index.min.js:1
314
+ msgid "Hour (1h)"
315
+ msgstr "Час (1 ч)"
316
+
317
+ #: classes/class-shortcode.php:271 templates/popup/index.php:72
318
+ #: media/js/blocks/dist/index.min.js:1
319
+ msgid "Half hour (30min)"
320
+ msgstr "Полчаса (30 мин)"
321
+
322
+ #: classes/class-shortcode.php:271 templates/popup/index.php:73
323
+ #: media/js/blocks/dist/index.min.js:1
324
+ msgid "Quarter hour (15min)"
325
+ msgstr "Четверть часа (15 мин)"
326
+
327
+ #: classes/class-shortcode.php:275
328
+ msgid "Filter style"
329
+ msgstr "Стиль для фильтра"
330
+
331
+ #: classes/class-shortcode.php:276 media/js/blocks/dist/index.min.js:1
332
+ msgid "Dropdown list"
333
+ msgstr "Выпадающий список"
334
+
335
+ #: classes/class-shortcode.php:276 templates/popup/index.php:82
336
+ #: media/js/blocks/dist/index.min.js:1
337
+ msgid "Tabs"
338
+ msgstr "Вкладки"
339
+
340
+ #: classes/class-shortcode.php:280 templates/popup/index.php:88
341
+ #: media/js/blocks/dist/index.min.js:1
342
+ msgid "Order of items in filter"
343
+ msgstr "Порядок элементов в фильтре"
344
+
345
+ #: classes/class-shortcode.php:281 classes/class-shortcode.php:367
346
+ #: templates/popup/index.php:91 templates/popup/index.php:172
347
+ #: media/js/blocks/dist/index.min.js:1
348
+ msgid "Default"
349
+ msgstr "По умолчанию"
350
+
351
+ #: classes/class-shortcode.php:281 templates/popup/index.php:92
352
+ #: media/js/blocks/dist/index.min.js:1
353
+ msgid "Menu Order"
354
+ msgstr "Порядок меню"
355
+
356
+ #: classes/class-shortcode.php:281 classes/class-shortcode.php:306
357
+ #: templates/popup/index.php:40 templates/popup/index.php:93
358
+ #: templates/widgets/gallery-list.php:3 media/js/blocks/dist/index.min.js:1
359
+ msgid "Title"
360
+ msgstr "Заголовок"
361
+
362
+ #: classes/class-shortcode.php:285
363
+ msgid "Filter label"
364
+ msgstr "Метка фильтра"
365
+
366
+ #: classes/class-shortcode.php:290
367
+ msgid "Hide 'All Events' view"
368
+ msgstr "Скрыть вид \"Все события\""
369
+
370
+ #: classes/class-shortcode.php:291 classes/class-shortcode.php:296
371
+ #: classes/class-shortcode.php:301 classes/class-shortcode.php:308
372
+ #: classes/class-shortcode.php:314 classes/class-shortcode.php:320
373
+ #: classes/class-shortcode.php:326 classes/class-shortcode.php:332
374
+ #: classes/class-shortcode.php:337 classes/class-shortcode.php:361
375
+ #: templates/events/metabox-event-options.php:45 templates/popup/index.php:108
376
+ #: templates/popup/index.php:117 templates/popup/index.php:127
377
+ #: templates/popup/index.php:135 templates/popup/index.php:144
378
+ #: templates/widgets/gallery-list.php:63 media/js/blocks/dist/index.min.js:1
379
+ msgid "No"
380
+ msgstr "Нет"
381
+
382
+ #: classes/class-shortcode.php:291 classes/class-shortcode.php:296
383
+ #: classes/class-shortcode.php:301 classes/class-shortcode.php:308
384
+ #: classes/class-shortcode.php:314 classes/class-shortcode.php:320
385
+ #: classes/class-shortcode.php:326 classes/class-shortcode.php:332
386
+ #: classes/class-shortcode.php:337 classes/class-shortcode.php:361
387
+ #: templates/events/metabox-event-options.php:46 templates/popup/index.php:109
388
+ #: templates/popup/index.php:118 templates/popup/index.php:126
389
+ #: templates/popup/index.php:136 templates/popup/index.php:145
390
+ #: templates/widgets/gallery-list.php:65 media/js/blocks/dist/index.min.js:1
391
+ msgid "Yes"
392
+ msgstr "Да"
393
+
394
+ #: classes/class-shortcode.php:295
395
+ msgid "Hide first (hours) column"
396
+ msgstr "Скрыть первый (с часами) столбец"
397
+
398
+ #: classes/class-shortcode.php:300
399
+ msgid "Hide empty rows"
400
+ msgstr "Скрыть пустые ряды"
401
+
402
+ #: classes/class-shortcode.php:312 templates/popup/index.php:41
403
+ #: media/js/blocks/dist/index.min.js:1
404
+ msgid "Time"
405
+ msgstr "Время"
406
+
407
+ #: classes/class-shortcode.php:318 templates/popup/index.php:42
408
+ #: media/js/blocks/dist/index.min.js:1
409
+ msgid "Subtitle"
410
+ msgstr "Подзаголовок"
411
+
412
+ #: classes/class-shortcode.php:324 templates/events/event-data.php:7
413
+ #: templates/popup/index.php:43 media/js/blocks/dist/index.min.js:1
414
+ msgid "Description"
415
+ msgstr "Описание"
416
+
417
+ #: classes/class-shortcode.php:330
418
+ msgid "User"
419
+ msgstr "Пользователь"
420
+
421
+ #: classes/class-shortcode.php:336
422
+ msgid "Disable event URL"
423
+ msgstr "Отключить URL события"
424
+
425
+ #: classes/class-shortcode.php:341
426
+ msgid "Text align"
427
+ msgstr "Выравнивание текста"
428
+
429
+ #: classes/class-shortcode.php:342 templates/popup/index.php:152
430
+ #: media/js/blocks/dist/index.min.js:1
431
+ msgid "center"
432
+ msgstr "по центру"
433
+
434
+ #: classes/class-shortcode.php:342 templates/popup/index.php:153
435
+ #: media/js/blocks/dist/index.min.js:1
436
+ msgid "left"
437
+ msgstr "слева"
438
+
439
+ #: classes/class-shortcode.php:342 templates/popup/index.php:154
440
+ #: media/js/blocks/dist/index.min.js:1
441
+ msgid "right"
442
+ msgstr "справа"
443
+
444
+ #: classes/class-shortcode.php:346
445
+ msgid "Id"
446
+ msgstr "Id"
447
+
448
+ #: classes/class-shortcode.php:350
449
+ msgid "Row height (in px)"
450
+ msgstr "Высота ряда (в пикселях)"
451
+
452
+ #: classes/class-shortcode.php:355
453
+ msgid "Base Font Size"
454
+ msgstr "Базовый размер шрифта"
455
+
456
+ #: classes/class-shortcode.php:360
457
+ msgid "Responsive"
458
+ msgstr "Адаптивные"
459
+
460
+ #: classes/class-shortcode.php:366 templates/popup/index.php:169
461
+ #: media/js/blocks/dist/index.min.js:1
462
+ msgid "Column width"
463
+ msgstr "Ширина столбца"
464
+
465
+ #: classes/class-shortcode.php:367 templates/popup/index.php:173
466
+ #: media/js/blocks/dist/index.min.js:1
467
+ msgid "Auto"
468
+ msgstr "Автоматически"
469
+
470
+ #: classes/class-shortcode.php:367 templates/popup/index.php:174
471
+ #: media/js/blocks/dist/index.min.js:1
472
+ msgid "Fixed"
473
+ msgstr "Фиксированное"
474
+
475
+ #: classes/controllers/class-controller-settings.php:70
476
+ msgid "Settings saved."
477
+ msgstr "Настройки сохранены."
478
+
479
+ #: classes/libs/parsers.php:44 classes/libs/parsers.php:74
480
+ #: classes/libs/parsers.php:82
481
+ msgid "There was an error when reading this WXR file"
482
+ msgstr "Ошибка при чтении файла WXR"
483
+
484
+ #: classes/libs/parsers.php:45
485
+ msgid ""
486
+ "Details are shown above. The importer will now try again with a different "
487
+ "parser..."
488
+ msgstr ""
489
+ "Подробности ниже. Сейчас плагин повторит попытку импортирования с другим "
490
+ "парсером..."
491
+
492
+ #: classes/libs/parsers.php:86 classes/libs/parsers.php:91
493
+ #: classes/libs/parsers.php:304 classes/libs/parsers.php:565
494
+ msgid ""
495
+ "This does not appear to be a WXR file, missing/invalid WXR version number"
496
+ msgstr "Кажется это файл WXR, пропущенный/неверный номер версии WXR"
497
+
498
+ #: classes/models/class-column.php:42 classes/modules/class-post.php:40
499
+ msgid "Timeslots"
500
+ msgstr "Временные интервалы"
501
+
502
+ #: classes/models/class-events.php:171
503
+ msgid "Tags"
504
+ msgstr "Ключевые слова"
505
+
506
+ #: classes/models/class-events.php:172
507
+ msgid "Categories"
508
+ msgstr "Категории"
509
+
510
+ #: classes/models/class-events.php:774
511
+ msgid "Duplicate"
512
+ msgstr "Дублировать"
513
+
514
+ #: classes/models/class-events.php:795
515
+ msgid "A post type mismatch has been detected."
516
+ msgstr "Обнаружено несоответствие типов постов."
517
+
518
+ #: classes/models/class-events.php:795
519
+ msgid "Sorry, you are not allowed to edit this item."
520
+ msgstr "У вас недостаточно прав для редактирования этого элемента."
521
+
522
+ #. translators: New post title of the duplicated post
523
+ #: classes/models/class-events.php:819
524
+ msgid "%s - Copy"
525
+ msgstr "%s - Копия"
526
+
527
+ #: classes/models/class-import.php:125
528
+ msgid "Assign Authors"
529
+ msgstr "Привязка авторов"
530
+
531
+ #: classes/models/class-import.php:126
532
+ msgid ""
533
+ "To make it easier for you to edit and save the imported content, you may "
534
+ "want to reassign the author of the imported item to an existing user of this "
535
+ "site. For example, you may want to import all the entries as <code>admin</"
536
+ "code>s entries."
537
+ msgstr ""
538
+ "Чтобы сделать проще редактирование и сохранение импортированного материала, "
539
+ "вы, возможно, захотите перепривязать автора импортированного элемента к "
540
+ "существующему пользователю этого сайта. Например, вы захотите импортировать "
541
+ "все записи как записи пользователя <code>admin</code>."
542
+
543
+ #: classes/models/class-import.php:128
544
+ msgid ""
545
+ "If a new user is created by WordPress, a new password will be randomly "
546
+ "generated and the new user&#8217;s role will be set as %s. Manually changing "
547
+ "the new user&#8217;s details will be necessary."
548
+ msgstr ""
549
+ "Если новый пользователь создан WordPress, новый пароль будет сгенерирован "
550
+ "случайным образом, и роль нового пользователя будет %s. Понадобятся "
551
+ "изменения деталей профиля нового пользователя вручную."
552
+
553
+ #: classes/models/class-import.php:138
554
+ msgid "Import Attachments"
555
+ msgstr "Импорт вложений"
556
+
557
+ #: classes/models/class-import.php:141
558
+ msgid "Download and import file attachments"
559
+ msgstr "Скачать и импортировать файлы вложений"
560
+
561
+ #: classes/models/class-import.php:145
562
+ msgid "Submit"
563
+ msgstr "Отправить"
564
+
565
+ #: classes/models/class-import.php:158
566
+ msgid "Import author:"
567
+ msgstr "Импорт автора:"
568
+
569
+ #: classes/models/class-import.php:169
570
+ msgid "or create new user with login name:"
571
+ msgstr "или создать нового пользователя с именем:"
572
+
573
+ #: classes/models/class-import.php:172
574
+ msgid "as a new user:"
575
+ msgstr "как новый пользователь:"
576
+
577
+ #: classes/models/class-import.php:180
578
+ msgid "assign posts to an existing user:"
579
+ msgstr "назначить записи существующему пользователю:"
580
+
581
+ #: classes/models/class-import.php:182
582
+ msgid "or assign posts to an existing user:"
583
+ msgstr "или привязать записи к существующему пользователю:"
584
+
585
+ #: classes/models/class-import.php:183
586
+ #: templates/column/metabox-column-options.php:23
587
+ msgid "- Select -"
588
+ msgstr "- Выбрать -"
589
+
590
+ #: classes/models/class-import.php:269
591
+ msgid "All done."
592
+ msgstr "Все готово."
593
+
594
+ #: classes/models/class-import.php:269
595
+ msgid "Have fun!"
596
+ msgstr "Наслаждайтесь!"
597
+
598
+ #: classes/models/class-import.php:270
599
+ msgid "Remember to update the passwords and roles of imported users."
600
+ msgstr "Не забудьте обновить пароли и роли импортированных пользователей."
601
+
602
+ #: classes/models/class-import.php:286
603
+ msgid "Fetching attachments is not enabled"
604
+ msgstr "Импортирование вложений отключено"
605
+
606
+ #: classes/models/class-import.php:299
607
+ msgid "Invalid file type"
608
+ msgstr "Неподходящий тип файла"
609
+
610
+ #: classes/models/class-import.php:379
611
+ msgid "Remote server did not respond"
612
+ msgstr "Удалённый сервер не&nbsp;отвечает"
613
+
614
+ #: classes/models/class-import.php:385
615
+ msgid "Remote server returned error response %1$d %2$s"
616
+ msgstr "Удалённый сервер выдал ошибку %1$d %2$s"
617
+
618
+ #: classes/models/class-import.php:394
619
+ msgid "Remote file is incorrect size"
620
+ msgstr "Удалённый файл неподходящего размера"
621
+
622
+ #: classes/models/class-import.php:399
623
+ msgid "Zero size file downloaded"
624
+ msgstr "Скачан пустой файл"
625
+
626
+ #: classes/models/class-import.php:405
627
+ msgid "Remote file is too large, limit is %s"
628
+ msgstr "Удалённый файл слишком велик. Текущее ограничение: %s"
629
+
630
+ #: classes/models/class-import.php:422 classes/models/class-import.php:426
631
+ #: classes/models/class-import.php:436
632
+ msgid "Sorry, there has been an error."
633
+ msgstr "К сожалению, возникла ошибка."
634
+
635
+ #: classes/models/class-import.php:427
636
+ msgid ""
637
+ "The export file could not be found at <code>%s</code>. It is likely that "
638
+ "this was caused by a permissions problem."
639
+ msgstr ""
640
+ "Экспортируемый файл не может быть найден в <code>%s</code>. Похоже, это "
641
+ "вызвано ошибкой прав доступа."
642
+
643
+ #: classes/models/class-import.php:444
644
+ msgid ""
645
+ "This WXR file (version %s) may not be supported by this version of the "
646
+ "importer. Please consider updating."
647
+ msgstr ""
648
+ "Данный файл WXR (версии %s) может не поддерживаться настоящей версией "
649
+ "плагина. Советуем обновить плагин."
650
+
651
+ #: classes/models/class-import.php:501
652
+ msgid ""
653
+ "Failed to import author %s. Their posts will be attributed to the current "
654
+ "user."
655
+ msgstr ""
656
+ "Не удалось импортировать автора \"%s\". Его статьи будут назначены текущему "
657
+ "пользователю."
658
+
659
+ #: classes/models/class-import.php:558
660
+ msgid ""
661
+ "Failed to create new user for %s. Their posts will be attributed to the "
662
+ "current user."
663
+ msgstr ""
664
+ "Не удалось создать нового пользователя для %s. Их записи будут отнесены к "
665
+ "текущему пользователю."
666
+
667
+ #: classes/models/class-import.php:609 classes/models/class-import.php:766
668
+ msgid "Failed to import %s %s"
669
+ msgstr "Не удалось импортировать %s %s"
670
+
671
+ #: classes/models/class-import.php:656
672
+ msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
673
+ msgstr "Не удалось импортировать &#8220;%s&#8221;: Неверный тип записи %s"
674
+
675
+ #: classes/models/class-import.php:673
676
+ msgid "%s &#8220;%s&#8221; already exists."
677
+ msgstr "%s &#8220;%s&#8221; уже существует."
678
+
679
+ #: classes/models/class-import.php:732
680
+ msgid "Failed to import %s &#8220;%s&#8221;"
681
+ msgstr "Не удалось импортировать %s &#8220;%s&#8221;"
682
+
683
+ #: classes/modules/class-post.php:42
684
+ msgid "Column Type"
685
+ msgstr "Тип столбца"
686
+
687
+ #: classes/widgets/class-mp-timetable-widget.php:22
688
+ msgid "Display upcoming events."
689
+ msgstr "Отобразить предстоящие события."
690
+
691
+ #: classes/widgets/class-mp-timetable-widget.php:24
692
+ msgid "Timetable Events"
693
+ msgstr "События в расписании"
694
+
695
+ #: templates-functions/actions-mp-event-functions.php:27
696
+ #: templates/theme/event-timeslots.php:7
697
+ msgid "Event Timeslots (%s)"
698
+ msgstr "Временные интервалы событий (%s)"
699
+
700
+ #: templates/column/metabox-column-options.php:11
701
+ msgid "Simple Column"
702
+ msgstr "Простой столбец"
703
+
704
+ #: templates/column/metabox-column-options.php:20
705
+ msgid "Day of the week"
706
+ msgstr "День недели"
707
+
708
+ #: templates/column/metabox-column-options.php:24
709
+ msgid "Sunday"
710
+ msgstr "Воскресенье"
711
+
712
+ #: templates/column/metabox-column-options.php:25
713
+ msgid "Monday"
714
+ msgstr "Понедельник"
715
+
716
+ #: templates/column/metabox-column-options.php:26
717
+ msgid "Tuesday"
718
+ msgstr "Вторник"
719
+
720
+ #: templates/column/metabox-column-options.php:27
721
+ msgid "Wednesday"
722
+ msgstr "Среда"
723
+
724
+ #: templates/column/metabox-column-options.php:28
725
+ msgid "Thursday"
726
+ msgstr "Четверг"
727
+
728
+ #: templates/column/metabox-column-options.php:29
729
+ msgid "Friday"
730
+ msgstr "Пятница"
731
+
732
+ #: templates/column/metabox-column-options.php:30
733
+ msgid "Saturday"
734
+ msgstr "Суббота"
735
+
736
+ #: templates/column/metabox-column-options.php:39
737
+ msgid "Date"
738
+ msgstr "Дата"
739
+
740
+ #: templates/events/event-data.php:5
741
+ msgid "Start"
742
+ msgstr "Начало"
743
+
744
+ #: templates/events/event-data.php:6
745
+ msgid "End"
746
+ msgstr "Окончание"
747
+
748
+ #. translators: Head means the leader of the event.
749
+ #: templates/events/event-data.php:10
750
+ msgid "Head"
751
+ msgstr "Руководитель"
752
+
753
+ #: templates/events/event-data.php:12
754
+ msgid "Actions"
755
+ msgstr "Действия"
756
+
757
+ #: templates/events/event-data.php:35
758
+ msgid "Edit event in the form below"
759
+ msgstr "Отредактируйте событие в форме ниже"
760
+
761
+ #: templates/events/event-data.php:36
762
+ msgid "Delete"
763
+ msgstr "Удалить"
764
+
765
+ #: templates/events/metabox-event-data.php:10
766
+ msgid "Add New / Edit Timeslot"
767
+ msgstr "Добавить новый / Редактировать интервал"
768
+
769
+ #: templates/events/metabox-event-data.php:13
770
+ msgid "Column:"
771
+ msgstr "Столбец:"
772
+
773
+ #: templates/events/metabox-event-data.php:21
774
+ msgid "Select column or <a target=\"_blank\" href=\"%s\">Add New</a>."
775
+ msgstr ""
776
+ "Выберите столбец или <a target=\"_blank\" href=\"%s\">Добавьте новый</a>."
777
+
778
+ #: templates/events/metabox-event-data.php:23
779
+ msgid "No columns found. <a href=\"%s\">Create at least one column first.</a>"
780
+ msgstr ""
781
+ "Столбцов не найдено. <a href=\"%s\">Создайте как минимум один столбец для "
782
+ "начала.</a>"
783
+
784
+ #: templates/events/metabox-event-data.php:29
785
+ msgid "Start Time:"
786
+ msgstr "Время начала:"
787
+
788
+ #: templates/events/metabox-event-data.php:32
789
+ #: templates/events/metabox-event-data.php:39
790
+ msgid "hh:mm"
791
+ msgstr "чч:мм"
792
+
793
+ #: templates/events/metabox-event-data.php:36
794
+ msgid "End Time:"
795
+ msgstr "Время окончания:"
796
+
797
+ #: templates/events/metabox-event-data.php:43
798
+ msgid "Description:"
799
+ msgstr "Описание:"
800
+
801
+ #. translators: Head means the leader of the event.
802
+ #: templates/events/metabox-event-data.php:49
803
+ msgid "Event Head:"
804
+ msgstr "Руководитель события:"
805
+
806
+ #: templates/events/metabox-event-data.php:58
807
+ msgid "none"
808
+ msgstr "нет"
809
+
810
+ #. translators: Button to add a new event.
811
+ #: templates/events/metabox-event-data.php:83
812
+ msgid "Add New"
813
+ msgstr "Добавить новый"
814
+
815
+ #: templates/events/metabox-event-options.php:4
816
+ msgid "Event Subtitle:"
817
+ msgstr "Подзаголовок события:"
818
+
819
+ #: templates/events/metabox-event-options.php:8
820
+ msgid "Background Color:"
821
+ msgstr "Цвет фона:"
822
+
823
+ #: templates/events/metabox-event-options.php:15
824
+ msgid "Background Hover Color:"
825
+ msgstr "Цвет фона при наведении:"
826
+
827
+ #: templates/events/metabox-event-options.php:22
828
+ msgid "Text Color:"
829
+ msgstr "Цвет текста:"
830
+
831
+ #: templates/events/metabox-event-options.php:29
832
+ msgid "Text Hover Color:"
833
+ msgstr "Цвет текста при наведении:"
834
+
835
+ #: templates/events/metabox-event-options.php:36
836
+ msgid "Custom Event URL:"
837
+ msgstr "Специальная ссылка на событие:"
838
+
839
+ #: templates/events/metabox-event-options.php:42
840
+ msgid "Disable link to this event:"
841
+ msgstr "Отключить ссылку на событие:"
842
+
843
+ #: templates/popup/index.php:12 templates/popup/index.php:23
844
+ #: templates/popup/index.php:34 templates/widgets/gallery-list.php:48
845
+ #: media/js/blocks/dist/index.min.js:1
846
+ msgid "Hold the Ctrl or Command key to select/deselect multiple options."
847
+ msgstr ""
848
+ "Удерживайте клавишу Ctrl или Command, чтобы выбрать / отменить выбор "
849
+ "нескольких параметров."
850
+
851
+ #: templates/popup/index.php:16 media/js/blocks/dist/index.min.js:1
852
+ msgid "Specific events"
853
+ msgstr "Конкретные события"
854
+
855
+ #: templates/popup/index.php:38
856
+ msgid "Fields to display:"
857
+ msgstr "Поля для отображения:"
858
+
859
+ #. translators: Head means the leader of the event.
860
+ #: templates/popup/index.php:47 media/js/blocks/dist/index.min.js:1
861
+ msgid "Event Head"
862
+ msgstr "Руководитель события"
863
+
864
+ #: templates/popup/index.php:50
865
+ msgid "Check the event parameter(s) to be displayed in the timetable."
866
+ msgstr "Отметьте параметры события, которые будут отображаться в расписании."
867
+
868
+ #: templates/popup/index.php:54 media/js/blocks/dist/index.min.js:1
869
+ msgid "Block height in pixels"
870
+ msgstr "Высота блока в пикселях"
871
+
872
+ #: templates/popup/index.php:57
873
+ msgid "Set height of the block"
874
+ msgstr "Установить высоту блока"
875
+
876
+ #: templates/popup/index.php:61 media/js/blocks/dist/index.min.js:1
877
+ msgid "Base font size"
878
+ msgstr "Базовый размер шрифта"
879
+
880
+ #: templates/popup/index.php:64 media/js/blocks/dist/index.min.js:1
881
+ msgid "Base font size for the table. Example 12px, 2em, 80%."
882
+ msgstr "Базовый размер шрифта для таблицы. Например, 12px, 2em, 80%."
883
+
884
+ #: templates/popup/index.php:68 media/js/blocks/dist/index.min.js:1
885
+ msgid "Time frame for event"
886
+ msgstr "Период времени для события"
887
+
888
+ #: templates/popup/index.php:78 media/js/blocks/dist/index.min.js:1
889
+ msgid "Filter events style"
890
+ msgstr "Стиль фильтра событий"
891
+
892
+ #: templates/popup/index.php:81
893
+ msgid "Dropdown"
894
+ msgstr "Выпадающий"
895
+
896
+ #: templates/popup/index.php:83
897
+ msgid "None"
898
+ msgstr "Ничего"
899
+
900
+ #: templates/popup/index.php:98 media/js/blocks/dist/index.min.js:1
901
+ msgid "Filter title to display all events"
902
+ msgstr "Заголовок фильтра для отображения всех событий"
903
+
904
+ #: templates/popup/index.php:104 media/js/blocks/dist/index.min.js:1
905
+ msgid "Hide 'All Events' option"
906
+ msgstr "Спрятать опцию \"Все события\""
907
+
908
+ #: templates/popup/index.php:114 media/js/blocks/dist/index.min.js:1
909
+ msgid "Hide column with hours"
910
+ msgstr "Прятать колонку с часами"
911
+
912
+ #: templates/popup/index.php:123 media/js/blocks/dist/index.min.js:1
913
+ msgid "Do not display empty rows"
914
+ msgstr "Не отображать пустые строки"
915
+
916
+ #: templates/popup/index.php:132 media/js/blocks/dist/index.min.js:1
917
+ msgid "Merge cells with common events"
918
+ msgstr "Обьеденить ячейки с одинаковыми событиями"
919
+
920
+ #: templates/popup/index.php:141 templates/widgets/gallery-list.php:59
921
+ #: media/js/blocks/dist/index.min.js:1
922
+ msgid "Disable event link"
923
+ msgstr "Отключить ссылку события"
924
+
925
+ #: templates/popup/index.php:150 media/js/blocks/dist/index.min.js:1
926
+ msgid "Horizontal align"
927
+ msgstr "Горизонтальное выравнивание"
928
+
929
+ #: templates/popup/index.php:159 media/js/blocks/dist/index.min.js:1
930
+ msgid "Vertical align"
931
+ msgstr "Вертикальное выравнивание"
932
+
933
+ #: templates/popup/index.php:161
934
+ msgid "default"
935
+ msgstr "по умолчанию"
936
+
937
+ #: templates/popup/index.php:162 media/js/blocks/dist/index.min.js:1
938
+ msgid "top"
939
+ msgstr "сверху"
940
+
941
+ #: templates/popup/index.php:163 media/js/blocks/dist/index.min.js:1
942
+ msgid "middle"
943
+ msgstr "посередине"
944
+
945
+ #: templates/popup/index.php:164 media/js/blocks/dist/index.min.js:1
946
+ msgid "bottom"
947
+ msgstr "снизу"
948
+
949
+ #: templates/popup/index.php:179 media/js/blocks/dist/index.min.js:1
950
+ msgid "Unique ID"
951
+ msgstr "Уникальный ID"
952
+
953
+ #: templates/popup/index.php:182 media/js/blocks/dist/index.min.js:1
954
+ msgid ""
955
+ "If you use more than one table on a page specify the unique ID for a "
956
+ "timetable. It is usually all lowercase and contains only letters, numbers, "
957
+ "and hyphens."
958
+ msgstr ""
959
+ "Если вы используете более одной таблицы на странице, укажите уникальный "
960
+ "идентификатор для расписания. Он, как правило, содержит только буквы в "
961
+ "нижнем регистре, цифры и дефис."
962
+
963
+ #: templates/popup/index.php:186 media/js/blocks/dist/index.min.js:1
964
+ msgid "CSS class"
965
+ msgstr "CSS класс"
966
+
967
+ #: templates/popup/index.php:192 media/js/blocks/dist/index.min.js:1
968
+ msgid "Mobile behavior"
969
+ msgstr "Отображение на мобильном"
970
+
971
+ #: templates/popup/index.php:195 media/js/blocks/dist/index.min.js:1
972
+ msgid "List"
973
+ msgstr "Список"
974
+
975
+ #: templates/popup/index.php:196 media/js/blocks/dist/index.min.js:1
976
+ msgid "Table"
977
+ msgstr "Таблица"
978
+
979
+ #: templates/popup/index.php:198
980
+ msgid ""
981
+ "Tick \"List\" to display events in a list view on mobile devices. Tick "
982
+ "\"Table\" to display events in a table."
983
+ msgstr ""
984
+ "Выберите \"Список\" для отображения событий в виде списка на мобильных "
985
+ "устройствах. Выберите \"Таблица\" для отображения событий в таблице."
986
+
987
+ #: templates/popup/index.php:204
988
+ msgid "Add Timetable"
989
+ msgstr "Добавить расписание"
990
+
991
+ #: templates/settings/general.php:2
992
+ msgid "General Settings"
993
+ msgstr "Основные настройки"
994
+
995
+ #: templates/settings/general.php:9
996
+ msgid "Template Mode"
997
+ msgstr "Режим шаблона"
998
+
999
+ #: templates/settings/general.php:13
1000
+ msgid "Theme Mode"
1001
+ msgstr "Режим темы"
1002
+
1003
+ #: templates/settings/general.php:14
1004
+ msgid "Developer Mode"
1005
+ msgstr "Режим разработчика"
1006
+
1007
+ #: templates/settings/general.php:16
1008
+ msgid ""
1009
+ "Choose Theme Mode to display the content with the styles of your theme. "
1010
+ "Choose Developer Mode to control appearance of the content with custom page "
1011
+ "templates, actions and filters."
1012
+ msgstr ""
1013
+ "Выберите режим \"Тема\" для отображения содержимого с помощью стилей вашей "
1014
+ "темы. Выберите режим \"Разработчик\", чтобы контролировать внешний вид "
1015
+ "содержимого с пользовательских шаблонов страниц, действий и фильтров."
1016
+
1017
+ #: templates/settings/general.php:16
1018
+ msgid ""
1019
+ "This option can't be changed if your theme is initially integrated with the "
1020
+ "plugin."
1021
+ msgstr ""
1022
+ "Эта опция не может быть изменена, если тема изначально интегрирована с "
1023
+ "плагином."
1024
+
1025
+ #: templates/settings/general.php:23
1026
+ msgid "Permalink Settings"
1027
+ msgstr "Настройки постоянных ссылок"
1028
+
1029
+ #: templates/settings/general.php:24
1030
+ msgid ""
1031
+ "Configure permalink settings in <a href=\"%s\">Settings > Permalinks</a>"
1032
+ msgstr ""
1033
+ "Настройте постоянные ссылки в <a href=\"%s\">Настройки > Постоянные ссылки</"
1034
+ "a>"
1035
+
1036
+ #: templates/settings/general.php:29
1037
+ msgid "Save"
1038
+ msgstr "Сохранить"
1039
+
1040
+ #: templates/shortcodes/empty-search-events.php:1
1041
+ #: templates/theme/widget-upcoming-view.php:54
1042
+ #: templates/widgets/widget-view.php:91
1043
+ msgid "no events found"
1044
+ msgstr "событий не найдено"
1045
+
1046
+ #: templates/templates-actions/action-sidebar.php:8
1047
+ #: templates/widgets/gallery-list.php:14
1048
+ msgid "Today upcoming events"
1049
+ msgstr "Предстоящие сегодня события"
1050
+
1051
+ #: templates/templates-actions/action-sidebar.php:13
1052
+ #: templates/widgets/gallery-list.php:16
1053
+ msgid "All upcoming events"
1054
+ msgstr "Все предстоящие события"
1055
+
1056
+ #: templates/widgets/gallery-list.php:10
1057
+ msgid "Events to display"
1058
+ msgstr "События для отображения"
1059
+
1060
+ #: templates/widgets/gallery-list.php:18
1061
+ msgid "Ongoing events"
1062
+ msgstr "Текущие события"
1063
+
1064
+ #: templates/widgets/gallery-list.php:23
1065
+ msgid "Input number of days"
1066
+ msgstr "Введите количество дней"
1067
+
1068
+ #: templates/widgets/gallery-list.php:28
1069
+ msgid "day"
1070
+ msgid_plural "days"
1071
+ msgstr[0] "день"
1072
+ msgstr[1] "дня"
1073
+ msgstr[2] "дней"
1074
+
1075
+ #: templates/widgets/gallery-list.php:32
1076
+ msgid "Event categories. Leave blank to display all."
1077
+ msgstr "Категории событий. Оставьте пустым для отображения всех."
1078
+
1079
+ #: templates/widgets/gallery-list.php:52
1080
+ msgid "Number of events to display"
1081
+ msgstr "Количество событий для отображения"
1082
+
1083
+ #: templates/widgets/gallery-list.php:70
1084
+ msgid "Custom link for events"
1085
+ msgstr "Специальные ссылки для событий"
1086
+
1087
+ #: templates/widgets/gallery-list.php:78
1088
+ msgid "Event background color"
1089
+ msgstr "Цвет фона событий"
1090
+
1091
+ #: templates/widgets/gallery-list.php:88
1092
+ msgid "Event background color on hover"
1093
+ msgstr "Цвет фона события при наведении"
1094
+
1095
+ #: templates/widgets/gallery-list.php:98
1096
+ msgid "Event text color"
1097
+ msgstr "Цвет текста события"
1098
+
1099
+ #: templates/widgets/gallery-list.php:108
1100
+ msgid "Event text color on hover"
1101
+ msgstr "Цвет текста события при наведении"
1102
+
1103
+ #: templates/widgets/gallery-list.php:118
1104
+ msgid "Event border color"
1105
+ msgstr "Цвет рамки события"
1106
+
1107
+ #: templates/widgets/gallery-list.php:128
1108
+ msgid "Event border color on hover"
1109
+ msgstr "Рамка события при наведении"
languages/mp-timetable.pot CHANGED
@@ -1,1063 +1,1132 @@
1
- #, fuzzy
2
- msgid ""
3
- msgstr ""
4
- "Project-Id-Version: Timetable and Event Schedule Plugin\n"
5
- "POT-Creation-Date: 2020-05-16 00:09+0300\n"
6
- "PO-Revision-Date: \n"
7
- "Last-Translator: \n"
8
- "Language-Team: MotoPress <info@getmotopress.com>\n"
9
- "Language: en\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
13
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
14
- "X-Generator: Poedit 2.2.1\n"
15
- "X-Poedit-SourceCharset: UTF-8\n"
16
- "X-Poedit-KeywordsList: esc_attr__;esc_html__;esc_attr_e;__;_e;_n;_x\n"
17
- "X-Poedit-Basepath: ..\n"
18
- "X-Poedit-SearchPath-0: .\n"
19
- "X-Poedit-SearchPathExcluded-0: classes/libs\n"
20
- "X-Poedit-SearchPathExcluded-1: node_modules\n"
21
-
22
- #: admin/help/index.php:10 templates/settings/general.php:41
23
- #, php-format
24
- msgid "If you like %1$s please leave us a %2$s rating."
25
- msgstr ""
26
-
27
- #: admin/import/export.php:1 admin/import/export.php:5
28
- msgid "Export"
29
- msgstr ""
30
-
31
- #: admin/import/greet.php:2
32
- msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
33
- msgstr ""
34
-
35
- #: admin/import/header.php:2
36
- msgid "Import / Export Timetable Plugin Data"
37
- msgstr ""
38
-
39
- #: admin/import/import.php:4
40
- msgid "Import"
41
- msgstr ""
42
-
43
- #: classes/blocks/class-timetable-block.php:79 classes/class-core.php:442
44
- #: classes/class-shortcode.php:70 classes/class-shortcode.php:286
45
- #: templates-functions/action-shortcode-functions.php:57
46
- #: templates-functions/action-shortcode-functions.php:71
47
- #: templates-functions/action-shortcode-functions.php:72
48
- msgid "All Events"
49
- msgstr ""
50
-
51
- #: classes/class-core.php:331 classes/class-core.php:342
52
- #: classes/class-core.php:346 classes/class-shortcode.php:265
53
- #: media/js/blocks/src/timetable/inspector.js:107 templates/popup/index.php:27
54
- msgid "Event categories"
55
- msgstr ""
56
-
57
- #: classes/class-core.php:332
58
- msgid "Event category"
59
- msgstr ""
60
-
61
- #: classes/class-core.php:333 classes/class-core.php:334
62
- msgid "Add New Event category"
63
- msgstr ""
64
-
65
- #: classes/class-core.php:335
66
- msgid "Edit Event category"
67
- msgstr ""
68
-
69
- #: classes/class-core.php:336
70
- msgid "New Event category"
71
- msgstr ""
72
-
73
- #: classes/class-core.php:337
74
- msgid "All Event categories"
75
- msgstr ""
76
-
77
- #: classes/class-core.php:338
78
- msgid "View Event category"
79
- msgstr ""
80
-
81
- #: classes/class-core.php:339
82
- msgid "Search Event category"
83
- msgstr ""
84
-
85
- #: classes/class-core.php:340
86
- msgid "No Event categories found"
87
- msgstr ""
88
-
89
- #: classes/class-core.php:341
90
- msgid "No Event categories found in Trash"
91
- msgstr ""
92
-
93
- #: classes/class-core.php:375 classes/class-core.php:386
94
- #: classes/class-core.php:390
95
- msgid "Event tags"
96
- msgstr ""
97
-
98
- #: classes/class-core.php:376
99
- msgid "Event tag"
100
- msgstr ""
101
-
102
- #: classes/class-core.php:377 classes/class-core.php:378
103
- msgid "Add New Event tag"
104
- msgstr ""
105
-
106
- #: classes/class-core.php:379
107
- msgid "Edit Event tag"
108
- msgstr ""
109
-
110
- #: classes/class-core.php:380
111
- msgid "New Event tag"
112
- msgstr ""
113
-
114
- #: classes/class-core.php:381
115
- msgid "All Event tags"
116
- msgstr ""
117
-
118
- #: classes/class-core.php:382
119
- msgid "View Event tag"
120
- msgstr ""
121
-
122
- #: classes/class-core.php:383
123
- msgid "Search Event tag"
124
- msgstr ""
125
-
126
- #: classes/class-core.php:384
127
- msgid "No Event tags found"
128
- msgstr ""
129
-
130
- #: classes/class-core.php:385
131
- msgid "No Event tags found in Trash"
132
- msgstr ""
133
-
134
- #: classes/class-core.php:436 classes/class-core.php:447
135
- #: classes/class-hooks.php:192 classes/class-shortcode.php:260
136
- msgid "Events"
137
- msgstr ""
138
-
139
- #: classes/class-core.php:437
140
- msgid "Event"
141
- msgstr ""
142
-
143
- #: classes/class-core.php:438 classes/class-core.php:439
144
- msgid "Add New Event"
145
- msgstr ""
146
-
147
- #: classes/class-core.php:440
148
- msgid "Edit Event"
149
- msgstr ""
150
-
151
- #: classes/class-core.php:441
152
- msgid "New Event"
153
- msgstr ""
154
-
155
- #: classes/class-core.php:443
156
- msgid "View Event"
157
- msgstr ""
158
-
159
- #: classes/class-core.php:444
160
- msgid "Search Event"
161
- msgstr ""
162
-
163
- #: classes/class-core.php:445
164
- msgid "No Events found"
165
- msgstr ""
166
-
167
- #: classes/class-core.php:446
168
- msgid "No Events found in Trash"
169
- msgstr ""
170
-
171
- #: classes/class-core.php:475 classes/class-core.php:486
172
- #: classes/class-hooks.php:200 media/js/blocks/src/timetable/inspector.js:89
173
- #: templates/popup/index.php:5
174
- msgid "Columns"
175
- msgstr ""
176
-
177
- #: classes/class-core.php:476 classes/class-shortcode.php:255
178
- #: templates/events/event-data.php:4
179
- msgid "Column"
180
- msgstr ""
181
-
182
- #: classes/class-core.php:477 classes/class-core.php:478
183
- msgid "Add New Column"
184
- msgstr ""
185
-
186
- #: classes/class-core.php:479
187
- msgid "Edit Column"
188
- msgstr ""
189
-
190
- #: classes/class-core.php:480
191
- msgid "New Column"
192
- msgstr ""
193
-
194
- #: classes/class-core.php:481
195
- msgid "All Columns"
196
- msgstr ""
197
-
198
- #: classes/class-core.php:482
199
- msgid "View Column"
200
- msgstr ""
201
-
202
- #: classes/class-core.php:483
203
- msgid "Search Column"
204
- msgstr ""
205
-
206
- #: classes/class-core.php:484
207
- msgid "No Columns found"
208
- msgstr ""
209
-
210
- #: classes/class-core.php:485
211
- msgid "No Columns found in Trash"
212
- msgstr ""
213
-
214
- #: classes/class-hooks.php:78
215
- msgid "Timetable Sidebar"
216
- msgstr ""
217
-
218
- #: classes/class-hooks.php:80 classes/class-hooks.php:188
219
- #: classes/class-shortcode.php:370 media/js/blocks/src/timetable/index.js:12
220
- msgid "Timetable"
221
- msgstr ""
222
-
223
- #: classes/class-hooks.php:179
224
- msgid "Import Timetable events, categories, tags and images."
225
- msgstr ""
226
-
227
- #: classes/class-hooks.php:196
228
- msgid "Add Event"
229
- msgstr ""
230
-
231
- #: classes/class-hooks.php:204
232
- msgid "Add Column"
233
- msgstr ""
234
-
235
- #: classes/class-hooks.php:208
236
- msgid "Event Categories"
237
- msgstr ""
238
-
239
- #: classes/class-hooks.php:212
240
- msgid "Event Tags"
241
- msgstr ""
242
-
243
- #: classes/class-hooks.php:216 classes/modules/class-post.php:41
244
- #: media/js/blocks/src/timetable/inspector.js:84
245
- msgid "Settings"
246
- msgstr ""
247
-
248
- #: classes/class-hooks.php:220
249
- msgid "Export / Import"
250
- msgstr ""
251
-
252
- #: classes/class-hooks.php:224
253
- msgid "Help & Shortcode"
254
- msgstr ""
255
-
256
- #: classes/class-hooks.php:288
257
- msgid "Quick Start Guide"
258
- msgstr ""
259
-
260
- #: classes/class-hooks.php:289
261
- msgid "Help"
262
- msgstr ""
263
-
264
- #: classes/class-hooks.php:290
265
- msgid "Leave a Review"
266
- msgstr ""
267
-
268
- #: classes/class-permalinks.php:26
269
- msgid "Timetable Permalinks"
270
- msgstr ""
271
-
272
- #: classes/class-permalinks.php:30
273
- msgid "Column base"
274
- msgstr ""
275
-
276
- #: classes/class-permalinks.php:37
277
- msgid "Event base"
278
- msgstr ""
279
-
280
- #: classes/class-permalinks.php:44
281
- msgid "Event Category base"
282
- msgstr ""
283
-
284
- #: classes/class-permalinks.php:51
285
- msgid "Event Tag base"
286
- msgstr ""
287
-
288
- #: classes/class-shortcode.php:270
289
- msgid "Hour measure"
290
- msgstr ""
291
-
292
- #: classes/class-shortcode.php:271
293
- #: media/js/blocks/src/timetable/inspector.js:161 templates/popup/index.php:66
294
- msgid "Hour (1h)"
295
- msgstr ""
296
-
297
- #: classes/class-shortcode.php:271
298
- #: media/js/blocks/src/timetable/inspector.js:162 templates/popup/index.php:67
299
- msgid "Half hour (30min)"
300
- msgstr ""
301
-
302
- #: classes/class-shortcode.php:271
303
- #: media/js/blocks/src/timetable/inspector.js:163 templates/popup/index.php:68
304
- msgid "Quarter hour (15min)"
305
- msgstr ""
306
-
307
- #: classes/class-shortcode.php:275
308
- msgid "Filter style"
309
- msgstr ""
310
-
311
- #: classes/class-shortcode.php:276
312
- #: media/js/blocks/src/timetable/inspector.js:171
313
- msgid "Dropdown list"
314
- msgstr ""
315
-
316
- #: classes/class-shortcode.php:276
317
- #: media/js/blocks/src/timetable/inspector.js:172 templates/popup/index.php:77
318
- msgid "Tabs"
319
- msgstr ""
320
-
321
- #: classes/class-shortcode.php:280
322
- #: media/js/blocks/src/timetable/inspector.js:176 templates/popup/index.php:83
323
- msgid "Order of items in filter"
324
- msgstr ""
325
-
326
- #: classes/class-shortcode.php:281 classes/class-shortcode.php:367
327
- #: media/js/blocks/src/timetable/inspector.js:180
328
- #: media/js/blocks/src/timetable/inspector.js:250
329
- #: media/js/blocks/src/timetable/inspector.js:261 templates/popup/index.php:86
330
- #: templates/popup/index.php:167
331
- msgid "Default"
332
- msgstr ""
333
-
334
- #: classes/class-shortcode.php:281
335
- #: media/js/blocks/src/timetable/inspector.js:181 templates/popup/index.php:87
336
- msgid "Menu Order"
337
- msgstr ""
338
-
339
- #: classes/class-shortcode.php:281 classes/class-shortcode.php:306
340
- #: media/js/blocks/src/timetable/inspector.js:114
341
- #: media/js/blocks/src/timetable/inspector.js:182 templates/popup/index.php:40
342
- #: templates/popup/index.php:88 templates/widgets/gallery-list.php:3
343
- msgid "Title"
344
- msgstr ""
345
-
346
- #: classes/class-shortcode.php:285
347
- msgid "Filter label"
348
- msgstr ""
349
-
350
- #: classes/class-shortcode.php:290
351
- msgid "Hide 'All Events' view"
352
- msgstr ""
353
-
354
- #: classes/class-shortcode.php:291 classes/class-shortcode.php:296
355
- #: classes/class-shortcode.php:301 classes/class-shortcode.php:308
356
- #: classes/class-shortcode.php:314 classes/class-shortcode.php:320
357
- #: classes/class-shortcode.php:326 classes/class-shortcode.php:332
358
- #: classes/class-shortcode.php:337 classes/class-shortcode.php:361
359
- #: media/js/blocks/src/timetable/inspector.js:195
360
- #: media/js/blocks/src/timetable/inspector.js:204
361
- #: media/js/blocks/src/timetable/inspector.js:213
362
- #: media/js/blocks/src/timetable/inspector.js:222
363
- #: media/js/blocks/src/timetable/inspector.js:231
364
- #: templates/events/metabox-event-options.php:45 templates/popup/index.php:103
365
- #: templates/popup/index.php:112 templates/popup/index.php:122
366
- #: templates/popup/index.php:130 templates/popup/index.php:139
367
- #: templates/widgets/gallery-list.php:63
368
- msgid "No"
369
- msgstr ""
370
-
371
- #: classes/class-shortcode.php:291 classes/class-shortcode.php:296
372
- #: classes/class-shortcode.php:301 classes/class-shortcode.php:308
373
- #: classes/class-shortcode.php:314 classes/class-shortcode.php:320
374
- #: classes/class-shortcode.php:326 classes/class-shortcode.php:332
375
- #: classes/class-shortcode.php:337 classes/class-shortcode.php:361
376
- #: media/js/blocks/src/timetable/inspector.js:196
377
- #: media/js/blocks/src/timetable/inspector.js:205
378
- #: media/js/blocks/src/timetable/inspector.js:214
379
- #: media/js/blocks/src/timetable/inspector.js:223
380
- #: media/js/blocks/src/timetable/inspector.js:232
381
- #: templates/events/metabox-event-options.php:46 templates/popup/index.php:104
382
- #: templates/popup/index.php:113 templates/popup/index.php:121
383
- #: templates/popup/index.php:131 templates/popup/index.php:140
384
- #: templates/widgets/gallery-list.php:65
385
- msgid "Yes"
386
- msgstr ""
387
-
388
- #: classes/class-shortcode.php:295
389
- msgid "Hide first (hours) column"
390
- msgstr ""
391
-
392
- #: classes/class-shortcode.php:300
393
- msgid "Hide empty rows"
394
- msgstr ""
395
-
396
- #: classes/class-shortcode.php:312
397
- #: media/js/blocks/src/timetable/inspector.js:121 templates/popup/index.php:41
398
- msgid "Time"
399
- msgstr ""
400
-
401
- #: classes/class-shortcode.php:318
402
- #: media/js/blocks/src/timetable/inspector.js:126 templates/popup/index.php:42
403
- msgid "Subtitle"
404
- msgstr ""
405
-
406
- #: classes/class-shortcode.php:324
407
- #: media/js/blocks/src/timetable/inspector.js:131
408
- #: templates/events/event-data.php:7 templates/popup/index.php:43
409
- msgid "Description"
410
- msgstr ""
411
-
412
- #: classes/class-shortcode.php:330
413
- msgid "User"
414
- msgstr ""
415
-
416
- #: classes/class-shortcode.php:336
417
- msgid "Disable event URL"
418
- msgstr ""
419
-
420
- #: classes/class-shortcode.php:341
421
- msgid "Text align"
422
- msgstr ""
423
-
424
- #: classes/class-shortcode.php:342
425
- #: media/js/blocks/src/timetable/inspector.js:240 templates/popup/index.php:147
426
- msgid "center"
427
- msgstr ""
428
-
429
- #: classes/class-shortcode.php:342
430
- #: media/js/blocks/src/timetable/inspector.js:241 templates/popup/index.php:148
431
- msgid "left"
432
- msgstr ""
433
-
434
- #: classes/class-shortcode.php:342
435
- #: media/js/blocks/src/timetable/inspector.js:242 templates/popup/index.php:149
436
- msgid "right"
437
- msgstr ""
438
-
439
- #: classes/class-shortcode.php:346
440
- msgid "Id"
441
- msgstr ""
442
-
443
- #: classes/class-shortcode.php:350
444
- msgid "Row height (in px)"
445
- msgstr ""
446
-
447
- #: classes/class-shortcode.php:355
448
- msgid "Base Font Size"
449
- msgstr ""
450
-
451
- #: classes/class-shortcode.php:360
452
- msgid "Responsive"
453
- msgstr ""
454
-
455
- #: classes/class-shortcode.php:366
456
- #: media/js/blocks/src/timetable/inspector.js:257 templates/popup/index.php:164
457
- msgid "Table layout"
458
- msgstr ""
459
-
460
- #: classes/class-shortcode.php:367
461
- #: media/js/blocks/src/timetable/inspector.js:262 templates/popup/index.php:168
462
- msgid "Auto"
463
- msgstr ""
464
-
465
- #: classes/class-shortcode.php:367
466
- #: media/js/blocks/src/timetable/inspector.js:263 templates/popup/index.php:169
467
- msgid "Fixed"
468
- msgstr ""
469
-
470
- #: classes/controllers/class-controller-settings.php:70
471
- msgid "Settings saved."
472
- msgstr ""
473
-
474
- #: classes/models/class-column.php:42 classes/modules/class-post.php:40
475
- msgid "Timeslots"
476
- msgstr ""
477
-
478
- #: classes/models/class-events.php:171
479
- msgid "Tags"
480
- msgstr ""
481
-
482
- #: classes/models/class-events.php:172
483
- msgid "Categories"
484
- msgstr ""
485
-
486
- #: classes/models/class-events.php:774
487
- msgid "Duplicate"
488
- msgstr ""
489
-
490
- #: classes/models/class-events.php:795
491
- msgid "A post type mismatch has been detected."
492
- msgstr ""
493
-
494
- #: classes/models/class-events.php:795 classes/models/class-events.php:893
495
- msgid "Sorry, you are not allowed to edit this item."
496
- msgstr ""
497
-
498
- #: classes/models/class-events.php:819
499
- #, php-format
500
- msgid "%s - Copy"
501
- msgstr ""
502
-
503
- #: classes/models/class-import.php:125
504
- msgid "Assign Authors"
505
- msgstr ""
506
-
507
- #: classes/models/class-import.php:126
508
- msgid ""
509
- "To make it easier for you to edit and save the imported content, you may "
510
- "want to reassign the author of the imported item to an existing user of this "
511
- "site. For example, you may want to import all the entries as <code>admin</"
512
- "code>s entries."
513
- msgstr ""
514
-
515
- #: classes/models/class-import.php:128
516
- #, php-format
517
- msgid ""
518
- "If a new user is created by WordPress, a new password will be randomly "
519
- "generated and the new user&#8217;s role will be set as %s. Manually changing "
520
- "the new user&#8217;s details will be necessary."
521
- msgstr ""
522
-
523
- #: classes/models/class-import.php:138
524
- msgid "Import Attachments"
525
- msgstr ""
526
-
527
- #: classes/models/class-import.php:141
528
- msgid "Download and import file attachments"
529
- msgstr ""
530
-
531
- #: classes/models/class-import.php:145
532
- msgid "Submit"
533
- msgstr ""
534
-
535
- #: classes/models/class-import.php:158
536
- msgid "Import author:"
537
- msgstr ""
538
-
539
- #: classes/models/class-import.php:169
540
- msgid "or create new user with login name:"
541
- msgstr ""
542
-
543
- #: classes/models/class-import.php:172
544
- msgid "as a new user:"
545
- msgstr ""
546
-
547
- #: classes/models/class-import.php:180
548
- msgid "assign posts to an existing user:"
549
- msgstr ""
550
-
551
- #: classes/models/class-import.php:182
552
- msgid "or assign posts to an existing user:"
553
- msgstr ""
554
-
555
- #: classes/models/class-import.php:183
556
- #: templates/column/metabox-column-options.php:23
557
- msgid "- Select -"
558
- msgstr ""
559
-
560
- #: classes/models/class-import.php:269
561
- msgid "All done."
562
- msgstr ""
563
-
564
- #: classes/models/class-import.php:269
565
- msgid "Have fun!"
566
- msgstr ""
567
-
568
- #: classes/models/class-import.php:270
569
- msgid "Remember to update the passwords and roles of imported users."
570
- msgstr ""
571
-
572
- #: classes/models/class-import.php:286
573
- msgid "Fetching attachments is not enabled"
574
- msgstr ""
575
-
576
- #: classes/models/class-import.php:299
577
- msgid "Invalid file type"
578
- msgstr ""
579
-
580
- #: classes/models/class-import.php:379
581
- msgid "Remote server did not respond"
582
- msgstr ""
583
-
584
- #: classes/models/class-import.php:385
585
- #, php-format
586
- msgid "Remote server returned error response %1$d %2$s"
587
- msgstr ""
588
-
589
- #: classes/models/class-import.php:394
590
- msgid "Remote file is incorrect size"
591
- msgstr ""
592
-
593
- #: classes/models/class-import.php:399
594
- msgid "Zero size file downloaded"
595
- msgstr ""
596
-
597
- #: classes/models/class-import.php:405
598
- #, php-format
599
- msgid "Remote file is too large, limit is %s"
600
- msgstr ""
601
-
602
- #: classes/models/class-import.php:422 classes/models/class-import.php:426
603
- #: classes/models/class-import.php:436
604
- msgid "Sorry, there has been an error."
605
- msgstr ""
606
-
607
- #: classes/models/class-import.php:427
608
- #, php-format
609
- msgid ""
610
- "The export file could not be found at <code>%s</code>. It is likely that "
611
- "this was caused by a permissions problem."
612
- msgstr ""
613
-
614
- #: classes/models/class-import.php:444
615
- #, php-format
616
- msgid ""
617
- "This WXR file (version %s) may not be supported by this version of the "
618
- "importer. Please consider updating."
619
- msgstr ""
620
-
621
- #: classes/models/class-import.php:501
622
- #, php-format
623
- msgid ""
624
- "Failed to import author %s. Their posts will be attributed to the current "
625
- "user."
626
- msgstr ""
627
-
628
- #: classes/models/class-import.php:558
629
- #, php-format
630
- msgid ""
631
- "Failed to create new user for %s. Their posts will be attributed to the "
632
- "current user."
633
- msgstr ""
634
-
635
- #: classes/models/class-import.php:609 classes/models/class-import.php:766
636
- #, php-format
637
- msgid "Failed to import %s %s"
638
- msgstr ""
639
-
640
- #: classes/models/class-import.php:656
641
- #, php-format
642
- msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
643
- msgstr ""
644
-
645
- #: classes/models/class-import.php:673
646
- #, php-format
647
- msgid "%s &#8220;%s&#8221; already exists."
648
- msgstr ""
649
-
650
- #: classes/models/class-import.php:732
651
- #, php-format
652
- msgid "Failed to import %s &#8220;%s&#8221;"
653
- msgstr ""
654
-
655
- #: classes/modules/class-post.php:42
656
- msgid "Column Type"
657
- msgstr ""
658
-
659
- #: classes/widgets/class-mp-timetable-widget.php:22
660
- msgid "Display upcoming events."
661
- msgstr ""
662
-
663
- #: classes/widgets/class-mp-timetable-widget.php:24
664
- msgid "Timetable Events"
665
- msgstr ""
666
-
667
- #: media/js/blocks/src/timetable/inspector.js:90
668
- #: media/js/blocks/src/timetable/inspector.js:99
669
- #: media/js/blocks/src/timetable/inspector.js:108 templates/popup/index.php:12
670
- #: templates/popup/index.php:23 templates/popup/index.php:34
671
- #: templates/widgets/gallery-list.php:48
672
- msgid "Hold the Ctrl or Command key to select/deselect multiple options."
673
- msgstr ""
674
-
675
- #: media/js/blocks/src/timetable/inspector.js:98 templates/popup/index.php:16
676
- msgid "Specific events"
677
- msgstr ""
678
-
679
- #: media/js/blocks/src/timetable/inspector.js:136 templates/popup/index.php:44
680
- msgid "Event Head"
681
- msgstr ""
682
-
683
- #: media/js/blocks/src/timetable/inspector.js:141 templates/popup/index.php:49
684
- msgid "Block height in pixels"
685
- msgstr ""
686
-
687
- #: media/js/blocks/src/timetable/inspector.js:151 templates/popup/index.php:56
688
- msgid "Base font size"
689
- msgstr ""
690
-
691
- #: media/js/blocks/src/timetable/inspector.js:152 templates/popup/index.php:59
692
- msgid "Base font size for the table. Example 12px, 2em, 80%."
693
- msgstr ""
694
-
695
- #: media/js/blocks/src/timetable/inspector.js:157 templates/popup/index.php:63
696
- msgid "Time frame for event"
697
- msgstr ""
698
-
699
- #: media/js/blocks/src/timetable/inspector.js:167 templates/popup/index.php:73
700
- msgid "Filter events style"
701
- msgstr ""
702
-
703
- #: media/js/blocks/src/timetable/inspector.js:186 templates/popup/index.php:93
704
- msgid "Filter title to display all events"
705
- msgstr ""
706
-
707
- #: media/js/blocks/src/timetable/inspector.js:191 templates/popup/index.php:99
708
- msgid "Hide 'All Events' option"
709
- msgstr ""
710
-
711
- #: media/js/blocks/src/timetable/inspector.js:200 templates/popup/index.php:109
712
- msgid "Hide column with hours"
713
- msgstr ""
714
-
715
- #: media/js/blocks/src/timetable/inspector.js:209 templates/popup/index.php:118
716
- msgid "Do not display empty rows"
717
- msgstr ""
718
-
719
- #: media/js/blocks/src/timetable/inspector.js:218 templates/popup/index.php:127
720
- msgid "Merge cells with common events"
721
- msgstr ""
722
-
723
- #: media/js/blocks/src/timetable/inspector.js:227 templates/popup/index.php:136
724
- #: templates/widgets/gallery-list.php:59
725
- msgid "Disable event link"
726
- msgstr ""
727
-
728
- #: media/js/blocks/src/timetable/inspector.js:236 templates/popup/index.php:145
729
- msgid "Horizontal align"
730
- msgstr ""
731
-
732
- #: media/js/blocks/src/timetable/inspector.js:246 templates/popup/index.php:154
733
- msgid "Vertical align"
734
- msgstr ""
735
-
736
- #: media/js/blocks/src/timetable/inspector.js:251 templates/popup/index.php:157
737
- msgid "top"
738
- msgstr ""
739
-
740
- #: media/js/blocks/src/timetable/inspector.js:252 templates/popup/index.php:158
741
- msgid "middle"
742
- msgstr ""
743
-
744
- #: media/js/blocks/src/timetable/inspector.js:253 templates/popup/index.php:159
745
- msgid "bottom"
746
- msgstr ""
747
-
748
- #: media/js/blocks/src/timetable/inspector.js:267 templates/popup/index.php:174
749
- msgid "Unique ID"
750
- msgstr ""
751
-
752
- #: media/js/blocks/src/timetable/inspector.js:268 templates/popup/index.php:177
753
- msgid ""
754
- "If you use more than one table on a page specify the unique ID for a "
755
- "timetable. It is usually all lowercase and contains only letters, numbers, "
756
- "and hyphens."
757
- msgstr ""
758
-
759
- #: media/js/blocks/src/timetable/inspector.js:273 templates/popup/index.php:181
760
- msgid "CSS class"
761
- msgstr ""
762
-
763
- #: media/js/blocks/src/timetable/inspector.js:278 templates/popup/index.php:187
764
- msgid "Mobile behavior"
765
- msgstr ""
766
-
767
- #: media/js/blocks/src/timetable/inspector.js:282 templates/popup/index.php:191
768
- msgid "Table"
769
- msgstr ""
770
-
771
- #: media/js/blocks/src/timetable/inspector.js:283 templates/popup/index.php:190
772
- msgid "List"
773
- msgstr ""
774
-
775
- #: templates-functions/actions-mp-event-functions.php:27
776
- #: templates/theme/event-timeslots.php:7
777
- #, php-format
778
- msgid "Event Timeslots (%s)"
779
- msgstr ""
780
-
781
- #: templates/column/metabox-column-options.php:11
782
- msgid "Simple Column"
783
- msgstr ""
784
-
785
- #: templates/column/metabox-column-options.php:20
786
- msgid "Day of the week"
787
- msgstr ""
788
-
789
- #: templates/column/metabox-column-options.php:24
790
- msgid "Sunday"
791
- msgstr ""
792
-
793
- #: templates/column/metabox-column-options.php:25
794
- msgid "Monday"
795
- msgstr ""
796
-
797
- #: templates/column/metabox-column-options.php:26
798
- msgid "Tuesday"
799
- msgstr ""
800
-
801
- #: templates/column/metabox-column-options.php:27
802
- msgid "Wednesday"
803
- msgstr ""
804
-
805
- #: templates/column/metabox-column-options.php:28
806
- msgid "Thursday"
807
- msgstr ""
808
-
809
- #: templates/column/metabox-column-options.php:29
810
- msgid "Friday"
811
- msgstr ""
812
-
813
- #: templates/column/metabox-column-options.php:30
814
- msgid "Saturday"
815
- msgstr ""
816
-
817
- #: templates/column/metabox-column-options.php:39
818
- msgid "Date"
819
- msgstr ""
820
-
821
- #: templates/events/event-data.php:5
822
- msgid "Start"
823
- msgstr ""
824
-
825
- #: templates/events/event-data.php:6
826
- msgid "End"
827
- msgstr ""
828
-
829
- #: templates/events/event-data.php:8
830
- msgid "Head"
831
- msgstr ""
832
-
833
- #: templates/events/event-data.php:9
834
- msgid "Actions"
835
- msgstr ""
836
-
837
- #: templates/events/event-data.php:32
838
- msgid "Edit event in the form below"
839
- msgstr ""
840
-
841
- #: templates/events/event-data.php:33
842
- msgid "Delete"
843
- msgstr ""
844
-
845
- #: templates/events/metabox-event-data.php:10
846
- msgid "Add New / Edit Timeslot"
847
- msgstr ""
848
-
849
- #: templates/events/metabox-event-data.php:13
850
- msgid "Column:"
851
- msgstr ""
852
-
853
- #: templates/events/metabox-event-data.php:21
854
- #, php-format
855
- msgid "Select column or <a target=\"_blank\" href=\"%s\">Add New</a>."
856
- msgstr ""
857
-
858
- #: templates/events/metabox-event-data.php:23
859
- #, php-format
860
- msgid "No columns found. <a href=\"%s\">Create at least one column first.</a>"
861
- msgstr ""
862
-
863
- #: templates/events/metabox-event-data.php:29
864
- msgid "Start Time:"
865
- msgstr ""
866
-
867
- #: templates/events/metabox-event-data.php:32
868
- #: templates/events/metabox-event-data.php:39
869
- msgid "hh:mm"
870
- msgstr ""
871
-
872
- #: templates/events/metabox-event-data.php:36
873
- msgid "End Time:"
874
- msgstr ""
875
-
876
- #: templates/events/metabox-event-data.php:43
877
- msgid "Description:"
878
- msgstr ""
879
-
880
- #: templates/events/metabox-event-data.php:47
881
- msgid "Event Head:"
882
- msgstr ""
883
-
884
- #: templates/events/metabox-event-data.php:55
885
- msgid "none"
886
- msgstr ""
887
-
888
- #: templates/events/metabox-event-data.php:78
889
- msgid "Add New"
890
- msgstr ""
891
-
892
- #: templates/events/metabox-event-options.php:4
893
- msgid "Event Subtitle:"
894
- msgstr ""
895
-
896
- #: templates/events/metabox-event-options.php:8
897
- msgid "Background Color:"
898
- msgstr ""
899
-
900
- #: templates/events/metabox-event-options.php:15
901
- msgid "Background Hover Color:"
902
- msgstr ""
903
-
904
- #: templates/events/metabox-event-options.php:22
905
- msgid "Text Color:"
906
- msgstr ""
907
-
908
- #: templates/events/metabox-event-options.php:29
909
- msgid "Text Hover Color:"
910
- msgstr ""
911
-
912
- #: templates/events/metabox-event-options.php:36
913
- msgid "Custom Event URL:"
914
- msgstr ""
915
-
916
- #: templates/events/metabox-event-options.php:42
917
- msgid "Disable link to this event:"
918
- msgstr ""
919
-
920
- #: templates/popup/index.php:38
921
- msgid "Fields to display:"
922
- msgstr ""
923
-
924
- #: templates/popup/index.php:45
925
- msgid "Check the event parameter(s) to be displayed in the timetable."
926
- msgstr ""
927
-
928
- #: templates/popup/index.php:52
929
- msgid "Set height of the block"
930
- msgstr ""
931
-
932
- #: templates/popup/index.php:76
933
- msgid "Dropdown"
934
- msgstr ""
935
-
936
- #: templates/popup/index.php:78
937
- msgid "None"
938
- msgstr ""
939
-
940
- #: templates/popup/index.php:156
941
- msgid "default"
942
- msgstr ""
943
-
944
- #: templates/popup/index.php:193
945
- msgid ""
946
- "Tick \"List\" to display events in a list view on mobile devices. Tick "
947
- "\"Table\" to display events in a table."
948
- msgstr ""
949
-
950
- #: templates/popup/index.php:199
951
- msgid "Add Timetable"
952
- msgstr ""
953
-
954
- #: templates/settings/general.php:2
955
- msgid "General Settings"
956
- msgstr ""
957
-
958
- #: templates/settings/general.php:9
959
- msgid "Template Mode"
960
- msgstr ""
961
-
962
- #: templates/settings/general.php:13
963
- msgid "Theme Mode"
964
- msgstr ""
965
-
966
- #: templates/settings/general.php:14
967
- msgid "Developer Mode"
968
- msgstr ""
969
-
970
- #: templates/settings/general.php:16
971
- msgid ""
972
- "Choose Theme Mode to display the content with the styles of your theme. "
973
- "Choose Developer Mode to control appearance of the content with custom page "
974
- "templates, actions and filters."
975
- msgstr ""
976
-
977
- #: templates/settings/general.php:16
978
- msgid ""
979
- "This option can't be changed if your theme is initially integrated with the "
980
- "plugin."
981
- msgstr ""
982
-
983
- #: templates/settings/general.php:23
984
- msgid "Permalink Settings"
985
- msgstr ""
986
-
987
- #: templates/settings/general.php:24
988
- #, php-format
989
- msgid ""
990
- "Configure permalink settings in <a href=\"%s\">Settings > Permalinks</a>"
991
- msgstr ""
992
-
993
- #: templates/settings/general.php:29
994
- msgid "Save"
995
- msgstr ""
996
-
997
- #: templates/shortcodes/empty-search-events.php:1
998
- #: templates/theme/widget-upcoming-view.php:54
999
- #: templates/widgets/widget-view.php:91
1000
- msgid "no events found"
1001
- msgstr ""
1002
-
1003
- #: templates/templates-actions/action-sidebar.php:8
1004
- #: templates/widgets/gallery-list.php:14
1005
- msgid "Today upcoming events"
1006
- msgstr ""
1007
-
1008
- #: templates/templates-actions/action-sidebar.php:13
1009
- #: templates/widgets/gallery-list.php:16
1010
- msgid "All upcoming events"
1011
- msgstr ""
1012
-
1013
- #: templates/widgets/gallery-list.php:10
1014
- msgid "Events to display"
1015
- msgstr ""
1016
-
1017
- #: templates/widgets/gallery-list.php:18
1018
- msgid "Ongoing events"
1019
- msgstr ""
1020
-
1021
- #: templates/widgets/gallery-list.php:23
1022
- msgid "Input number of days"
1023
- msgstr ""
1024
-
1025
- #: templates/widgets/gallery-list.php:28
1026
- msgid "day"
1027
- msgstr ""
1028
-
1029
- #: templates/widgets/gallery-list.php:32
1030
- msgid "Event categories. Leave blank to display all."
1031
- msgstr ""
1032
-
1033
- #: templates/widgets/gallery-list.php:52
1034
- msgid "Number of events to display"
1035
- msgstr ""
1036
-
1037
- #: templates/widgets/gallery-list.php:70
1038
- msgid "Custom link for events"
1039
- msgstr ""
1040
-
1041
- #: templates/widgets/gallery-list.php:78
1042
- msgid "Event background color"
1043
- msgstr ""
1044
-
1045
- #: templates/widgets/gallery-list.php:88
1046
- msgid "Event background color on hover"
1047
- msgstr ""
1048
-
1049
- #: templates/widgets/gallery-list.php:98
1050
- msgid "Event text color"
1051
- msgstr ""
1052
-
1053
- #: templates/widgets/gallery-list.php:108
1054
- msgid "Event text color on hover"
1055
- msgstr ""
1056
-
1057
- #: templates/widgets/gallery-list.php:118
1058
- msgid "Event border color"
1059
- msgstr ""
1060
-
1061
- #: templates/widgets/gallery-list.php:128
1062
- msgid "Event border color on hover"
1063
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2021 MotoPress
2
+ # This file is distributed under the same license as the Timetable and Event Schedule plugin.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: Timetable and Event Schedule 2.3.13\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/mp-timetable\n"
7
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
8
+ "Language-Team: LANGUAGE <LL@li.org>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "POT-Creation-Date: 2021-02-03T19:20:41+00:00\n"
13
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
14
+ "X-Generator: WP-CLI 2.4.0\n"
15
+ "X-Domain: mp-timetable\n"
16
+
17
+ #. Plugin Name of the plugin
18
+ msgid "Timetable and Event Schedule"
19
+ msgstr ""
20
+
21
+ #. Plugin URI of the plugin
22
+ msgid "https://motopress.com/products/timetable-event-schedule/"
23
+ msgstr ""
24
+
25
+ #. Description of the plugin
26
+ msgid "Smart time-management tool with a clean minimalist design for featuring your timetables and upcoming events."
27
+ msgstr ""
28
+
29
+ #. Author of the plugin
30
+ msgid "MotoPress"
31
+ msgstr ""
32
+
33
+ #. Author URI of the plugin
34
+ msgid "https://motopress.com"
35
+ msgstr ""
36
+
37
+ #. translators: 1: Timetable and Event Schedule 2:: five stars rating
38
+ #: admin/help/index.php:10
39
+ #: templates/settings/general.php:41
40
+ msgid "If you like %1$s please leave us a %2$s rating."
41
+ msgstr ""
42
+
43
+ #: admin/import/export.php:1
44
+ #: admin/import/export.php:5
45
+ msgid "Export"
46
+ msgstr ""
47
+
48
+ #: admin/import/greet.php:2
49
+ msgid "Choose a WXR (.xml) file to upload, then click Upload file and import."
50
+ msgstr ""
51
+
52
+ #: admin/import/header.php:2
53
+ msgid "Import / Export Timetable Plugin Data"
54
+ msgstr ""
55
+
56
+ #: admin/import/import.php:4
57
+ msgid "Import"
58
+ msgstr ""
59
+
60
+ #: classes/blocks/class-timetable-block.php:92
61
+ #: classes/class-core.php:443
62
+ #: classes/class-shortcode.php:70
63
+ #: classes/class-shortcode.php:286
64
+ #: templates-functions/action-shortcode-functions.php:57
65
+ #: templates-functions/action-shortcode-functions.php:71
66
+ #: templates-functions/action-shortcode-functions.php:72
67
+ msgid "All Events"
68
+ msgstr ""
69
+
70
+ #: classes/class-core.php:332
71
+ #: classes/class-core.php:343
72
+ #: classes/class-core.php:347
73
+ #: classes/class-shortcode.php:265
74
+ #: templates/popup/index.php:27
75
+ #: media/js/blocks/dist/index.min.js:1
76
+ msgid "Event categories"
77
+ msgstr ""
78
+
79
+ #: classes/class-core.php:333
80
+ msgid "Event category"
81
+ msgstr ""
82
+
83
+ #: classes/class-core.php:334
84
+ #: classes/class-core.php:335
85
+ msgid "Add New Event category"
86
+ msgstr ""
87
+
88
+ #: classes/class-core.php:336
89
+ msgid "Edit Event category"
90
+ msgstr ""
91
+
92
+ #: classes/class-core.php:337
93
+ msgid "New Event category"
94
+ msgstr ""
95
+
96
+ #: classes/class-core.php:338
97
+ msgid "All Event categories"
98
+ msgstr ""
99
+
100
+ #: classes/class-core.php:339
101
+ msgid "View Event category"
102
+ msgstr ""
103
+
104
+ #: classes/class-core.php:340
105
+ msgid "Search Event category"
106
+ msgstr ""
107
+
108
+ #: classes/class-core.php:341
109
+ msgid "No Event categories found"
110
+ msgstr ""
111
+
112
+ #: classes/class-core.php:342
113
+ msgid "No Event categories found in Trash"
114
+ msgstr ""
115
+
116
+ #: classes/class-core.php:376
117
+ #: classes/class-core.php:387
118
+ #: classes/class-core.php:391
119
+ msgid "Event tags"
120
+ msgstr ""
121
+
122
+ #: classes/class-core.php:377
123
+ msgid "Event tag"
124
+ msgstr ""
125
+
126
+ #: classes/class-core.php:378
127
+ #: classes/class-core.php:379
128
+ msgid "Add New Event tag"
129
+ msgstr ""
130
+
131
+ #: classes/class-core.php:380
132
+ msgid "Edit Event tag"
133
+ msgstr ""
134
+
135
+ #: classes/class-core.php:381
136
+ msgid "New Event tag"
137
+ msgstr ""
138
+
139
+ #: classes/class-core.php:382
140
+ msgid "All Event tags"
141
+ msgstr ""
142
+
143
+ #: classes/class-core.php:383
144
+ msgid "View Event tag"
145
+ msgstr ""
146
+
147
+ #: classes/class-core.php:384
148
+ msgid "Search Event tag"
149
+ msgstr ""
150
+
151
+ #: classes/class-core.php:385
152
+ msgid "No Event tags found"
153
+ msgstr ""
154
+
155
+ #: classes/class-core.php:386
156
+ msgid "No Event tags found in Trash"
157
+ msgstr ""
158
+
159
+ #: classes/class-core.php:437
160
+ #: classes/class-core.php:448
161
+ #: classes/class-hooks.php:192
162
+ #: classes/class-shortcode.php:260
163
+ msgid "Events"
164
+ msgstr ""
165
+
166
+ #: classes/class-core.php:438
167
+ msgid "Event"
168
+ msgstr ""
169
+
170
+ #: classes/class-core.php:439
171
+ #: classes/class-core.php:440
172
+ msgid "Add New Event"
173
+ msgstr ""
174
+
175
+ #: classes/class-core.php:441
176
+ msgid "Edit Event"
177
+ msgstr ""
178
+
179
+ #: classes/class-core.php:442
180
+ msgid "New Event"
181
+ msgstr ""
182
+
183
+ #: classes/class-core.php:444
184
+ msgid "View Event"
185
+ msgstr ""
186
+
187
+ #: classes/class-core.php:445
188
+ msgid "Search Event"
189
+ msgstr ""
190
+
191
+ #: classes/class-core.php:446
192
+ msgid "No Events found"
193
+ msgstr ""
194
+
195
+ #: classes/class-core.php:447
196
+ msgid "No Events found in Trash"
197
+ msgstr ""
198
+
199
+ #: classes/class-core.php:476
200
+ #: classes/class-core.php:487
201
+ #: classes/class-hooks.php:200
202
+ #: templates/popup/index.php:5
203
+ #: media/js/blocks/dist/index.min.js:1
204
+ msgid "Columns"
205
+ msgstr ""
206
+
207
+ #: classes/class-core.php:477
208
+ #: classes/class-shortcode.php:255
209
+ #: templates/events/event-data.php:4
210
+ msgid "Column"
211
+ msgstr ""
212
+
213
+ #: classes/class-core.php:478
214
+ #: classes/class-core.php:479
215
+ msgid "Add New Column"
216
+ msgstr ""
217
+
218
+ #: classes/class-core.php:480
219
+ msgid "Edit Column"
220
+ msgstr ""
221
+
222
+ #: classes/class-core.php:481
223
+ msgid "New Column"
224
+ msgstr ""
225
+
226
+ #: classes/class-core.php:482
227
+ msgid "All Columns"
228
+ msgstr ""
229
+
230
+ #: classes/class-core.php:483
231
+ msgid "View Column"
232
+ msgstr ""
233
+
234
+ #: classes/class-core.php:484
235
+ msgid "Search Column"
236
+ msgstr ""
237
+
238
+ #: classes/class-core.php:485
239
+ msgid "No Columns found"
240
+ msgstr ""
241
+
242
+ #: classes/class-core.php:486
243
+ msgid "No Columns found in Trash"
244
+ msgstr ""
245
+
246
+ #: classes/class-hooks.php:78
247
+ msgid "Timetable Sidebar"
248
+ msgstr ""
249
+
250
+ #: classes/class-hooks.php:80
251
+ #: classes/class-hooks.php:188
252
+ #: classes/class-shortcode.php:370
253
+ #: media/js/blocks/dist/index.min.js:1
254
+ msgid "Timetable"
255
+ msgstr ""
256
+
257
+ #: classes/class-hooks.php:179
258
+ msgid "Import Timetable events, categories, tags and images."
259
+ msgstr ""
260
+
261
+ #: classes/class-hooks.php:196
262
+ msgid "Add Event"
263
+ msgstr ""
264
+
265
+ #: classes/class-hooks.php:204
266
+ msgid "Add Column"
267
+ msgstr ""
268
+
269
+ #: classes/class-hooks.php:208
270
+ msgid "Event Categories"
271
+ msgstr ""
272
+
273
+ #: classes/class-hooks.php:212
274
+ msgid "Event Tags"
275
+ msgstr ""
276
+
277
+ #: classes/class-hooks.php:216
278
+ #: classes/modules/class-post.php:41
279
+ #: media/js/blocks/dist/index.min.js:1
280
+ msgid "Settings"
281
+ msgstr ""
282
+
283
+ #: classes/class-hooks.php:220
284
+ msgid "Export / Import"
285
+ msgstr ""
286
+
287
+ #: classes/class-hooks.php:224
288
+ msgid "Help & Shortcode"
289
+ msgstr ""
290
+
291
+ #: classes/class-hooks.php:288
292
+ msgid "Quick Start Guide"
293
+ msgstr ""
294
+
295
+ #: classes/class-hooks.php:289
296
+ msgid "Help"
297
+ msgstr ""
298
+
299
+ #: classes/class-hooks.php:290
300
+ msgid "Leave a Review"
301
+ msgstr ""
302
+
303
+ #: classes/class-permalinks.php:26
304
+ msgid "Timetable Permalinks"
305
+ msgstr ""
306
+
307
+ #: classes/class-permalinks.php:30
308
+ msgid "Column base"
309
+ msgstr ""
310
+
311
+ #: classes/class-permalinks.php:37
312
+ msgid "Event base"
313
+ msgstr ""
314
+
315
+ #: classes/class-permalinks.php:44
316
+ msgid "Event Category base"
317
+ msgstr ""
318
+
319
+ #: classes/class-permalinks.php:51
320
+ msgid "Event Tag base"
321
+ msgstr ""
322
+
323
+ #: classes/class-shortcode.php:270
324
+ msgid "Hour measure"
325
+ msgstr ""
326
+
327
+ #: classes/class-shortcode.php:271
328
+ #: templates/popup/index.php:71
329
+ #: media/js/blocks/dist/index.min.js:1
330
+ msgid "Hour (1h)"
331
+ msgstr ""
332
+
333
+ #: classes/class-shortcode.php:271
334
+ #: templates/popup/index.php:72
335
+ #: media/js/blocks/dist/index.min.js:1
336
+ msgid "Half hour (30min)"
337
+ msgstr ""
338
+
339
+ #: classes/class-shortcode.php:271
340
+ #: templates/popup/index.php:73
341
+ #: media/js/blocks/dist/index.min.js:1
342
+ msgid "Quarter hour (15min)"
343
+ msgstr ""
344
+
345
+ #: classes/class-shortcode.php:275
346
+ msgid "Filter style"
347
+ msgstr ""
348
+
349
+ #: classes/class-shortcode.php:276
350
+ #: media/js/blocks/dist/index.min.js:1
351
+ msgid "Dropdown list"
352
+ msgstr ""
353
+
354
+ #: classes/class-shortcode.php:276
355
+ #: templates/popup/index.php:82
356
+ #: media/js/blocks/dist/index.min.js:1
357
+ msgid "Tabs"
358
+ msgstr ""
359
+
360
+ #: classes/class-shortcode.php:280
361
+ #: templates/popup/index.php:88
362
+ #: media/js/blocks/dist/index.min.js:1
363
+ msgid "Order of items in filter"
364
+ msgstr ""
365
+
366
+ #: classes/class-shortcode.php:281
367
+ #: classes/class-shortcode.php:367
368
+ #: templates/popup/index.php:91
369
+ #: templates/popup/index.php:172
370
+ #: media/js/blocks/dist/index.min.js:1
371
+ msgid "Default"
372
+ msgstr ""
373
+
374
+ #: classes/class-shortcode.php:281
375
+ #: templates/popup/index.php:92
376
+ #: media/js/blocks/dist/index.min.js:1
377
+ msgid "Menu Order"
378
+ msgstr ""
379
+
380
+ #: classes/class-shortcode.php:281
381
+ #: classes/class-shortcode.php:306
382
+ #: templates/popup/index.php:40
383
+ #: templates/popup/index.php:93
384
+ #: templates/widgets/gallery-list.php:3
385
+ #: media/js/blocks/dist/index.min.js:1
386
+ msgid "Title"
387
+ msgstr ""
388
+
389
+ #: classes/class-shortcode.php:285
390
+ msgid "Filter label"
391
+ msgstr ""
392
+
393
+ #: classes/class-shortcode.php:290
394
+ msgid "Hide 'All Events' view"
395
+ msgstr ""
396
+
397
+ #: classes/class-shortcode.php:291
398
+ #: classes/class-shortcode.php:296
399
+ #: classes/class-shortcode.php:301
400
+ #: classes/class-shortcode.php:308
401
+ #: classes/class-shortcode.php:314
402
+ #: classes/class-shortcode.php:320
403
+ #: classes/class-shortcode.php:326
404
+ #: classes/class-shortcode.php:332
405
+ #: classes/class-shortcode.php:337
406
+ #: classes/class-shortcode.php:361
407
+ #: templates/events/metabox-event-options.php:45
408
+ #: templates/popup/index.php:108
409
+ #: templates/popup/index.php:117
410
+ #: templates/popup/index.php:127
411
+ #: templates/popup/index.php:135
412
+ #: templates/popup/index.php:144
413
+ #: templates/widgets/gallery-list.php:63
414
+ #: media/js/blocks/dist/index.min.js:1
415
+ msgid "No"
416
+ msgstr ""
417
+
418
+ #: classes/class-shortcode.php:291
419
+ #: classes/class-shortcode.php:296
420
+ #: classes/class-shortcode.php:301
421
+ #: classes/class-shortcode.php:308
422
+ #: classes/class-shortcode.php:314
423
+ #: classes/class-shortcode.php:320
424
+ #: classes/class-shortcode.php:326
425
+ #: classes/class-shortcode.php:332
426
+ #: classes/class-shortcode.php:337
427
+ #: classes/class-shortcode.php:361
428
+ #: templates/events/metabox-event-options.php:46
429
+ #: templates/popup/index.php:109
430
+ #: templates/popup/index.php:118
431
+ #: templates/popup/index.php:126
432
+ #: templates/popup/index.php:136
433
+ #: templates/popup/index.php:145
434
+ #: templates/widgets/gallery-list.php:65
435
+ #: media/js/blocks/dist/index.min.js:1
436
+ msgid "Yes"
437
+ msgstr ""
438
+
439
+ #: classes/class-shortcode.php:295
440
+ msgid "Hide first (hours) column"
441
+ msgstr ""
442
+
443
+ #: classes/class-shortcode.php:300
444
+ msgid "Hide empty rows"
445
+ msgstr ""
446
+
447
+ #: classes/class-shortcode.php:312
448
+ #: templates/popup/index.php:41
449
+ #: media/js/blocks/dist/index.min.js:1
450
+ msgid "Time"
451
+ msgstr ""
452
+
453
+ #: classes/class-shortcode.php:318
454
+ #: templates/popup/index.php:42
455
+ #: media/js/blocks/dist/index.min.js:1
456
+ msgid "Subtitle"
457
+ msgstr ""
458
+
459
+ #: classes/class-shortcode.php:324
460
+ #: templates/events/event-data.php:7
461
+ #: templates/popup/index.php:43
462
+ #: media/js/blocks/dist/index.min.js:1
463
+ msgid "Description"
464
+ msgstr ""
465
+
466
+ #: classes/class-shortcode.php:330
467
+ msgid "User"
468
+ msgstr ""
469
+
470
+ #: classes/class-shortcode.php:336
471
+ msgid "Disable event URL"
472
+ msgstr ""
473
+
474
+ #: classes/class-shortcode.php:341
475
+ msgid "Text align"
476
+ msgstr ""
477
+
478
+ #: classes/class-shortcode.php:342
479
+ #: templates/popup/index.php:152
480
+ #: media/js/blocks/dist/index.min.js:1
481
+ msgid "center"
482
+ msgstr ""
483
+
484
+ #: classes/class-shortcode.php:342
485
+ #: templates/popup/index.php:153
486
+ #: media/js/blocks/dist/index.min.js:1
487
+ msgid "left"
488
+ msgstr ""
489
+
490
+ #: classes/class-shortcode.php:342
491
+ #: templates/popup/index.php:154
492
+ #: media/js/blocks/dist/index.min.js:1
493
+ msgid "right"
494
+ msgstr ""
495
+
496
+ #: classes/class-shortcode.php:346
497
+ msgid "Id"
498
+ msgstr ""
499
+
500
+ #: classes/class-shortcode.php:350
501
+ msgid "Row height (in px)"
502
+ msgstr ""
503
+
504
+ #: classes/class-shortcode.php:355
505
+ msgid "Base Font Size"
506
+ msgstr ""
507
+
508
+ #: classes/class-shortcode.php:360
509
+ msgid "Responsive"
510
+ msgstr ""
511
+
512
+ #: classes/class-shortcode.php:366
513
+ #: templates/popup/index.php:169
514
+ #: media/js/blocks/dist/index.min.js:1
515
+ msgid "Column width"
516
+ msgstr ""
517
+
518
+ #: classes/class-shortcode.php:367
519
+ #: templates/popup/index.php:173
520
+ #: media/js/blocks/dist/index.min.js:1
521
+ msgid "Auto"
522
+ msgstr ""
523
+
524
+ #: classes/class-shortcode.php:367
525
+ #: templates/popup/index.php:174
526
+ #: media/js/blocks/dist/index.min.js:1
527
+ msgid "Fixed"
528
+ msgstr ""
529
+
530
+ #: classes/controllers/class-controller-settings.php:70
531
+ msgid "Settings saved."
532
+ msgstr ""
533
+
534
+ #: classes/libs/parsers.php:44
535
+ #: classes/libs/parsers.php:74
536
+ #: classes/libs/parsers.php:82
537
+ msgid "There was an error when reading this WXR file"
538
+ msgstr ""
539
+
540
+ #: classes/libs/parsers.php:45
541
+ msgid "Details are shown above. The importer will now try again with a different parser..."
542
+ msgstr ""
543
+
544
+ #: classes/libs/parsers.php:86
545
+ #: classes/libs/parsers.php:91
546
+ #: classes/libs/parsers.php:304
547
+ #: classes/libs/parsers.php:565
548
+ msgid "This does not appear to be a WXR file, missing/invalid WXR version number"
549
+ msgstr ""
550
+
551
+ #: classes/models/class-column.php:42
552
+ #: classes/modules/class-post.php:40
553
+ msgid "Timeslots"
554
+ msgstr ""
555
+
556
+ #: classes/models/class-events.php:171
557
+ msgid "Tags"
558
+ msgstr ""
559
+
560
+ #: classes/models/class-events.php:172
561
+ msgid "Categories"
562
+ msgstr ""
563
+
564
+ #: classes/models/class-events.php:774
565
+ msgid "Duplicate"
566
+ msgstr ""
567
+
568
+ #: classes/models/class-events.php:795
569
+ msgid "A post type mismatch has been detected."
570
+ msgstr ""
571
+
572
+ #: classes/models/class-events.php:795
573
+ msgid "Sorry, you are not allowed to edit this item."
574
+ msgstr ""
575
+
576
+ #. translators: New post title of the duplicated post
577
+ #: classes/models/class-events.php:819
578
+ msgid "%s - Copy"
579
+ msgstr ""
580
+
581
+ #: classes/models/class-import.php:125
582
+ msgid "Assign Authors"
583
+ msgstr ""
584
+
585
+ #: classes/models/class-import.php:126
586
+ msgid "To make it easier for you to edit and save the imported content, you may want to reassign the author of the imported item to an existing user of this site. For example, you may want to import all the entries as <code>admin</code>s entries."
587
+ msgstr ""
588
+
589
+ #: classes/models/class-import.php:128
590
+ msgid "If a new user is created by WordPress, a new password will be randomly generated and the new user&#8217;s role will be set as %s. Manually changing the new user&#8217;s details will be necessary."
591
+ msgstr ""
592
+
593
+ #: classes/models/class-import.php:138
594
+ msgid "Import Attachments"
595
+ msgstr ""
596
+
597
+ #: classes/models/class-import.php:141
598
+ msgid "Download and import file attachments"
599
+ msgstr ""
600
+
601
+ #: classes/models/class-import.php:145
602
+ msgid "Submit"
603
+ msgstr ""
604
+
605
+ #: classes/models/class-import.php:158
606
+ msgid "Import author:"
607
+ msgstr ""
608
+
609
+ #: classes/models/class-import.php:169
610
+ msgid "or create new user with login name:"
611
+ msgstr ""
612
+
613
+ #: classes/models/class-import.php:172
614
+ msgid "as a new user:"
615
+ msgstr ""
616
+
617
+ #: classes/models/class-import.php:180
618
+ msgid "assign posts to an existing user:"
619
+ msgstr ""
620
+
621
+ #: classes/models/class-import.php:182
622
+ msgid "or assign posts to an existing user:"
623
+ msgstr ""
624
+
625
+ #: classes/models/class-import.php:183
626
+ #: templates/column/metabox-column-options.php:23
627
+ msgid "- Select -"
628
+ msgstr ""
629
+
630
+ #: classes/models/class-import.php:269
631
+ msgid "All done."
632
+ msgstr ""
633
+
634
+ #: classes/models/class-import.php:269
635
+ msgid "Have fun!"
636
+ msgstr ""
637
+
638
+ #: classes/models/class-import.php:270
639
+ msgid "Remember to update the passwords and roles of imported users."
640
+ msgstr ""
641
+
642
+ #: classes/models/class-import.php:286
643
+ msgid "Fetching attachments is not enabled"
644
+ msgstr ""
645
+
646
+ #: classes/models/class-import.php:299
647
+ msgid "Invalid file type"
648
+ msgstr ""
649
+
650
+ #: classes/models/class-import.php:379
651
+ msgid "Remote server did not respond"
652
+ msgstr ""
653
+
654
+ #: classes/models/class-import.php:385
655
+ msgid "Remote server returned error response %1$d %2$s"
656
+ msgstr ""
657
+
658
+ #: classes/models/class-import.php:394
659
+ msgid "Remote file is incorrect size"
660
+ msgstr ""
661
+
662
+ #: classes/models/class-import.php:399
663
+ msgid "Zero size file downloaded"
664
+ msgstr ""
665
+
666
+ #: classes/models/class-import.php:405
667
+ msgid "Remote file is too large, limit is %s"
668
+ msgstr ""
669
+
670
+ #: classes/models/class-import.php:422
671
+ #: classes/models/class-import.php:426
672
+ #: classes/models/class-import.php:436
673
+ msgid "Sorry, there has been an error."
674
+ msgstr ""
675
+
676
+ #: classes/models/class-import.php:427
677
+ msgid "The export file could not be found at <code>%s</code>. It is likely that this was caused by a permissions problem."
678
+ msgstr ""
679
+
680
+ #: classes/models/class-import.php:444
681
+ msgid "This WXR file (version %s) may not be supported by this version of the importer. Please consider updating."
682
+ msgstr ""
683
+
684
+ #: classes/models/class-import.php:501
685
+ msgid "Failed to import author %s. Their posts will be attributed to the current user."
686
+ msgstr ""
687
+
688
+ #: classes/models/class-import.php:558
689
+ msgid "Failed to create new user for %s. Their posts will be attributed to the current user."
690
+ msgstr ""
691
+
692
+ #: classes/models/class-import.php:609
693
+ #: classes/models/class-import.php:766
694
+ msgid "Failed to import %s %s"
695
+ msgstr ""
696
+
697
+ #: classes/models/class-import.php:656
698
+ msgid "Failed to import &#8220;%s&#8221;: Invalid post type %s"
699
+ msgstr ""
700
+
701
+ #: classes/models/class-import.php:673
702
+ msgid "%s &#8220;%s&#8221; already exists."
703
+ msgstr ""
704
+
705
+ #: classes/models/class-import.php:732
706
+ msgid "Failed to import %s &#8220;%s&#8221;"
707
+ msgstr ""
708
+
709
+ #: classes/modules/class-post.php:42
710
+ msgid "Column Type"
711
+ msgstr ""
712
+
713
+ #: classes/widgets/class-mp-timetable-widget.php:22
714
+ msgid "Display upcoming events."
715
+ msgstr ""
716
+
717
+ #: classes/widgets/class-mp-timetable-widget.php:24
718
+ msgid "Timetable Events"
719
+ msgstr ""
720
+
721
+ #: templates-functions/actions-mp-event-functions.php:27
722
+ #: templates/theme/event-timeslots.php:7
723
+ msgid "Event Timeslots (%s)"
724
+ msgstr ""
725
+
726
+ #: templates/column/metabox-column-options.php:11
727
+ msgid "Simple Column"
728
+ msgstr ""
729
+
730
+ #: templates/column/metabox-column-options.php:20
731
+ msgid "Day of the week"
732
+ msgstr ""
733
+
734
+ #: templates/column/metabox-column-options.php:24
735
+ msgid "Sunday"
736
+ msgstr ""
737
+
738
+ #: templates/column/metabox-column-options.php:25
739
+ msgid "Monday"
740
+ msgstr ""
741
+
742
+ #: templates/column/metabox-column-options.php:26
743
+ msgid "Tuesday"
744
+ msgstr ""
745
+
746
+ #: templates/column/metabox-column-options.php:27
747
+ msgid "Wednesday"
748
+ msgstr ""
749
+
750
+ #: templates/column/metabox-column-options.php:28
751
+ msgid "Thursday"
752
+ msgstr ""
753
+
754
+ #: templates/column/metabox-column-options.php:29
755
+ msgid "Friday"
756
+ msgstr ""
757
+
758
+ #: templates/column/metabox-column-options.php:30
759
+ msgid "Saturday"
760
+ msgstr ""
761
+
762
+ #: templates/column/metabox-column-options.php:39
763
+ msgid "Date"
764
+ msgstr ""
765
+
766
+ #: templates/events/event-data.php:5
767
+ msgid "Start"
768
+ msgstr ""
769
+
770
+ #: templates/events/event-data.php:6
771
+ msgid "End"
772
+ msgstr ""
773
+
774
+ #. translators: Head means the leader of the event.
775
+ #: templates/events/event-data.php:10
776
+ msgid "Head"
777
+ msgstr ""
778
+
779
+ #: templates/events/event-data.php:12
780
+ msgid "Actions"
781
+ msgstr ""
782
+
783
+ #: templates/events/event-data.php:35
784
+ msgid "Edit event in the form below"
785
+ msgstr ""
786
+
787
+ #: templates/events/event-data.php:36
788
+ msgid "Delete"
789
+ msgstr ""
790
+
791
+ #: templates/events/metabox-event-data.php:10
792
+ msgid "Add New / Edit Timeslot"
793
+ msgstr ""
794
+
795
+ #: templates/events/metabox-event-data.php:13
796
+ msgid "Column:"
797
+ msgstr ""
798
+
799
+ #: templates/events/metabox-event-data.php:21
800
+ msgid "Select column or <a target=\"_blank\" href=\"%s\">Add New</a>."
801
+ msgstr ""
802
+
803
+ #: templates/events/metabox-event-data.php:23
804
+ msgid "No columns found. <a href=\"%s\">Create at least one column first.</a>"
805
+ msgstr ""
806
+
807
+ #: templates/events/metabox-event-data.php:29
808
+ msgid "Start Time:"
809
+ msgstr ""
810
+
811
+ #: templates/events/metabox-event-data.php:32
812
+ #: templates/events/metabox-event-data.php:39
813
+ msgid "hh:mm"
814
+ msgstr ""
815
+
816
+ #: templates/events/metabox-event-data.php:36
817
+ msgid "End Time:"
818
+ msgstr ""
819
+
820
+ #: templates/events/metabox-event-data.php:43
821
+ msgid "Description:"
822
+ msgstr ""
823
+
824
+ #. translators: Head means the leader of the event.
825
+ #: templates/events/metabox-event-data.php:49
826
+ msgid "Event Head:"
827
+ msgstr ""
828
+
829
+ #: templates/events/metabox-event-data.php:58
830
+ msgid "none"
831
+ msgstr ""
832
+
833
+ #. translators: Button to add a new event.
834
+ #: templates/events/metabox-event-data.php:83
835
+ msgid "Add New"
836
+ msgstr ""
837
+
838
+ #: templates/events/metabox-event-options.php:4
839
+ msgid "Event Subtitle:"
840
+ msgstr ""
841
+
842
+ #: templates/events/metabox-event-options.php:8
843
+ msgid "Background Color:"
844
+ msgstr ""
845
+
846
+ #: templates/events/metabox-event-options.php:15
847
+ msgid "Background Hover Color:"
848
+ msgstr ""
849
+
850
+ #: templates/events/metabox-event-options.php:22
851
+ msgid "Text Color:"
852
+ msgstr ""
853
+
854
+ #: templates/events/metabox-event-options.php:29
855
+ msgid "Text Hover Color:"
856
+ msgstr ""
857
+
858
+ #: templates/events/metabox-event-options.php:36
859
+ msgid "Custom Event URL:"
860
+ msgstr ""
861
+
862
+ #: templates/events/metabox-event-options.php:42
863
+ msgid "Disable link to this event:"
864
+ msgstr ""
865
+
866
+ #: templates/popup/index.php:12
867
+ #: templates/popup/index.php:23
868
+ #: templates/popup/index.php:34
869
+ #: templates/widgets/gallery-list.php:48
870
+ #: media/js/blocks/dist/index.min.js:1
871
+ msgid "Hold the Ctrl or Command key to select/deselect multiple options."
872
+ msgstr ""
873
+
874
+ #: templates/popup/index.php:16
875
+ #: media/js/blocks/dist/index.min.js:1
876
+ msgid "Specific events"
877
+ msgstr ""
878
+
879
+ #: templates/popup/index.php:38
880
+ msgid "Fields to display:"
881
+ msgstr ""
882
+
883
+ #. translators: Head means the leader of the event.
884
+ #: templates/popup/index.php:47
885
+ #: media/js/blocks/dist/index.min.js:1
886
+ msgid "Event Head"
887
+ msgstr ""
888
+
889
+ #: templates/popup/index.php:50
890
+ msgid "Check the event parameter(s) to be displayed in the timetable."
891
+ msgstr ""
892
+
893
+ #: templates/popup/index.php:54
894
+ #: media/js/blocks/dist/index.min.js:1
895
+ msgid "Block height in pixels"
896
+ msgstr ""
897
+
898
+ #: templates/popup/index.php:57
899
+ msgid "Set height of the block"
900
+ msgstr ""
901
+
902
+ #: templates/popup/index.php:61
903
+ #: media/js/blocks/dist/index.min.js:1
904
+ msgid "Base font size"
905
+ msgstr ""
906
+
907
+ #: templates/popup/index.php:64
908
+ #: media/js/blocks/dist/index.min.js:1
909
+ msgid "Base font size for the table. Example 12px, 2em, 80%."
910
+ msgstr ""
911
+
912
+ #: templates/popup/index.php:68
913
+ #: media/js/blocks/dist/index.min.js:1
914
+ msgid "Time frame for event"
915
+ msgstr ""
916
+
917
+ #: templates/popup/index.php:78
918
+ #: media/js/blocks/dist/index.min.js:1
919
+ msgid "Filter events style"
920
+ msgstr ""
921
+
922
+ #: templates/popup/index.php:81
923
+ msgid "Dropdown"
924
+ msgstr ""
925
+
926
+ #: templates/popup/index.php:83
927
+ msgid "None"
928
+ msgstr ""
929
+
930
+ #: templates/popup/index.php:98
931
+ #: media/js/blocks/dist/index.min.js:1
932
+ msgid "Filter title to display all events"
933
+ msgstr ""
934
+
935
+ #: templates/popup/index.php:104
936
+ #: media/js/blocks/dist/index.min.js:1
937
+ msgid "Hide 'All Events' option"
938
+ msgstr ""
939
+
940
+ #: templates/popup/index.php:114
941
+ #: media/js/blocks/dist/index.min.js:1
942
+ msgid "Hide column with hours"
943
+ msgstr ""
944
+
945
+ #: templates/popup/index.php:123
946
+ #: media/js/blocks/dist/index.min.js:1
947
+ msgid "Do not display empty rows"
948
+ msgstr ""
949
+
950
+ #: templates/popup/index.php:132
951
+ #: media/js/blocks/dist/index.min.js:1
952
+ msgid "Merge cells with common events"
953
+ msgstr ""
954
+
955
+ #: templates/popup/index.php:141
956
+ #: templates/widgets/gallery-list.php:59
957
+ #: media/js/blocks/dist/index.min.js:1
958
+ msgid "Disable event link"
959
+ msgstr ""
960
+
961
+ #: templates/popup/index.php:150
962
+ #: media/js/blocks/dist/index.min.js:1
963
+ msgid "Horizontal align"
964
+ msgstr ""
965
+
966
+ #: templates/popup/index.php:159
967
+ #: media/js/blocks/dist/index.min.js:1
968
+ msgid "Vertical align"
969
+ msgstr ""
970
+
971
+ #: templates/popup/index.php:161
972
+ msgid "default"
973
+ msgstr ""
974
+
975
+ #: templates/popup/index.php:162
976
+ #: media/js/blocks/dist/index.min.js:1
977
+ msgid "top"
978
+ msgstr ""
979
+
980
+ #: templates/popup/index.php:163
981
+ #: media/js/blocks/dist/index.min.js:1
982
+ msgid "middle"
983
+ msgstr ""
984
+
985
+ #: templates/popup/index.php:164
986
+ #: media/js/blocks/dist/index.min.js:1
987
+ msgid "bottom"
988
+ msgstr ""
989
+
990
+ #: templates/popup/index.php:179
991
+ #: media/js/blocks/dist/index.min.js:1
992
+ msgid "Unique ID"
993
+ msgstr ""
994
+
995
+ #: templates/popup/index.php:182
996
+ #: media/js/blocks/dist/index.min.js:1
997
+ msgid "If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens."
998
+ msgstr ""
999
+
1000
+ #: templates/popup/index.php:186
1001
+ #: media/js/blocks/dist/index.min.js:1
1002
+ msgid "CSS class"
1003
+ msgstr ""
1004
+
1005
+ #: templates/popup/index.php:192
1006
+ #: media/js/blocks/dist/index.min.js:1
1007
+ msgid "Mobile behavior"
1008
+ msgstr ""
1009
+
1010
+ #: templates/popup/index.php:195
1011
+ #: media/js/blocks/dist/index.min.js:1
1012
+ msgid "List"
1013
+ msgstr ""
1014
+
1015
+ #: templates/popup/index.php:196
1016
+ #: media/js/blocks/dist/index.min.js:1
1017
+ msgid "Table"
1018
+ msgstr ""
1019
+
1020
+ #: templates/popup/index.php:198
1021
+ msgid "Tick \"List\" to display events in a list view on mobile devices. Tick \"Table\" to display events in a table."
1022
+ msgstr ""
1023
+
1024
+ #: templates/popup/index.php:204
1025
+ msgid "Add Timetable"
1026
+ msgstr ""
1027
+
1028
+ #: templates/settings/general.php:2
1029
+ msgid "General Settings"
1030
+ msgstr ""
1031
+
1032
+ #: templates/settings/general.php:9
1033
+ msgid "Template Mode"
1034
+ msgstr ""
1035
+
1036
+ #: templates/settings/general.php:13
1037
+ msgid "Theme Mode"
1038
+ msgstr ""
1039
+
1040
+ #: templates/settings/general.php:14
1041
+ msgid "Developer Mode"
1042
+ msgstr ""
1043
+
1044
+ #: templates/settings/general.php:16
1045
+ msgid "Choose Theme Mode to display the content with the styles of your theme. Choose Developer Mode to control appearance of the content with custom page templates, actions and filters."
1046
+ msgstr ""
1047
+
1048
+ #: templates/settings/general.php:16
1049
+ msgid "This option can't be changed if your theme is initially integrated with the plugin."
1050
+ msgstr ""
1051
+
1052
+ #: templates/settings/general.php:23
1053
+ msgid "Permalink Settings"
1054
+ msgstr ""
1055
+
1056
+ #: templates/settings/general.php:24
1057
+ msgid "Configure permalink settings in <a href=\"%s\">Settings > Permalinks</a>"
1058
+ msgstr ""
1059
+
1060
+ #: templates/settings/general.php:29
1061
+ msgid "Save"
1062
+ msgstr ""
1063
+
1064
+ #: templates/shortcodes/empty-search-events.php:1
1065
+ #: templates/theme/widget-upcoming-view.php:54
1066
+ #: templates/widgets/widget-view.php:91
1067
+ msgid "no events found"
1068
+ msgstr ""
1069
+
1070
+ #: templates/templates-actions/action-sidebar.php:8
1071
+ #: templates/widgets/gallery-list.php:14
1072
+ msgid "Today upcoming events"
1073
+ msgstr ""
1074
+
1075
+ #: templates/templates-actions/action-sidebar.php:13
1076
+ #: templates/widgets/gallery-list.php:16
1077
+ msgid "All upcoming events"
1078
+ msgstr ""
1079
+
1080
+ #: templates/widgets/gallery-list.php:10
1081
+ msgid "Events to display"
1082
+ msgstr ""
1083
+
1084
+ #: templates/widgets/gallery-list.php:18
1085
+ msgid "Ongoing events"
1086
+ msgstr ""
1087
+
1088
+ #: templates/widgets/gallery-list.php:23
1089
+ msgid "Input number of days"
1090
+ msgstr ""
1091
+
1092
+ #: templates/widgets/gallery-list.php:28
1093
+ msgid "day"
1094
+ msgid_plural "days"
1095
+ msgstr[0] ""
1096
+ msgstr[1] ""
1097
+
1098
+ #: templates/widgets/gallery-list.php:32
1099
+ msgid "Event categories. Leave blank to display all."
1100
+ msgstr ""
1101
+
1102
+ #: templates/widgets/gallery-list.php:52
1103
+ msgid "Number of events to display"
1104
+ msgstr ""
1105
+
1106
+ #: templates/widgets/gallery-list.php:70
1107
+ msgid "Custom link for events"
1108
+ msgstr ""
1109
+
1110
+ #: templates/widgets/gallery-list.php:78
1111
+ msgid "Event background color"
1112
+ msgstr ""
1113
+
1114
+ #: templates/widgets/gallery-list.php:88
1115
+ msgid "Event background color on hover"
1116
+ msgstr ""
1117
+
1118
+ #: templates/widgets/gallery-list.php:98
1119
+ msgid "Event text color"
1120
+ msgstr ""
1121
+
1122
+ #: templates/widgets/gallery-list.php:108
1123
+ msgid "Event text color on hover"
1124
+ msgstr ""
1125
+
1126
+ #: templates/widgets/gallery-list.php:118
1127
+ msgid "Event border color"
1128
+ msgstr ""
1129
+
1130
+ #: templates/widgets/gallery-list.php:128
1131
+ msgid "Event border color on hover"
1132
+ msgstr ""
languages/po2json.txt DELETED
@@ -1 +0,0 @@
1
- po2json .\languages\mp-timetable-ru_RU.po .\languages\mp-timetable-ru_RU-mptt-blocks-js.json -f jed
 
media/css/admin.css CHANGED
@@ -1 +1 @@
1
- #mp-event_data #add_event_table #event_end,#mp-event_data #add_event_table #event_start{min-width:100px}#mp-event_data .spinner.left{float:none}#mp-event_data .events-list-wrapper{max-height:360px;overflow-y:auto;overflow-x:hidden;margin-bottom:1em}#mp-event_data #events-list .active *{background-color:#F7FCFE}#mp-event_data #events-list .active td:first-child{border-left:4px solid #0091cd}#mp-event_data #events-list .delete-event-button,#mp-event_data #events-list .edit-event-button{margin:0 5px 10px 0;position:relative;width:2em;height:2em}#mp-event_data #events-list .delete-event-button.icon:before,#mp-event_data #events-list .edit-event-button.icon:before{font-family:Dashicons;font-variant:normal;font-weight:400;height:100%;left:0;line-height:1.85;margin:0;position:absolute;text-align:center;text-indent:0;text-transform:none;top:0;width:100%}@media screen and (max-width:1200px){#mp-event_data #events-list .event-description{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}}#column-options .mp-date,#column-options .mp-weekday{margin:10px 0 0}div[id^=jBoxID].jBox-Modal .jBox-container{overflow:hidden}div[id^=jBoxID].jBox-Modal .jBox-content{max-width:980px;max-height:800px;padding:0;overflow:hidden}div[id^=jBoxID].jBox-Modal .jBox-content>form{height:100%;overflow:hidden;position:relative}div[id^=jBoxID].jBox-Modal .jBox-content>form .mptt-shortcode-settings-wrapper{height:calc(100% - 60px);overflow-y:scroll;padding:0 15px 0 10px}div[id^=jBoxID].jBox-Modal .jBox-content>form .mptt-shortcode-submit-wrapper{background:#f4f5f6;border-top:1px solid #ddd;padding:15px;position:relative;text-align:left}#add_event_options_table.form-table tr>:first-child,#add_event_table.form-table tr>:first-child{vertical-align:top;text-align:left;padding:20px 10px 20px 0;width:200px;line-height:1.3;font-weight:600}select.mptt-resize-vertical{resize:vertical;min-height:4em}
1
+ #mp-event_data #add_event_table #event_end,#mp-event_data #add_event_table #event_start{min-width:100px}#mp-event_data .spinner.left{float:none}#mp-event_data .events-list-wrapper{max-height:360px;overflow-y:auto;overflow-x:hidden;margin-bottom:1em}#mp-event_data #events-list .active *{background-color:#F7FCFE}#mp-event_data #events-list .active td:first-child{border-left:4px solid #0091cd}#mp-event_data #events-list .delete-event-button,#mp-event_data #events-list .edit-event-button{margin:0 5px 10px 0;position:relative;width:2em;height:2em}#mp-event_data #events-list .delete-event-button.icon:before,#mp-event_data #events-list .edit-event-button.icon:before{font-family:Dashicons;font-variant:normal;font-weight:400;height:100%;left:0;line-height:1.85;margin:0;position:absolute;text-align:center;text-indent:0;text-transform:none;top:0;width:100%}@media screen and (max-width:1200px){#mp-event_data #events-list .event-description{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}#column-options .mp-date,#column-options .mp-weekday{margin:10px 0 0}div[id^=jBoxID].jBox-Modal .jBox-container{overflow:hidden}div[id^=jBoxID].jBox-Modal .jBox-content{max-width:980px;max-height:800px;padding:0;overflow:hidden}div[id^=jBoxID].jBox-Modal .jBox-content>form{height:100%;overflow:hidden;position:relative}div[id^=jBoxID].jBox-Modal .jBox-content>form .mptt-shortcode-settings-wrapper{height:calc(100% - 60px);overflow-y:scroll;padding:0 15px 0 10px}div[id^=jBoxID].jBox-Modal .jBox-content>form .mptt-shortcode-submit-wrapper{background:#f4f5f6;border-top:1px solid #ddd;padding:15px;position:relative;text-align:left}#add_event_options_table.form-table tr>:first-child,#add_event_table.form-table tr>:first-child{vertical-align:top;text-align:left;padding:20px 10px 20px 0;width:200px;line-height:1.3;font-weight:600}select.mptt-resize-vertical{resize:vertical;min-height:4em}
media/css/spectrum.css CHANGED
@@ -1,507 +1,507 @@
1
- /***
2
- Spectrum Colorpicker v1.8.1
3
- https://github.com/bgrins/spectrum
4
- Author: Brian Grinstead
5
- License: MIT
6
- ***/
7
-
8
- .sp-container {
9
- position:absolute;
10
- top:0;
11
- left:0;
12
- display:inline-block;
13
- *display: inline;
14
- *zoom: 1;
15
- /* https://github.com/bgrins/spectrum/issues/40 */
16
- z-index: 9999994;
17
- overflow: hidden;
18
- }
19
- .sp-container.sp-flat {
20
- position: relative;
21
- }
22
-
23
- /* Fix for * { box-sizing: border-box; } */
24
- .sp-container,
25
- .sp-container * {
26
- -webkit-box-sizing: content-box;
27
- -moz-box-sizing: content-box;
28
- box-sizing: content-box;
29
- }
30
-
31
- /* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
32
- .sp-top {
33
- position:relative;
34
- width: 100%;
35
- display:inline-block;
36
- }
37
- .sp-top-inner {
38
- position:absolute;
39
- top:0;
40
- left:0;
41
- bottom:0;
42
- right:0;
43
- }
44
- .sp-color {
45
- position: absolute;
46
- top:0;
47
- left:0;
48
- bottom:0;
49
- right:20%;
50
- }
51
- .sp-hue {
52
- position: absolute;
53
- top:0;
54
- right:0;
55
- bottom:0;
56
- left:84%;
57
- height: 100%;
58
- }
59
-
60
- .sp-clear-enabled .sp-hue {
61
- top:33px;
62
- height: 77.5%;
63
- }
64
-
65
- .sp-fill {
66
- padding-top: 80%;
67
- }
68
- .sp-sat, .sp-val {
69
- position: absolute;
70
- top:0;
71
- left:0;
72
- right:0;
73
- bottom:0;
74
- }
75
-
76
- .sp-alpha-enabled .sp-top {
77
- margin-bottom: 18px;
78
- }
79
- .sp-alpha-enabled .sp-alpha {
80
- display: block;
81
- }
82
- .sp-alpha-handle {
83
- position:absolute;
84
- top:-4px;
85
- bottom: -4px;
86
- width: 6px;
87
- left: 50%;
88
- cursor: pointer;
89
- border: 1px solid black;
90
- background: white;
91
- opacity: .8;
92
- }
93
- .sp-alpha {
94
- display: none;
95
- position: absolute;
96
- bottom: -14px;
97
- right: 0;
98
- left: 0;
99
- height: 8px;
100
- }
101
- .sp-alpha-inner {
102
- border: solid 1px #333;
103
- }
104
-
105
- .sp-clear {
106
- display: none;
107
- }
108
-
109
- .sp-clear.sp-clear-display {
110
- background-position: center;
111
- }
112
-
113
- .sp-clear-enabled .sp-clear {
114
- display: block;
115
- position:absolute;
116
- top:0px;
117
- right:0;
118
- bottom:0;
119
- left:84%;
120
- height: 28px;
121
- }
122
-
123
- /* Don't allow text selection */
124
- .sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
125
- -webkit-user-select:none;
126
- -moz-user-select: -moz-none;
127
- -o-user-select:none;
128
- user-select: none;
129
- }
130
-
131
- .sp-container.sp-input-disabled .sp-input-container {
132
- display: none;
133
- }
134
- .sp-container.sp-buttons-disabled .sp-button-container {
135
- display: none;
136
- }
137
- .sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
138
- display: none;
139
- }
140
- .sp-palette-only .sp-picker-container {
141
- display: none;
142
- }
143
- .sp-palette-disabled .sp-palette-container {
144
- display: none;
145
- }
146
-
147
- .sp-initial-disabled .sp-initial {
148
- display: none;
149
- }
150
-
151
-
152
- /* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
153
- .sp-sat {
154
- background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
155
- background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
156
- background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
157
- background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
158
- background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
159
- background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
160
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
161
- filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
162
- }
163
- .sp-val {
164
- background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
165
- background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
166
- background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
167
- background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
168
- background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
169
- background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
170
- -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
171
- filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
172
- }
173
-
174
- .sp-hue {
175
- background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
176
- background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
177
- background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
178
- background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
179
- background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
180
- background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
181
- }
182
-
183
- /* IE filters do not support multiple color stops.
184
- Generate 6 divs, line them up, and do two color gradients for each.
185
- Yes, really.
186
- */
187
- .sp-1 {
188
- height:17%;
189
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
190
- }
191
- .sp-2 {
192
- height:16%;
193
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
194
- }
195
- .sp-3 {
196
- height:17%;
197
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
198
- }
199
- .sp-4 {
200
- height:17%;
201
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
202
- }
203
- .sp-5 {
204
- height:16%;
205
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
206
- }
207
- .sp-6 {
208
- height:17%;
209
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
210
- }
211
-
212
- .sp-hidden {
213
- display: none !important;
214
- }
215
-
216
- /* Clearfix hack */
217
- .sp-cf:before, .sp-cf:after { content: ""; display: table; }
218
- .sp-cf:after { clear: both; }
219
- .sp-cf { *zoom: 1; }
220
-
221
- /* Mobile devices, make hue slider bigger so it is easier to slide */
222
- @media (max-device-width: 480px) {
223
- .sp-color { right: 40%; }
224
- .sp-hue { left: 63%; }
225
- .sp-fill { padding-top: 60%; }
226
- }
227
- .sp-dragger {
228
- border-radius: 5px;
229
- height: 5px;
230
- width: 5px;
231
- border: 1px solid #fff;
232
- background: #000;
233
- cursor: pointer;
234
- position:absolute;
235
- top:0;
236
- left: 0;
237
- }
238
- .sp-slider {
239
- position: absolute;
240
- top:0;
241
- cursor:pointer;
242
- height: 3px;
243
- left: -1px;
244
- right: -1px;
245
- border: 1px solid #000;
246
- background: white;
247
- opacity: .8;
248
- }
249
-
250
- /*
251
- Theme authors:
252
- Here are the basic themeable display options (colors, fonts, global widths).
253
- See http://bgrins.github.io/spectrum/themes/ for instructions.
254
- */
255
-
256
- .sp-container {
257
- border-radius: 0;
258
- background-color: #ECECEC;
259
- border: solid 1px #f0c49B;
260
- padding: 0;
261
- }
262
- .sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
263
- font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
264
- -webkit-box-sizing: border-box;
265
- -moz-box-sizing: border-box;
266
- -ms-box-sizing: border-box;
267
- box-sizing: border-box;
268
- }
269
- .sp-top {
270
- margin-bottom: 3px;
271
- }
272
- .sp-color, .sp-hue, .sp-clear {
273
- border: solid 1px #666;
274
- }
275
-
276
- /* Input */
277
- .sp-input-container {
278
- float:right;
279
- width: 100px;
280
- margin-bottom: 4px;
281
- }
282
- .sp-initial-disabled .sp-input-container {
283
- width: 100%;
284
- }
285
- .sp-input {
286
- font-size: 12px !important;
287
- border: 1px inset;
288
- padding: 4px 5px;
289
- margin: 0;
290
- width: 100%;
291
- background:transparent;
292
- border-radius: 3px;
293
- color: #222;
294
- }
295
- .sp-input:focus {
296
- border: 1px solid orange;
297
- }
298
- .sp-input.sp-validation-error {
299
- border: 1px solid red;
300
- background: #fdd;
301
- }
302
- .sp-picker-container , .sp-palette-container {
303
- float:left;
304
- position: relative;
305
- padding: 10px;
306
- padding-bottom: 300px;
307
- margin-bottom: -290px;
308
- }
309
- .sp-picker-container {
310
- width: 172px;
311
- border-left: solid 1px #fff;
312
- }
313
-
314
- /* Palettes */
315
- .sp-palette-container {
316
- border-right: solid 1px #ccc;
317
- }
318
-
319
- .sp-palette-only .sp-palette-container {
320
- border: 0;
321
- }
322
-
323
- .sp-palette .sp-thumb-el {
324
- display: block;
325
- position:relative;
326
- float:left;
327
- width: 24px;
328
- height: 15px;
329
- margin: 3px;
330
- cursor: pointer;
331
- border:solid 2px transparent;
332
- }
333
- .sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
334
- border-color: orange;
335
- }
336
- .sp-thumb-el {
337
- position:relative;
338
- }
339
-
340
- /* Initial */
341
- .sp-initial {
342
- float: left;
343
- border: solid 1px #333;
344
- }
345
- .sp-initial span {
346
- width: 30px;
347
- height: 25px;
348
- border:none;
349
- display:block;
350
- float:left;
351
- margin:0;
352
- }
353
-
354
- .sp-initial .sp-clear-display {
355
- background-position: center;
356
- }
357
-
358
- /* Buttons */
359
- .sp-palette-button-container,
360
- .sp-button-container {
361
- float: right;
362
- }
363
-
364
- /* Replacer (the little preview div that shows up instead of the <input>) */
365
- .sp-replacer {
366
- margin:0;
367
- overflow:hidden;
368
- cursor:pointer;
369
- padding: 4px;
370
- display:inline-block;
371
- *zoom: 1;
372
- *display: inline;
373
- border: solid 1px #91765d;
374
- background: #eee;
375
- color: #333;
376
- vertical-align: middle;
377
- }
378
- .sp-replacer:hover, .sp-replacer.sp-active {
379
- border-color: #F0C49B;
380
- color: #111;
381
- }
382
- .sp-replacer.sp-disabled {
383
- cursor:default;
384
- border-color: silver;
385
- color: silver;
386
- }
387
- .sp-dd {
388
- padding: 2px 0;
389
- height: 16px;
390
- line-height: 16px;
391
- float:left;
392
- font-size:10px;
393
- }
394
- .sp-preview {
395
- position:relative;
396
- width:25px;
397
- height: 20px;
398
- border: solid 1px #222;
399
- margin-right: 5px;
400
- float:left;
401
- z-index: 0;
402
- }
403
-
404
- .sp-palette {
405
- *width: 220px;
406
- max-width: 220px;
407
- }
408
- .sp-palette .sp-thumb-el {
409
- width:16px;
410
- height: 16px;
411
- margin:2px 1px;
412
- border: solid 1px #d0d0d0;
413
- }
414
-
415
- .sp-container {
416
- padding-bottom:0;
417
- }
418
-
419
-
420
- /* Buttons: http://hellohappy.org/css3-buttons/ */
421
- .sp-container button {
422
- background-color: #eeeeee;
423
- background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
424
- background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
425
- background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
426
- background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
427
- background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
428
- border: 1px solid #ccc;
429
- border-bottom: 1px solid #bbb;
430
- border-radius: 3px;
431
- color: #333;
432
- font-size: 14px;
433
- line-height: 1;
434
- padding: 5px 4px;
435
- text-align: center;
436
- text-shadow: 0 1px 0 #eee;
437
- vertical-align: middle;
438
- }
439
- .sp-container button:hover {
440
- background-color: #dddddd;
441
- background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
442
- background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
443
- background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
444
- background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
445
- background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
446
- border: 1px solid #bbb;
447
- border-bottom: 1px solid #999;
448
- cursor: pointer;
449
- text-shadow: 0 1px 0 #ddd;
450
- }
451
- .sp-container button:active {
452
- border: 1px solid #aaa;
453
- border-bottom: 1px solid #888;
454
- -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
455
- -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
456
- -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
457
- -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
458
- box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
459
- }
460
- .sp-cancel {
461
- font-size: 11px;
462
- color: #d93f3f !important;
463
- margin:0;
464
- padding:2px;
465
- margin-right: 5px;
466
- vertical-align: middle;
467
- text-decoration:none;
468
-
469
- }
470
- .sp-cancel:hover {
471
- color: #d93f3f !important;
472
- text-decoration: underline;
473
- }
474
-
475
-
476
- .sp-palette span:hover, .sp-palette span.sp-thumb-active {
477
- border-color: #000;
478
- }
479
-
480
- .sp-preview, .sp-alpha, .sp-thumb-el {
481
- position:relative;
482
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
483
- }
484
- .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
485
- display:block;
486
- position:absolute;
487
- top:0;left:0;bottom:0;right:0;
488
- }
489
-
490
- .sp-palette .sp-thumb-inner {
491
- background-position: 50% 50%;
492
- background-repeat: no-repeat;
493
- }
494
-
495
- .sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
496
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
497
- }
498
-
499
- .sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
500
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
501
- }
502
-
503
- .sp-clear-display {
504
- background-repeat:no-repeat;
505
- background-position: center;
506
- background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
507
- }
1
+ /***
2
+ Spectrum Colorpicker v1.8.1
3
+ https://github.com/bgrins/spectrum
4
+ Author: Brian Grinstead
5
+ License: MIT
6
+ ***/
7
+
8
+ .sp-container {
9
+ position:absolute;
10
+ top:0;
11
+ left:0;
12
+ display:inline-block;
13
+ *display: inline;
14
+ *zoom: 1;
15
+ /* https://github.com/bgrins/spectrum/issues/40 */
16
+ z-index: 9999994;
17
+ overflow: hidden;
18
+ }
19
+ .sp-container.sp-flat {
20
+ position: relative;
21
+ }
22
+
23
+ /* Fix for * { box-sizing: border-box; } */
24
+ .sp-container,
25
+ .sp-container * {
26
+ -webkit-box-sizing: content-box;
27
+ -moz-box-sizing: content-box;
28
+ box-sizing: content-box;
29
+ }
30
+
31
+ /* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */
32
+ .sp-top {
33
+ position:relative;
34
+ width: 100%;
35
+ display:inline-block;
36
+ }
37
+ .sp-top-inner {
38
+ position:absolute;
39
+ top:0;
40
+ left:0;
41
+ bottom:0;
42
+ right:0;
43
+ }
44
+ .sp-color {
45
+ position: absolute;
46
+ top:0;
47
+ left:0;
48
+ bottom:0;
49
+ right:20%;
50
+ }
51
+ .sp-hue {
52
+ position: absolute;
53
+ top:0;
54
+ right:0;
55
+ bottom:0;
56
+ left:84%;
57
+ height: 100%;
58
+ }
59
+
60
+ .sp-clear-enabled .sp-hue {
61
+ top:33px;
62
+ height: 77.5%;
63
+ }
64
+
65
+ .sp-fill {
66
+ padding-top: 80%;
67
+ }
68
+ .sp-sat, .sp-val {
69
+ position: absolute;
70
+ top:0;
71
+ left:0;
72
+ right:0;
73
+ bottom:0;
74
+ }
75
+
76
+ .sp-alpha-enabled .sp-top {
77
+ margin-bottom: 18px;
78
+ }
79
+ .sp-alpha-enabled .sp-alpha {
80
+ display: block;
81
+ }
82
+ .sp-alpha-handle {
83
+ position:absolute;
84
+ top:-4px;
85
+ bottom: -4px;
86
+ width: 6px;
87
+ left: 50%;
88
+ cursor: pointer;
89
+ border: 1px solid black;
90
+ background: white;
91
+ opacity: .8;
92
+ }
93
+ .sp-alpha {
94
+ display: none;
95
+ position: absolute;
96
+ bottom: -14px;
97
+ right: 0;
98
+ left: 0;
99
+ height: 8px;
100
+ }
101
+ .sp-alpha-inner {
102
+ border: solid 1px #333;
103
+ }
104
+
105
+ .sp-clear {
106
+ display: none;
107
+ }
108
+
109
+ .sp-clear.sp-clear-display {
110
+ background-position: center;
111
+ }
112
+
113
+ .sp-clear-enabled .sp-clear {
114
+ display: block;
115
+ position:absolute;
116
+ top:0px;
117
+ right:0;
118
+ bottom:0;
119
+ left:84%;
120
+ height: 28px;
121
+ }
122
+
123
+ /* Don't allow text selection */
124
+ .sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button {
125
+ -webkit-user-select:none;
126
+ -moz-user-select: -moz-none;
127
+ -o-user-select:none;
128
+ user-select: none;
129
+ }
130
+
131
+ .sp-container.sp-input-disabled .sp-input-container {
132
+ display: none;
133
+ }
134
+ .sp-container.sp-buttons-disabled .sp-button-container {
135
+ display: none;
136
+ }
137
+ .sp-container.sp-palette-buttons-disabled .sp-palette-button-container {
138
+ display: none;
139
+ }
140
+ .sp-palette-only .sp-picker-container {
141
+ display: none;
142
+ }
143
+ .sp-palette-disabled .sp-palette-container {
144
+ display: none;
145
+ }
146
+
147
+ .sp-initial-disabled .sp-initial {
148
+ display: none;
149
+ }
150
+
151
+
152
+ /* Gradients for hue, saturation and value instead of images. Not pretty... but it works */
153
+ .sp-sat {
154
+ background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0)));
155
+ background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0));
156
+ background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
157
+ background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
158
+ background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0));
159
+ background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0));
160
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)";
161
+ filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81');
162
+ }
163
+ .sp-val {
164
+ background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0)));
165
+ background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0));
166
+ background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
167
+ background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
168
+ background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0));
169
+ background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0));
170
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)";
171
+ filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000');
172
+ }
173
+
174
+ .sp-hue {
175
+ background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
176
+ background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
177
+ background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
178
+ background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000));
179
+ background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
180
+ background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
181
+ }
182
+
183
+ /* IE filters do not support multiple color stops.
184
+ Generate 6 divs, line them up, and do two color gradients for each.
185
+ Yes, really.
186
+ */
187
+ .sp-1 {
188
+ height:17%;
189
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00');
190
+ }
191
+ .sp-2 {
192
+ height:16%;
193
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00');
194
+ }
195
+ .sp-3 {
196
+ height:17%;
197
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff');
198
+ }
199
+ .sp-4 {
200
+ height:17%;
201
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff');
202
+ }
203
+ .sp-5 {
204
+ height:16%;
205
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff');
206
+ }
207
+ .sp-6 {
208
+ height:17%;
209
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000');
210
+ }
211
+
212
+ .sp-hidden {
213
+ display: none !important;
214
+ }
215
+
216
+ /* Clearfix hack */
217
+ .sp-cf:before, .sp-cf:after { content: ""; display: table; }
218
+ .sp-cf:after { clear: both; }
219
+ .sp-cf { *zoom: 1; }
220
+
221
+ /* Mobile devices, make hue slider bigger so it is easier to slide */
222
+ @media (max-device-width: 480px) {
223
+ .sp-color { right: 40%; }
224
+ .sp-hue { left: 63%; }
225
+ .sp-fill { padding-top: 60%; }
226
+ }
227
+ .sp-dragger {
228
+ border-radius: 5px;
229
+ height: 5px;
230
+ width: 5px;
231
+ border: 1px solid #fff;
232
+ background: #000;
233
+ cursor: pointer;
234
+ position:absolute;
235
+ top:0;
236
+ left: 0;
237
+ }
238
+ .sp-slider {
239
+ position: absolute;
240
+ top:0;
241
+ cursor:pointer;
242
+ height: 3px;
243
+ left: -1px;
244
+ right: -1px;
245
+ border: 1px solid #000;
246
+ background: white;
247
+ opacity: .8;
248
+ }
249
+
250
+ /*
251
+ Theme authors:
252
+ Here are the basic themeable display options (colors, fonts, global widths).
253
+ See http://bgrins.github.io/spectrum/themes/ for instructions.
254
+ */
255
+
256
+ .sp-container {
257
+ border-radius: 0;
258
+ background-color: #ECECEC;
259
+ border: solid 1px #f0c49B;
260
+ padding: 0;
261
+ }
262
+ .sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear {
263
+ font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif;
264
+ -webkit-box-sizing: border-box;
265
+ -moz-box-sizing: border-box;
266
+ -ms-box-sizing: border-box;
267
+ box-sizing: border-box;
268
+ }
269
+ .sp-top {
270
+ margin-bottom: 3px;
271
+ }
272
+ .sp-color, .sp-hue, .sp-clear {
273
+ border: solid 1px #666;
274
+ }
275
+
276
+ /* Input */
277
+ .sp-input-container {
278
+ float:right;
279
+ width: 100px;
280
+ margin-bottom: 4px;
281
+ }
282
+ .sp-initial-disabled .sp-input-container {
283
+ width: 100%;
284
+ }
285
+ .sp-input {
286
+ font-size: 12px !important;
287
+ border: 1px inset;
288
+ padding: 4px 5px;
289
+ margin: 0;
290
+ width: 100%;
291
+ background:transparent;
292
+ border-radius: 3px;
293
+ color: #222;
294
+ }
295
+ .sp-input:focus {
296
+ border: 1px solid orange;
297
+ }
298
+ .sp-input.sp-validation-error {
299
+ border: 1px solid red;
300
+ background: #fdd;
301
+ }
302
+ .sp-picker-container , .sp-palette-container {
303
+ float:left;
304
+ position: relative;
305
+ padding: 10px;
306
+ padding-bottom: 300px;
307
+ margin-bottom: -290px;
308
+ }
309
+ .sp-picker-container {
310
+ width: 172px;
311
+ border-left: solid 1px #fff;
312
+ }
313
+
314
+ /* Palettes */
315
+ .sp-palette-container {
316
+ border-right: solid 1px #ccc;
317
+ }
318
+
319
+ .sp-palette-only .sp-palette-container {
320
+ border: 0;
321
+ }
322
+
323
+ .sp-palette .sp-thumb-el {
324
+ display: block;
325
+ position:relative;
326
+ float:left;
327
+ width: 24px;
328
+ height: 15px;
329
+ margin: 3px;
330
+ cursor: pointer;
331
+ border:solid 2px transparent;
332
+ }
333
+ .sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active {
334
+ border-color: orange;
335
+ }
336
+ .sp-thumb-el {
337
+ position:relative;
338
+ }
339
+
340
+ /* Initial */
341
+ .sp-initial {
342
+ float: left;
343
+ border: solid 1px #333;
344
+ }
345
+ .sp-initial span {
346
+ width: 30px;
347
+ height: 25px;
348
+ border:none;
349
+ display:block;
350
+ float:left;
351
+ margin:0;
352
+ }
353
+
354
+ .sp-initial .sp-clear-display {
355
+ background-position: center;
356
+ }
357
+
358
+ /* Buttons */
359
+ .sp-palette-button-container,
360
+ .sp-button-container {
361
+ float: right;
362
+ }
363
+
364
+ /* Replacer (the little preview div that shows up instead of the <input>) */
365
+ .sp-replacer {
366
+ margin:0;
367
+ overflow:hidden;
368
+ cursor:pointer;
369
+ padding: 4px;
370
+ display:inline-block;
371
+ *zoom: 1;
372
+ *display: inline;
373
+ border: solid 1px #91765d;
374
+ background: #eee;
375
+ color: #333;
376
+ vertical-align: middle;
377
+ }
378
+ .sp-replacer:hover, .sp-replacer.sp-active {
379
+ border-color: #F0C49B;
380
+ color: #111;
381
+ }
382
+ .sp-replacer.sp-disabled {
383
+ cursor:default;
384
+ border-color: silver;
385
+ color: silver;
386
+ }
387
+ .sp-dd {
388
+ padding: 2px 0;
389
+ height: 16px;
390
+ line-height: 16px;
391
+ float:left;
392
+ font-size:10px;
393
+ }
394
+ .sp-preview {
395
+ position:relative;
396
+ width:25px;
397
+ height: 20px;
398
+ border: solid 1px #222;
399
+ margin-right: 5px;
400
+ float:left;
401
+ z-index: 0;
402
+ }
403
+
404
+ .sp-palette {
405
+ *width: 220px;
406
+ max-width: 220px;
407
+ }
408
+ .sp-palette .sp-thumb-el {
409
+ width:16px;
410
+ height: 16px;
411
+ margin:2px 1px;
412
+ border: solid 1px #d0d0d0;
413
+ }
414
+
415
+ .sp-container {
416
+ padding-bottom:0;
417
+ }
418
+
419
+
420
+ /* Buttons: http://hellohappy.org/css3-buttons/ */
421
+ .sp-container button {
422
+ background-color: #eeeeee;
423
+ background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc);
424
+ background-image: -moz-linear-gradient(top, #eeeeee, #cccccc);
425
+ background-image: -ms-linear-gradient(top, #eeeeee, #cccccc);
426
+ background-image: -o-linear-gradient(top, #eeeeee, #cccccc);
427
+ background-image: linear-gradient(to bottom, #eeeeee, #cccccc);
428
+ border: 1px solid #ccc;
429
+ border-bottom: 1px solid #bbb;
430
+ border-radius: 3px;
431
+ color: #333;
432
+ font-size: 14px;
433
+ line-height: 1;
434
+ padding: 5px 4px;
435
+ text-align: center;
436
+ text-shadow: 0 1px 0 #eee;
437
+ vertical-align: middle;
438
+ }
439
+ .sp-container button:hover {
440
+ background-color: #dddddd;
441
+ background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb);
442
+ background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb);
443
+ background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb);
444
+ background-image: -o-linear-gradient(top, #dddddd, #bbbbbb);
445
+ background-image: linear-gradient(to bottom, #dddddd, #bbbbbb);
446
+ border: 1px solid #bbb;
447
+ border-bottom: 1px solid #999;
448
+ cursor: pointer;
449
+ text-shadow: 0 1px 0 #ddd;
450
+ }
451
+ .sp-container button:active {
452
+ border: 1px solid #aaa;
453
+ border-bottom: 1px solid #888;
454
+ -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
455
+ -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
456
+ -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
457
+ -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
458
+ box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee;
459
+ }
460
+ .sp-cancel {
461
+ font-size: 11px;
462
+ color: #d93f3f !important;
463
+ margin:0;
464
+ padding:2px;
465
+ margin-right: 5px;
466
+ vertical-align: middle;
467
+ text-decoration:none;
468
+
469
+ }
470
+ .sp-cancel:hover {
471
+ color: #d93f3f !important;
472
+ text-decoration: underline;
473
+ }
474
+
475
+
476
+ .sp-palette span:hover, .sp-palette span.sp-thumb-active {
477
+ border-color: #000;
478
+ }
479
+
480
+ .sp-preview, .sp-alpha, .sp-thumb-el {
481
+ position:relative;
482
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==);
483
+ }
484
+ .sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner {
485
+ display:block;
486
+ position:absolute;
487
+ top:0;left:0;bottom:0;right:0;
488
+ }
489
+
490
+ .sp-palette .sp-thumb-inner {
491
+ background-position: 50% 50%;
492
+ background-repeat: no-repeat;
493
+ }
494
+
495
+ .sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner {
496
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=);
497
+ }
498
+
499
+ .sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner {
500
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=);
501
+ }
502
+
503
+ .sp-clear-display {
504
+ background-repeat:no-repeat;
505
+ background-position: center;
506
+ background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==);
507
+ }
media/js/blocks/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function n(l){if(t[l])return t[l].exports;var a=t[l]={i:l,l:!1,exports:{}};return e[l].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,l){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:l})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var l=Object.create(null);if(n.r(l),Object.defineProperty(l,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(l,a,function(t){return e[t]}.bind(null,a));return l},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t){e.exports=lodash},,,function(e,t,n){"use strict";n.r(t);var l=n(0);function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n<t.length;n++){var l=t[n];l.enumerable=l.enumerable||!1,l.configurable=!0,"value"in l&&(l.writable=!0),Object.defineProperty(e,l.key,l)}}function i(e,t){return!t||"object"!==a(t)&&"function"!=typeof t?u(e):t}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function c(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function p(e){return(p=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function m(e,t){return(m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var s=wp.i18n.__,b=wp.element.Component,f=wp.editor.InspectorControls,v=wp.components,h=v.SelectControl,d=v.CheckboxControl,y=v.PanelBody,g=v.TextControl,_=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&m(e,t)}(_,e);var t,n,a,b,v=(t=_,function(){var e,n=p(t);if(c()){var l=p(this).constructor;e=Reflect.construct(n,arguments,l)}else e=n.apply(this,arguments);return i(this,e)});function _(){var e;return o(this,_),(e=v.apply(this,arguments)).setOptions=e.setOptions.bind(u(e)),e}return n=_,(a=[{key:"setOptions",value:function(e){var t=[];return e&&(t=e.map((function(e){return{value:e.id.toString(),label:Object(l.get)(e,["title","raw"])||Object(l.get)(e,["name"])}}))),t}},{key:"render",value:function(){var e=this.props,t=e.attributes,n=t.col,l=t.events,a=t.event_categ,o=t.increment,r=t.view,i=t.view_sort,u=t.label,c=t.hide_label,p=t.hide_hrs,m=t.hide_empty_rows,b=t.title,v=t.time,_=t.sub_title,w=t.description,C=t.user,E=t.group,R=t.disable_event_url,O=t.text_align,S=t.text_align_vertical,j=t.id,k=t.custom_class,x=t.row_height,T=t.font_size,P=t.responsive,D=t.table_layout,I=e.selectedEvents,N=e.selectedColumns,H=e.selectedEventCategories,z=e.setAttributes;return React.createElement(f,null,React.createElement(y,{title:s("Settings","mp-timetable")},React.createElement(h,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:s("Columns","mp-timetable"),help:s("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:n,onChange:function(e){return z({col:e})},options:this.setOptions(N)}),React.createElement(h,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:s("Specific events","mp-timetable"),help:s("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:l,onChange:function(e){return z({events:e})},options:this.setOptions(I)}),React.createElement(h,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:s("Event categories","mp-timetable"),help:s("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:a,onChange:function(e){return z({event_categ:e})},options:this.setOptions(H)}),React.createElement(d,{label:s("Title","mp-timetable"),checked:"1"==b,onChange:function(e){z({title:e?"1":"0"})}}),React.createElement(d,{label:s("Time","mp-timetable"),checked:"1"==v,onChange:function(e){z({time:e?"1":"0"})}}),React.createElement(d,{label:s("Subtitle","mp-timetable"),checked:"1"==_,onChange:function(e){z({sub_title:e?"1":"0"})}}),React.createElement(d,{label:s("Description","mp-timetable"),checked:"1"==w,onChange:function(e){z({description:e?"1":"0"})}}),React.createElement(d,{label:s("Event Head","mp-timetable"),checked:"1"==C,onChange:function(e){z({user:e?"1":"0"})}}),React.createElement(g,{label:s("Block height in pixels","mp-timetable"),type:"number",value:isNaN(x)?0:parseInt(x),onChange:function(e){z({row_height:e.toString()})},min:1,step:1}),React.createElement(g,{label:s("Base font size","mp-timetable"),help:s("Base font size for the table. Example 12px, 2em, 80%.","mp-timetable"),value:T,onChange:function(e){return z({font_size:e})}}),React.createElement(h,{label:s("Time frame for event","mp-timetable"),value:o,onChange:function(e){return z({increment:e})},options:[{value:"1",label:s("Hour (1h)","mp-timetable")},{value:"0.5",label:s("Half hour (30min)","mp-timetable")},{value:"0.25",label:s("Quarter hour (15min)","mp-timetable")}]}),React.createElement(h,{label:s("Filter events style","mp-timetable"),value:r,onChange:function(e){return z({view:e})},options:[{value:"dropdown_list",label:s("Dropdown list","mp-timetable")},{value:"tabs",label:s("Tabs","mp-timetable")}]}),React.createElement(h,{label:s("Order of items in filter","mp-timetable"),value:i,onChange:function(e){return z({view_sort:e})},options:[{value:"",label:s("Default","mp-timetable")},{value:"menu_order",label:s("Menu Order","mp-timetable")},{value:"post_title",label:s("Title","mp-timetable")}]}),React.createElement(g,{label:s("Filter title to display all events","mp-timetable"),value:u,onChange:function(e){return z({label:e})}}),React.createElement(h,{label:s("Hide 'All Events' option","mp-timetable"),value:c,onChange:function(e){return z({hide_label:e})},options:[{value:"0",label:s("No","mp-timetable")},{value:"1",label:s("Yes","mp-timetable")}]}),React.createElement(h,{label:s("Hide column with hours","mp-timetable"),value:p,onChange:function(e){return z({hide_hrs:e})},options:[{value:"0",label:s("No","mp-timetable")},{value:"1",label:s("Yes","mp-timetable")}]}),React.createElement(h,{label:s("Do not display empty rows","mp-timetable"),value:m,onChange:function(e){return z({hide_empty_rows:e})},options:[{value:"0",label:s("No","mp-timetable")},{value:"1",label:s("Yes","mp-timetable")}]}),React.createElement(h,{label:s("Merge cells with common events","mp-timetable"),value:E,onChange:function(e){return z({group:e})},options:[{value:"0",label:s("No","mp-timetable")},{value:"1",label:s("Yes","mp-timetable")}]}),React.createElement(h,{label:s("Disable event link","mp-timetable"),value:R,onChange:function(e){return z({disable_event_url:e})},options:[{value:"0",label:s("No","mp-timetable")},{value:"1",label:s("Yes","mp-timetable")}]}),React.createElement(h,{label:s("Horizontal align","mp-timetable"),value:O,onChange:function(e){return z({text_align:e})},options:[{value:"center",label:s("center","mp-timetable")},{value:"left",label:s("left","mp-timetable")},{value:"right",label:s("right","mp-timetable")}]}),React.createElement(h,{label:s("Vertical align","mp-timetable"),value:S,onChange:function(e){return z({text_align_vertical:e})},options:[{value:"default",label:s("Default","mp-timetable")},{value:"top",label:s("top","mp-timetable")},{value:"middle",label:s("middle","mp-timetable")},{value:"bottom",label:s("bottom","mp-timetable")}]}),React.createElement(h,{label:s("Table layout","mp-timetable"),value:D,onChange:function(e){return z({table_layout:e})},options:[{value:"",label:s("Default","mp-timetable")},{value:"auto",label:s("Auto","mp-timetable")},{value:"fixed",label:s("Fixed","mp-timetable")}]}),React.createElement(g,{label:s("Unique ID","mp-timetable"),help:s("If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.","mp-timetable"),value:j,onChange:function(e){return z({id:e})}}),React.createElement(g,{label:s("CSS class","mp-timetable"),value:k,onChange:function(e){return z({custom_class:e})}}),React.createElement(h,{label:s("Mobile behavior","mp-timetable"),value:P,onChange:function(e){return z({responsive:e})},options:[{value:"0",label:s("Table","mp-timetable")},{value:"1",label:s("List","mp-timetable")}]})))}}])&&r(n.prototype,a),b&&r(n,b),_}(b);function w(e){return(w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function C(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function E(e,t){for(var n=0;n<t.length;n++){var l=t[n];l.enumerable=l.enumerable||!1,l.configurable=!0,"value"in l&&(l.writable=!0),Object.defineProperty(e,l.key,l)}}function R(e,t){return!t||"object"!==w(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function O(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function S(e){return(S=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function j(e,t){return(j=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}wp.i18n.__;var k=wp.element,x=k.Component,T=k.Fragment,P=wp.compose.compose,D=wp.components,I=D.Disabled,N=D.ServerSideRender,H=wp.data.withSelect,z=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&j(e,t)}(i,e);var t,n,a,o,r=(t=i,function(){var e,n=S(t);if(O()){var l=S(this).constructor;e=Reflect.construct(n,arguments,l)}else e=n.apply(this,arguments);return R(this,e)});function i(){return C(this,i),r.apply(this,arguments)}return n=i,(a=[{key:"initTable",value:function(){var e=this.props.clientId,t=jQuery("#block-".concat(e)),n=setInterval((function(){t.find(".mptt-shortcode-wrapper").length&&!t.find(".mptt-shortcode-wrapper").hasClass("table-init")&&(clearInterval(n),window.mptt.tableInit())}),1)}},{key:"componentDidUpdate",value:function(e,t){Object(l.isEqual)(this.props.attributes,e.attributes)||this.initTable()}},{key:"componentDidMount",value:function(){this.initTable()}},{key:"render",value:function(){var e=this.props.attributes;return e.events,e.event_categ,React.createElement(T,null,React.createElement(_,this.props),React.createElement(I,null,React.createElement(N,{block:"mp-timetable/timetable",attributes:this.props.attributes})))}}])&&E(n.prototype,a),o&&E(n,o),i}(x),M=P([H((function(e,t){var n=e("core"),a=n.getEntityRecords,o=(n.getCategories,a("postType","mp-event",{per_page:-1,orderby:"title",order:"asc"})),r=a("postType","mp-column",{per_page:-1}),i=a("taxonomy","mp-event_category",{per_page:-1});return{selectedEvents:o?o.map((function(e){return Object(l.pick)(e,["id","title"])})):null,selectedColumns:r?r.map((function(e){return Object(l.pick)(e,["id","title"])})):null,selectedEventCategories:i?i.map((function(e){return Object(l.pick)(e,["id","name"])})):null}}))])(z);(0,wp.blocks.registerBlockType)("mp-timetable/timetable",{title:(0,wp.i18n.__)("Timetable","mp-timetable"),category:"common",icon:"calendar",supports:{align:["wide","full"]},getEditWrapperProps:function(e){var t=e.align;if(["wide","full"].includes(t))return{"data-align":t}},edit:M,save:function(){return null}})}]);
1
+ window.wp=window.wp||{},window.wp["./media/js/blocks/dist/index"]=function(e){var t={};function n(l){if(t[l])return t[l].exports;var a=t[l]={i:l,l:!1,exports:{}};return e[l].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,l){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:l})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var l=Object.create(null);if(n.r(l),Object.defineProperty(l,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(l,a,function(t){return e[t]}.bind(null,a));return l},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=4)}([function(e,t){e.exports=window.wp.i18n},function(e,t){e.exports=window.lodash},,,function(e,t,n){"use strict";n.r(t);var l=n(1),a=n(0);function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var n=0;n<t.length;n++){var l=t[n];l.enumerable=l.enumerable||!1,l.configurable=!0,"value"in l&&(l.writable=!0),Object.defineProperty(e,l.key,l)}}function c(e,t){return!t||"object"!==o(t)&&"function"!=typeof t?u(e):t}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function b(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function p(e){return(p=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function m(e,t){return(m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var s=wp.element.Component,f=wp.editor.InspectorControls,_=wp.components,v=_.SelectControl,d=_.CheckboxControl,h=_.PanelBody,y=_.TextControl,O=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&m(e,t)}(O,e);var t,n,o,s,_=(t=O,function(){var e,n=p(t);if(b()){var l=p(this).constructor;e=Reflect.construct(n,arguments,l)}else e=n.apply(this,arguments);return c(this,e)});function O(){var e;return r(this,O),(e=_.apply(this,arguments)).setOptions=e.setOptions.bind(u(e)),e}return n=O,(o=[{key:"setOptions",value:function(e){var t=[];return e&&(t=e.map((function(e){return{value:e.id.toString(),label:Object(l.get)(e,["title","raw"])||Object(l.get)(e,["name"])}}))),t}},{key:"render",value:function(){var e=this.props,t=e.attributes,n=t.col,l=t.events,o=t.event_categ,r=t.increment,i=t.view,c=t.view_sort,u=t.label,b=t.hide_label,p=t.hide_hrs,m=t.hide_empty_rows,s=t.title,_=t.time,O=t.sub_title,j=t.description,g=t.user,w=t.group,C=t.disable_event_url,E=t.text_align,R=t.text_align_vertical,S=t.id,k=t.custom_class,x=t.row_height,T=t.font_size,P=t.responsive,D=t.table_layout,I=e.selectedEvents,N=e.selectedColumns,H=e.selectedEventCategories,z=e.setAttributes;return React.createElement(f,null,React.createElement(h,{title:Object(a.__)("Settings","mp-timetable")},React.createElement(v,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:Object(a.__)("Columns","mp-timetable"),help:Object(a.__)("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:n,onChange:function(e){return z({col:e})},options:this.setOptions(N)}),React.createElement(v,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:Object(a.__)("Specific events","mp-timetable"),help:Object(a.__)("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:l,onChange:function(e){return z({events:e})},options:this.setOptions(I)}),React.createElement(v,{className:"timetable-wp56-fix",multiple:!0,size:"7",label:Object(a.__)("Event categories","mp-timetable"),help:Object(a.__)("Hold the Ctrl or Command key to select/deselect multiple options.","mp-timetable"),value:o,onChange:function(e){return z({event_categ:e})},options:this.setOptions(H)}),React.createElement(d,{label:Object(a.__)("Title","mp-timetable"),checked:"1"==s,onChange:function(e){z({title:e?"1":"0"})}}),React.createElement(d,{label:Object(a.__)("Time","mp-timetable"),checked:"1"==_,onChange:function(e){z({time:e?"1":"0"})}}),React.createElement(d,{label:Object(a.__)("Subtitle","mp-timetable"),checked:"1"==O,onChange:function(e){z({sub_title:e?"1":"0"})}}),React.createElement(d,{label:Object(a.__)("Description","mp-timetable"),checked:"1"==j,onChange:function(e){z({description:e?"1":"0"})}}),React.createElement(d,{label:Object(a.__)("Event Head","mp-timetable"),checked:"1"==g,onChange:function(e){z({user:e?"1":"0"})}}),React.createElement(y,{label:Object(a.__)("Block height in pixels","mp-timetable"),type:"number",value:isNaN(x)?0:parseInt(x),onChange:function(e){z({row_height:e.toString()})},min:1,step:1}),React.createElement(y,{label:Object(a.__)("Base font size","mp-timetable"),help:Object(a.__)("Base font size for the table. Example 12px, 2em, 80%.","mp-timetable"),value:T,onChange:function(e){return z({font_size:e})}}),React.createElement(v,{label:Object(a.__)("Time frame for event","mp-timetable"),value:r,onChange:function(e){return z({increment:e})},options:[{value:"1",label:Object(a.__)("Hour (1h)","mp-timetable")},{value:"0.5",label:Object(a.__)("Half hour (30min)","mp-timetable")},{value:"0.25",label:Object(a.__)("Quarter hour (15min)","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Filter events style","mp-timetable"),value:i,onChange:function(e){return z({view:e})},options:[{value:"dropdown_list",label:Object(a.__)("Dropdown list","mp-timetable")},{value:"tabs",label:Object(a.__)("Tabs","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Order of items in filter","mp-timetable"),value:c,onChange:function(e){return z({view_sort:e})},options:[{value:"",label:Object(a.__)("Default","mp-timetable")},{value:"menu_order",label:Object(a.__)("Menu Order","mp-timetable")},{value:"post_title",label:Object(a.__)("Title","mp-timetable")}]}),React.createElement(y,{label:Object(a.__)("Filter title to display all events","mp-timetable"),value:u,onChange:function(e){return z({label:e})}}),React.createElement(v,{label:Object(a.__)("Hide 'All Events' option","mp-timetable"),value:b,onChange:function(e){return z({hide_label:e})},options:[{value:"0",label:Object(a.__)("No","mp-timetable")},{value:"1",label:Object(a.__)("Yes","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Hide column with hours","mp-timetable"),value:p,onChange:function(e){return z({hide_hrs:e})},options:[{value:"0",label:Object(a.__)("No","mp-timetable")},{value:"1",label:Object(a.__)("Yes","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Do not display empty rows","mp-timetable"),value:m,onChange:function(e){return z({hide_empty_rows:e})},options:[{value:"0",label:Object(a.__)("No","mp-timetable")},{value:"1",label:Object(a.__)("Yes","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Merge cells with common events","mp-timetable"),value:w,onChange:function(e){return z({group:e})},options:[{value:"0",label:Object(a.__)("No","mp-timetable")},{value:"1",label:Object(a.__)("Yes","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Disable event link","mp-timetable"),value:C,onChange:function(e){return z({disable_event_url:e})},options:[{value:"0",label:Object(a.__)("No","mp-timetable")},{value:"1",label:Object(a.__)("Yes","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Horizontal align","mp-timetable"),value:E,onChange:function(e){return z({text_align:e})},options:[{value:"center",label:Object(a.__)("center","mp-timetable")},{value:"left",label:Object(a.__)("left","mp-timetable")},{value:"right",label:Object(a.__)("right","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Vertical align","mp-timetable"),value:R,onChange:function(e){return z({text_align_vertical:e})},options:[{value:"default",label:Object(a.__)("Default","mp-timetable")},{value:"top",label:Object(a.__)("top","mp-timetable")},{value:"middle",label:Object(a.__)("middle","mp-timetable")},{value:"bottom",label:Object(a.__)("bottom","mp-timetable")}]}),React.createElement(v,{label:Object(a.__)("Column width","mp-timetable"),value:D,onChange:function(e){return z({table_layout:e})},options:[{value:"",label:Object(a.__)("Default","mp-timetable")},{value:"auto",label:Object(a.__)("Auto","mp-timetable")},{value:"fixed",label:Object(a.__)("Fixed","mp-timetable")}]}),React.createElement(y,{label:Object(a.__)("Unique ID","mp-timetable"),help:Object(a.__)("If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.","mp-timetable"),value:S,onChange:function(e){return z({id:e})}}),React.createElement(y,{label:Object(a.__)("CSS class","mp-timetable"),value:k,onChange:function(e){return z({custom_class:e})}}),React.createElement(v,{label:Object(a.__)("Mobile behavior","mp-timetable"),value:P,onChange:function(e){return z({responsive:e})},options:[{value:"0",label:Object(a.__)("Table","mp-timetable")},{value:"1",label:Object(a.__)("List","mp-timetable")}]})))}}])&&i(n.prototype,o),s&&i(n,s),O}(s);function j(e){return(j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function g(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var n=0;n<t.length;n++){var l=t[n];l.enumerable=l.enumerable||!1,l.configurable=!0,"value"in l&&(l.writable=!0),Object.defineProperty(e,l.key,l)}}function C(e,t){return!t||"object"!==j(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function E(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function R(e){return(R=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function S(e,t){return(S=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}var k=wp.element,x=k.Component,T=k.Fragment,P=wp.compose.compose,D=wp.components,I=D.Disabled,N=D.ServerSideRender,H=wp.data.withSelect,z=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&S(e,t)}(i,e);var t,n,a,o,r=(t=i,function(){var e,n=R(t);if(E()){var l=R(this).constructor;e=Reflect.construct(n,arguments,l)}else e=n.apply(this,arguments);return C(this,e)});function i(){return g(this,i),r.apply(this,arguments)}return n=i,(a=[{key:"initTable",value:function(){var e=this.props.clientId,t=jQuery("#block-".concat(e)),n=setInterval((function(){t.find(".mptt-shortcode-wrapper").length&&!t.find(".mptt-shortcode-wrapper").hasClass("table-init")&&(clearInterval(n),window.mptt.tableInit())}),1)}},{key:"componentDidUpdate",value:function(e,t){Object(l.isEqual)(this.props.attributes,e.attributes)||this.initTable()}},{key:"componentDidMount",value:function(){this.initTable()}},{key:"render",value:function(){var e=this.props.attributes;return e.events,e.event_categ,React.createElement(T,null,React.createElement(O,this.props),React.createElement(I,null,React.createElement(N,{block:"mp-timetable/timetable",attributes:this.props.attributes})))}}])&&w(n.prototype,a),o&&w(n,o),i}(x),M=P([H((function(e,t){var n=e("core"),a=n.getEntityRecords,o=(n.getCategories,a("postType","mp-event",{per_page:-1,orderby:"title",order:"asc"})),r=a("postType","mp-column",{per_page:-1}),i=a("taxonomy","mp-event_category",{per_page:-1});return{selectedEvents:o?o.map((function(e){return Object(l.pick)(e,["id","title"])})):null,selectedColumns:r?r.map((function(e){return Object(l.pick)(e,["id","title"])})):null,selectedEventCategories:i?i.map((function(e){return Object(l.pick)(e,["id","name"])})):null}}))])(z);(0,wp.blocks.registerBlockType)("mp-timetable/timetable",{title:Object(a.__)("Timetable","mp-timetable"),category:"common",icon:"calendar",supports:{align:["wide","full"]},getEditWrapperProps:function(e){var t=e.align;if(["wide","full"].includes(t))return{"data-align":t}},edit:M,save:function(){return null}})}]);
media/js/blocks/src/timetable/edit.js CHANGED
@@ -1,91 +1,91 @@
1
- import Inspector from './inspector';
2
-
3
- import { pick, isEqual } from "lodash";
4
-
5
- const {__} = wp.i18n;
6
- const { Component, Fragment } = wp.element;
7
- const { compose } = wp.compose;
8
-
9
- const {
10
- Disabled,
11
- ServerSideRender
12
- } = wp.components;
13
-
14
- const {
15
- withSelect
16
- } = wp.data;
17
-
18
- class Edit extends Component {
19
- constructor() {
20
- super(...arguments);
21
- }
22
-
23
- initTable(){
24
- const { clientId } = this.props;
25
- const $block = jQuery( `#block-${clientId}` );
26
-
27
- //Set timer and check when table is load fully, and then initialize table data, and after stop timer
28
- const waitLoadTable = setInterval( () => {
29
- if ($block.find('.mptt-shortcode-wrapper').length && !$block.find('.mptt-shortcode-wrapper').hasClass('table-init')){
30
- clearInterval(waitLoadTable);
31
- window.mptt.tableInit();
32
- }
33
- }, 1);
34
- }
35
-
36
- componentDidUpdate(prevProps, prevState) {
37
- if (!isEqual(this.props.attributes, prevProps.attributes)) {
38
- this.initTable();
39
- }
40
- }
41
-
42
- componentDidMount() {
43
- this.initTable();
44
- }
45
-
46
- render() {
47
-
48
- const {
49
- attributes: {
50
- events,
51
- event_categ
52
- }
53
- } = this.props;
54
-
55
- return (
56
- <Fragment>
57
- <Inspector {...this.props }/>
58
- <Disabled>
59
- <ServerSideRender
60
- block="mp-timetable/timetable"
61
- attributes={this.props.attributes}
62
- />
63
- </Disabled>
64
- </Fragment>
65
- );
66
- }
67
- }
68
-
69
- export default compose([
70
- withSelect(( select, props ) => {
71
- const { getEntityRecords, getCategories } = select( "core" );
72
-
73
- let events = getEntityRecords( "postType", "mp-event", {per_page: -1, orderby: 'title', order: 'asc'} );
74
- let columns = getEntityRecords( "postType", "mp-column", {per_page: -1} );
75
- let eventCategories = getEntityRecords( "taxonomy", "mp-event_category", {per_page: -1} );
76
-
77
- return {
78
- selectedEvents: events ? events .map((event) => {
79
- return pick( event, [ 'id', 'title' ])
80
- }) : null,
81
-
82
- selectedColumns: columns ? columns.map((column) => {
83
- return pick( column, [ 'id', 'title' ])
84
- }) : null,
85
-
86
- selectedEventCategories: eventCategories ? eventCategories.map((categorie) => {
87
- return pick( categorie, [ 'id', 'name' ])
88
- }) : null
89
- };
90
- }),
91
- ])(Edit);
1
+ import Inspector from './inspector';
2
+
3
+ import { pick, isEqual } from "lodash";
4
+ import { __ } from 'wp.i18n';
5
+
6
+ const { Component, Fragment } = wp.element;
7
+ const { compose } = wp.compose;
8
+
9
+ const {
10
+ Disabled,
11
+ ServerSideRender
12
+ } = wp.components;
13
+
14
+ const {
15
+ withSelect
16
+ } = wp.data;
17
+
18
+ class Edit extends Component {
19
+ constructor() {
20
+ super(...arguments);
21
+ }
22
+
23
+ initTable(){
24
+ const { clientId } = this.props;
25
+ const $block = jQuery( `#block-${clientId}` );
26
+
27
+ //Set timer and check when table is load fully, and then initialize table data, and after stop timer
28
+ const waitLoadTable = setInterval( () => {
29
+ if ($block.find('.mptt-shortcode-wrapper').length && !$block.find('.mptt-shortcode-wrapper').hasClass('table-init')){
30
+ clearInterval(waitLoadTable);
31
+ window.mptt.tableInit();
32
+ }
33
+ }, 1);
34
+ }
35
+
36
+ componentDidUpdate(prevProps, prevState) {
37
+ if (!isEqual(this.props.attributes, prevProps.attributes)) {
38
+ this.initTable();
39
+ }
40
+ }
41
+
42
+ componentDidMount() {
43
+ this.initTable();
44
+ }
45
+
46
+ render() {
47
+
48
+ const {
49
+ attributes: {
50
+ events,
51
+ event_categ
52
+ }
53
+ } = this.props;
54
+
55
+ return (
56
+ <Fragment>
57
+ <Inspector {...this.props }/>
58
+ <Disabled>
59
+ <ServerSideRender
60
+ block="mp-timetable/timetable"
61
+ attributes={this.props.attributes}
62
+ />
63
+ </Disabled>
64
+ </Fragment>
65
+ );
66
+ }
67
+ }
68
+
69
+ export default compose([
70
+ withSelect(( select, props ) => {
71
+ const { getEntityRecords, getCategories } = select( "core" );
72
+
73
+ let events = getEntityRecords( "postType", "mp-event", {per_page: -1, orderby: 'title', order: 'asc'} );
74
+ let columns = getEntityRecords( "postType", "mp-column", {per_page: -1} );
75
+ let eventCategories = getEntityRecords( "taxonomy", "mp-event_category", {per_page: -1} );
76
+
77
+ return {
78
+ selectedEvents: events ? events .map((event) => {
79
+ return pick( event, [ 'id', 'title' ])
80
+ }) : null,
81
+
82
+ selectedColumns: columns ? columns.map((column) => {
83
+ return pick( column, [ 'id', 'title' ])
84
+ }) : null,
85
+
86
+ selectedEventCategories: eventCategories ? eventCategories.map((categorie) => {
87
+ return pick( categorie, [ 'id', 'name' ])
88
+ }) : null
89
+ };
90
+ }),
91
+ ])(Edit);
media/js/blocks/src/timetable/index.js CHANGED
@@ -1,29 +1,28 @@
1
- import edit from './edit';
2
-
3
- const {
4
- registerBlockType,
5
- } = wp.blocks;
6
-
7
- const { __ } = wp.i18n;
8
-
9
- export default registerBlockType(
10
- 'mp-timetable/timetable',
11
- {
12
- title: __('Timetable', 'mp-timetable'),
13
- category: 'common',
14
- icon: 'calendar',
15
- supports: {
16
- align: [ 'wide', 'full' ],
17
- },
18
- getEditWrapperProps( attributes ) {
19
- const { align } = attributes;
20
- if ( [ 'wide', 'full' ].includes( align ) ) {
21
- return { 'data-align': align };
22
- }
23
- },
24
- edit,
25
- save: () => {
26
- return null;
27
- },
28
- }
29
  )
1
+ import edit from './edit';
2
+ import { __ } from 'wp.i18n';
3
+
4
+ const {
5
+ registerBlockType,
6
+ } = wp.blocks;
7
+
8
+ export default registerBlockType(
9
+ 'mp-timetable/timetable',
10
+ {
11
+ title: __('Timetable', 'mp-timetable'),
12
+ category: 'common',
13
+ icon: 'calendar',
14
+ supports: {
15
+ align: [ 'wide', 'full' ],
16
+ },
17
+ getEditWrapperProps( attributes ) {
18
+ const { align } = attributes;
19
+ if ( [ 'wide', 'full' ].includes( align ) ) {
20
+ return { 'data-align': align };
21
+ }
22
+ },
23
+ edit,
24
+ save: () => {
25
+ return null;
26
+ },
27
+ }
 
28
  )
media/js/blocks/src/timetable/inspector.js CHANGED
@@ -1,296 +1,296 @@
1
- import { get } from "lodash";
2
-
3
- const {__} = wp.i18n;
4
- const {Component} = wp.element;
5
-
6
- const {
7
- InspectorControls,
8
- } = wp.editor;
9
-
10
- const {
11
- SelectControl,
12
- CheckboxControl,
13
- PanelBody,
14
- TextControl,
15
-
16
- } = wp.components;
17
-
18
- class Inspector extends Component {
19
- constructor() {
20
- super(...arguments);
21
-
22
- this.setOptions = this.setOptions.bind( this );
23
- }
24
-
25
- setOptions(data) {
26
- let options = [];
27
- if (data) {
28
- options = data.map((event => {
29
- return {
30
- value: event.id.toString(),
31
- label: get( event, [ 'title', 'raw' ] ) || get( event, [ 'name' ] )
32
- }
33
- }));
34
- }
35
- return options;
36
- }
37
-
38
- render() {
39
-
40
- const {
41
- attributes: {
42
- col,
43
- events,
44
- event_categ,
45
-
46
- increment,
47
- view,
48
- view_sort,
49
- label,
50
-
51
- hide_label,
52
- hide_hrs,
53
- hide_empty_rows,
54
-
55
- title,
56
- time,
57
- sub_title,
58
- description,
59
- user,
60
-
61
- group,
62
- disable_event_url,
63
- text_align,
64
- text_align_vertical,
65
- id,
66
- custom_class,
67
-
68
- row_height,
69
- font_size,
70
- responsive,
71
- table_layout,
72
- },
73
-
74
- selectedEvents,
75
- selectedColumns,
76
- selectedEventCategories,
77
-
78
- setAttributes,
79
- } = this.props;
80
-
81
- return (
82
- <InspectorControls>
83
- <PanelBody
84
- title={__('Settings', 'mp-timetable')}
85
- >
86
- <SelectControl
87
- className="timetable-wp56-fix"
88
- multiple
89
- size="7"
90
- label={__('Columns', 'mp-timetable')}
91
- help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
92
- value={col}
93
- onChange={col => setAttributes({col})}
94
- options={this.setOptions(selectedColumns)}
95
- />
96
- <SelectControl
97
- className="timetable-wp56-fix"
98
- multiple
99
- size="7"
100
- label={__('Specific events', 'mp-timetable')}
101
- help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
102
- value={events}
103
- onChange={events => setAttributes({events})}
104
- options={this.setOptions(selectedEvents )}
105
- />
106
- <SelectControl
107
- className="timetable-wp56-fix"
108
- multiple
109
- size="7"
110
- label={__('Event categories', 'mp-timetable')}
111
- help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
112
- value={event_categ}
113
- onChange={event_categ => setAttributes({event_categ})}
114
- options={this.setOptions(selectedEventCategories)}
115
- />
116
- <CheckboxControl
117
- label={__('Title', 'mp-timetable')}
118
- checked={title == '1' ? true : false}
119
- onChange={(title) => {
120
- setAttributes({title: title ? '1' : '0'})
121
- }}
122
- />
123
- <CheckboxControl
124
- label={__('Time', 'mp-timetable')}
125
- checked={time == '1' ? true : false}
126
- onChange={(time) => { setAttributes({time: time ? '1' : '0'}) }}
127
- />
128
- <CheckboxControl
129
- label={__('Subtitle', 'mp-timetable')}
130
- checked={sub_title == '1' ? true : false}
131
- onChange={(sub_title) => { setAttributes({sub_title: sub_title ? '1' : '0'}) }}
132
- />
133
- <CheckboxControl
134
- label={__('Description', 'mp-timetable')}
135
- checked={description == '1' ? true : false}
136
- onChange={(description) => { setAttributes({description: description ? '1' : '0'}) }}
137
- />
138
- <CheckboxControl
139
- label={__('Event Head', 'mp-timetable')}
140
- checked={user == '1' ? true : false}
141
- onChange={(user) => { setAttributes({user: user ? '1' : '0'}) }}
142
- />
143
- <TextControl
144
- label={__('Block height in pixels', 'mp-timetable')}
145
- type={'number'}
146
- value={isNaN(row_height) ? 0 : parseInt(row_height)}
147
- onChange={row_height => {
148
- setAttributes({ row_height: row_height.toString() });
149
- }}
150
- min={1}
151
- step={1}
152
- />
153
- <TextControl
154
- label={__('Base font size', 'mp-timetable')}
155
- help={__('Base font size for the table. Example 12px, 2em, 80%.', 'mp-timetable')}
156
- value={font_size}
157
- onChange={font_size => setAttributes({font_size})}
158
- />
159
- <SelectControl
160
- label={__('Time frame for event', 'mp-timetable')}
161
- value={increment}
162
- onChange={increment => setAttributes({ increment })}
163
- options={[
164
- { value: '1' , label: __( 'Hour (1h)' , 'mp-timetable' ) },
165
- { value: '0.5' , label: __( 'Half hour (30min)' , 'mp-timetable' ) },
166
- { value: '0.25', label: __( 'Quarter hour (15min)' , 'mp-timetable' ) },
167
- ]}
168
- />
169
- <SelectControl
170
- label={__('Filter events style', 'mp-timetable')}
171
- value={view}
172
- onChange={view => setAttributes({ view })}
173
- options={[
174
- { value: 'dropdown_list', label: __( 'Dropdown list', 'mp-timetable' ) },
175
- { value: 'tabs' , label: __( 'Tabs' , 'mp-timetable' ) },
176
- ]}
177
- />
178
- <SelectControl
179
- label={__('Order of items in filter', 'mp-timetable')}
180
- value={view_sort}
181
- onChange={view_sort => setAttributes({ view_sort })}
182
- options={[
183
- { value: '' , label: __( 'Default', 'mp-timetable' ) },
184
- { value: 'menu_order' , label: __( 'Menu Order', 'mp-timetable' ) },
185
- { value: 'post_title' , label: __( 'Title', 'mp-timetable' ) },
186
- ]}
187
- />
188
- <TextControl
189
- label={__('Filter title to display all events', 'mp-timetable')}
190
- value={label}
191
- onChange={label => setAttributes({ label })}
192
- />
193
- <SelectControl
194
- label={__('Hide \'All Events\' option', 'mp-timetable')}
195
- value={hide_label}
196
- onChange={hide_label => setAttributes({ hide_label })}
197
- options={[
198
- { value: '0', label: __( 'No' , 'mp-timetable' ) },
199
- { value: '1', label: __( 'Yes', 'mp-timetable' ) },
200
- ]}
201
- />
202
- <SelectControl
203
- label={__('Hide column with hours', 'mp-timetable')}
204
- value={hide_hrs}
205
- onChange={hide_hrs => setAttributes({ hide_hrs })}
206
- options={[
207
- { value: '0', label: __( 'No' , 'mp-timetable' ) },
208
- { value: '1', label: __( 'Yes', 'mp-timetable' ) },
209
- ]}
210
- />
211
- <SelectControl
212
- label={__('Do not display empty rows', 'mp-timetable')}
213
- value={hide_empty_rows}
214
- onChange={hide_empty_rows => setAttributes({ hide_empty_rows })}
215
- options={[
216
- { value: '0', label: __( 'No' , 'mp-timetable' ) },
217
- { value: '1', label: __( 'Yes', 'mp-timetable' ) },
218
- ]}
219
- />
220
- <SelectControl
221
- label={__('Merge cells with common events', 'mp-timetable')}
222
- value={group}
223
- onChange={group => setAttributes({ group })}
224
- options={[
225
- { value: '0', label: __( 'No' , 'mp-timetable' ) },
226
- { value: '1', label: __( 'Yes', 'mp-timetable' ) },
227
- ]}
228
- />
229
- <SelectControl
230
- label={__('Disable event link', 'mp-timetable')}
231
- value={disable_event_url}
232
- onChange={disable_event_url => setAttributes({ disable_event_url })}
233
- options={[
234
- { value: '0', label: __( 'No' , 'mp-timetable' ) },
235
- { value: '1', label: __( 'Yes', 'mp-timetable' ) },
236
- ]}
237
- />
238
- <SelectControl
239
- label={__('Horizontal align', 'mp-timetable')}
240
- value={text_align}
241
- onChange={text_align => setAttributes({ text_align })}
242
- options={[
243
- { value: 'center', label: __( 'center', 'mp-timetable' ) },
244
- { value: 'left', label: __( 'left' , 'mp-timetable' ) },
245
- { value: 'right', label: __( 'right' , 'mp-timetable' ) },
246
- ]}
247
- />
248
- <SelectControl
249
- label={__('Vertical align', 'mp-timetable')}
250
- value={text_align_vertical}
251
- onChange={text_align_vertical => setAttributes({ text_align_vertical })}
252
- options={[
253
- { value: 'default', label: __( 'Default', 'mp-timetable' ) },
254
- { value: 'top', label: __( 'top' , 'mp-timetable' ) },
255
- { value: 'middle', label: __( 'middle' , 'mp-timetable' ) },
256
- { value: 'bottom', label: __( 'bottom' , 'mp-timetable' ) },
257
- ]}
258
- />
259
- <SelectControl
260
- label={__('Table layout', 'mp-timetable')}
261
- value={table_layout}
262
- onChange={table_layout => setAttributes({ table_layout })}
263
- options={[
264
- { value: '', label: __( 'Default', 'mp-timetable' ) },
265
- { value: 'auto', label: __( 'Auto' , 'mp-timetable' ) },
266
- { value: 'fixed', label: __( 'Fixed' , 'mp-timetable' ) },
267
- ]}
268
- />
269
- <TextControl
270
- label={__('Unique ID', 'mp-timetable')}
271
- help={__('If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'mp-timetable')}
272
- value={id}
273
- onChange={id => setAttributes({id})}
274
- />
275
- <TextControl
276
- label={__('CSS class', 'mp-timetable')}
277
- value={custom_class}
278
- onChange={custom_class => setAttributes({custom_class})}
279
- />
280
- <SelectControl
281
- label={__('Mobile behavior', 'mp-timetable')}
282
- value={responsive}
283
- onChange={responsive => setAttributes({responsive})}
284
- options={[
285
- { value: '0', label: __( 'Table' , 'mp-timetable' ) },
286
- { value: '1', label: __( 'List', 'mp-timetable' ) },
287
- ]}
288
- />
289
-
290
- </PanelBody>
291
- </InspectorControls>
292
- );
293
- }
294
- }
295
-
296
  export default (Inspector);
1
+ import { get } from "lodash";
2
+ import { __ } from 'wp.i18n';
3
+
4
+ const {Component} = wp.element;
5
+
6
+ const {
7
+ InspectorControls,
8
+ } = wp.editor;
9
+
10
+ const {
11
+ SelectControl,
12
+ CheckboxControl,
13
+ PanelBody,
14
+ TextControl,
15
+
16
+ } = wp.components;
17
+
18
+ class Inspector extends Component {
19
+ constructor() {
20
+ super(...arguments);
21
+
22
+ this.setOptions = this.setOptions.bind( this );
23
+ }
24
+
25
+ setOptions(data) {
26
+ let options = [];
27
+ if (data) {
28
+ options = data.map((event => {
29
+ return {
30
+ value: event.id.toString(),
31
+ label: get( event, [ 'title', 'raw' ] ) || get( event, [ 'name' ] )
32
+ }
33
+ }));
34
+ }
35
+ return options;
36
+ }
37
+
38
+ render() {
39
+
40
+ const {
41
+ attributes: {
42
+ col,
43
+ events,
44
+ event_categ,
45
+
46
+ increment,
47
+ view,
48
+ view_sort,
49
+ label,
50
+
51
+ hide_label,
52
+ hide_hrs,
53
+ hide_empty_rows,
54
+
55
+ title,
56
+ time,
57
+ sub_title,
58
+ description,
59
+ user,
60
+
61
+ group,
62
+ disable_event_url,
63
+ text_align,
64
+ text_align_vertical,
65
+ id,
66
+ custom_class,
67
+
68
+ row_height,
69
+ font_size,
70
+ responsive,
71
+ table_layout,
72
+ },
73
+
74
+ selectedEvents,
75
+ selectedColumns,
76
+ selectedEventCategories,
77
+
78
+ setAttributes,
79
+ } = this.props;
80
+
81
+ return (
82
+ <InspectorControls>
83
+ <PanelBody
84
+ title={__('Settings', 'mp-timetable')}
85
+ >
86
+ <SelectControl
87
+ className="timetable-wp56-fix"
88
+ multiple
89
+ size="7"
90
+ label={__('Columns', 'mp-timetable')}
91
+ help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
92
+ value={col}
93
+ onChange={col => setAttributes({col})}
94
+ options={this.setOptions(selectedColumns)}
95
+ />
96
+ <SelectControl
97
+ className="timetable-wp56-fix"
98
+ multiple
99
+ size="7"
100
+ label={__('Specific events', 'mp-timetable')}
101
+ help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
102
+ value={events}
103
+ onChange={events => setAttributes({events})}
104
+ options={this.setOptions(selectedEvents )}
105
+ />
106
+ <SelectControl
107
+ className="timetable-wp56-fix"
108
+ multiple
109
+ size="7"
110
+ label={__('Event categories', 'mp-timetable')}
111
+ help={__('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable')}
112
+ value={event_categ}
113
+ onChange={event_categ => setAttributes({event_categ})}
114
+ options={this.setOptions(selectedEventCategories)}
115
+ />
116
+ <CheckboxControl
117
+ label={__('Title', 'mp-timetable')}
118
+ checked={title == '1' ? true : false}
119
+ onChange={(title) => {
120
+ setAttributes({title: title ? '1' : '0'})
121
+ }}
122
+ />
123
+ <CheckboxControl
124
+ label={__('Time', 'mp-timetable')}
125
+ checked={time == '1' ? true : false}
126
+ onChange={(time) => { setAttributes({time: time ? '1' : '0'}) }}
127
+ />
128
+ <CheckboxControl
129
+ label={__('Subtitle', 'mp-timetable')}
130
+ checked={sub_title == '1' ? true : false}
131
+ onChange={(sub_title) => { setAttributes({sub_title: sub_title ? '1' : '0'}) }}
132
+ />
133
+ <CheckboxControl
134
+ label={__('Description', 'mp-timetable')}
135
+ checked={description == '1' ? true : false}
136
+ onChange={(description) => { setAttributes({description: description ? '1' : '0'}) }}
137
+ />
138
+ <CheckboxControl
139
+ label={__('Event Head', 'mp-timetable')}
140
+ checked={user == '1' ? true : false}
141
+ onChange={(user) => { setAttributes({user: user ? '1' : '0'}) }}
142
+ />
143
+ <TextControl
144
+ label={__('Block height in pixels', 'mp-timetable')}
145
+ type={'number'}
146
+ value={isNaN(row_height) ? 0 : parseInt(row_height)}
147
+ onChange={row_height => {
148
+ setAttributes({ row_height: row_height.toString() });
149
+ }}
150
+ min={1}
151
+ step={1}
152
+ />
153
+ <TextControl
154
+ label={__('Base font size', 'mp-timetable')}
155
+ help={__('Base font size for the table. Example 12px, 2em, 80%.', 'mp-timetable')}
156
+ value={font_size}
157
+ onChange={font_size => setAttributes({font_size})}
158
+ />
159
+ <SelectControl
160
+ label={__('Time frame for event', 'mp-timetable')}
161
+ value={increment}
162
+ onChange={increment => setAttributes({ increment })}
163
+ options={[
164
+ { value: '1' , label: __( 'Hour (1h)' , 'mp-timetable' ) },
165
+ { value: '0.5' , label: __( 'Half hour (30min)' , 'mp-timetable' ) },
166
+ { value: '0.25', label: __( 'Quarter hour (15min)' , 'mp-timetable' ) },
167
+ ]}
168
+ />
169
+ <SelectControl
170
+ label={__('Filter events style', 'mp-timetable')}
171
+ value={view}
172
+ onChange={view => setAttributes({ view })}
173
+ options={[
174
+ { value: 'dropdown_list', label: __( 'Dropdown list', 'mp-timetable' ) },
175
+ { value: 'tabs' , label: __( 'Tabs' , 'mp-timetable' ) },
176
+ ]}
177
+ />
178
+ <SelectControl
179
+ label={__('Order of items in filter', 'mp-timetable')}
180
+ value={view_sort}
181
+ onChange={view_sort => setAttributes({ view_sort })}
182
+ options={[
183
+ { value: '' , label: __( 'Default', 'mp-timetable' ) },
184
+ { value: 'menu_order' , label: __( 'Menu Order', 'mp-timetable' ) },
185
+ { value: 'post_title' , label: __( 'Title', 'mp-timetable' ) },
186
+ ]}
187
+ />
188
+ <TextControl
189
+ label={__('Filter title to display all events', 'mp-timetable')}
190
+ value={label}
191
+ onChange={label => setAttributes({ label })}
192
+ />
193
+ <SelectControl
194
+ label={__('Hide \'All Events\' option', 'mp-timetable')}
195
+ value={hide_label}
196
+ onChange={hide_label => setAttributes({ hide_label })}
197
+ options={[
198
+ { value: '0', label: __( 'No' , 'mp-timetable' ) },
199
+ { value: '1', label: __( 'Yes', 'mp-timetable' ) },
200
+ ]}
201
+ />
202
+ <SelectControl
203
+ label={__('Hide column with hours', 'mp-timetable')}
204
+ value={hide_hrs}
205
+ onChange={hide_hrs => setAttributes({ hide_hrs })}
206
+ options={[
207
+ { value: '0', label: __( 'No' , 'mp-timetable' ) },
208
+ { value: '1', label: __( 'Yes', 'mp-timetable' ) },
209
+ ]}
210
+ />
211
+ <SelectControl
212
+ label={__('Do not display empty rows', 'mp-timetable')}
213
+ value={hide_empty_rows}
214
+ onChange={hide_empty_rows => setAttributes({ hide_empty_rows })}
215
+ options={[
216
+ { value: '0', label: __( 'No' , 'mp-timetable' ) },
217
+ { value: '1', label: __( 'Yes', 'mp-timetable' ) },
218
+ ]}
219
+ />
220
+ <SelectControl
221
+ label={__('Merge cells with common events', 'mp-timetable')}
222
+ value={group}
223
+ onChange={group => setAttributes({ group })}
224
+ options={[
225
+ { value: '0', label: __( 'No' , 'mp-timetable' ) },
226
+ { value: '1', label: __( 'Yes', 'mp-timetable' ) },
227
+ ]}
228
+ />
229
+ <SelectControl
230
+ label={__('Disable event link', 'mp-timetable')}
231
+ value={disable_event_url}
232
+ onChange={disable_event_url => setAttributes({ disable_event_url })}
233
+ options={[
234
+ { value: '0', label: __( 'No' , 'mp-timetable' ) },
235
+ { value: '1', label: __( 'Yes', 'mp-timetable' ) },
236
+ ]}
237
+ />
238
+ <SelectControl
239
+ label={__('Horizontal align', 'mp-timetable')}
240
+ value={text_align}
241
+ onChange={text_align => setAttributes({ text_align })}
242
+ options={[
243
+ { value: 'center', label: __( 'center', 'mp-timetable' ) },
244
+ { value: 'left', label: __( 'left' , 'mp-timetable' ) },
245
+ { value: 'right', label: __( 'right' , 'mp-timetable' ) },
246
+ ]}
247
+ />
248
+ <SelectControl
249
+ label={__('Vertical align', 'mp-timetable')}
250
+ value={text_align_vertical}
251
+ onChange={text_align_vertical => setAttributes({ text_align_vertical })}
252
+ options={[
253
+ { value: 'default', label: __( 'Default', 'mp-timetable' ) },
254
+ { value: 'top', label: __( 'top' , 'mp-timetable' ) },
255
+ { value: 'middle', label: __( 'middle' , 'mp-timetable' ) },
256
+ { value: 'bottom', label: __( 'bottom' , 'mp-timetable' ) },
257
+ ]}
258
+ />
259
+ <SelectControl
260
+ label={__('Column width', 'mp-timetable')}
261
+ value={table_layout}
262
+ onChange={table_layout => setAttributes({ table_layout })}
263
+ options={[
264
+ { value: '', label: __( 'Default', 'mp-timetable' ) },
265
+ { value: 'auto', label: __( 'Auto' , 'mp-timetable' ) },
266
+ { value: 'fixed', label: __( 'Fixed' , 'mp-timetable' ) },
267
+ ]}
268
+ />
269
+ <TextControl
270
+ label={__('Unique ID', 'mp-timetable')}
271
+ help={__('If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'mp-timetable')}
272
+ value={id}
273
+ onChange={id => setAttributes({id})}
274
+ />
275
+ <TextControl
276
+ label={__('CSS class', 'mp-timetable')}
277
+ value={custom_class}
278
+ onChange={custom_class => setAttributes({custom_class})}
279
+ />
280
+ <SelectControl
281
+ label={__('Mobile behavior', 'mp-timetable')}
282
+ value={responsive}
283
+ onChange={responsive => setAttributes({responsive})}
284
+ options={[
285
+ { value: '0', label: __( 'Table' , 'mp-timetable' ) },
286
+ { value: '1', label: __( 'List', 'mp-timetable' ) },
287
+ ]}
288
+ />
289
+
290
+ </PanelBody>
291
+ </InspectorControls>
292
+ );
293
+ }
294
+ }
295
+
296
  export default (Inspector);
media/js/events/event.min.js CHANGED
@@ -1 +1 @@
1
- !function(t){var e={};function n(i){if(e[i])return e[i].exports;var a=e[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)n.d(i,a,function(e){return t[e]}.bind(null,a));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=2)}({2:function(t,e){Registry.register("Event",function(t){"use strict";var e;return{getInstance:function(){return e||(e={event_id:"",eventsData:{},init:function(){e.initTimePicker(),e.addEventButton(),e.initDeleteButtons(),e.initEditButtons(),e.initColorPicker(),e.initDatePicker(),e.columnRadioBox()},initTimePicker:function(){var e=Boolean(parseInt(t("#time_format").val()));t("#event_start").timepicker({showPeriod:e,showPeriodLabels:e,defaultTime:"00:00"}),t("#event_end").timepicker({showPeriod:e,showPeriodLabels:e,defaultTime:"00:00"})},initSlider:function(n,i){var a=!_.isUndefined(i)&&Boolean(i),r=n.replace(/^\D+/g,"");t(n).carouFredSel({items:{visible:3},direction:"up",scroll:{items:1,easing:"swing",pauseOnHover:!0,onAfter:function(e){e.items.old.each((function(){t(this).removeClass("visible")})),e.items.visible.each((function(){t(this).addClass("visible")}))}},auto:{play:a,timeoutDuration:3e3},prev:{button:"#mp_prev_button"+r},next:{button:"#mp_next_button"+r}}),t(n).trigger("currentVisible",(function(t){t.addClass("visible")})),e.setColorSettings(n+" .mptt-colorized")},initDeleteButton:function(){var e=t("#events-list");e.find("li.event").find("i.operation-button.dashicons-no.dashicons").off("click").on("click",(function(){e.find("li.event").length>1?t(this).parents("li.event").remove():e.remove()}))},initColorPicker:function(e){_.isUndefined(e)&&(e="");var n=t(e+" input.clr-picker"),i=t(e+" input.regular-text");n.spectrum("destroy"),n.spectrum({preferredFormat:"rgb",showInput:!0,showAlpha:!0,allowEmpty:!0,palette:[["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]],showPalette:!0,show:function(e){t(this).val(e)},hide:function(e){t(this).parents(".select-color").find(".regular-text").val(t(this).val())},change:function(e){t(this).parents(".select-color").find('input:not([type="hidden"])').val(t(this).val())}}),i.off("keyup").on("keyup",(function(){var e=t(this).parents(".select-color"),n=e.find(".clr-picker"),i=e.find(".regular-text").val();e.find(".sp-preview-inner").css({"background-color":i}),n.spectrum("set",i)}))},addEventButton:function(){t(document).on("click.admin","#add_mp_event",(function(){t(this).hasClass("edit")?e.updateEventData():e.renderEventItem()}))},initDeleteButtons:function(){t(document).on("click.admin","#events-list .delete-event-button",(function(){var n=t(this).attr("data-id");e.deleteEvent(n)}))},initEditButtons:function(){t(document).on("click.admin","#events-list .edit-event-button",(function(){var n=t(this).attr("data-id"),i=t(this).parent().parent();t(this).parent().find(".spinner").addClass("is-active"),Registry._get("adminFunctions").wpAjax({controller:"events",action:"get_event_data",id:n},(function(n){var a=t("#add_mp_event"),r=t("#events-list");r.find(".spinner").removeClass("is-active"),r.find(" tr").removeClass("active"),i.addClass("active"),t("#event_start").val(n.event_start),t("#event_end").val(n.event_end),t("#description").val(n.description),t("#user_id").val(n.user_id),t("#weekday_id").val(n.column_id),a.addClass("edit"),a.val("Update"),e.event_id=n.id}),(function(t){console.warn(t)}))}))},deleteEvent:function(e){Registry._get("adminFunctions").wpAjax({controller:"events",action:"delete",id:e},(function(n){var i=t("#events-list").find('tr[data-id="'+e+'"]');i.length&&i.remove()}),(function(t){console.log(t)}))},updateEventItem:function(){var n=t("#events-list").find('tr[data-id="'+e.event_id+'"]'),i=t("#user_id");n.find("td.event-column").text(t("#weekday_id").find("option:selected").text()),n.find("td.event-start").text(t("#event_start").val()),n.find("td.event-end").text(t("#event_end").val()),n.find("td.event-user-id").text("-1"===i.val()?"":i.find("option:selected").text()),n.find("td.event-description").text(t("#description").val()),e.event_id=null,t("#add_mp_event").removeClass("edit").val("Add New")},updateEventData:function(){var n=t("#add_event_table").find(".spinner");n.addClass("is-active"),Registry._get("adminFunctions").wpAjax({controller:"events",action:"update_event_data",data:{id:Registry._get("Event").event_id,event_start:t("#event_start").val(),event_end:t("#event_end").val(),description:t("#description").val(),user_id:t("#user_id").val(),weekday_ids:t("#weekday_id").val()}},(function(){n.removeClass("is-active"),e.updateEventItem(),e.clearTable()}),(function(t){n.removeClass("is-active"),console.log(t)}))},renderEventItem:function(){var n=t("#weekday_id"),i=t("#user_id"),a=n.find("option:selected").val(),r=t("#event_start"),s=t("#event_end"),o=t("#description"),d={tag:"tr",attrs:{},content:[{tag:"td",attrs:{style:"display:none;"},content:[{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][weekday_ids][]",value:a}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][event_start][]",value:r.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][event_end][]",value:s.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][description][]",value:o.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][user_id][]",value:i.val()}}]},{tag:"td",attrs:{class:"event-column"},content:[n.find("option:selected").text()]},{tag:"td",attrs:{class:"event-start"},content:[r.val()]},{tag:"td",attrs:{class:"event-end"},content:[s.val()]},{tag:"td",attrs:{class:"event-description"},content:[o.val()]},{tag:"td",attrs:{class:"event-user-id"},content:["-1"===i.val()?"":i.find("option:selected").text()]},{tag:"td",attrs:{},content:[]}]},c=Registry._get("adminFunctions").getHtml(d);t("#events-list").find("tbody").append(c),t(".events-list-wrapper").scrollTop(1e10),e.clearTable()},setEventHeight:function(e){var n=e.parent().outerHeight(),i=t("body"),a=e.height(),r=e.data("min-height"),s=e.find(".mptt-inner-event-content").height();e.css("position","").css("width","").css("min-height",""),i.hasClass("mprm_ie_browser")?(s=e.css("height","").find(".mptt-inner-event-content").height(),e.height(a),s<=r?e.css("max-height",r):(e.css("height",""),e.css("max-height",s))):s<=r?e.css("min-height",r):e.css("min-height",s),n<a&&e.height(a)},recalculate_Height:function(e,n){var i=t(".mptt-event-container",e),a=i.length,r=0,s=0,o=e.height();t("body").hasClass("mprm_ie_browser")?(r=o/(a>0?a:1),_.isUndefined(n)?t.each(i,(function(){var e=t(this);if(e.height(r),_.isEmpty(e.data("min-height"))){var n=e.height();0===n?e.data("min-height",r):e.data("min-height",n)}e.css("top",s+"px"),e.removeClass("mptt-hidden"),s+=r})):n.height(r)):(r=100/(a>0?a:1),_.isUndefined(n)?t.each(i,(function(){var e=t(this);e.height(r+"%"),_.isEmpty(e.data("min-height"))&&e.data("min-height",e.height()),e.css("top",s+"%"),e.removeClass("mptt-hidden"),s+=r})):n.height(r+"%"))},setEventsHeight:function(){var n=t(".mptt-shortcode-wrapper").find("table").find("td.event");t.each(n,(function(){var n=t(this);e.recalculate_Height(n)}))},setColorSettings:function(n){_.isUndefined(n)&&(n=".mptt-colorized");var i=t(n);t.each(i,(function(){var n=t(this),i=n.attr("data-bg_hover_color"),a=n.attr("data-hover_color"),r=n.parent();switch(n.attr("data-type")){case"column":case"event":n.hover((function(){_.isEmpty(i)||n.css("background-color",i),_.isEmpty(a)||n.css("color",a),e.setEventHeight(n)}),(function(){n.css("max-height","").css("min-height",""),e.recalculate_Height(r,n),n.css("background-color",n.attr("data-bg_color")),n.css("color",n.attr("data-color"))}));break;case"widget":n.hover((function(){n.css("background-color",n.attr("data-background-hover-color")),n.css("color",t(this).attr("data-hover-color")),n.css("border-left-color",n.attr("data-hover-border-color"))}),(function(){n.css("background-color",n.attr("data-background-color")),n.css("color",n.attr("data-color")),n.css("border-left-color",n.attr("data-border-color"))}))}}))},clearTable:function(){var e=t("#weekday_id");t("#add_event_table input:not(.button),#add_event_table textarea").val(""),e.val(e.find("option:first").attr("value"))},getRowSpan:function(e,n){for(var i=[],a=[],r=n.attr("data-column-id"),s=n.closest("tr").next("tr"),o=s.find('td[data-column-id="'+r+'"]'),d=s.length>0&&o.length>0&&o.children().length>0;!d;){if(0==s.next("tr").length){d=!0,s=!1;break}d=(o=(s=s.next("tr")).find('td[data-column-id="'+r+'"]')).children().length>0}var c=!1;s&&(c=s.data("index")),t.each(e,(function(e){var n=t(this).attr("data-start"),r=t(this).attr("data-end");a[e]=n,i[e]=r}));var l=Math.min.apply(Math,a),v=Math.max.apply(Math,i);c&&v>c&&(v=c);var f=v-l;return f<1?1:f},responsiveFilter:function(e){var n="all",i=e.parents(".mptt-shortcode-wrapper");n=e.is("select")?e.val():e.attr("href").replace("#","");var a=i.find(".mptt-list-event");"all"!==n?(a.hide(),i.find('.mptt-list-event[data-event-id="'+n+'"]').show()):a.show(),t.each(i.find(".mptt-column"),(function(){t(this).show(),t(this).find(".mptt-list-event:visible").length<1&&t(this).hide()}))},filterStatic:function(t,n){var i=t.parents(".mptt-shortcode-wrapper"),a="#all",r=_.isEmpty(i.attr("id"))?"not-set":i.attr("id");a=t.is("select")?t.val():t.attr("href").replace("#",""),0==n||void 0===n.originalEvent||(window.location.hash=r+":"+a),i.find("table").hide(),i.find('table[id="#'+a+'"]').fadeIn(),e.setEventsHeight()},setClassTd:function(){t.each(t(".mptt-event-container"),(function(){t(this).parents("td").addClass("event")}))},initTableData:function(){e.setClassTd(),e.setRowSpanTd();var n="."+MPTT.table_class;t(n).data("hide_empty_row")&&e.hideEmptyRows()},filterShortcodeEvents:function(){var n=t(".mptt-menu");n.length&&(n.off("change").on("change",(function(n){e.filterStatic(t(this),n),e.responsiveFilter(t(this))})),t(".mptt-navigation-tabs.mptt-menu a").off("click").on("click",(function(n){var i=t(this);i.parents(".mptt-navigation-tabs.mptt-menu").find("li").removeClass("active"),i.parents("li").addClass("active"),e.filterStatic(i,n),e.responsiveFilter(i)})))},showCurrentEvent:function(t,e){t.find(".mptt-menu").hasClass("mptt-navigation-tabs")?t.find(".mptt-navigation-tabs").find('a[href="#'+e+'"]').click():t.find(".mptt-menu").hasClass("mptt-navigation-select")&&t.find('.mptt-navigation-select option[value="'+e+'"]')?t.find(".mptt-navigation-select").val(e).change():t.find('table[id="#all"]').fadeIn()},getFilterByHash:function(){var n=window.location.hash;if(!_.isUndefined(n)){var i=n.split(":"),a=i[0],r=i[1],s=t(".mptt-shortcode-wrapper");r=_.isUndefined(r)?"all":r,1===s.length?e.showCurrentEvent(s,r):t.each(s,(function(n,i){var s=t(i);"#"+s.attr("id")===a?e.showCurrentEvent(s,r):e.showCurrentEvent(s,"all")}))}e.setEventsHeight()},removeCellsAfterChangeColSpan:function(t,e,n,i){for(;t<e;t++){var a=n.find('th[data-index="'+t+'"]').data("column-id");i.find('td:not(.event)[data-column-id="'+a+'"]').remove()}},removeCellsAfterChangeRowSpan:function(t,n,i,a){for(var r=t.parents("tr").attr("data-index"),s=n+parseInt(r)-1,o=t.attr("colspan"),d=i.find('th[data-column-id="'+a+'"]').data("index"),c=parseInt(d)+parseInt(o);r<s;r++){var l=i.find("tr.mptt-shortcode-row-"+(parseInt(r)+1));if(l.length){if(l.find('td.event[data-column-id="'+a+'"]').length&&(n-=s-r)<2){n=1;break}o>1&&e.removeCellsAfterChangeColSpan(d,c,i,l),l.find('td:not(.event)[data-column-id="'+a+'"]').remove()}}return n},setRowSpanTd:function(){var n="."+MPTT.table_class;t.each(t(n),(function(){var n=t(this);t.each(n.find("td.event"),(function(){var i=t(this),a=i.find(".mptt-event-container"),r=i.attr("data-column-id"),s=i.attr("data-row_height"),o=e.getRowSpan(a,i);!_.isUndefined(o)&&o>1&&(o=e.removeCellsAfterChangeRowSpan(i,o,n,r),isNaN(s)||i.css("height",o*s)),i.attr("rowspan",o)}))}))},hideEmptyRows:function(){var e="."+MPTT.table_class,n=t(e+" tbody tr"),i=t(e).first().find("th").length;t.each(n,(function(e,n){0===t(n).find("td.event").length&&t(n).find("td").length===i&&t(n).remove()}))},displaySettings:function(){var e=t(".view_settings");e.length&&e.change((function(){"all"===t(this).val()?(t(this).attr("id"),t(this).parents(".mptt-container").find(".next-days").css("display","block")):t(this).parents(".mptt-container").find(".next-days").css("display","none")}))},timeMode:function(e){if(e){var n="."+t(this).attr("id");t("#"+e).change((function(){"server"===t(this).val()?(t(this).attr("id"),t(this).parents(".mptt-container").find(n).css("display","block")):t(this).parents(".mptt-container").find(n).css("display","none")}))}},initDatePicker:function(){var e=t("#datepicker");e.length&&e.datepicker({dateFormat:"d/m/yy",setDate:Date.parse(e.val())})},columnRadioBox:function(){var e=t("#datepicker"),n=t('input.option-input[name="column[column_option]"]'),i=t("select.mp-weekday");n.length&&n.on("change",(function(){switch(t(this).val()){case"simple":i.prop("disabled",!0),e.prop("disabled",!0);break;case"weekday":i.prop("disabled",!1),e.val("").prop("disabled",!0);break;case"date":i.prop("disabled",!0),e.prop("disabled",!1)}}))}}),e}}}(jQuery))}});
1
+ window.wp=window.wp||{},window.wp["./media/js/events/event"]=function(t){var e={};function n(i){if(e[i])return e[i].exports;var a=e[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)n.d(i,a,function(e){return t[e]}.bind(null,a));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=3)}({3:function(t,e){Registry.register("Event",function(t){"use strict";var e;return{getInstance:function(){return e||(e={event_id:"",eventsData:{},init:function(){e.initTimePicker(),e.addEventButton(),e.initDeleteButtons(),e.initEditButtons(),e.initColorPicker(),e.initDatePicker(),e.columnRadioBox()},initTimePicker:function(){var e=Boolean(parseInt(t("#time_format").val()));t("#event_start").timepicker({showPeriod:e,showPeriodLabels:e,defaultTime:"00:00"}),t("#event_end").timepicker({showPeriod:e,showPeriodLabels:e,defaultTime:"00:00"})},initSlider:function(n,i){var a=!_.isUndefined(i)&&Boolean(i),r=n.replace(/^\D+/g,"");t(n).carouFredSel({items:{visible:3},direction:"up",scroll:{items:1,easing:"swing",pauseOnHover:!0,onAfter:function(e){e.items.old.each((function(){t(this).removeClass("visible")})),e.items.visible.each((function(){t(this).addClass("visible")}))}},auto:{play:a,timeoutDuration:3e3},prev:{button:"#mp_prev_button"+r},next:{button:"#mp_next_button"+r}}),t(n).trigger("currentVisible",(function(t){t.addClass("visible")})),e.setColorSettings(n+" .mptt-colorized")},initDeleteButton:function(){var e=t("#events-list");e.find("li.event").find("i.operation-button.dashicons-no.dashicons").off("click").on("click",(function(){e.find("li.event").length>1?t(this).parents("li.event").remove():e.remove()}))},initColorPicker:function(e){_.isUndefined(e)&&(e="");var n=t(e+" input.clr-picker"),i=t(e+" input.regular-text");n.spectrum("destroy"),n.spectrum({preferredFormat:"rgb",showInput:!0,showAlpha:!0,allowEmpty:!0,palette:[["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]],showPalette:!0,show:function(e){t(this).val(e)},hide:function(e){t(this).parents(".select-color").find(".regular-text").val(t(this).val())},change:function(e){t(this).parents(".select-color").find('input:not([type="hidden"])').val(t(this).val())}}),i.off("keyup").on("keyup",(function(){var e=t(this).parents(".select-color"),n=e.find(".clr-picker"),i=e.find(".regular-text").val();e.find(".sp-preview-inner").css({"background-color":i}),n.spectrum("set",i)}))},addEventButton:function(){t(document).on("click.admin","#add_mp_event",(function(){t(this).hasClass("edit")?e.updateEventData():e.renderEventItem()}))},initDeleteButtons:function(){t(document).on("click.admin","#events-list .delete-event-button",(function(){var n=t(this).attr("data-id");e.deleteEvent(n)}))},initEditButtons:function(){t(document).on("click.admin","#events-list .edit-event-button",(function(){var n=t(this).attr("data-id"),i=t(this).parent().parent();t(this).parent().find(".spinner").addClass("is-active"),Registry._get("adminFunctions").wpAjax({controller:"events",action:"get_event_data",id:n},(function(n){var a=t("#add_mp_event"),r=t("#events-list");r.find(".spinner").removeClass("is-active"),r.find(" tr").removeClass("active"),i.addClass("active"),t("#event_start").val(n.event_start),t("#event_end").val(n.event_end),t("#description").val(n.description),t("#user_id").val(n.user_id),t("#weekday_id").val(n.column_id),a.addClass("edit"),a.val("Update"),e.event_id=n.id}),(function(t){console.warn(t)}))}))},deleteEvent:function(e){Registry._get("adminFunctions").wpAjax({controller:"events",action:"delete",id:e},(function(n){var i=t("#events-list").find('tr[data-id="'+e+'"]');i.length&&i.remove()}),(function(t){console.log(t)}))},updateEventItem:function(){var n=t("#events-list").find('tr[data-id="'+e.event_id+'"]'),i=t("#user_id");n.find("td.event-column").text(t("#weekday_id").find("option:selected").text()),n.find("td.event-start").text(t("#event_start").val()),n.find("td.event-end").text(t("#event_end").val()),n.find("td.event-user-id").text("-1"===i.val()?"":i.find("option:selected").text()),n.find("td.event-description").text(t("#description").val()),e.event_id=null,t("#add_mp_event").removeClass("edit").val("Add New")},updateEventData:function(){var n=t("#add_event_table").find(".spinner");n.addClass("is-active"),Registry._get("adminFunctions").wpAjax({controller:"events",action:"update_event_data",data:{id:Registry._get("Event").event_id,event_start:t("#event_start").val(),event_end:t("#event_end").val(),description:t("#description").val(),user_id:t("#user_id").val(),weekday_ids:t("#weekday_id").val()}},(function(){n.removeClass("is-active"),e.updateEventItem(),e.clearTable()}),(function(t){n.removeClass("is-active"),console.log(t)}))},renderEventItem:function(){var n=t("#weekday_id"),i=t("#user_id"),a=n.find("option:selected").val(),r=t("#event_start"),o=t("#event_end"),s=t("#description"),d={tag:"tr",attrs:{},content:[{tag:"td",attrs:{style:"display:none;"},content:[{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][weekday_ids][]",value:a}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][event_start][]",value:r.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][event_end][]",value:o.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][description][]",value:s.val()}},{tag:"input",attrs:{type:"hidden",name:"event_data["+a+"][user_id][]",value:i.val()}}]},{tag:"td",attrs:{class:"event-column"},content:[n.find("option:selected").text()]},{tag:"td",attrs:{class:"event-start"},content:[r.val()]},{tag:"td",attrs:{class:"event-end"},content:[o.val()]},{tag:"td",attrs:{class:"event-description"},content:[s.val()]},{tag:"td",attrs:{class:"event-user-id"},content:["-1"===i.val()?"":i.find("option:selected").text()]},{tag:"td",attrs:{},content:[]}]},c=Registry._get("adminFunctions").getHtml(d);t("#events-list").find("tbody").append(c),t(".events-list-wrapper").scrollTop(1e10),e.clearTable()},setEventHeight:function(e){var n=e.parent().outerHeight(),i=t("body"),a=e.height(),r=e.data("min-height"),o=e.find(".mptt-inner-event-content").height();e.css("position","").css("width","").css("min-height",""),i.hasClass("mprm_ie_browser")?(o=e.css("height","").find(".mptt-inner-event-content").height(),e.height(a),o<=r?e.css("max-height",r):(e.css("height",""),e.css("max-height",o))):o<=r?e.css("min-height",r):e.css("min-height",o),n<a&&e.height(a)},recalculate_Height:function(e,n){var i=t(".mptt-event-container",e),a=i.length,r=0,o=0,s=e.height();t("body").hasClass("mprm_ie_browser")?(r=s/(a>0?a:1),_.isUndefined(n)?t.each(i,(function(){var e=t(this);if(e.height(r),_.isEmpty(e.data("min-height"))){var n=e.height();0===n?e.data("min-height",r):e.data("min-height",n)}e.css("top",o+"px"),e.removeClass("mptt-hidden"),o+=r})):n.height(r)):(r=100/(a>0?a:1),_.isUndefined(n)?t.each(i,(function(){var e=t(this);e.height(r+"%"),_.isEmpty(e.data("min-height"))&&e.data("min-height",e.height()),e.css("top",o+"%"),e.removeClass("mptt-hidden"),o+=r})):n.height(r+"%"))},setEventsHeight:function(){var n=t(".mptt-shortcode-wrapper").find("table").find("td.event");t.each(n,(function(){var n=t(this);e.recalculate_Height(n)}))},setColorSettings:function(n){_.isUndefined(n)&&(n=".mptt-colorized");var i=t(n);t.each(i,(function(){var n=t(this),i=n.attr("data-bg_hover_color"),a=n.attr("data-hover_color"),r=n.parent();switch(n.attr("data-type")){case"column":case"event":n.hover((function(){_.isEmpty(i)||n.css("background-color",i),_.isEmpty(a)||n.css("color",a),e.setEventHeight(n)}),(function(){n.css("max-height","").css("min-height",""),e.recalculate_Height(r,n),n.css("background-color",n.attr("data-bg_color")),n.css("color",n.attr("data-color"))}));break;case"widget":n.hover((function(){n.css("background-color",n.attr("data-background-hover-color")),n.css("color",t(this).attr("data-hover-color")),n.css("border-left-color",n.attr("data-hover-border-color"))}),(function(){n.css("background-color",n.attr("data-background-color")),n.css("color",n.attr("data-color")),n.css("border-left-color",n.attr("data-border-color"))}))}}))},clearTable:function(){var e=t("#weekday_id");t("#add_event_table input:not(.button),#add_event_table textarea").val(""),e.val(e.find("option:first").attr("value"))},getRowSpan:function(e,n){for(var i=[],a=[],r=n.attr("data-column-id"),o=n.closest("tr").next("tr"),s=o.find('td[data-column-id="'+r+'"]'),d=o.length>0&&s.length>0&&s.children().length>0;!d;){if(0==o.next("tr").length){d=!0,o=!1;break}d=(s=(o=o.next("tr")).find('td[data-column-id="'+r+'"]')).children().length>0}var c=!1;o&&(c=o.data("index")),t.each(e,(function(e){var n=t(this).attr("data-start"),r=t(this).attr("data-end");a[e]=n,i[e]=r}));var l=Math.min.apply(Math,a),v=Math.max.apply(Math,i);c&&v>c&&(v=c);var f=v-l;return f<1?1:f},responsiveFilter:function(e){var n="all",i=e.parents(".mptt-shortcode-wrapper");n=e.is("select")?e.val():e.attr("href").replace("#","");var a=i.find(".mptt-list-event");"all"!==n?(a.hide(),i.find('.mptt-list-event[data-event-id="'+n+'"]').show()):a.show(),t.each(i.find(".mptt-column"),(function(){t(this).show(),t(this).find(".mptt-list-event:visible").length<1&&t(this).hide()}))},filterStatic:function(t,n){var i=t.parents(".mptt-shortcode-wrapper"),a="#all",r=_.isEmpty(i.attr("id"))?"not-set":i.attr("id");a=t.is("select")?t.val():t.attr("href").replace("#",""),0==n||void 0===n.originalEvent||(window.location.hash=r+":"+a),i.find("table").hide(),i.find('table[id="#'+a+'"]').fadeIn(),e.setEventsHeight()},setClassTd:function(){t.each(t(".mptt-event-container"),(function(){t(this).parents("td").addClass("event")}))},initTableData:function(){e.setClassTd(),e.setRowSpanTd();var n="."+MPTT.table_class;t(n).data("hide_empty_row")&&e.hideEmptyRows()},filterShortcodeEvents:function(){var n=t(".mptt-menu");n.length&&(n.off("change").on("change",(function(n){e.filterStatic(t(this),n),e.responsiveFilter(t(this))})),t(".mptt-navigation-tabs.mptt-menu a").off("click").on("click",(function(n){var i=t(this);i.parents(".mptt-navigation-tabs.mptt-menu").find("li").removeClass("active"),i.parents("li").addClass("active"),e.filterStatic(i,n),e.responsiveFilter(i)})))},showCurrentEvent:function(t,e){t.find(".mptt-menu").hasClass("mptt-navigation-tabs")?t.find(".mptt-navigation-tabs").find('a[href="#'+e+'"]').click():t.find(".mptt-menu").hasClass("mptt-navigation-select")&&t.find('.mptt-navigation-select option[value="'+e+'"]')?t.find(".mptt-navigation-select").val(e).change():t.find('table[id="#all"]').fadeIn()},getFilterByHash:function(){var n=window.location.hash;if(!_.isUndefined(n)){var i=n.split(":"),a=i[0],r=i[1],o=t(".mptt-shortcode-wrapper");r=_.isUndefined(r)?"all":r,1===o.length?e.showCurrentEvent(o,r):t.each(o,(function(n,i){var o=t(i);"#"+o.attr("id")===a?e.showCurrentEvent(o,r):e.showCurrentEvent(o,"all")}))}e.setEventsHeight()},removeCellsAfterChangeColSpan:function(t,e,n,i){for(;t<e;t++){var a=n.find('th[data-index="'+t+'"]').data("column-id");i.find('td:not(.event)[data-column-id="'+a+'"]').remove()}},removeCellsAfterChangeRowSpan:function(t,n,i,a){for(var r=t.parents("tr").attr("data-index"),o=n+parseInt(r)-1,s=t.attr("colspan"),d=i.find('th[data-column-id="'+a+'"]').data("index"),c=parseInt(d)+parseInt(s);r<o;r++){var l=i.find("tr.mptt-shortcode-row-"+(parseInt(r)+1));if(l.length){if(l.find('td.event[data-column-id="'+a+'"]').length&&(n-=o-r)<2){n=1;break}s>1&&e.removeCellsAfterChangeColSpan(d,c,i,l),l.find('td:not(.event)[data-column-id="'+a+'"]').remove()}}return n},setRowSpanTd:function(){var n="."+MPTT.table_class;t.each(t(n),(function(){var n=t(this);t.each(n.find("td.event"),(function(){var i=t(this),a=i.find(".mptt-event-container"),r=i.attr("data-column-id"),o=i.attr("data-row_height"),s=e.getRowSpan(a,i);!_.isUndefined(s)&&s>1&&(s=e.removeCellsAfterChangeRowSpan(i,s,n,r),isNaN(o)||i.css("height",s*o)),i.attr("rowspan",s)}))}))},hideEmptyRows:function(){var e="."+MPTT.table_class,n=t(e+" tbody tr"),i=t(e).first().find("th").length;t.each(n,(function(e,n){0===t(n).find("td.event").length&&t(n).find("td").length===i&&t(n).remove()}))},displaySettings:function(){var e=t(".view_settings");e.length&&e.change((function(){"all"===t(this).val()?(t(this).attr("id"),t(this).parents(".mptt-container").find(".next-days").css("display","block")):t(this).parents(".mptt-container").find(".next-days").css("display","none")}))},timeMode:function(e){if(e){var n="."+t(this).attr("id");t("#"+e).change((function(){"server"===t(this).val()?(t(this).attr("id"),t(this).parents(".mptt-container").find(n).css("display","block")):t(this).parents(".mptt-container").find(n).css("display","none")}))}},initDatePicker:function(){var e=t("#datepicker");e.length&&e.datepicker({dateFormat:"d/m/yy",setDate:Date.parse(e.val())})},columnRadioBox:function(){var e=t("#datepicker"),n=t('input.option-input[name="column[column_option]"]'),i=t("select.mp-weekday");n.length&&n.on("change",(function(){switch(t(this).val()){case"simple":i.prop("disabled",!0),e.prop("disabled",!0);break;case"weekday":i.prop("disabled",!1),e.val("").prop("disabled",!0);break;case"date":i.prop("disabled",!0),e.prop("disabled",!1)}}))}}),e}}}(jQuery))}});
media/js/lib/spectrum.js CHANGED
@@ -1,2341 +1,2341 @@
1
- // Spectrum Colorpicker v1.8.1
2
- // https://github.com/bgrins/spectrum
3
- // Author: Brian Grinstead
4
- // License: MIT
5
-
6
- (function (factory) {
7
- "use strict";
8
-
9
- if (typeof define === 'function' && define.amd) { // AMD
10
- define(['jquery'], factory);
11
- }
12
- else if (typeof exports == "object" && typeof module == "object") { // CommonJS
13
- module.exports = factory(require('jquery'));
14
- }
15
- else { // Browser
16
- factory(jQuery);
17
- }
18
- })(function($, undefined) {
19
- "use strict";
20
-
21
- var defaultOpts = {
22
-
23
- // Callbacks
24
- beforeShow: noop,
25
- move: noop,
26
- change: noop,
27
- show: noop,
28
- hide: noop,
29
-
30
- // Options
31
- color: false,
32
- flat: false,
33
- showInput: false,
34
- allowEmpty: false,
35
- showButtons: true,
36
- clickoutFiresChange: true,
37
- showInitial: false,
38
- showPalette: false,
39
- showPaletteOnly: false,
40
- hideAfterPaletteSelect: false,
41
- togglePaletteOnly: false,
42
- showSelectionPalette: true,
43
- localStorageKey: false,
44
- appendTo: "body",
45
- maxSelectionSize: 7,
46
- cancelText: "cancel",
47
- chooseText: "choose",
48
- togglePaletteMoreText: "more",
49
- togglePaletteLessText: "less",
50
- clearText: "Clear Color Selection",
51
- noColorSelectedText: "No Color Selected",
52
- preferredFormat: false,
53
- className: "", // Deprecated - use containerClassName and replacerClassName instead.
54
- containerClassName: "",
55
- replacerClassName: "",
56
- showAlpha: false,
57
- theme: "sp-light",
58
- palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
59
- selectionPalette: [],
60
- disabled: false,
61
- offset: null
62
- },
63
- spectrums = [],
64
- IE = !!/msie/i.exec( window.navigator.userAgent ),
65
- rgbaSupport = (function() {
66
- function contains( str, substr ) {
67
- return !!~('' + str).indexOf(substr);
68
- }
69
-
70
- var elem = document.createElement('div');
71
- var style = elem.style;
72
- style.cssText = 'background-color:rgba(0,0,0,.5)';
73
- return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
74
- })(),
75
- replaceInput = [
76
- "<div class='sp-replacer'>",
77
- "<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
78
- "<div class='sp-dd'>&#9660;</div>",
79
- "</div>"
80
- ].join(''),
81
- markup = (function () {
82
-
83
- // IE does not support gradients with multiple stops, so we need to simulate
84
- // that for the rainbow slider with 8 divs that each have a single gradient
85
- var gradientFix = "";
86
- if (IE) {
87
- for (var i = 1; i <= 6; i++) {
88
- gradientFix += "<div class='sp-" + i + "'></div>";
89
- }
90
- }
91
-
92
- return [
93
- "<div class='sp-container sp-hidden'>",
94
- "<div class='sp-palette-container'>",
95
- "<div class='sp-palette sp-thumb sp-cf'></div>",
96
- "<div class='sp-palette-button-container sp-cf'>",
97
- "<button type='button' class='sp-palette-toggle'></button>",
98
- "</div>",
99
- "</div>",
100
- "<div class='sp-picker-container'>",
101
- "<div class='sp-top sp-cf'>",
102
- "<div class='sp-fill'></div>",
103
- "<div class='sp-top-inner'>",
104
- "<div class='sp-color'>",
105
- "<div class='sp-sat'>",
106
- "<div class='sp-val'>",
107
- "<div class='sp-dragger'></div>",
108
- "</div>",
109
- "</div>",
110
- "</div>",
111
- "<div class='sp-clear sp-clear-display'>",
112
- "</div>",
113
- "<div class='sp-hue'>",
114
- "<div class='sp-slider'></div>",
115
- gradientFix,
116
- "</div>",
117
- "</div>",
118
- "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
119
- "</div>",
120
- "<div class='sp-input-container sp-cf'>",
121
- "<input class='sp-input' type='text' spellcheck='false' />",
122
- "</div>",
123
- "<div class='sp-initial sp-thumb sp-cf'></div>",
124
- "<div class='sp-button-container sp-cf'>",
125
- "<a class='sp-cancel' href='#'></a>",
126
- "<button type='button' class='sp-choose'></button>",
127
- "</div>",
128
- "</div>",
129
- "</div>"
130
- ].join("");
131
- })();
132
-
133
- function paletteTemplate (p, color, className, opts) {
134
- var html = [];
135
- for (var i = 0; i < p.length; i++) {
136
- var current = p[i];
137
- if(current) {
138
- var tiny = tinycolor(current);
139
- var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
140
- c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
141
- var formattedString = tiny.toString(opts.preferredFormat || "rgb");
142
- var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
143
- html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';"></span></span>');
144
- } else {
145
- var cls = 'sp-clear-display';
146
- html.push($('<div />')
147
- .append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
148
- .attr('title', opts.noColorSelectedText)
149
- )
150
- .html()
151
- );
152
- }
153
- }
154
- return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
155
- }
156
-
157
- function hideAll() {
158
- for (var i = 0; i < spectrums.length; i++) {
159
- if (spectrums[i]) {
160
- spectrums[i].hide();
161
- }
162
- }
163
- }
164
-
165
- function instanceOptions(o, callbackContext) {
166
- var opts = $.extend({}, defaultOpts, o);
167
- opts.callbacks = {
168
- 'move': bind(opts.move, callbackContext),
169
- 'change': bind(opts.change, callbackContext),
170
- 'show': bind(opts.show, callbackContext),
171
- 'hide': bind(opts.hide, callbackContext),
172
- 'beforeShow': bind(opts.beforeShow, callbackContext)
173
- };
174
-
175
- return opts;
176
- }
177
-
178
- function spectrum(element, o) {
179
-
180
- var opts = instanceOptions(o, element),
181
- flat = opts.flat,
182
- showSelectionPalette = opts.showSelectionPalette,
183
- localStorageKey = opts.localStorageKey,
184
- theme = opts.theme,
185
- callbacks = opts.callbacks,
186
- resize = throttle(reflow, 10),
187
- visible = false,
188
- isDragging = false,
189
- dragWidth = 0,
190
- dragHeight = 0,
191
- dragHelperHeight = 0,
192
- slideHeight = 0,
193
- slideWidth = 0,
194
- alphaWidth = 0,
195
- alphaSlideHelperWidth = 0,
196
- slideHelperHeight = 0,
197
- currentHue = 0,
198
- currentSaturation = 0,
199
- currentValue = 0,
200
- currentAlpha = 1,
201
- palette = [],
202
- paletteArray = [],
203
- paletteLookup = {},
204
- selectionPalette = opts.selectionPalette.slice(0),
205
- maxSelectionSize = opts.maxSelectionSize,
206
- draggingClass = "sp-dragging",
207
- shiftMovementDirection = null;
208
-
209
- var doc = element.ownerDocument,
210
- body = doc.body,
211
- boundElement = $(element),
212
- disabled = false,
213
- container = $(markup, doc).addClass(theme),
214
- pickerContainer = container.find(".sp-picker-container"),
215
- dragger = container.find(".sp-color"),
216
- dragHelper = container.find(".sp-dragger"),
217
- slider = container.find(".sp-hue"),
218
- slideHelper = container.find(".sp-slider"),
219
- alphaSliderInner = container.find(".sp-alpha-inner"),
220
- alphaSlider = container.find(".sp-alpha"),
221
- alphaSlideHelper = container.find(".sp-alpha-handle"),
222
- textInput = container.find(".sp-input"),
223
- paletteContainer = container.find(".sp-palette"),
224
- initialColorContainer = container.find(".sp-initial"),
225
- cancelButton = container.find(".sp-cancel"),
226
- clearButton = container.find(".sp-clear"),
227
- chooseButton = container.find(".sp-choose"),
228
- toggleButton = container.find(".sp-palette-toggle"),
229
- isInput = boundElement.is("input"),
230
- isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(),
231
- shouldReplace = isInput && !flat,
232
- replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
233
- offsetElement = (shouldReplace) ? replacer : boundElement,
234
- previewElement = replacer.find(".sp-preview-inner"),
235
- initialColor = opts.color || (isInput && boundElement.val()),
236
- colorOnShow = false,
237
- currentPreferredFormat = opts.preferredFormat,
238
- clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
239
- isEmpty = !initialColor,
240
- allowEmpty = opts.allowEmpty && !isInputTypeColor;
241
-
242
- function applyOptions() {
243
-
244
- if (opts.showPaletteOnly) {
245
- opts.showPalette = true;
246
- }
247
-
248
- toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
249
-
250
- if (opts.palette) {
251
- palette = opts.palette.slice(0);
252
- paletteArray = $.isArray(palette[0]) ? palette : [palette];
253
- paletteLookup = {};
254
- for (var i = 0; i < paletteArray.length; i++) {
255
- for (var j = 0; j < paletteArray[i].length; j++) {
256
- var rgb = tinycolor(paletteArray[i][j]).toRgbString();
257
- paletteLookup[rgb] = true;
258
- }
259
- }
260
- }
261
-
262
- container.toggleClass("sp-flat", flat);
263
- container.toggleClass("sp-input-disabled", !opts.showInput);
264
- container.toggleClass("sp-alpha-enabled", opts.showAlpha);
265
- container.toggleClass("sp-clear-enabled", allowEmpty);
266
- container.toggleClass("sp-buttons-disabled", !opts.showButtons);
267
- container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
268
- container.toggleClass("sp-palette-disabled", !opts.showPalette);
269
- container.toggleClass("sp-palette-only", opts.showPaletteOnly);
270
- container.toggleClass("sp-initial-disabled", !opts.showInitial);
271
- container.addClass(opts.className).addClass(opts.containerClassName);
272
-
273
- reflow();
274
- }
275
-
276
- function initialize() {
277
-
278
- if (IE) {
279
- container.find("*:not(input)").attr("unselectable", "on");
280
- }
281
-
282
- applyOptions();
283
-
284
- if (shouldReplace) {
285
- boundElement.after(replacer).hide();
286
- }
287
-
288
- if (!allowEmpty) {
289
- clearButton.hide();
290
- }
291
-
292
- if (flat) {
293
- boundElement.after(container).hide();
294
- }
295
- else {
296
-
297
- var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
298
- if (appendTo.length !== 1) {
299
- appendTo = $("body");
300
- }
301
-
302
- appendTo.append(container);
303
- }
304
-
305
- updateSelectionPaletteFromStorage();
306
-
307
- offsetElement.on("click.spectrum touchstart.spectrum", function (e) {
308
- if (!disabled) {
309
- toggle();
310
- }
311
-
312
- e.stopPropagation();
313
-
314
- if (!$(e.target).is("input")) {
315
- e.preventDefault();
316
- }
317
- });
318
-
319
- if(boundElement.is(":disabled") || (opts.disabled === true)) {
320
- disable();
321
- }
322
-
323
- // Prevent clicks from bubbling up to document. This would cause it to be hidden.
324
- container.click(stopPropagation);
325
-
326
- // Handle user typed input
327
- textInput.change(setFromTextInput);
328
- textInput.on("paste", function () {
329
- setTimeout(setFromTextInput, 1);
330
- });
331
- textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
332
-
333
- cancelButton.text(opts.cancelText);
334
- cancelButton.on("click.spectrum", function (e) {
335
- e.stopPropagation();
336
- e.preventDefault();
337
- revert();
338
- hide();
339
- });
340
-
341
- clearButton.attr("title", opts.clearText);
342
- clearButton.on("click.spectrum", function (e) {
343
- e.stopPropagation();
344
- e.preventDefault();
345
- isEmpty = true;
346
- move();
347
-
348
- if(flat) {
349
- //for the flat style, this is a change event
350
- updateOriginalInput(true);
351
- }
352
- });
353
-
354
- chooseButton.text(opts.chooseText);
355
- chooseButton.on("click.spectrum", function (e) {
356
- e.stopPropagation();
357
- e.preventDefault();
358
-
359
- if (IE && textInput.is(":focus")) {
360
- textInput.trigger('change');
361
- }
362
-
363
- if (isValid()) {
364
- updateOriginalInput(true);
365
- hide();
366
- }
367
- });
368
-
369
- toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
370
- toggleButton.on("click.spectrum", function (e) {
371
- e.stopPropagation();
372
- e.preventDefault();
373
-
374
- opts.showPaletteOnly = !opts.showPaletteOnly;
375
-
376
- // To make sure the Picker area is drawn on the right, next to the
377
- // Palette area (and not below the palette), first move the Palette
378
- // to the left to make space for the picker, plus 5px extra.
379
- // The 'applyOptions' function puts the whole container back into place
380
- // and takes care of the button-text and the sp-palette-only CSS class.
381
- if (!opts.showPaletteOnly && !flat) {
382
- container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));
383
- }
384
- applyOptions();
385
- });
386
-
387
- draggable(alphaSlider, function (dragX, dragY, e) {
388
- currentAlpha = (dragX / alphaWidth);
389
- isEmpty = false;
390
- if (e.shiftKey) {
391
- currentAlpha = Math.round(currentAlpha * 10) / 10;
392
- }
393
-
394
- move();
395
- }, dragStart, dragStop);
396
-
397
- draggable(slider, function (dragX, dragY) {
398
- currentHue = parseFloat(dragY / slideHeight);
399
- isEmpty = false;
400
- if (!opts.showAlpha) {
401
- currentAlpha = 1;
402
- }
403
- move();
404
- }, dragStart, dragStop);
405
-
406
- draggable(dragger, function (dragX, dragY, e) {
407
-
408
- // shift+drag should snap the movement to either the x or y axis.
409
- if (!e.shiftKey) {
410
- shiftMovementDirection = null;
411
- }
412
- else if (!shiftMovementDirection) {
413
- var oldDragX = currentSaturation * dragWidth;
414
- var oldDragY = dragHeight - (currentValue * dragHeight);
415
- var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
416
-
417
- shiftMovementDirection = furtherFromX ? "x" : "y";
418
- }
419
-
420
- var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
421
- var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
422
-
423
- if (setSaturation) {
424
- currentSaturation = parseFloat(dragX / dragWidth);
425
- }
426
- if (setValue) {
427
- currentValue = parseFloat((dragHeight - dragY) / dragHeight);
428
- }
429
-
430
- isEmpty = false;
431
- if (!opts.showAlpha) {
432
- currentAlpha = 1;
433
- }
434
-
435
- move();
436
-
437
- }, dragStart, dragStop);
438
-
439
- if (!!initialColor) {
440
- set(initialColor);
441
-
442
- // In case color was black - update the preview UI and set the format
443
- // since the set function will not run (default color is black).
444
- updateUI();
445
- currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;
446
-
447
- addColorToSelectionPalette(initialColor);
448
- }
449
- else {
450
- updateUI();
451
- }
452
-
453
- if (flat) {
454
- show();
455
- }
456
-
457
- function paletteElementClick(e) {
458
- if (e.data && e.data.ignore) {
459
- set($(e.target).closest(".sp-thumb-el").data("color"));
460
- move();
461
- }
462
- else {
463
- set($(e.target).closest(".sp-thumb-el").data("color"));
464
- move();
465
-
466
- // If the picker is going to close immediately, a palette selection
467
- // is a change. Otherwise, it's a move only.
468
- if (opts.hideAfterPaletteSelect) {
469
- updateOriginalInput(true);
470
- hide();
471
- } else {
472
- updateOriginalInput();
473
- }
474
- }
475
-
476
- return false;
477
- }
478
-
479
- var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
480
- paletteContainer.on(paletteEvent, ".sp-thumb-el", paletteElementClick);
481
- initialColorContainer.on(paletteEvent, ".sp-thumb-el:nth-child(1)", { ignore: true }, paletteElementClick);
482
- }
483
-
484
- function updateSelectionPaletteFromStorage() {
485
-
486
- if (localStorageKey && window.localStorage) {
487
-
488
- // Migrate old palettes over to new format. May want to remove this eventually.
489
- try {
490
- var oldPalette = window.localStorage[localStorageKey].split(",#");
491
- if (oldPalette.length > 1) {
492
- delete window.localStorage[localStorageKey];
493
- $.each(oldPalette, function(i, c) {
494
- addColorToSelectionPalette(c);
495
- });
496
- }
497
- }
498
- catch(e) { }
499
-
500
- try {
501
- selectionPalette = window.localStorage[localStorageKey].split(";");
502
- }
503
- catch (e) { }
504
- }
505
- }
506
-
507
- function addColorToSelectionPalette(color) {
508
- if (showSelectionPalette) {
509
- var rgb = tinycolor(color).toRgbString();
510
- if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
511
- selectionPalette.push(rgb);
512
- while(selectionPalette.length > maxSelectionSize) {
513
- selectionPalette.shift();
514
- }
515
- }
516
-
517
- if (localStorageKey && window.localStorage) {
518
- try {
519
- window.localStorage[localStorageKey] = selectionPalette.join(";");
520
- }
521
- catch(e) { }
522
- }
523
- }
524
- }
525
-
526
- function getUniqueSelectionPalette() {
527
- var unique = [];
528
- if (opts.showPalette) {
529
- for (var i = 0; i < selectionPalette.length; i++) {
530
- var rgb = tinycolor(selectionPalette[i]).toRgbString();
531
-
532
- if (!paletteLookup[rgb]) {
533
- unique.push(selectionPalette[i]);
534
- }
535
- }
536
- }
537
-
538
- return unique.reverse().slice(0, opts.maxSelectionSize);
539
- }
540
-
541
- function drawPalette() {
542
-
543
- var currentColor = get();
544
-
545
- var html = $.map(paletteArray, function (palette, i) {
546
- return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
547
- });
548
-
549
- updateSelectionPaletteFromStorage();
550
-
551
- if (selectionPalette) {
552
- html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
553
- }
554
-
555
- paletteContainer.html(html.join(""));
556
- }
557
-
558
- function drawInitial() {
559
- if (opts.showInitial) {
560
- var initial = colorOnShow;
561
- var current = get();
562
- initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
563
- }
564
- }
565
-
566
- function dragStart() {
567
- if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
568
- reflow();
569
- }
570
- isDragging = true;
571
- container.addClass(draggingClass);
572
- shiftMovementDirection = null;
573
- boundElement.trigger('dragstart.spectrum', [ get() ]);
574
- }
575
-
576
- function dragStop() {
577
- isDragging = false;
578
- container.removeClass(draggingClass);
579
- boundElement.trigger('dragstop.spectrum', [ get() ]);
580
- }
581
-
582
- function setFromTextInput() {
583
-
584
- var value = textInput.val();
585
-
586
- if ((value === null || value === "") && allowEmpty) {
587
- set(null);
588
- move();
589
- updateOriginalInput();
590
- }
591
- else {
592
- var tiny = tinycolor(value);
593
- if (tiny.isValid()) {
594
- set(tiny);
595
- move();
596
- updateOriginalInput();
597
- }
598
- else {
599
- textInput.addClass("sp-validation-error");
600
- }
601
- }
602
- }
603
-
604
- function toggle() {
605
- if (visible) {
606
- hide();
607
- }
608
- else {
609
- show();
610
- }
611
- }
612
-
613
- function show() {
614
- var event = $.Event('beforeShow.spectrum');
615
-
616
- if (visible) {
617
- reflow();
618
- return;
619
- }
620
-
621
- boundElement.trigger(event, [ get() ]);
622
-
623
- if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
624
- return;
625
- }
626
-
627
- hideAll();
628
- visible = true;
629
-
630
- $(doc).on("keydown.spectrum", onkeydown);
631
- $(doc).on("click.spectrum", clickout);
632
- $(window).on("resize.spectrum", resize);
633
- replacer.addClass("sp-active");
634
- container.removeClass("sp-hidden");
635
-
636
- reflow();
637
- updateUI();
638
-
639
- colorOnShow = get();
640
-
641
- drawInitial();
642
- callbacks.show(colorOnShow);
643
- boundElement.trigger('show.spectrum', [ colorOnShow ]);
644
- }
645
-
646
- function onkeydown(e) {
647
- // Close on ESC
648
- if (e.keyCode === 27) {
649
- hide();
650
- }
651
- }
652
-
653
- function clickout(e) {
654
- // Return on right click.
655
- if (e.button == 2) { return; }
656
-
657
- // If a drag event was happening during the mouseup, don't hide
658
- // on click.
659
- if (isDragging) { return; }
660
-
661
- if (clickoutFiresChange) {
662
- updateOriginalInput(true);
663
- }
664
- else {
665
- revert();
666
- }
667
- hide();
668
- }
669
-
670
- function hide() {
671
- // Return if hiding is unnecessary
672
- if (!visible || flat) { return; }
673
- visible = false;
674
-
675
- $(doc).off("keydown.spectrum", onkeydown);
676
- $(doc).off("click.spectrum", clickout);
677
- $(window).off("resize.spectrum", resize);
678
-
679
- replacer.removeClass("sp-active");
680
- container.addClass("sp-hidden");
681
-
682
- callbacks.hide(get());
683
- boundElement.trigger('hide.spectrum', [ get() ]);
684
- }
685
-
686
- function revert() {
687
- set(colorOnShow, true);
688
- updateOriginalInput(true);
689
- }
690
-
691
- function set(color, ignoreFormatChange) {
692
- if (tinycolor.equals(color, get())) {
693
- // Update UI just in case a validation error needs
694
- // to be cleared.
695
- updateUI();
696
- return;
697
- }
698
-
699
- var newColor, newHsv;
700
- if (!color && allowEmpty) {
701
- isEmpty = true;
702
- } else {
703
- isEmpty = false;
704
- newColor = tinycolor(color);
705
- newHsv = newColor.toHsv();
706
-
707
- currentHue = (newHsv.h % 360) / 360;
708
- currentSaturation = newHsv.s;
709
- currentValue = newHsv.v;
710
- currentAlpha = newHsv.a;
711
- }
712
- updateUI();
713
-
714
- if (newColor && newColor.isValid() && !ignoreFormatChange) {
715
- currentPreferredFormat = opts.preferredFormat || newColor.getFormat();
716
- }
717
- }
718
-
719
- function get(opts) {
720
- opts = opts || { };
721
-
722
- if (allowEmpty && isEmpty) {
723
- return null;
724
- }
725
-
726
- return tinycolor.fromRatio({
727
- h: currentHue,
728
- s: currentSaturation,
729
- v: currentValue,
730
- a: Math.round(currentAlpha * 1000) / 1000
731
- }, { format: opts.format || currentPreferredFormat });
732
- }
733
-
734
- function isValid() {
735
- return !textInput.hasClass("sp-validation-error");
736
- }
737
-
738
- function move() {
739
- updateUI();
740
-
741
- callbacks.move(get());
742
- boundElement.trigger('move.spectrum', [ get() ]);
743
- }
744
-
745
- function updateUI() {
746
-
747
- textInput.removeClass("sp-validation-error");
748
-
749
- updateHelperLocations();
750
-
751
- // Update dragger background color (gradients take care of saturation and value).
752
- var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
753
- dragger.css("background-color", flatColor.toHexString());
754
-
755
- // Get a format that alpha will be included in (hex and names ignore alpha)
756
- var format = currentPreferredFormat;
757
- if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
758
- if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
759
- format = "rgb";
760
- }
761
- }
762
-
763
- var realColor = get({ format: format }),
764
- displayColor = '';
765
-
766
- //reset background info for preview element
767
- previewElement.removeClass("sp-clear-display");
768
- previewElement.css('background-color', 'transparent');
769
-
770
- if (!realColor && allowEmpty) {
771
- // Update the replaced elements background with icon indicating no color selection
772
- previewElement.addClass("sp-clear-display");
773
- }
774
- else {
775
- var realHex = realColor.toHexString(),
776
- realRgb = realColor.toRgbString();
777
-
778
- // Update the replaced elements background color (with actual selected color)
779
- if (rgbaSupport || realColor.alpha === 1) {
780
- previewElement.css("background-color", realRgb);
781
- }
782
- else {
783
- previewElement.css("background-color", "transparent");
784
- previewElement.css("filter", realColor.toFilter());
785
- }
786
-
787
- if (opts.showAlpha) {
788
- var rgb = realColor.toRgb();
789
- rgb.a = 0;
790
- var realAlpha = tinycolor(rgb).toRgbString();
791
- var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
792
-
793
- if (IE) {
794
- alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
795
- }
796
- else {
797
- alphaSliderInner.css("background", "-webkit-" + gradient);
798
- alphaSliderInner.css("background", "-moz-" + gradient);
799
- alphaSliderInner.css("background", "-ms-" + gradient);
800
- // Use current syntax gradient on unprefixed property.
801
- alphaSliderInner.css("background",
802
- "linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
803
- }
804
- }
805
-
806
- displayColor = realColor.toString(format);
807
- }
808
-
809
- // Update the text entry input as it changes happen
810
- if (opts.showInput) {
811
- textInput.val(displayColor);
812
- }
813
-
814
- if (opts.showPalette) {
815
- drawPalette();
816
- }
817
-
818
- drawInitial();
819
- }
820
-
821
- function updateHelperLocations() {
822
- var s = currentSaturation;
823
- var v = currentValue;
824
-
825
- if(allowEmpty && isEmpty) {
826
- //if selected color is empty, hide the helpers
827
- alphaSlideHelper.hide();
828
- slideHelper.hide();
829
- dragHelper.hide();
830
- }
831
- else {
832
- //make sure helpers are visible
833
- alphaSlideHelper.show();
834
- slideHelper.show();
835
- dragHelper.show();
836
-
837
- // Where to show the little circle in that displays your current selected color
838
- var dragX = s * dragWidth;
839
- var dragY = dragHeight - (v * dragHeight);
840
- dragX = Math.max(
841
- -dragHelperHeight,
842
- Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
843
- );
844
- dragY = Math.max(
845
- -dragHelperHeight,
846
- Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
847
- );
848
- dragHelper.css({
849
- "top": dragY + "px",
850
- "left": dragX + "px"
851
- });
852
-
853
- var alphaX = currentAlpha * alphaWidth;
854
- alphaSlideHelper.css({
855
- "left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
856
- });
857
-
858
- // Where to show the bar that displays your current selected hue
859
- var slideY = (currentHue) * slideHeight;
860
- slideHelper.css({
861
- "top": (slideY - slideHelperHeight) + "px"
862
- });
863
- }
864
- }
865
-
866
- function updateOriginalInput(fireCallback) {
867
- var color = get(),
868
- displayColor = '',
869
- hasChanged = !tinycolor.equals(color, colorOnShow);
870
-
871
- if (color) {
872
- displayColor = color.toString(currentPreferredFormat);
873
- // Update the selection palette with the current color
874
- addColorToSelectionPalette(color);
875
- }
876
-
877
- if (isInput) {
878
- boundElement.val(displayColor);
879
- }
880
-
881
- if (fireCallback && hasChanged) {
882
- callbacks.change(color);
883
- boundElement.trigger('change', [ color ]);
884
- }
885
- }
886
-
887
- function reflow() {
888
- if (!visible) {
889
- return; // Calculations would be useless and wouldn't be reliable anyways
890
- }
891
- dragWidth = dragger.width();
892
- dragHeight = dragger.height();
893
- dragHelperHeight = dragHelper.height();
894
- slideWidth = slider.width();
895
- slideHeight = slider.height();
896
- slideHelperHeight = slideHelper.height();
897
- alphaWidth = alphaSlider.width();
898
- alphaSlideHelperWidth = alphaSlideHelper.width();
899
-
900
- if (!flat) {
901
- container.css("position", "absolute");
902
- if (opts.offset) {
903
- container.offset(opts.offset);
904
- } else {
905
- container.offset(getOffset(container, offsetElement));
906
- }
907
- }
908
-
909
- updateHelperLocations();
910
-
911
- if (opts.showPalette) {
912
- drawPalette();
913
- }
914
-
915
- boundElement.trigger('reflow.spectrum');
916
- }
917
-
918
- function destroy() {
919
- boundElement.show();
920
- offsetElement.off("click.spectrum touchstart.spectrum");
921
- container.remove();
922
- replacer.remove();
923
- spectrums[spect.id] = null;
924
- }
925
-
926
- function option(optionName, optionValue) {
927
- if (optionName === undefined) {
928
- return $.extend({}, opts);
929
- }
930
- if (optionValue === undefined) {
931
- return opts[optionName];
932
- }
933
-
934
- opts[optionName] = optionValue;
935
-
936
- if (optionName === "preferredFormat") {
937
- currentPreferredFormat = opts.preferredFormat;
938
- }
939
- applyOptions();
940
- }
941
-
942
- function enable() {
943
- disabled = false;
944
- boundElement.attr("disabled", false);
945
- offsetElement.removeClass("sp-disabled");
946
- }
947
-
948
- function disable() {
949
- hide();
950
- disabled = true;
951
- boundElement.attr("disabled", true);
952
- offsetElement.addClass("sp-disabled");
953
- }
954
-
955
- function setOffset(coord) {
956
- opts.offset = coord;
957
- reflow();
958
- }
959
-
960
- initialize();
961
-
962
- var spect = {
963
- show: show,
964
- hide: hide,
965
- toggle: toggle,
966
- reflow: reflow,
967
- option: option,
968
- enable: enable,
969
- disable: disable,
970
- offset: setOffset,
971
- set: function (c) {
972
- set(c);
973
- updateOriginalInput();
974
- },
975
- get: get,
976
- destroy: destroy,
977
- container: container
978
- };
979
-
980
- spect.id = spectrums.push(spect) - 1;
981
-
982
- return spect;
983
- }
984
-
985
- /**
986
- * checkOffset - get the offset below/above and left/right element depending on screen position
987
- * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
988
- */
989
- function getOffset(picker, input) {
990
- var extraY = 0;
991
- var dpWidth = picker.outerWidth();
992
- var dpHeight = picker.outerHeight();
993
- var inputHeight = input.outerHeight();
994
- var doc = picker[0].ownerDocument;
995
- var docElem = doc.documentElement;
996
- var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
997
- var viewHeight = docElem.clientHeight + $(doc).scrollTop();
998
- var offset = input.offset();
999
- var offsetLeft = offset.left;
1000
- var offsetTop = offset.top;
1001
-
1002
- offsetTop += inputHeight;
1003
-
1004
- offsetLeft -=
1005
- Math.min(offsetLeft, (offsetLeft + dpWidth > viewWidth && viewWidth > dpWidth) ?
1006
- Math.abs(offsetLeft + dpWidth - viewWidth) : 0);
1007
-
1008
- offsetTop -=
1009
- Math.min(offsetTop, ((offsetTop + dpHeight > viewHeight && viewHeight > dpHeight) ?
1010
- Math.abs(dpHeight + inputHeight - extraY) : extraY));
1011
-
1012
- return {
1013
- top: offsetTop,
1014
- bottom: offset.bottom,
1015
- left: offsetLeft,
1016
- right: offset.right,
1017
- width: offset.width,
1018
- height: offset.height
1019
- };
1020
- }
1021
-
1022
- /**
1023
- * noop - do nothing
1024
- */
1025
- function noop() {
1026
-
1027
- }
1028
-
1029
- /**
1030
- * stopPropagation - makes the code only doing this a little easier to read in line
1031
- */
1032
- function stopPropagation(e) {
1033
- e.stopPropagation();
1034
- }
1035
-
1036
- /**
1037
- * Create a function bound to a given object
1038
- * Thanks to underscore.js
1039
- */
1040
- function bind(func, obj) {
1041
- var slice = Array.prototype.slice;
1042
- var args = slice.call(arguments, 2);
1043
- return function () {
1044
- return func.apply(obj, args.concat(slice.call(arguments)));
1045
- };
1046
- }
1047
-
1048
- /**
1049
- * Lightweight drag helper. Handles containment within the element, so that
1050
- * when dragging, the x is within [0,element.width] and y is within [0,element.height]
1051
- */
1052
- function draggable(element, onmove, onstart, onstop) {
1053
- onmove = onmove || function () { };
1054
- onstart = onstart || function () { };
1055
- onstop = onstop || function () { };
1056
- var doc = document;
1057
- var dragging = false;
1058
- var offset = {};
1059
- var maxHeight = 0;
1060
- var maxWidth = 0;
1061
- var hasTouch = ('ontouchstart' in window);
1062
-
1063
- var duringDragEvents = {};
1064
- duringDragEvents["selectstart"] = prevent;
1065
- duringDragEvents["dragstart"] = prevent;
1066
- duringDragEvents["touchmove mousemove"] = move;
1067
- duringDragEvents["touchend mouseup"] = stop;
1068
-
1069
- function prevent(e) {
1070
- if (e.stopPropagation) {
1071
- e.stopPropagation();
1072
- }
1073
- if (e.preventDefault) {
1074
- e.preventDefault();
1075
- }
1076
- e.returnValue = false;
1077
- }
1078
-
1079
- function move(e) {
1080
- if (dragging) {
1081
- // Mouseup happened outside of window
1082
- if (IE && doc.documentMode < 9 && !e.button) {
1083
- return stop();
1084
- }
1085
-
1086
- var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
1087
- var pageX = t0 && t0.pageX || e.pageX;
1088
- var pageY = t0 && t0.pageY || e.pageY;
1089
-
1090
- var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
1091
- var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
1092
-
1093
- if (hasTouch) {
1094
- // Stop scrolling in iOS
1095
- prevent(e);
1096
- }
1097
-
1098
- onmove.apply(element, [dragX, dragY, e]);
1099
- }
1100
- }
1101
-
1102
- function start(e) {
1103
- var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
1104
-
1105
- if (!rightclick && !dragging) {
1106
- if (onstart.apply(element, arguments) !== false) {
1107
- dragging = true;
1108
- maxHeight = $(element).height();
1109
- maxWidth = $(element).width();
1110
- offset = $(element).offset();
1111
-
1112
- $(doc).on(duringDragEvents);
1113
- $(doc.body).addClass("sp-dragging");
1114
-
1115
- move(e);
1116
-
1117
- prevent(e);
1118
- }
1119
- }
1120
- }
1121
-
1122
- function stop() {
1123
- if (dragging) {
1124
- $(doc).off(duringDragEvents);
1125
- $(doc.body).removeClass("sp-dragging");
1126
-
1127
- // Wait a tick before notifying observers to allow the click event
1128
- // to fire in Chrome.
1129
- setTimeout(function() {
1130
- onstop.apply(element, arguments);
1131
- }, 0);
1132
- }
1133
- dragging = false;
1134
- }
1135
-
1136
- $(element).on("touchstart mousedown", start);
1137
- }
1138
-
1139
- function throttle(func, wait, debounce) {
1140
- var timeout;
1141
- return function () {
1142
- var context = this, args = arguments;
1143
- var throttler = function () {
1144
- timeout = null;
1145
- func.apply(context, args);
1146
- };
1147
- if (debounce) clearTimeout(timeout);
1148
- if (debounce || !timeout) timeout = setTimeout(throttler, wait);
1149
- };
1150
- }
1151
-
1152
- function inputTypeColorSupport() {
1153
- return $.fn.spectrum.inputTypeColorSupport();
1154
- }
1155
-
1156
- /**
1157
- * Define a jQuery plugin
1158
- */
1159
- var dataID = "spectrum.id";
1160
- $.fn.spectrum = function (opts, extra) {
1161
-
1162
- if (typeof opts == "string") {
1163
-
1164
- var returnValue = this;
1165
- var args = Array.prototype.slice.call( arguments, 1 );
1166
-
1167
- this.each(function () {
1168
- var spect = spectrums[$(this).data(dataID)];
1169
- if (spect) {
1170
- var method = spect[opts];
1171
- if (!method) {
1172
- throw new Error( "Spectrum: no such method: '" + opts + "'" );
1173
- }
1174
-
1175
- if (opts == "get") {
1176
- returnValue = spect.get();
1177
- }
1178
- else if (opts == "container") {
1179
- returnValue = spect.container;
1180
- }
1181
- else if (opts == "option") {
1182
- returnValue = spect.option.apply(spect, args);
1183
- }
1184
- else if (opts == "destroy") {
1185
- spect.destroy();
1186
- $(this).removeData(dataID);
1187
- }
1188
- else {
1189
- method.apply(spect, args);
1190
- }
1191
- }
1192
- });
1193
-
1194
- return returnValue;
1195
- }
1196
-
1197
- // Initializing a new instance of spectrum
1198
- return this.spectrum("destroy").each(function () {
1199
- var options = $.extend({}, $(this).data(), opts);
1200
- var spect = spectrum(this, options);
1201
- $(this).data(dataID, spect.id);
1202
- });
1203
- };
1204
-
1205
- $.fn.spectrum.load = true;
1206
- $.fn.spectrum.loadOpts = {};
1207
- $.fn.spectrum.draggable = draggable;
1208
- $.fn.spectrum.defaults = defaultOpts;
1209
- $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
1210
- if (typeof inputTypeColorSupport._cachedResult === "undefined") {
1211
- var colorInput = $("<input type='color'/>")[0]; // if color element is supported, value will default to not null
1212
- inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== "";
1213
- }
1214
- return inputTypeColorSupport._cachedResult;
1215
- };
1216
-
1217
- $.spectrum = { };
1218
- $.spectrum.localization = { };
1219
- $.spectrum.palettes = { };
1220
-
1221
- $.fn.spectrum.processNativeColorInputs = function () {
1222
- var colorInputs = $("input[type=color]");
1223
- if (colorInputs.length && !inputTypeColorSupport()) {
1224
- colorInputs.spectrum({
1225
- preferredFormat: "hex6"
1226
- });
1227
- }
1228
- };
1229
-
1230
- // TinyColor v1.1.2
1231
- // https://github.com/bgrins/TinyColor
1232
- // Brian Grinstead, MIT License
1233
-
1234
- (function() {
1235
-
1236
- var trimLeft = /^[\s,#]+/,
1237
- trimRight = /\s+$/,
1238
- tinyCounter = 0,
1239
- math = Math,
1240
- mathRound = math.round,
1241
- mathMin = math.min,
1242
- mathMax = math.max,
1243
- mathRandom = math.random;
1244
-
1245
- var tinycolor = function(color, opts) {
1246
-
1247
- color = (color) ? color : '';
1248
- opts = opts || { };
1249
-
1250
- // If input is already a tinycolor, return itself
1251
- if (color instanceof tinycolor) {
1252
- return color;
1253
- }
1254
- // If we are called as a function, call using new instead
1255
- if (!(this instanceof tinycolor)) {
1256
- return new tinycolor(color, opts);
1257
- }
1258
-
1259
- var rgb = inputToRGB(color);
1260
- this._originalInput = color;
1261
- this._r = rgb.r;
1262
- this._g = rgb.g;
1263
- this._b = rgb.b;
1264
- this._a = rgb.a;
1265
- this._roundA = mathRound(1000 * this._a) / 1000;
1266
- this._format = opts.format || rgb.format;
1267
- this._gradientType = opts.gradientType;
1268
-
1269
- // Don't let the range of [0,255] come back in [0,1].
1270
- // Potentially lose a little bit of precision here, but will fix issues where
1271
- // .5 gets interpreted as half of the total, instead of half of 1
1272
- // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1273
- if (this._r < 1) { this._r = mathRound(this._r); }
1274
- if (this._g < 1) { this._g = mathRound(this._g); }
1275
- if (this._b < 1) { this._b = mathRound(this._b); }
1276
-
1277
- this._ok = rgb.ok;
1278
- this._tc_id = tinyCounter++;
1279
- };
1280
-
1281
- tinycolor.prototype = {
1282
- isDark: function() {
1283
- return this.getBrightness() < 128;
1284
- },
1285
- isLight: function() {
1286
- return !this.isDark();
1287
- },
1288
- isValid: function() {
1289
- return this._ok;
1290
- },
1291
- getOriginalInput: function() {
1292
- return this._originalInput;
1293
- },
1294
- getFormat: function() {
1295
- return this._format;
1296
- },
1297
- getAlpha: function() {
1298
- return this._a;
1299
- },
1300
- getBrightness: function() {
1301
- var rgb = this.toRgb();
1302
- return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
1303
- },
1304
- setAlpha: function(value) {
1305
- this._a = boundAlpha(value);
1306
- this._roundA = mathRound(1000 * this._a) / 1000;
1307
- return this;
1308
- },
1309
- toHsv: function() {
1310
- var hsv = rgbToHsv(this._r, this._g, this._b);
1311
- return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
1312
- },
1313
- toHsvString: function() {
1314
- var hsv = rgbToHsv(this._r, this._g, this._b);
1315
- var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1316
- return (this._a == 1) ?
1317
- "hsv(" + h + ", " + s + "%, " + v + "%)" :
1318
- "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
1319
- },
1320
- toHsl: function() {
1321
- var hsl = rgbToHsl(this._r, this._g, this._b);
1322
- return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
1323
- },
1324
- toHslString: function() {
1325
- var hsl = rgbToHsl(this._r, this._g, this._b);
1326
- var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1327
- return (this._a == 1) ?
1328
- "hsl(" + h + ", " + s + "%, " + l + "%)" :
1329
- "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
1330
- },
1331
- toHex: function(allow3Char) {
1332
- return rgbToHex(this._r, this._g, this._b, allow3Char);
1333
- },
1334
- toHexString: function(allow3Char) {
1335
- return '#' + this.toHex(allow3Char);
1336
- },
1337
- toHex8: function() {
1338
- return rgbaToHex(this._r, this._g, this._b, this._a);
1339
- },
1340
- toHex8String: function() {
1341
- return '#' + this.toHex8();
1342
- },
1343
- toRgb: function() {
1344
- return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
1345
- },
1346
- toRgbString: function() {
1347
- return (this._a == 1) ?
1348
- "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
1349
- "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
1350
- },
1351
- toPercentageRgb: function() {
1352
- return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
1353
- },
1354
- toPercentageRgbString: function() {
1355
- return (this._a == 1) ?
1356
- "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
1357
- "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
1358
- },
1359
- toName: function() {
1360
- if (this._a === 0) {
1361
- return "transparent";
1362
- }
1363
-
1364
- if (this._a < 1) {
1365
- return false;
1366
- }
1367
-
1368
- return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
1369
- },
1370
- toFilter: function(secondColor) {
1371
- var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
1372
- var secondHex8String = hex8String;
1373
- var gradientType = this._gradientType ? "GradientType = 1, " : "";
1374
-
1375
- if (secondColor) {
1376
- var s = tinycolor(secondColor);
1377
- secondHex8String = s.toHex8String();
1378
- }
1379
-
1380
- return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
1381
- },
1382
- toString: function(format) {
1383
- var formatSet = !!format;
1384
- format = format || this._format;
1385
-
1386
- var formattedString = false;
1387
- var hasAlpha = this._a < 1 && this._a >= 0;
1388
- var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1389
-
1390
- if (needsAlphaFormat) {
1391
- // Special case for "transparent", all other non-alpha formats
1392
- // will return rgba when there is transparency.
1393
- if (format === "name" && this._a === 0) {
1394
- return this.toName();
1395
- }
1396
- return this.toRgbString();
1397
- }
1398
- if (format === "rgb") {
1399
- formattedString = this.toRgbString();
1400
- }
1401
- if (format === "prgb") {
1402
- formattedString = this.toPercentageRgbString();
1403
- }
1404
- if (format === "hex" || format === "hex6") {
1405
- formattedString = this.toHexString();
1406
- }
1407
- if (format === "hex3") {
1408
- formattedString = this.toHexString(true);
1409
- }
1410
- if (format === "hex8") {
1411
- formattedString = this.toHex8String();
1412
- }
1413
- if (format === "name") {
1414
- formattedString = this.toName();
1415
- }
1416
- if (format === "hsl") {
1417
- formattedString = this.toHslString();
1418
- }
1419
- if (format === "hsv") {
1420
- formattedString = this.toHsvString();
1421
- }
1422
-
1423
- return formattedString || this.toHexString();
1424
- },
1425
-
1426
- _applyModification: function(fn, args) {
1427
- var color = fn.apply(null, [this].concat([].slice.call(args)));
1428
- this._r = color._r;
1429
- this._g = color._g;
1430
- this._b = color._b;
1431
- this.setAlpha(color._a);
1432
- return this;
1433
- },
1434
- lighten: function() {
1435
- return this._applyModification(lighten, arguments);
1436
- },
1437
- brighten: function() {
1438
- return this._applyModification(brighten, arguments);
1439
- },
1440
- darken: function() {
1441
- return this._applyModification(darken, arguments);
1442
- },
1443
- desaturate: function() {
1444
- return this._applyModification(desaturate, arguments);
1445
- },
1446
- saturate: function() {
1447
- return this._applyModification(saturate, arguments);
1448
- },
1449
- greyscale: function() {
1450
- return this._applyModification(greyscale, arguments);
1451
- },
1452
- spin: function() {
1453
- return this._applyModification(spin, arguments);
1454
- },
1455
-
1456
- _applyCombination: function(fn, args) {
1457
- return fn.apply(null, [this].concat([].slice.call(args)));
1458
- },
1459
- analogous: function() {
1460
- return this._applyCombination(analogous, arguments);
1461
- },
1462
- complement: function() {
1463
- return this._applyCombination(complement, arguments);
1464
- },
1465
- monochromatic: function() {
1466
- return this._applyCombination(monochromatic, arguments);
1467
- },
1468
- splitcomplement: function() {
1469
- return this._applyCombination(splitcomplement, arguments);
1470
- },
1471
- triad: function() {
1472
- return this._applyCombination(triad, arguments);
1473
- },
1474
- tetrad: function() {
1475
- return this._applyCombination(tetrad, arguments);
1476
- }
1477
- };
1478
-
1479
- // If input is an object, force 1 into "1.0" to handle ratios properly
1480
- // String input requires "1.0" as input, so 1 will be treated as 1
1481
- tinycolor.fromRatio = function(color, opts) {
1482
- if (typeof color == "object") {
1483
- var newColor = {};
1484
- for (var i in color) {
1485
- if (color.hasOwnProperty(i)) {
1486
- if (i === "a") {
1487
- newColor[i] = color[i];
1488
- }
1489
- else {
1490
- newColor[i] = convertToPercentage(color[i]);
1491
- }
1492
- }
1493
- }
1494
- color = newColor;
1495
- }
1496
-
1497
- return tinycolor(color, opts);
1498
- };
1499
-
1500
- // Given a string or object, convert that input to RGB
1501
- // Possible string inputs:
1502
- //
1503
- // "red"
1504
- // "#f00" or "f00"
1505
- // "#ff0000" or "ff0000"
1506
- // "#ff000000" or "ff000000"
1507
- // "rgb 255 0 0" or "rgb (255, 0, 0)"
1508
- // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1509
- // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1510
- // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1511
- // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1512
- // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1513
- // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1514
- //
1515
- function inputToRGB(color) {
1516
-
1517
- var rgb = { r: 0, g: 0, b: 0 };
1518
- var a = 1;
1519
- var ok = false;
1520
- var format = false;
1521
-
1522
- if (typeof color == "string") {
1523
- color = stringInputToObject(color);
1524
- }
1525
-
1526
- if (typeof color == "object") {
1527
- if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1528
- rgb = rgbToRgb(color.r, color.g, color.b);
1529
- ok = true;
1530
- format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1531
- }
1532
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1533
- color.s = convertToPercentage(color.s);
1534
- color.v = convertToPercentage(color.v);
1535
- rgb = hsvToRgb(color.h, color.s, color.v);
1536
- ok = true;
1537
- format = "hsv";
1538
- }
1539
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1540
- color.s = convertToPercentage(color.s);
1541
- color.l = convertToPercentage(color.l);
1542
- rgb = hslToRgb(color.h, color.s, color.l);
1543
- ok = true;
1544
- format = "hsl";
1545
- }
1546
-
1547
- if (color.hasOwnProperty("a")) {
1548
- a = color.a;
1549
- }
1550
- }
1551
-
1552
- a = boundAlpha(a);
1553
-
1554
- return {
1555
- ok: ok,
1556
- format: color.format || format,
1557
- r: mathMin(255, mathMax(rgb.r, 0)),
1558
- g: mathMin(255, mathMax(rgb.g, 0)),
1559
- b: mathMin(255, mathMax(rgb.b, 0)),
1560
- a: a
1561
- };
1562
- }
1563
-
1564
-
1565
- // Conversion Functions
1566
- // --------------------
1567
-
1568
- // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1569
- // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1570
-
1571
- // `rgbToRgb`
1572
- // Handle bounds / percentage checking to conform to CSS color spec
1573
- // <http://www.w3.org/TR/css3-color/>
1574
- // *Assumes:* r, g, b in [0, 255] or [0, 1]
1575
- // *Returns:* { r, g, b } in [0, 255]
1576
- function rgbToRgb(r, g, b){
1577
- return {
1578
- r: bound01(r, 255) * 255,
1579
- g: bound01(g, 255) * 255,
1580
- b: bound01(b, 255) * 255
1581
- };
1582
- }
1583
-
1584
- // `rgbToHsl`
1585
- // Converts an RGB color value to HSL.
1586
- // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1587
- // *Returns:* { h, s, l } in [0,1]
1588
- function rgbToHsl(r, g, b) {
1589
-
1590
- r = bound01(r, 255);
1591
- g = bound01(g, 255);
1592
- b = bound01(b, 255);
1593
-
1594
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1595
- var h, s, l = (max + min) / 2;
1596
-
1597
- if(max == min) {
1598
- h = s = 0; // achromatic
1599
- }
1600
- else {
1601
- var d = max - min;
1602
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1603
- switch(max) {
1604
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1605
- case g: h = (b - r) / d + 2; break;
1606
- case b: h = (r - g) / d + 4; break;
1607
- }
1608
-
1609
- h /= 6;
1610
- }
1611
-
1612
- return { h: h, s: s, l: l };
1613
- }
1614
-
1615
- // `hslToRgb`
1616
- // Converts an HSL color value to RGB.
1617
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1618
- // *Returns:* { r, g, b } in the set [0, 255]
1619
- function hslToRgb(h, s, l) {
1620
- var r, g, b;
1621
-
1622
- h = bound01(h, 360);
1623
- s = bound01(s, 100);
1624
- l = bound01(l, 100);
1625
-
1626
- function hue2rgb(p, q, t) {
1627
- if(t < 0) t += 1;
1628
- if(t > 1) t -= 1;
1629
- if(t < 1/6) return p + (q - p) * 6 * t;
1630
- if(t < 1/2) return q;
1631
- if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1632
- return p;
1633
- }
1634
-
1635
- if(s === 0) {
1636
- r = g = b = l; // achromatic
1637
- }
1638
- else {
1639
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1640
- var p = 2 * l - q;
1641
- r = hue2rgb(p, q, h + 1/3);
1642
- g = hue2rgb(p, q, h);
1643
- b = hue2rgb(p, q, h - 1/3);
1644
- }
1645
-
1646
- return { r: r * 255, g: g * 255, b: b * 255 };
1647
- }
1648
-
1649
- // `rgbToHsv`
1650
- // Converts an RGB color value to HSV
1651
- // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1652
- // *Returns:* { h, s, v } in [0,1]
1653
- function rgbToHsv(r, g, b) {
1654
-
1655
- r = bound01(r, 255);
1656
- g = bound01(g, 255);
1657
- b = bound01(b, 255);
1658
-
1659
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1660
- var h, s, v = max;
1661
-
1662
- var d = max - min;
1663
- s = max === 0 ? 0 : d / max;
1664
-
1665
- if(max == min) {
1666
- h = 0; // achromatic
1667
- }
1668
- else {
1669
- switch(max) {
1670
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1671
- case g: h = (b - r) / d + 2; break;
1672
- case b: h = (r - g) / d + 4; break;
1673
- }
1674
- h /= 6;
1675
- }
1676
- return { h: h, s: s, v: v };
1677
- }
1678
-
1679
- // `hsvToRgb`
1680
- // Converts an HSV color value to RGB.
1681
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1682
- // *Returns:* { r, g, b } in the set [0, 255]
1683
- function hsvToRgb(h, s, v) {
1684
-
1685
- h = bound01(h, 360) * 6;
1686
- s = bound01(s, 100);
1687
- v = bound01(v, 100);
1688
-
1689
- var i = math.floor(h),
1690
- f = h - i,
1691
- p = v * (1 - s),
1692
- q = v * (1 - f * s),
1693
- t = v * (1 - (1 - f) * s),
1694
- mod = i % 6,
1695
- r = [v, q, p, p, t, v][mod],
1696
- g = [t, v, v, q, p, p][mod],
1697
- b = [p, p, t, v, v, q][mod];
1698
-
1699
- return { r: r * 255, g: g * 255, b: b * 255 };
1700
- }
1701
-
1702
- // `rgbToHex`
1703
- // Converts an RGB color to hex
1704
- // Assumes r, g, and b are contained in the set [0, 255]
1705
- // Returns a 3 or 6 character hex
1706
- function rgbToHex(r, g, b, allow3Char) {
1707
-
1708
- var hex = [
1709
- pad2(mathRound(r).toString(16)),
1710
- pad2(mathRound(g).toString(16)),
1711
- pad2(mathRound(b).toString(16))
1712
- ];
1713
-
1714
- // Return a 3 character hex if possible
1715
- if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1716
- return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1717
- }
1718
-
1719
- return hex.join("");
1720
- }
1721
- // `rgbaToHex`
1722
- // Converts an RGBA color plus alpha transparency to hex
1723
- // Assumes r, g, b and a are contained in the set [0, 255]
1724
- // Returns an 8 character hex
1725
- function rgbaToHex(r, g, b, a) {
1726
-
1727
- var hex = [
1728
- pad2(convertDecimalToHex(a)),
1729
- pad2(mathRound(r).toString(16)),
1730
- pad2(mathRound(g).toString(16)),
1731
- pad2(mathRound(b).toString(16))
1732
- ];
1733
-
1734
- return hex.join("");
1735
- }
1736
-
1737
- // `equals`
1738
- // Can be called with any tinycolor input
1739
- tinycolor.equals = function (color1, color2) {
1740
- if (!color1 || !color2) { return false; }
1741
- return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1742
- };
1743
- tinycolor.random = function() {
1744
- return tinycolor.fromRatio({
1745
- r: mathRandom(),
1746
- g: mathRandom(),
1747
- b: mathRandom()
1748
- });
1749
- };
1750
-
1751
-
1752
- // Modification Functions
1753
- // ----------------------
1754
- // Thanks to less.js for some of the basics here
1755
- // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1756
-
1757
- function desaturate(color, amount) {
1758
- amount = (amount === 0) ? 0 : (amount || 10);
1759
- var hsl = tinycolor(color).toHsl();
1760
- hsl.s -= amount / 100;
1761
- hsl.s = clamp01(hsl.s);
1762
- return tinycolor(hsl);
1763
- }
1764
-
1765
- function saturate(color, amount) {
1766
- amount = (amount === 0) ? 0 : (amount || 10);
1767
- var hsl = tinycolor(color).toHsl();
1768
- hsl.s += amount / 100;
1769
- hsl.s = clamp01(hsl.s);
1770
- return tinycolor(hsl);
1771
- }
1772
-
1773
- function greyscale(color) {
1774
- return tinycolor(color).desaturate(100);
1775
- }
1776
-
1777
- function lighten (color, amount) {
1778
- amount = (amount === 0) ? 0 : (amount || 10);
1779
- var hsl = tinycolor(color).toHsl();
1780
- hsl.l += amount / 100;
1781
- hsl.l = clamp01(hsl.l);
1782
- return tinycolor(hsl);
1783
- }
1784
-
1785
- function brighten(color, amount) {
1786
- amount = (amount === 0) ? 0 : (amount || 10);
1787
- var rgb = tinycolor(color).toRgb();
1788
- rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
1789
- rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
1790
- rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
1791
- return tinycolor(rgb);
1792
- }
1793
-
1794
- function darken (color, amount) {
1795
- amount = (amount === 0) ? 0 : (amount || 10);
1796
- var hsl = tinycolor(color).toHsl();
1797
- hsl.l -= amount / 100;
1798
- hsl.l = clamp01(hsl.l);
1799
- return tinycolor(hsl);
1800
- }
1801
-
1802
- // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
1803
- // Values outside of this range will be wrapped into this range.
1804
- function spin(color, amount) {
1805
- var hsl = tinycolor(color).toHsl();
1806
- var hue = (mathRound(hsl.h) + amount) % 360;
1807
- hsl.h = hue < 0 ? 360 + hue : hue;
1808
- return tinycolor(hsl);
1809
- }
1810
-
1811
- // Combination Functions
1812
- // ---------------------
1813
- // Thanks to jQuery xColor for some of the ideas behind these
1814
- // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1815
-
1816
- function complement(color) {
1817
- var hsl = tinycolor(color).toHsl();
1818
- hsl.h = (hsl.h + 180) % 360;
1819
- return tinycolor(hsl);
1820
- }
1821
-
1822
- function triad(color) {
1823
- var hsl = tinycolor(color).toHsl();
1824
- var h = hsl.h;
1825
- return [
1826
- tinycolor(color),
1827
- tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1828
- tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1829
- ];
1830
- }
1831
-
1832
- function tetrad(color) {
1833
- var hsl = tinycolor(color).toHsl();
1834
- var h = hsl.h;
1835
- return [
1836
- tinycolor(color),
1837
- tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1838
- tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1839
- tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1840
- ];
1841
- }
1842
-
1843
- function splitcomplement(color) {
1844
- var hsl = tinycolor(color).toHsl();
1845
- var h = hsl.h;
1846
- return [
1847
- tinycolor(color),
1848
- tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1849
- tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1850
- ];
1851
- }
1852
-
1853
- function analogous(color, results, slices) {
1854
- results = results || 6;
1855
- slices = slices || 30;
1856
-
1857
- var hsl = tinycolor(color).toHsl();
1858
- var part = 360 / slices;
1859
- var ret = [tinycolor(color)];
1860
-
1861
- for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1862
- hsl.h = (hsl.h + part) % 360;
1863
- ret.push(tinycolor(hsl));
1864
- }
1865
- return ret;
1866
- }
1867
-
1868
- function monochromatic(color, results) {
1869
- results = results || 6;
1870
- var hsv = tinycolor(color).toHsv();
1871
- var h = hsv.h, s = hsv.s, v = hsv.v;
1872
- var ret = [];
1873
- var modification = 1 / results;
1874
-
1875
- while (results--) {
1876
- ret.push(tinycolor({ h: h, s: s, v: v}));
1877
- v = (v + modification) % 1;
1878
- }
1879
-
1880
- return ret;
1881
- }
1882
-
1883
- // Utility Functions
1884
- // ---------------------
1885
-
1886
- tinycolor.mix = function(color1, color2, amount) {
1887
- amount = (amount === 0) ? 0 : (amount || 50);
1888
-
1889
- var rgb1 = tinycolor(color1).toRgb();
1890
- var rgb2 = tinycolor(color2).toRgb();
1891
-
1892
- var p = amount / 100;
1893
- var w = p * 2 - 1;
1894
- var a = rgb2.a - rgb1.a;
1895
-
1896
- var w1;
1897
-
1898
- if (w * a == -1) {
1899
- w1 = w;
1900
- } else {
1901
- w1 = (w + a) / (1 + w * a);
1902
- }
1903
-
1904
- w1 = (w1 + 1) / 2;
1905
-
1906
- var w2 = 1 - w1;
1907
-
1908
- var rgba = {
1909
- r: rgb2.r * w1 + rgb1.r * w2,
1910
- g: rgb2.g * w1 + rgb1.g * w2,
1911
- b: rgb2.b * w1 + rgb1.b * w2,
1912
- a: rgb2.a * p + rgb1.a * (1 - p)
1913
- };
1914
-
1915
- return tinycolor(rgba);
1916
- };
1917
-
1918
-
1919
- // Readability Functions
1920
- // ---------------------
1921
- // <http://www.w3.org/TR/AERT#color-contrast>
1922
-
1923
- // `readability`
1924
- // Analyze the 2 colors and returns an object with the following properties:
1925
- // `brightness`: difference in brightness between the two colors
1926
- // `color`: difference in color/hue between the two colors
1927
- tinycolor.readability = function(color1, color2) {
1928
- var c1 = tinycolor(color1);
1929
- var c2 = tinycolor(color2);
1930
- var rgb1 = c1.toRgb();
1931
- var rgb2 = c2.toRgb();
1932
- var brightnessA = c1.getBrightness();
1933
- var brightnessB = c2.getBrightness();
1934
- var colorDiff = (
1935
- Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +
1936
- Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +
1937
- Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)
1938
- );
1939
-
1940
- return {
1941
- brightness: Math.abs(brightnessA - brightnessB),
1942
- color: colorDiff
1943
- };
1944
- };
1945
-
1946
- // `readable`
1947
- // http://www.w3.org/TR/AERT#color-contrast
1948
- // Ensure that foreground and background color combinations provide sufficient contrast.
1949
- // *Example*
1950
- // tinycolor.isReadable("#000", "#111") => false
1951
- tinycolor.isReadable = function(color1, color2) {
1952
- var readability = tinycolor.readability(color1, color2);
1953
- return readability.brightness > 125 && readability.color > 500;
1954
- };
1955
-
1956
- // `mostReadable`
1957
- // Given a base color and a list of possible foreground or background
1958
- // colors for that base, returns the most readable color.
1959
- // *Example*
1960
- // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1961
- tinycolor.mostReadable = function(baseColor, colorList) {
1962
- var bestColor = null;
1963
- var bestScore = 0;
1964
- var bestIsReadable = false;
1965
- for (var i=0; i < colorList.length; i++) {
1966
-
1967
- // We normalize both around the "acceptable" breaking point,
1968
- // but rank brightness constrast higher than hue.
1969
-
1970
- var readability = tinycolor.readability(baseColor, colorList[i]);
1971
- var readable = readability.brightness > 125 && readability.color > 500;
1972
- var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1973
-
1974
- if ((readable && ! bestIsReadable) ||
1975
- (readable && bestIsReadable && score > bestScore) ||
1976
- ((! readable) && (! bestIsReadable) && score > bestScore)) {
1977
- bestIsReadable = readable;
1978
- bestScore = score;
1979
- bestColor = tinycolor(colorList[i]);
1980
- }
1981
- }
1982
- return bestColor;
1983
- };
1984
-
1985
-
1986
- // Big List of Colors
1987
- // ------------------
1988
- // <http://www.w3.org/TR/css3-color/#svg-color>
1989
- var names = tinycolor.names = {
1990
- aliceblue: "f0f8ff",
1991
- antiquewhite: "faebd7",
1992
- aqua: "0ff",
1993
- aquamarine: "7fffd4",
1994
- azure: "f0ffff",
1995
- beige: "f5f5dc",
1996
- bisque: "ffe4c4",
1997
- black: "000",
1998
- blanchedalmond: "ffebcd",
1999
- blue: "00f",
2000
- blueviolet: "8a2be2",
2001
- brown: "a52a2a",
2002
- burlywood: "deb887",
2003
- burntsienna: "ea7e5d",
2004
- cadetblue: "5f9ea0",
2005
- chartreuse: "7fff00",
2006
- chocolate: "d2691e",
2007
- coral: "ff7f50",
2008
- cornflowerblue: "6495ed",
2009
- cornsilk: "fff8dc",
2010
- crimson: "dc143c",
2011
- cyan: "0ff",
2012
- darkblue: "00008b",
2013
- darkcyan: "008b8b",
2014
- darkgoldenrod: "b8860b",
2015
- darkgray: "a9a9a9",
2016
- darkgreen: "006400",
2017
- darkgrey: "a9a9a9",
2018
- darkkhaki: "bdb76b",
2019
- darkmagenta: "8b008b",
2020
- darkolivegreen: "556b2f",
2021
- darkorange: "ff8c00",
2022
- darkorchid: "9932cc",
2023
- darkred: "8b0000",
2024
- darksalmon: "e9967a",
2025
- darkseagreen: "8fbc8f",
2026
- darkslateblue: "483d8b",
2027
- darkslategray: "2f4f4f",
2028
- darkslategrey: "2f4f4f",
2029
- darkturquoise: "00ced1",
2030
- darkviolet: "9400d3",
2031
- deeppink: "ff1493",
2032
- deepskyblue: "00bfff",
2033
- dimgray: "696969",
2034
- dimgrey: "696969",
2035
- dodgerblue: "1e90ff",
2036
- firebrick: "b22222",
2037
- floralwhite: "fffaf0",
2038
- forestgreen: "228b22",
2039
- fuchsia: "f0f",
2040
- gainsboro: "dcdcdc",
2041
- ghostwhite: "f8f8ff",
2042
- gold: "ffd700",
2043
- goldenrod: "daa520",
2044
- gray: "808080",
2045
- green: "008000",
2046
- greenyellow: "adff2f",
2047
- grey: "808080",
2048
- honeydew: "f0fff0",
2049
- hotpink: "ff69b4",
2050
- indianred: "cd5c5c",
2051
- indigo: "4b0082",
2052
- ivory: "fffff0",
2053
- khaki: "f0e68c",
2054
- lavender: "e6e6fa",
2055
- lavenderblush: "fff0f5",
2056
- lawngreen: "7cfc00",
2057
- lemonchiffon: "fffacd",
2058
- lightblue: "add8e6",
2059
- lightcoral: "f08080",
2060
- lightcyan: "e0ffff",
2061
- lightgoldenrodyellow: "fafad2",
2062
- lightgray: "d3d3d3",
2063
- lightgreen: "90ee90",
2064
- lightgrey: "d3d3d3",
2065
- lightpink: "ffb6c1",
2066
- lightsalmon: "ffa07a",
2067
- lightseagreen: "20b2aa",
2068
- lightskyblue: "87cefa",
2069
- lightslategray: "789",
2070
- lightslategrey: "789",
2071
- lightsteelblue: "b0c4de",
2072
- lightyellow: "ffffe0",
2073
- lime: "0f0",
2074
- limegreen: "32cd32",
2075
- linen: "faf0e6",
2076
- magenta: "f0f",
2077
- maroon: "800000",
2078
- mediumaquamarine: "66cdaa",
2079
- mediumblue: "0000cd",
2080
- mediumorchid: "ba55d3",
2081
- mediumpurple: "9370db",
2082
- mediumseagreen: "3cb371",
2083
- mediumslateblue: "7b68ee",
2084
- mediumspringgreen: "00fa9a",
2085
- mediumturquoise: "48d1cc",
2086
- mediumvioletred: "c71585",
2087
- midnightblue: "191970",
2088
- mintcream: "f5fffa",
2089
- mistyrose: "ffe4e1",
2090
- moccasin: "ffe4b5",
2091
- navajowhite: "ffdead",
2092
- navy: "000080",
2093
- oldlace: "fdf5e6",
2094
- olive: "808000",
2095
- olivedrab: "6b8e23",
2096
- orange: "ffa500",
2097
- orangered: "ff4500",
2098
- orchid: "da70d6",
2099
- palegoldenrod: "eee8aa",
2100
- palegreen: "98fb98",
2101
- paleturquoise: "afeeee",
2102
- palevioletred: "db7093",
2103
- papayawhip: "ffefd5",
2104
- peachpuff: "ffdab9",
2105
- peru: "cd853f",
2106
- pink: "ffc0cb",
2107
- plum: "dda0dd",
2108
- powderblue: "b0e0e6",
2109
- purple: "800080",
2110
- rebeccapurple: "663399",
2111
- red: "f00",
2112
- rosybrown: "bc8f8f",
2113
- royalblue: "4169e1",
2114
- saddlebrown: "8b4513",
2115
- salmon: "fa8072",
2116
- sandybrown: "f4a460",
2117
- seagreen: "2e8b57",
2118
- seashell: "fff5ee",
2119
- sienna: "a0522d",
2120
- silver: "c0c0c0",
2121
- skyblue: "87ceeb",
2122
- slateblue: "6a5acd",
2123
- slategray: "708090",
2124
- slategrey: "708090",
2125
- snow: "fffafa",
2126
- springgreen: "00ff7f",
2127
- steelblue: "4682b4",
2128
- tan: "d2b48c",
2129
- teal: "008080",
2130
- thistle: "d8bfd8",
2131
- tomato: "ff6347",
2132
- turquoise: "40e0d0",
2133
- violet: "ee82ee",
2134
- wheat: "f5deb3",
2135
- white: "fff",
2136
- whitesmoke: "f5f5f5",
2137
- yellow: "ff0",
2138
- yellowgreen: "9acd32"
2139
- };
2140
-
2141
- // Make it easy to access colors via `hexNames[hex]`
2142
- var hexNames = tinycolor.hexNames = flip(names);
2143
-
2144
-
2145
- // Utilities
2146
- // ---------
2147
-
2148
- // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
2149
- function flip(o) {
2150
- var flipped = { };
2151
- for (var i in o) {
2152
- if (o.hasOwnProperty(i)) {
2153
- flipped[o[i]] = i;
2154
- }
2155
- }
2156
- return flipped;
2157
- }
2158
-
2159
- // Return a valid alpha value [0,1] with all invalid values being set to 1
2160
- function boundAlpha(a) {
2161
- a = parseFloat(a);
2162
-
2163
- if (isNaN(a) || a < 0 || a > 1) {
2164
- a = 1;
2165
- }
2166
-
2167
- return a;
2168
- }
2169
-
2170
- // Take input from [0, n] and return it as [0, 1]
2171
- function bound01(n, max) {
2172
- if (isOnePointZero(n)) { n = "100%"; }
2173
-
2174
- var processPercent = isPercentage(n);
2175
- n = mathMin(max, mathMax(0, parseFloat(n)));
2176
-
2177
- // Automatically convert percentage into number
2178
- if (processPercent) {
2179
- n = parseInt(n * max, 10) / 100;
2180
- }
2181
-
2182
- // Handle floating point rounding errors
2183
- if ((math.abs(n - max) < 0.000001)) {
2184
- return 1;
2185
- }
2186
-
2187
- // Convert into [0, 1] range if it isn't already
2188
- return (n % max) / parseFloat(max);
2189
- }
2190
-
2191
- // Force a number between 0 and 1
2192
- function clamp01(val) {
2193
- return mathMin(1, mathMax(0, val));
2194
- }
2195
-
2196
- // Parse a base-16 hex value into a base-10 integer
2197
- function parseIntFromHex(val) {
2198
- return parseInt(val, 16);
2199
- }
2200
-
2201
- // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
2202
- // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
2203
- function isOnePointZero(n) {
2204
- return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
2205
- }
2206
-
2207
- // Check to see if string passed in is a percentage
2208
- function isPercentage(n) {
2209
- return typeof n === "string" && n.indexOf('%') != -1;
2210
- }
2211
-
2212
- // Force a hex value to have 2 characters
2213
- function pad2(c) {
2214
- return c.length == 1 ? '0' + c : '' + c;
2215
- }
2216
-
2217
- // Replace a decimal with it's percentage value
2218
- function convertToPercentage(n) {
2219
- if (n <= 1) {
2220
- n = (n * 100) + "%";
2221
- }
2222
-
2223
- return n;
2224
- }
2225
-
2226
- // Converts a decimal to a hex value
2227
- function convertDecimalToHex(d) {
2228
- return Math.round(parseFloat(d) * 255).toString(16);
2229
- }
2230
- // Converts a hex value to a decimal
2231
- function convertHexToDecimal(h) {
2232
- return (parseIntFromHex(h) / 255);
2233
- }
2234
-
2235
- var matchers = (function() {
2236
-
2237
- // <http://www.w3.org/TR/css3-values/#integers>
2238
- var CSS_INTEGER = "[-\\+]?\\d+%?";
2239
-
2240
- // <http://www.w3.org/TR/css3-values/#number-value>
2241
- var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
2242
-
2243
- // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
2244
- var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
2245
-
2246
- // Actual matching.
2247
- // Parentheses and commas are optional, but not required.
2248
- // Whitespace can take the place of commas or opening paren
2249
- var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2250
- var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2251
-
2252
- return {
2253
- rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
2254
- rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
2255
- hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
2256
- hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
2257
- hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
2258
- hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
2259
- hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
2260
- hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
2261
- hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
2262
- };
2263
- })();
2264
-
2265
- // `stringInputToObject`
2266
- // Permissive string parsing. Take in a number of formats, and output an object
2267
- // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
2268
- function stringInputToObject(color) {
2269
-
2270
- color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
2271
- var named = false;
2272
- if (names[color]) {
2273
- color = names[color];
2274
- named = true;
2275
- }
2276
- else if (color == 'transparent') {
2277
- return { r: 0, g: 0, b: 0, a: 0, format: "name" };
2278
- }
2279
-
2280
- // Try to match string input using regular expressions.
2281
- // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
2282
- // Just return an object and let the conversion functions handle that.
2283
- // This way the result will be the same whether the tinycolor is initialized with string or object.
2284
- var match;
2285
- if ((match = matchers.rgb.exec(color))) {
2286
- return { r: match[1], g: match[2], b: match[3] };
2287
- }
2288
- if ((match = matchers.rgba.exec(color))) {
2289
- return { r: match[1], g: match[2], b: match[3], a: match[4] };
2290
- }
2291
- if ((match = matchers.hsl.exec(color))) {
2292
- return { h: match[1], s: match[2], l: match[3] };
2293
- }
2294
- if ((match = matchers.hsla.exec(color))) {
2295
- return { h: match[1], s: match[2], l: match[3], a: match[4] };
2296
- }
2297
- if ((match = matchers.hsv.exec(color))) {
2298
- return { h: match[1], s: match[2], v: match[3] };
2299
- }
2300
- if ((match = matchers.hsva.exec(color))) {
2301
- return { h: match[1], s: match[2], v: match[3], a: match[4] };
2302
- }
2303
- if ((match = matchers.hex8.exec(color))) {
2304
- return {
2305
- a: convertHexToDecimal(match[1]),
2306
- r: parseIntFromHex(match[2]),
2307
- g: parseIntFromHex(match[3]),
2308
- b: parseIntFromHex(match[4]),
2309
- format: named ? "name" : "hex8"
2310
- };
2311
- }
2312
- if ((match = matchers.hex6.exec(color))) {
2313
- return {
2314
- r: parseIntFromHex(match[1]),
2315
- g: parseIntFromHex(match[2]),
2316
- b: parseIntFromHex(match[3]),
2317
- format: named ? "name" : "hex"
2318
- };
2319
- }
2320
- if ((match = matchers.hex3.exec(color))) {
2321
- return {
2322
- r: parseIntFromHex(match[1] + '' + match[1]),
2323
- g: parseIntFromHex(match[2] + '' + match[2]),
2324
- b: parseIntFromHex(match[3] + '' + match[3]),
2325
- format: named ? "name" : "hex"
2326
- };
2327
- }
2328
-
2329
- return false;
2330
- }
2331
-
2332
- window.tinycolor = tinycolor;
2333
- })();
2334
-
2335
- $(function () {
2336
- if ($.fn.spectrum.load) {
2337
- $.fn.spectrum.processNativeColorInputs();
2338
- }
2339
- });
2340
-
2341
- });
1
+ // Spectrum Colorpicker v1.8.1
2
+ // https://github.com/bgrins/spectrum
3
+ // Author: Brian Grinstead
4
+ // License: MIT
5
+
6
+ (function (factory) {
7
+ "use strict";
8
+
9
+ if (typeof define === 'function' && define.amd) { // AMD
10
+ define(['jquery'], factory);
11
+ }
12
+ else if (typeof exports == "object" && typeof module == "object") { // CommonJS
13
+ module.exports = factory(require('jquery'));
14
+ }
15
+ else { // Browser
16
+ factory(jQuery);
17
+ }
18
+ })(function($, undefined) {
19
+ "use strict";
20
+
21
+ var defaultOpts = {
22
+
23
+ // Callbacks
24
+ beforeShow: noop,
25
+ move: noop,
26
+ change: noop,
27
+ show: noop,
28
+ hide: noop,
29
+
30
+ // Options
31
+ color: false,
32
+ flat: false,
33
+ showInput: false,
34
+ allowEmpty: false,
35
+ showButtons: true,
36
+ clickoutFiresChange: true,
37
+ showInitial: false,
38
+ showPalette: false,
39
+ showPaletteOnly: false,
40
+ hideAfterPaletteSelect: false,
41
+ togglePaletteOnly: false,
42
+ showSelectionPalette: true,
43
+ localStorageKey: false,
44
+ appendTo: "body",
45
+ maxSelectionSize: 7,
46
+ cancelText: "cancel",
47
+ chooseText: "choose",
48
+ togglePaletteMoreText: "more",
49
+ togglePaletteLessText: "less",
50
+ clearText: "Clear Color Selection",
51
+ noColorSelectedText: "No Color Selected",
52
+ preferredFormat: false,
53
+ className: "", // Deprecated - use containerClassName and replacerClassName instead.
54
+ containerClassName: "",
55
+ replacerClassName: "",
56
+ showAlpha: false,
57
+ theme: "sp-light",
58
+ palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
59
+ selectionPalette: [],
60
+ disabled: false,
61
+ offset: null
62
+ },
63
+ spectrums = [],
64
+ IE = !!/msie/i.exec( window.navigator.userAgent ),
65
+ rgbaSupport = (function() {
66
+ function contains( str, substr ) {
67
+ return !!~('' + str).indexOf(substr);
68
+ }
69
+
70
+ var elem = document.createElement('div');
71
+ var style = elem.style;
72
+ style.cssText = 'background-color:rgba(0,0,0,.5)';
73
+ return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
74
+ })(),
75
+ replaceInput = [
76
+ "<div class='sp-replacer'>",
77
+ "<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
78
+ "<div class='sp-dd'>&#9660;</div>",
79
+ "</div>"
80
+ ].join(''),
81
+ markup = (function () {
82
+
83
+ // IE does not support gradients with multiple stops, so we need to simulate
84
+ // that for the rainbow slider with 8 divs that each have a single gradient
85
+ var gradientFix = "";
86
+ if (IE) {
87
+ for (var i = 1; i <= 6; i++) {
88
+ gradientFix += "<div class='sp-" + i + "'></div>";
89
+ }
90
+ }
91
+
92
+ return [
93
+ "<div class='sp-container sp-hidden'>",
94
+ "<div class='sp-palette-container'>",
95
+ "<div class='sp-palette sp-thumb sp-cf'></div>",
96
+ "<div class='sp-palette-button-container sp-cf'>",
97
+ "<button type='button' class='sp-palette-toggle'></button>",
98
+ "</div>",
99
+ "</div>",
100
+ "<div class='sp-picker-container'>",
101
+ "<div class='sp-top sp-cf'>",
102
+ "<div class='sp-fill'></div>",
103
+ "<div class='sp-top-inner'>",
104
+ "<div class='sp-color'>",
105
+ "<div class='sp-sat'>",
106
+ "<div class='sp-val'>",
107
+ "<div class='sp-dragger'></div>",
108
+ "</div>",
109
+ "</div>",
110
+ "</div>",
111
+ "<div class='sp-clear sp-clear-display'>",
112
+ "</div>",
113
+ "<div class='sp-hue'>",
114
+ "<div class='sp-slider'></div>",
115
+ gradientFix,
116
+ "</div>",
117
+ "</div>",
118
+ "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
119
+ "</div>",
120
+ "<div class='sp-input-container sp-cf'>",
121
+ "<input class='sp-input' type='text' spellcheck='false' />",
122
+ "</div>",
123
+ "<div class='sp-initial sp-thumb sp-cf'></div>",
124
+ "<div class='sp-button-container sp-cf'>",
125
+ "<a class='sp-cancel' href='#'></a>",
126
+ "<button type='button' class='sp-choose'></button>",
127
+ "</div>",
128
+ "</div>",
129
+ "</div>"
130
+ ].join("");
131
+ })();
132
+
133
+ function paletteTemplate (p, color, className, opts) {
134
+ var html = [];
135
+ for (var i = 0; i < p.length; i++) {
136
+ var current = p[i];
137
+ if(current) {
138
+ var tiny = tinycolor(current);
139
+ var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
140
+ c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
141
+ var formattedString = tiny.toString(opts.preferredFormat || "rgb");
142
+ var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
143
+ html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';"></span></span>');
144
+ } else {
145
+ var cls = 'sp-clear-display';
146
+ html.push($('<div />')
147
+ .append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
148
+ .attr('title', opts.noColorSelectedText)
149
+ )
150
+ .html()
151
+ );
152
+ }
153
+ }
154
+ return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
155
+ }
156
+
157
+ function hideAll() {
158
+ for (var i = 0; i < spectrums.length; i++) {
159
+ if (spectrums[i]) {
160
+ spectrums[i].hide();
161
+ }
162
+ }
163
+ }
164
+
165
+ function instanceOptions(o, callbackContext) {
166
+ var opts = $.extend({}, defaultOpts, o);
167
+ opts.callbacks = {
168
+ 'move': bind(opts.move, callbackContext),
169
+ 'change': bind(opts.change, callbackContext),
170
+ 'show': bind(opts.show, callbackContext),
171
+ 'hide': bind(opts.hide, callbackContext),
172
+ 'beforeShow': bind(opts.beforeShow, callbackContext)
173
+ };
174
+
175
+ return opts;
176
+ }
177
+
178
+ function spectrum(element, o) {
179
+
180
+ var opts = instanceOptions(o, element),
181
+ flat = opts.flat,
182
+ showSelectionPalette = opts.showSelectionPalette,
183
+ localStorageKey = opts.localStorageKey,
184
+ theme = opts.theme,
185
+ callbacks = opts.callbacks,
186
+ resize = throttle(reflow, 10),
187
+ visible = false,
188
+ isDragging = false,
189
+ dragWidth = 0,
190
+ dragHeight = 0,
191
+ dragHelperHeight = 0,
192
+ slideHeight = 0,
193
+ slideWidth = 0,
194
+ alphaWidth = 0,
195
+ alphaSlideHelperWidth = 0,
196
+ slideHelperHeight = 0,
197
+ currentHue = 0,
198
+ currentSaturation = 0,
199
+ currentValue = 0,
200
+ currentAlpha = 1,
201
+ palette = [],
202
+ paletteArray = [],
203
+ paletteLookup = {},
204
+ selectionPalette = opts.selectionPalette.slice(0),
205
+ maxSelectionSize = opts.maxSelectionSize,
206
+ draggingClass = "sp-dragging",
207
+ shiftMovementDirection = null;
208
+
209
+ var doc = element.ownerDocument,
210
+ body = doc.body,
211
+ boundElement = $(element),
212
+ disabled = false,
213
+ container = $(markup, doc).addClass(theme),
214
+ pickerContainer = container.find(".sp-picker-container"),
215
+ dragger = container.find(".sp-color"),
216
+ dragHelper = container.find(".sp-dragger"),
217
+ slider = container.find(".sp-hue"),
218
+ slideHelper = container.find(".sp-slider"),
219
+ alphaSliderInner = container.find(".sp-alpha-inner"),
220
+ alphaSlider = container.find(".sp-alpha"),
221
+ alphaSlideHelper = container.find(".sp-alpha-handle"),
222
+ textInput = container.find(".sp-input"),
223
+ paletteContainer = container.find(".sp-palette"),
224
+ initialColorContainer = container.find(".sp-initial"),
225
+ cancelButton = container.find(".sp-cancel"),
226
+ clearButton = container.find(".sp-clear"),
227
+ chooseButton = container.find(".sp-choose"),
228
+ toggleButton = container.find(".sp-palette-toggle"),
229
+ isInput = boundElement.is("input"),
230
+ isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(),
231
+ shouldReplace = isInput && !flat,
232
+ replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
233
+ offsetElement = (shouldReplace) ? replacer : boundElement,
234
+ previewElement = replacer.find(".sp-preview-inner"),
235
+ initialColor = opts.color || (isInput && boundElement.val()),
236
+ colorOnShow = false,
237
+ currentPreferredFormat = opts.preferredFormat,
238
+ clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
239
+ isEmpty = !initialColor,
240
+ allowEmpty = opts.allowEmpty && !isInputTypeColor;
241
+
242
+ function applyOptions() {
243
+
244
+ if (opts.showPaletteOnly) {
245
+ opts.showPalette = true;
246
+ }
247
+
248
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
249
+
250
+ if (opts.palette) {
251
+ palette = opts.palette.slice(0);
252
+ paletteArray = $.isArray(palette[0]) ? palette : [palette];
253
+ paletteLookup = {};
254
+ for (var i = 0; i < paletteArray.length; i++) {
255
+ for (var j = 0; j < paletteArray[i].length; j++) {
256
+ var rgb = tinycolor(paletteArray[i][j]).toRgbString();
257
+ paletteLookup[rgb] = true;
258
+ }
259
+ }
260
+ }
261
+
262
+ container.toggleClass("sp-flat", flat);
263
+ container.toggleClass("sp-input-disabled", !opts.showInput);
264
+ container.toggleClass("sp-alpha-enabled", opts.showAlpha);
265
+ container.toggleClass("sp-clear-enabled", allowEmpty);
266
+ container.toggleClass("sp-buttons-disabled", !opts.showButtons);
267
+ container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
268
+ container.toggleClass("sp-palette-disabled", !opts.showPalette);
269
+ container.toggleClass("sp-palette-only", opts.showPaletteOnly);
270
+ container.toggleClass("sp-initial-disabled", !opts.showInitial);
271
+ container.addClass(opts.className).addClass(opts.containerClassName);
272
+
273
+ reflow();
274
+ }
275
+
276
+ function initialize() {
277
+
278
+ if (IE) {
279
+ container.find("*:not(input)").attr("unselectable", "on");
280
+ }
281
+
282
+ applyOptions();
283
+
284
+ if (shouldReplace) {
285
+ boundElement.after(replacer).hide();
286
+ }
287
+
288
+ if (!allowEmpty) {
289
+ clearButton.hide();
290
+ }
291
+
292
+ if (flat) {
293
+ boundElement.after(container).hide();
294
+ }
295
+ else {
296
+
297
+ var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
298
+ if (appendTo.length !== 1) {
299
+ appendTo = $("body");
300
+ }
301
+
302
+ appendTo.append(container);
303
+ }
304
+
305
+ updateSelectionPaletteFromStorage();
306
+
307
+ offsetElement.on("click.spectrum touchstart.spectrum", function (e) {
308
+ if (!disabled) {
309
+ toggle();
310
+ }
311
+
312
+ e.stopPropagation();
313
+
314
+ if (!$(e.target).is("input")) {
315
+ e.preventDefault();
316
+ }
317
+ });
318
+
319
+ if(boundElement.is(":disabled") || (opts.disabled === true)) {
320
+ disable();
321
+ }
322
+
323
+ // Prevent clicks from bubbling up to document. This would cause it to be hidden.
324
+ container.click(stopPropagation);
325
+
326
+ // Handle user typed input
327
+ textInput.change(setFromTextInput);
328
+ textInput.on("paste", function () {
329
+ setTimeout(setFromTextInput, 1);
330
+ });
331
+ textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
332
+
333
+ cancelButton.text(opts.cancelText);
334
+ cancelButton.on("click.spectrum", function (e) {
335
+ e.stopPropagation();
336
+ e.preventDefault();
337
+ revert();
338
+ hide();
339
+ });
340
+
341
+ clearButton.attr("title", opts.clearText);
342
+ clearButton.on("click.spectrum", function (e) {
343
+ e.stopPropagation();
344
+ e.preventDefault();
345
+ isEmpty = true;
346
+ move();
347
+
348
+ if(flat) {
349
+ //for the flat style, this is a change event
350
+ updateOriginalInput(true);
351
+ }
352
+ });
353
+
354
+ chooseButton.text(opts.chooseText);
355
+ chooseButton.on("click.spectrum", function (e) {
356
+ e.stopPropagation();
357
+ e.preventDefault();
358
+
359
+ if (IE && textInput.is(":focus")) {
360
+ textInput.trigger('change');
361
+ }
362
+
363
+ if (isValid()) {
364
+ updateOriginalInput(true);
365
+ hide();
366
+ }
367
+ });
368
+
369
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
370
+ toggleButton.on("click.spectrum", function (e) {
371
+ e.stopPropagation();
372
+ e.preventDefault();
373
+
374
+ opts.showPaletteOnly = !opts.showPaletteOnly;
375
+
376
+ // To make sure the Picker area is drawn on the right, next to the
377
+ // Palette area (and not below the palette), first move the Palette
378
+ // to the left to make space for the picker, plus 5px extra.
379
+ // The 'applyOptions' function puts the whole container back into place
380
+ // and takes care of the button-text and the sp-palette-only CSS class.
381
+ if (!opts.showPaletteOnly && !flat) {
382
+ container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));
383
+ }
384
+ applyOptions();
385
+ });
386
+
387
+ draggable(alphaSlider, function (dragX, dragY, e) {
388
+ currentAlpha = (dragX / alphaWidth);
389
+ isEmpty = false;
390
+ if (e.shiftKey) {
391
+ currentAlpha = Math.round(currentAlpha * 10) / 10;
392
+ }
393
+
394
+ move();
395
+ }, dragStart, dragStop);
396
+
397
+ draggable(slider, function (dragX, dragY) {
398
+ currentHue = parseFloat(dragY / slideHeight);
399
+ isEmpty = false;
400
+ if (!opts.showAlpha) {
401
+ currentAlpha = 1;
402
+ }
403
+ move();
404
+ }, dragStart, dragStop);
405
+
406
+ draggable(dragger, function (dragX, dragY, e) {
407
+
408
+ // shift+drag should snap the movement to either the x or y axis.
409
+ if (!e.shiftKey) {
410
+ shiftMovementDirection = null;
411
+ }
412
+ else if (!shiftMovementDirection) {
413
+ var oldDragX = currentSaturation * dragWidth;
414
+ var oldDragY = dragHeight - (currentValue * dragHeight);
415
+ var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
416
+
417
+ shiftMovementDirection = furtherFromX ? "x" : "y";
418
+ }
419
+
420
+ var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
421
+ var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
422
+
423
+ if (setSaturation) {
424
+ currentSaturation = parseFloat(dragX / dragWidth);
425
+ }
426
+ if (setValue) {
427
+ currentValue = parseFloat((dragHeight - dragY) / dragHeight);
428
+ }
429
+
430
+ isEmpty = false;
431
+ if (!opts.showAlpha) {
432
+ currentAlpha = 1;
433
+ }
434
+
435
+ move();
436
+
437
+ }, dragStart, dragStop);
438
+
439
+ if (!!initialColor) {
440
+ set(initialColor);
441
+
442
+ // In case color was black - update the preview UI and set the format
443
+ // since the set function will not run (default color is black).
444
+ updateUI();
445
+ currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;
446
+
447
+ addColorToSelectionPalette(initialColor);
448
+ }
449
+ else {
450
+ updateUI();
451
+ }
452
+
453
+ if (flat) {
454
+ show();
455
+ }
456
+
457
+ function paletteElementClick(e) {
458
+ if (e.data && e.data.ignore) {
459
+ set($(e.target).closest(".sp-thumb-el").data("color"));
460
+ move();
461
+ }
462
+ else {
463
+ set($(e.target).closest(".sp-thumb-el").data("color"));
464
+ move();
465
+
466
+ // If the picker is going to close immediately, a palette selection
467
+ // is a change. Otherwise, it's a move only.
468
+ if (opts.hideAfterPaletteSelect) {
469
+ updateOriginalInput(true);
470
+ hide();
471
+ } else {
472
+ updateOriginalInput();
473
+ }
474
+ }
475
+
476
+ return false;
477
+ }
478
+
479
+ var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
480
+ paletteContainer.on(paletteEvent, ".sp-thumb-el", paletteElementClick);
481
+ initialColorContainer.on(paletteEvent, ".sp-thumb-el:nth-child(1)", { ignore: true }, paletteElementClick);
482
+ }
483
+
484
+ function updateSelectionPaletteFromStorage() {
485
+
486
+ if (localStorageKey && window.localStorage) {
487
+
488
+ // Migrate old palettes over to new format. May want to remove this eventually.
489
+ try {
490
+ var oldPalette = window.localStorage[localStorageKey].split(",#");
491
+ if (oldPalette.length > 1) {
492
+ delete window.localStorage[localStorageKey];
493
+ $.each(oldPalette, function(i, c) {
494
+ addColorToSelectionPalette(c);
495
+ });
496
+ }
497
+ }
498
+ catch(e) { }
499
+
500
+ try {
501
+ selectionPalette = window.localStorage[localStorageKey].split(";");
502
+ }
503
+ catch (e) { }
504
+ }
505
+ }
506
+
507
+ function addColorToSelectionPalette(color) {
508
+ if (showSelectionPalette) {
509
+ var rgb = tinycolor(color).toRgbString();
510
+ if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
511
+ selectionPalette.push(rgb);
512
+ while(selectionPalette.length > maxSelectionSize) {
513
+ selectionPalette.shift();
514
+ }
515
+ }
516
+
517
+ if (localStorageKey && window.localStorage) {
518
+ try {
519
+ window.localStorage[localStorageKey] = selectionPalette.join(";");
520
+ }
521
+ catch(e) { }
522
+ }
523
+ }
524
+ }
525
+
526
+ function getUniqueSelectionPalette() {
527
+ var unique = [];
528
+ if (opts.showPalette) {
529
+ for (var i = 0; i < selectionPalette.length; i++) {
530
+ var rgb = tinycolor(selectionPalette[i]).toRgbString();
531
+
532
+ if (!paletteLookup[rgb]) {
533
+ unique.push(selectionPalette[i]);
534
+ }
535
+ }
536
+ }
537
+
538
+ return unique.reverse().slice(0, opts.maxSelectionSize);
539
+ }
540
+
541
+ function drawPalette() {
542
+
543
+ var currentColor = get();
544
+
545
+ var html = $.map(paletteArray, function (palette, i) {
546
+ return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
547
+ });
548
+
549
+ updateSelectionPaletteFromStorage();
550
+
551
+ if (selectionPalette) {
552
+ html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
553
+ }
554
+
555
+ paletteContainer.html(html.join(""));
556
+ }
557
+
558
+ function drawInitial() {
559
+ if (opts.showInitial) {
560
+ var initial = colorOnShow;
561
+ var current = get();
562
+ initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
563
+ }
564
+ }
565
+
566
+ function dragStart() {
567
+ if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
568
+ reflow();
569
+ }
570
+ isDragging = true;
571
+ container.addClass(draggingClass);
572
+ shiftMovementDirection = null;
573
+ boundElement.trigger('dragstart.spectrum', [ get() ]);
574
+ }
575
+
576
+ function dragStop() {
577
+ isDragging = false;
578
+ container.removeClass(draggingClass);
579
+ boundElement.trigger('dragstop.spectrum', [ get() ]);
580
+ }
581
+
582
+ function setFromTextInput() {
583
+
584
+ var value = textInput.val();
585
+
586
+ if ((value === null || value === "") && allowEmpty) {
587
+ set(null);
588
+ move();
589
+ updateOriginalInput();
590
+ }
591
+ else {
592
+ var tiny = tinycolor(value);
593
+ if (tiny.isValid()) {
594
+ set(tiny);
595
+ move();
596
+ updateOriginalInput();
597
+ }
598
+ else {
599
+ textInput.addClass("sp-validation-error");
600
+ }
601
+ }
602
+ }
603
+
604
+ function toggle() {
605
+ if (visible) {
606
+ hide();
607
+ }
608
+ else {
609
+ show();
610
+ }
611
+ }
612
+
613
+ function show() {
614
+ var event = $.Event('beforeShow.spectrum');
615
+
616
+ if (visible) {
617
+ reflow();
618
+ return;
619
+ }
620
+
621
+ boundElement.trigger(event, [ get() ]);
622
+
623
+ if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
624
+ return;
625
+ }
626
+
627
+ hideAll();
628
+ visible = true;
629
+
630
+ $(doc).on("keydown.spectrum", onkeydown);
631
+ $(doc).on("click.spectrum", clickout);
632
+ $(window).on("resize.spectrum", resize);
633
+ replacer.addClass("sp-active");
634
+ container.removeClass("sp-hidden");
635
+
636
+ reflow();
637
+ updateUI();
638
+
639
+ colorOnShow = get();
640
+
641
+ drawInitial();
642
+ callbacks.show(colorOnShow);
643
+ boundElement.trigger('show.spectrum', [ colorOnShow ]);
644
+ }
645
+
646
+ function onkeydown(e) {
647
+ // Close on ESC
648
+ if (e.keyCode === 27) {
649
+ hide();
650
+ }
651
+ }
652
+
653
+ function clickout(e) {
654
+ // Return on right click.
655
+ if (e.button == 2) { return; }
656
+
657
+ // If a drag event was happening during the mouseup, don't hide
658
+ // on click.
659
+ if (isDragging) { return; }
660
+
661
+ if (clickoutFiresChange) {
662
+ updateOriginalInput(true);
663
+ }
664
+ else {
665
+ revert();
666
+ }
667
+ hide();
668
+ }
669
+
670
+ function hide() {
671
+ // Return if hiding is unnecessary
672
+ if (!visible || flat) { return; }
673
+ visible = false;
674
+
675
+ $(doc).off("keydown.spectrum", onkeydown);
676
+ $(doc).off("click.spectrum", clickout);
677
+ $(window).off("resize.spectrum", resize);
678
+
679
+ replacer.removeClass("sp-active");
680
+ container.addClass("sp-hidden");
681
+
682
+ callbacks.hide(get());
683
+ boundElement.trigger('hide.spectrum', [ get() ]);
684
+ }
685
+
686
+ function revert() {
687
+ set(colorOnShow, true);
688
+ updateOriginalInput(true);
689
+ }
690
+
691
+ function set(color, ignoreFormatChange) {
692
+ if (tinycolor.equals(color, get())) {
693
+ // Update UI just in case a validation error needs
694
+ // to be cleared.
695
+ updateUI();
696
+ return;
697
+ }
698
+
699
+ var newColor, newHsv;
700
+ if (!color && allowEmpty) {
701
+ isEmpty = true;
702
+ } else {
703
+ isEmpty = false;
704
+ newColor = tinycolor(color);
705
+ newHsv = newColor.toHsv();
706
+
707
+ currentHue = (newHsv.h % 360) / 360;
708
+ currentSaturation = newHsv.s;
709
+ currentValue = newHsv.v;
710
+ currentAlpha = newHsv.a;
711
+ }
712
+ updateUI();
713
+
714
+ if (newColor && newColor.isValid() && !ignoreFormatChange) {
715
+ currentPreferredFormat = opts.preferredFormat || newColor.getFormat();
716
+ }
717
+ }
718
+
719
+ function get(opts) {
720
+ opts = opts || { };
721
+
722
+ if (allowEmpty && isEmpty) {
723
+ return null;
724
+ }
725
+
726
+ return tinycolor.fromRatio({
727
+ h: currentHue,
728
+ s: currentSaturation,
729
+ v: currentValue,
730
+ a: Math.round(currentAlpha * 1000) / 1000
731
+ }, { format: opts.format || currentPreferredFormat });
732
+ }
733
+
734
+ function isValid() {
735
+ return !textInput.hasClass("sp-validation-error");
736
+ }
737
+
738
+ function move() {
739
+ updateUI();
740
+
741
+ callbacks.move(get());
742
+ boundElement.trigger('move.spectrum', [ get() ]);
743
+ }
744
+
745
+ function updateUI() {
746
+
747
+ textInput.removeClass("sp-validation-error");
748
+
749
+ updateHelperLocations();
750
+
751
+ // Update dragger background color (gradients take care of saturation and value).
752
+ var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
753
+ dragger.css("background-color", flatColor.toHexString());
754
+
755
+ // Get a format that alpha will be included in (hex and names ignore alpha)
756
+ var format = currentPreferredFormat;
757
+ if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
758
+ if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
759
+ format = "rgb";
760
+ }
761
+ }
762
+
763
+ var realColor = get({ format: format }),
764
+ displayColor = '';
765
+
766
+ //reset background info for preview element
767
+ previewElement.removeClass("sp-clear-display");
768
+ previewElement.css('background-color', 'transparent');
769
+
770
+ if (!realColor && allowEmpty) {
771
+ // Update the replaced elements background with icon indicating no color selection
772
+ previewElement.addClass("sp-clear-display");
773
+ }
774
+ else {
775
+ var realHex = realColor.toHexString(),
776
+ realRgb = realColor.toRgbString();
777
+
778
+ // Update the replaced elements background color (with actual selected color)
779
+ if (rgbaSupport || realColor.alpha === 1) {
780
+ previewElement.css("background-color", realRgb);
781
+ }
782
+ else {
783
+ previewElement.css("background-color", "transparent");
784
+ previewElement.css("filter", realColor.toFilter());
785
+ }
786
+
787
+ if (opts.showAlpha) {
788
+ var rgb = realColor.toRgb();
789
+ rgb.a = 0;
790
+ var realAlpha = tinycolor(rgb).toRgbString();
791
+ var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
792
+
793
+ if (IE) {
794
+ alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
795
+ }
796
+ else {
797
+ alphaSliderInner.css("background", "-webkit-" + gradient);
798
+ alphaSliderInner.css("background", "-moz-" + gradient);
799
+ alphaSliderInner.css("background", "-ms-" + gradient);
800
+ // Use current syntax gradient on unprefixed property.
801
+ alphaSliderInner.css("background",
802
+ "linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
803
+ }
804
+ }
805
+
806
+ displayColor = realColor.toString(format);
807
+ }
808
+
809
+ // Update the text entry input as it changes happen
810
+ if (opts.showInput) {
811
+ textInput.val(displayColor);
812
+ }
813
+
814
+ if (opts.showPalette) {
815
+ drawPalette();
816
+ }
817
+
818
+ drawInitial();
819
+ }
820
+
821
+ function updateHelperLocations() {
822
+ var s = currentSaturation;
823
+ var v = currentValue;
824
+
825
+ if(allowEmpty && isEmpty) {
826
+ //if selected color is empty, hide the helpers
827
+ alphaSlideHelper.hide();
828
+ slideHelper.hide();
829
+ dragHelper.hide();
830
+ }
831
+ else {
832
+ //make sure helpers are visible
833
+ alphaSlideHelper.show();
834
+ slideHelper.show();
835
+ dragHelper.show();
836
+
837
+ // Where to show the little circle in that displays your current selected color
838
+ var dragX = s * dragWidth;
839
+ var dragY = dragHeight - (v * dragHeight);
840
+ dragX = Math.max(
841
+ -dragHelperHeight,
842
+ Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
843
+ );
844
+ dragY = Math.max(
845
+ -dragHelperHeight,
846
+ Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
847
+ );
848
+ dragHelper.css({
849
+ "top": dragY + "px",
850
+ "left": dragX + "px"
851
+ });
852
+
853
+ var alphaX = currentAlpha * alphaWidth;
854
+ alphaSlideHelper.css({
855
+ "left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
856
+ });
857
+
858
+ // Where to show the bar that displays your current selected hue
859
+ var slideY = (currentHue) * slideHeight;
860
+ slideHelper.css({
861
+ "top": (slideY - slideHelperHeight) + "px"
862
+ });
863
+ }
864
+ }
865
+
866
+ function updateOriginalInput(fireCallback) {
867
+ var color = get(),
868
+ displayColor = '',
869
+ hasChanged = !tinycolor.equals(color, colorOnShow);
870
+
871
+ if (color) {
872
+ displayColor = color.toString(currentPreferredFormat);
873
+ // Update the selection palette with the current color
874
+ addColorToSelectionPalette(color);
875
+ }
876
+
877
+ if (isInput) {
878
+ boundElement.val(displayColor);
879
+ }
880
+
881
+ if (fireCallback && hasChanged) {
882
+ callbacks.change(color);
883
+ boundElement.trigger('change', [ color ]);
884
+ }
885
+ }
886
+
887
+ function reflow() {
888
+ if (!visible) {
889
+ return; // Calculations would be useless and wouldn't be reliable anyways
890
+ }
891
+ dragWidth = dragger.width();
892
+ dragHeight = dragger.height();
893
+ dragHelperHeight = dragHelper.height();
894
+ slideWidth = slider.width();
895
+ slideHeight = slider.height();
896
+ slideHelperHeight = slideHelper.height();
897
+ alphaWidth = alphaSlider.width();
898
+ alphaSlideHelperWidth = alphaSlideHelper.width();
899
+
900
+ if (!flat) {
901
+ container.css("position", "absolute");
902
+ if (opts.offset) {
903
+ container.offset(opts.offset);
904
+ } else {
905
+ container.offset(getOffset(container, offsetElement));
906
+ }
907
+ }
908
+
909
+ updateHelperLocations();
910
+
911
+ if (opts.showPalette) {
912
+ drawPalette();
913
+ }
914
+
915
+ boundElement.trigger('reflow.spectrum');
916
+ }
917
+
918
+ function destroy() {
919
+ boundElement.show();
920
+ offsetElement.off("click.spectrum touchstart.spectrum");
921
+ container.remove();
922
+ replacer.remove();
923
+ spectrums[spect.id] = null;
924
+ }
925
+
926
+ function option(optionName, optionValue) {
927
+ if (optionName === undefined) {
928
+ return $.extend({}, opts);
929
+ }
930
+ if (optionValue === undefined) {
931
+ return opts[optionName];
932
+ }
933
+
934
+ opts[optionName] = optionValue;
935
+
936
+ if (optionName === "preferredFormat") {
937
+ currentPreferredFormat = opts.preferredFormat;
938
+ }
939
+ applyOptions();
940
+ }
941
+
942
+ function enable() {
943
+ disabled = false;
944
+ boundElement.attr("disabled", false);
945
+ offsetElement.removeClass("sp-disabled");
946
+ }
947
+
948
+ function disable() {
949
+ hide();
950
+ disabled = true;
951
+ boundElement.attr("disabled", true);
952
+ offsetElement.addClass("sp-disabled");
953
+ }
954
+
955
+ function setOffset(coord) {
956
+ opts.offset = coord;
957
+ reflow();
958
+ }
959
+
960
+ initialize();
961
+
962
+ var spect = {
963
+ show: show,
964
+ hide: hide,
965
+ toggle: toggle,
966
+ reflow: reflow,
967
+ option: option,
968
+ enable: enable,
969
+ disable: disable,
970
+ offset: setOffset,
971
+ set: function (c) {
972
+ set(c);
973
+ updateOriginalInput();
974
+ },
975
+ get: get,
976
+ destroy: destroy,
977
+ container: container
978
+ };
979
+
980
+ spect.id = spectrums.push(spect) - 1;
981
+
982
+ return spect;
983
+ }
984
+
985
+ /**
986
+ * checkOffset - get the offset below/above and left/right element depending on screen position
987
+ * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
988
+ */
989
+ function getOffset(picker, input) {
990
+ var extraY = 0;
991
+ var dpWidth = picker.outerWidth();
992
+ var dpHeight = picker.outerHeight();
993
+ var inputHeight = input.outerHeight();
994
+ var doc = picker[0].ownerDocument;
995
+ var docElem = doc.documentElement;
996
+ var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
997
+ var viewHeight = docElem.clientHeight + $(doc).scrollTop();
998
+ var offset = input.offset();
999
+ var offsetLeft = offset.left;
1000
+ var offsetTop = offset.top;
1001
+
1002
+ offsetTop += inputHeight;
1003
+
1004
+ offsetLeft -=
1005
+ Math.min(offsetLeft, (offsetLeft + dpWidth > viewWidth && viewWidth > dpWidth) ?
1006
+ Math.abs(offsetLeft + dpWidth - viewWidth) : 0);
1007
+
1008
+ offsetTop -=
1009
+ Math.min(offsetTop, ((offsetTop + dpHeight > viewHeight && viewHeight > dpHeight) ?
1010
+ Math.abs(dpHeight + inputHeight - extraY) : extraY));
1011
+
1012
+ return {
1013
+ top: offsetTop,
1014
+ bottom: offset.bottom,
1015
+ left: offsetLeft,
1016
+ right: offset.right,
1017
+ width: offset.width,
1018
+ height: offset.height
1019
+ };
1020
+ }
1021
+
1022
+ /**
1023
+ * noop - do nothing
1024
+ */
1025
+ function noop() {
1026
+
1027
+ }
1028
+
1029
+ /**
1030
+ * stopPropagation - makes the code only doing this a little easier to read in line
1031
+ */
1032
+ function stopPropagation(e) {
1033
+ e.stopPropagation();
1034
+ }
1035
+
1036
+ /**
1037
+ * Create a function bound to a given object
1038
+ * Thanks to underscore.js
1039
+ */
1040
+ function bind(func, obj) {
1041
+ var slice = Array.prototype.slice;
1042
+ var args = slice.call(arguments, 2);
1043
+ return function () {
1044
+ return func.apply(obj, args.concat(slice.call(arguments)));
1045
+ };
1046
+ }
1047
+
1048
+ /**
1049
+ * Lightweight drag helper. Handles containment within the element, so that
1050
+ * when dragging, the x is within [0,element.width] and y is within [0,element.height]
1051
+ */
1052
+ function draggable(element, onmove, onstart, onstop) {
1053
+ onmove = onmove || function () { };
1054
+ onstart = onstart || function () { };
1055
+ onstop = onstop || function () { };
1056
+ var doc = document;
1057
+ var dragging = false;
1058
+ var offset = {};
1059
+ var maxHeight = 0;
1060
+ var maxWidth = 0;
1061
+ var hasTouch = ('ontouchstart' in window);
1062
+
1063
+ var duringDragEvents = {};
1064
+ duringDragEvents["selectstart"] = prevent;
1065
+ duringDragEvents["dragstart"] = prevent;
1066
+ duringDragEvents["touchmove mousemove"] = move;
1067
+ duringDragEvents["touchend mouseup"] = stop;
1068
+
1069
+ function prevent(e) {
1070
+ if (e.stopPropagation) {
1071
+ e.stopPropagation();
1072
+ }
1073
+ if (e.preventDefault) {
1074
+ e.preventDefault();
1075
+ }
1076
+ e.returnValue = false;
1077
+ }
1078
+
1079
+ function move(e) {
1080
+ if (dragging) {
1081
+ // Mouseup happened outside of window
1082
+ if (IE && doc.documentMode < 9 && !e.button) {
1083
+ return stop();
1084
+ }
1085
+
1086
+ var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
1087
+ var pageX = t0 && t0.pageX || e.pageX;
1088
+ var pageY = t0 && t0.pageY || e.pageY;
1089
+
1090
+ var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
1091
+ var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
1092
+
1093
+ if (hasTouch) {
1094
+ // Stop scrolling in iOS
1095
+ prevent(e);
1096
+ }
1097
+
1098
+ onmove.apply(element, [dragX, dragY, e]);
1099
+ }
1100
+ }
1101
+
1102
+ function start(e) {
1103
+ var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
1104
+
1105
+ if (!rightclick && !dragging) {
1106
+ if (onstart.apply(element, arguments) !== false) {
1107
+ dragging = true;
1108
+ maxHeight = $(element).height();
1109
+ maxWidth = $(element).width();
1110
+ offset = $(element).offset();
1111
+
1112
+ $(doc).on(duringDragEvents);
1113
+ $(doc.body).addClass("sp-dragging");
1114
+
1115
+ move(e);
1116
+
1117
+ prevent(e);
1118
+ }
1119
+ }
1120
+ }
1121
+
1122
+ function stop() {
1123
+ if (dragging) {
1124
+ $(doc).off(duringDragEvents);
1125
+ $(doc.body).removeClass("sp-dragging");
1126
+
1127
+ // Wait a tick before notifying observers to allow the click event
1128
+ // to fire in Chrome.
1129
+ setTimeout(function() {
1130
+ onstop.apply(element, arguments);
1131
+ }, 0);
1132
+ }
1133
+ dragging = false;
1134
+ }
1135
+
1136
+ $(element).on("touchstart mousedown", start);
1137
+ }
1138
+
1139
+ function throttle(func, wait, debounce) {
1140
+ var timeout;
1141
+ return function () {
1142
+ var context = this, args = arguments;
1143
+ var throttler = function () {
1144
+ timeout = null;
1145
+ func.apply(context, args);
1146
+ };
1147
+ if (debounce) clearTimeout(timeout);
1148
+ if (debounce || !timeout) timeout = setTimeout(throttler, wait);
1149
+ };
1150
+ }
1151
+
1152
+ function inputTypeColorSupport() {
1153
+ return $.fn.spectrum.inputTypeColorSupport();
1154
+ }
1155
+
1156
+ /**
1157
+ * Define a jQuery plugin
1158
+ */
1159
+ var dataID = "spectrum.id";
1160
+ $.fn.spectrum = function (opts, extra) {
1161
+
1162
+ if (typeof opts == "string") {
1163
+
1164
+ var returnValue = this;
1165
+ var args = Array.prototype.slice.call( arguments, 1 );
1166
+
1167
+ this.each(function () {
1168
+ var spect = spectrums[$(this).data(dataID)];
1169
+ if (spect) {
1170
+ var method = spect[opts];
1171
+ if (!method) {
1172
+ throw new Error( "Spectrum: no such method: '" + opts + "'" );
1173
+ }
1174
+
1175
+ if (opts == "get") {
1176
+ returnValue = spect.get();
1177
+ }
1178
+ else if (opts == "container") {
1179
+ returnValue = spect.container;
1180
+ }
1181
+ else if (opts == "option") {
1182
+ returnValue = spect.option.apply(spect, args);
1183
+ }
1184
+ else if (opts == "destroy") {
1185
+ spect.destroy();
1186
+ $(this).removeData(dataID);
1187
+ }
1188
+ else {
1189
+ method.apply(spect, args);
1190
+ }
1191
+ }
1192
+ });
1193
+
1194
+ return returnValue;
1195
+ }
1196
+
1197
+ // Initializing a new instance of spectrum
1198
+ return this.spectrum("destroy").each(function () {
1199
+ var options = $.extend({}, $(this).data(), opts);
1200
+ var spect = spectrum(this, options);
1201
+ $(this).data(dataID, spect.id);
1202
+ });
1203
+ };
1204
+
1205
+ $.fn.spectrum.load = true;
1206
+ $.fn.spectrum.loadOpts = {};
1207
+ $.fn.spectrum.draggable = draggable;
1208
+ $.fn.spectrum.defaults = defaultOpts;
1209
+ $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
1210
+ if (typeof inputTypeColorSupport._cachedResult === "undefined") {
1211
+ var colorInput = $("<input type='color'/>")[0]; // if color element is supported, value will default to not null
1212
+ inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== "";
1213
+ }
1214
+ return inputTypeColorSupport._cachedResult;
1215
+ };
1216
+
1217
+ $.spectrum = { };
1218
+ $.spectrum.localization = { };
1219
+ $.spectrum.palettes = { };
1220
+
1221
+ $.fn.spectrum.processNativeColorInputs = function () {
1222
+ var colorInputs = $("input[type=color]");
1223
+ if (colorInputs.length && !inputTypeColorSupport()) {
1224
+ colorInputs.spectrum({
1225
+ preferredFormat: "hex6"
1226
+ });
1227
+ }
1228
+ };
1229
+
1230
+ // TinyColor v1.1.2
1231
+ // https://github.com/bgrins/TinyColor
1232
+ // Brian Grinstead, MIT License
1233
+
1234
+ (function() {
1235
+
1236
+ var trimLeft = /^[\s,#]+/,
1237
+ trimRight = /\s+$/,
1238
+ tinyCounter = 0,
1239
+ math = Math,
1240
+ mathRound = math.round,
1241
+ mathMin = math.min,
1242
+ mathMax = math.max,
1243
+ mathRandom = math.random;
1244
+
1245
+ var tinycolor = function(color, opts) {
1246
+
1247
+ color = (color) ? color : '';
1248
+ opts = opts || { };
1249
+
1250
+ // If input is already a tinycolor, return itself
1251
+ if (color instanceof tinycolor) {
1252
+ return color;
1253
+ }
1254
+ // If we are called as a function, call using new instead
1255
+ if (!(this instanceof tinycolor)) {
1256
+ return new tinycolor(color, opts);
1257
+ }
1258
+
1259
+ var rgb = inputToRGB(color);
1260
+ this._originalInput = color;
1261
+ this._r = rgb.r;
1262
+ this._g = rgb.g;
1263
+ this._b = rgb.b;
1264
+ this._a = rgb.a;
1265
+ this._roundA = mathRound(1000 * this._a) / 1000;
1266
+ this._format = opts.format || rgb.format;
1267
+ this._gradientType = opts.gradientType;
1268
+
1269
+ // Don't let the range of [0,255] come back in [0,1].
1270
+ // Potentially lose a little bit of precision here, but will fix issues where
1271
+ // .5 gets interpreted as half of the total, instead of half of 1
1272
+ // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1273
+ if (this._r < 1) { this._r = mathRound(this._r); }
1274
+ if (this._g < 1) { this._g = mathRound(this._g); }
1275
+ if (this._b < 1) { this._b = mathRound(this._b); }
1276
+
1277
+ this._ok = rgb.ok;
1278
+ this._tc_id = tinyCounter++;
1279
+ };
1280
+
1281
+ tinycolor.prototype = {
1282
+ isDark: function() {
1283
+ return this.getBrightness() < 128;
1284
+ },
1285
+ isLight: function() {
1286
+ return !this.isDark();
1287
+ },
1288
+ isValid: function() {
1289
+ return this._ok;
1290
+ },
1291
+ getOriginalInput: function() {
1292
+ return this._originalInput;
1293
+ },
1294
+ getFormat: function() {
1295
+ return this._format;
1296
+ },
1297
+ getAlpha: function() {
1298
+ return this._a;
1299
+ },
1300
+ getBrightness: function() {
1301
+ var rgb = this.toRgb();
1302
+ return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
1303
+ },
1304
+ setAlpha: function(value) {
1305
+ this._a = boundAlpha(value);
1306
+ this._roundA = mathRound(1000 * this._a) / 1000;
1307
+ return this;
1308
+ },
1309
+ toHsv: function() {
1310
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1311
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
1312
+ },
1313
+ toHsvString: function() {
1314
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1315
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1316
+ return (this._a == 1) ?
1317
+ "hsv(" + h + ", " + s + "%, " + v + "%)" :
1318
+ "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
1319
+ },
1320
+ toHsl: function() {
1321
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1322
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
1323
+ },
1324
+ toHslString: function() {
1325
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1326
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1327
+ return (this._a == 1) ?
1328
+ "hsl(" + h + ", " + s + "%, " + l + "%)" :
1329
+ "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
1330
+ },
1331
+ toHex: function(allow3Char) {
1332
+ return rgbToHex(this._r, this._g, this._b, allow3Char);
1333
+ },
1334
+ toHexString: function(allow3Char) {
1335
+ return '#' + this.toHex(allow3Char);
1336
+ },
1337
+ toHex8: function() {
1338
+ return rgbaToHex(this._r, this._g, this._b, this._a);
1339
+ },
1340
+ toHex8String: function() {
1341
+ return '#' + this.toHex8();
1342
+ },
1343
+ toRgb: function() {
1344
+ return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
1345
+ },
1346
+ toRgbString: function() {
1347
+ return (this._a == 1) ?
1348
+ "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
1349
+ "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
1350
+ },
1351
+ toPercentageRgb: function() {
1352
+ return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
1353
+ },
1354
+ toPercentageRgbString: function() {
1355
+ return (this._a == 1) ?
1356
+ "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
1357
+ "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
1358
+ },
1359
+ toName: function() {
1360
+ if (this._a === 0) {
1361
+ return "transparent";
1362
+ }
1363
+
1364
+ if (this._a < 1) {
1365
+ return false;
1366
+ }
1367
+
1368
+ return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
1369
+ },
1370
+ toFilter: function(secondColor) {
1371
+ var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
1372
+ var secondHex8String = hex8String;
1373
+ var gradientType = this._gradientType ? "GradientType = 1, " : "";
1374
+
1375
+ if (secondColor) {
1376
+ var s = tinycolor(secondColor);
1377
+ secondHex8String = s.toHex8String();
1378
+ }
1379
+
1380
+ return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
1381
+ },
1382
+ toString: function(format) {
1383
+ var formatSet = !!format;
1384
+ format = format || this._format;
1385
+
1386
+ var formattedString = false;
1387
+ var hasAlpha = this._a < 1 && this._a >= 0;
1388
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1389
+
1390
+ if (needsAlphaFormat) {
1391
+ // Special case for "transparent", all other non-alpha formats
1392
+ // will return rgba when there is transparency.
1393
+ if (format === "name" && this._a === 0) {
1394
+ return this.toName();
1395
+ }
1396
+ return this.toRgbString();
1397
+ }
1398
+ if (format === "rgb") {
1399
+ formattedString = this.toRgbString();
1400
+ }
1401
+ if (format === "prgb") {
1402
+ formattedString = this.toPercentageRgbString();
1403
+ }
1404
+ if (format === "hex" || format === "hex6") {
1405
+ formattedString = this.toHexString();
1406
+ }
1407
+ if (format === "hex3") {
1408
+ formattedString = this.toHexString(true);
1409
+ }
1410
+ if (format === "hex8") {
1411
+ formattedString = this.toHex8String();
1412
+ }
1413
+ if (format === "name") {
1414
+ formattedString = this.toName();
1415
+ }
1416
+ if (format === "hsl") {
1417
+ formattedString = this.toHslString();
1418
+ }
1419
+ if (format === "hsv") {
1420
+ formattedString = this.toHsvString();
1421
+ }
1422
+
1423
+ return formattedString || this.toHexString();
1424
+ },
1425
+
1426
+ _applyModification: function(fn, args) {
1427
+ var color = fn.apply(null, [this].concat([].slice.call(args)));
1428
+ this._r = color._r;
1429
+ this._g = color._g;
1430
+ this._b = color._b;
1431
+ this.setAlpha(color._a);
1432
+ return this;
1433
+ },
1434
+ lighten: function() {
1435
+ return this._applyModification(lighten, arguments);
1436
+ },
1437
+ brighten: function() {
1438
+ return this._applyModification(brighten, arguments);
1439
+ },
1440
+ darken: function() {
1441
+ return this._applyModification(darken, arguments);
1442
+ },
1443
+ desaturate: function() {
1444
+ return this._applyModification(desaturate, arguments);
1445
+ },
1446
+ saturate: function() {
1447
+ return this._applyModification(saturate, arguments);
1448
+ },
1449
+ greyscale: function() {
1450
+ return this._applyModification(greyscale, arguments);
1451
+ },
1452
+ spin: function() {
1453
+ return this._applyModification(spin, arguments);
1454
+ },
1455
+
1456
+ _applyCombination: function(fn, args) {
1457
+ return fn.apply(null, [this].concat([].slice.call(args)));
1458
+ },
1459
+ analogous: function() {
1460
+ return this._applyCombination(analogous, arguments);
1461
+ },
1462
+ complement: function() {
1463
+ return this._applyCombination(complement, arguments);
1464
+ },
1465
+ monochromatic: function() {
1466
+ return this._applyCombination(monochromatic, arguments);
1467
+ },
1468
+ splitcomplement: function() {
1469
+ return this._applyCombination(splitcomplement, arguments);
1470
+ },
1471
+ triad: function() {
1472
+ return this._applyCombination(triad, arguments);
1473
+ },
1474
+ tetrad: function() {
1475
+ return this._applyCombination(tetrad, arguments);
1476
+ }
1477
+ };
1478
+
1479
+ // If input is an object, force 1 into "1.0" to handle ratios properly
1480
+ // String input requires "1.0" as input, so 1 will be treated as 1
1481
+ tinycolor.fromRatio = function(color, opts) {
1482
+ if (typeof color == "object") {
1483
+ var newColor = {};
1484
+ for (var i in color) {
1485
+ if (color.hasOwnProperty(i)) {
1486
+ if (i === "a") {
1487
+ newColor[i] = color[i];
1488
+ }
1489
+ else {
1490
+ newColor[i] = convertToPercentage(color[i]);
1491
+ }
1492
+ }
1493
+ }
1494
+ color = newColor;
1495
+ }
1496
+
1497
+ return tinycolor(color, opts);
1498
+ };
1499
+
1500
+ // Given a string or object, convert that input to RGB
1501
+ // Possible string inputs:
1502
+ //
1503
+ // "red"
1504
+ // "#f00" or "f00"
1505
+ // "#ff0000" or "ff0000"
1506
+ // "#ff000000" or "ff000000"
1507
+ // "rgb 255 0 0" or "rgb (255, 0, 0)"
1508
+ // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1509
+ // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1510
+ // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1511
+ // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1512
+ // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1513
+ // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1514
+ //
1515
+ function inputToRGB(color) {
1516
+
1517
+ var rgb = { r: 0, g: 0, b: 0 };
1518
+ var a = 1;
1519
+ var ok = false;
1520
+ var format = false;
1521
+
1522
+ if (typeof color == "string") {
1523
+ color = stringInputToObject(color);
1524
+ }
1525
+
1526
+ if (typeof color == "object") {
1527
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1528
+ rgb = rgbToRgb(color.r, color.g, color.b);
1529
+ ok = true;
1530
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1531
+ }
1532
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1533
+ color.s = convertToPercentage(color.s);
1534
+ color.v = convertToPercentage(color.v);
1535
+ rgb = hsvToRgb(color.h, color.s, color.v);
1536
+ ok = true;
1537
+ format = "hsv";
1538
+ }
1539
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1540
+ color.s = convertToPercentage(color.s);
1541
+ color.l = convertToPercentage(color.l);
1542
+ rgb = hslToRgb(color.h, color.s, color.l);
1543
+ ok = true;
1544
+ format = "hsl";
1545
+ }
1546
+
1547
+ if (color.hasOwnProperty("a")) {
1548
+ a = color.a;
1549
+ }
1550
+ }
1551
+
1552
+ a = boundAlpha(a);
1553
+
1554
+ return {
1555
+ ok: ok,
1556
+ format: color.format || format,
1557
+ r: mathMin(255, mathMax(rgb.r, 0)),
1558
+ g: mathMin(255, mathMax(rgb.g, 0)),
1559
+ b: mathMin(255, mathMax(rgb.b, 0)),
1560
+ a: a
1561
+ };
1562
+ }
1563
+
1564
+
1565
+ // Conversion Functions
1566
+ // --------------------
1567
+
1568
+ // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1569
+ // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1570
+
1571
+ // `rgbToRgb`
1572
+ // Handle bounds / percentage checking to conform to CSS color spec
1573
+ // <http://www.w3.org/TR/css3-color/>
1574
+ // *Assumes:* r, g, b in [0, 255] or [0, 1]
1575
+ // *Returns:* { r, g, b } in [0, 255]
1576
+ function rgbToRgb(r, g, b){
1577
+ return {
1578
+ r: bound01(r, 255) * 255,
1579
+ g: bound01(g, 255) * 255,
1580
+ b: bound01(b, 255) * 255
1581
+ };
1582
+ }
1583
+
1584
+ // `rgbToHsl`
1585
+ // Converts an RGB color value to HSL.
1586
+ // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1587
+ // *Returns:* { h, s, l } in [0,1]
1588
+ function rgbToHsl(r, g, b) {
1589
+
1590
+ r = bound01(r, 255);
1591
+ g = bound01(g, 255);
1592
+ b = bound01(b, 255);
1593
+
1594
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1595
+ var h, s, l = (max + min) / 2;
1596
+
1597
+ if(max == min) {
1598
+ h = s = 0; // achromatic
1599
+ }
1600
+ else {
1601
+ var d = max - min;
1602
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1603
+ switch(max) {
1604
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1605
+ case g: h = (b - r) / d + 2; break;
1606
+ case b: h = (r - g) / d + 4; break;
1607
+ }
1608
+
1609
+ h /= 6;
1610
+ }
1611
+
1612
+ return { h: h, s: s, l: l };
1613
+ }
1614
+
1615
+ // `hslToRgb`
1616
+ // Converts an HSL color value to RGB.
1617
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1618
+ // *Returns:* { r, g, b } in the set [0, 255]
1619
+ function hslToRgb(h, s, l) {
1620
+ var r, g, b;
1621
+
1622
+ h = bound01(h, 360);
1623
+ s = bound01(s, 100);
1624
+ l = bound01(l, 100);
1625
+
1626
+ function hue2rgb(p, q, t) {
1627
+ if(t < 0) t += 1;
1628
+ if(t > 1) t -= 1;
1629
+ if(t < 1/6) return p + (q - p) * 6 * t;
1630
+ if(t < 1/2) return q;
1631
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1632
+ return p;
1633
+ }
1634
+
1635
+ if(s === 0) {
1636
+ r = g = b = l; // achromatic
1637
+ }
1638
+ else {
1639
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1640
+ var p = 2 * l - q;
1641
+ r = hue2rgb(p, q, h + 1/3);
1642
+ g = hue2rgb(p, q, h);
1643
+ b = hue2rgb(p, q, h - 1/3);
1644
+ }
1645
+
1646
+ return { r: r * 255, g: g * 255, b: b * 255 };
1647
+ }
1648
+
1649
+ // `rgbToHsv`
1650
+ // Converts an RGB color value to HSV
1651
+ // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1652
+ // *Returns:* { h, s, v } in [0,1]
1653
+ function rgbToHsv(r, g, b) {
1654
+
1655
+ r = bound01(r, 255);
1656
+ g = bound01(g, 255);
1657
+ b = bound01(b, 255);
1658
+
1659
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1660
+ var h, s, v = max;
1661
+
1662
+ var d = max - min;
1663
+ s = max === 0 ? 0 : d / max;
1664
+
1665
+ if(max == min) {
1666
+ h = 0; // achromatic
1667
+ }
1668
+ else {
1669
+ switch(max) {
1670
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1671
+ case g: h = (b - r) / d + 2; break;
1672
+ case b: h = (r - g) / d + 4; break;
1673
+ }
1674
+ h /= 6;
1675
+ }
1676
+ return { h: h, s: s, v: v };
1677
+ }
1678
+
1679
+ // `hsvToRgb`
1680
+ // Converts an HSV color value to RGB.
1681
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1682
+ // *Returns:* { r, g, b } in the set [0, 255]
1683
+ function hsvToRgb(h, s, v) {
1684
+
1685
+ h = bound01(h, 360) * 6;
1686
+ s = bound01(s, 100);
1687
+ v = bound01(v, 100);
1688
+
1689
+ var i = math.floor(h),
1690
+ f = h - i,
1691
+ p = v * (1 - s),
1692
+ q = v * (1 - f * s),
1693
+ t = v * (1 - (1 - f) * s),
1694
+ mod = i % 6,
1695
+ r = [v, q, p, p, t, v][mod],
1696
+ g = [t, v, v, q, p, p][mod],
1697
+ b = [p, p, t, v, v, q][mod];
1698
+
1699
+ return { r: r * 255, g: g * 255, b: b * 255 };
1700
+ }
1701
+
1702
+ // `rgbToHex`
1703
+ // Converts an RGB color to hex
1704
+ // Assumes r, g, and b are contained in the set [0, 255]
1705
+ // Returns a 3 or 6 character hex
1706
+ function rgbToHex(r, g, b, allow3Char) {
1707
+
1708
+ var hex = [
1709
+ pad2(mathRound(r).toString(16)),
1710
+ pad2(mathRound(g).toString(16)),
1711
+ pad2(mathRound(b).toString(16))
1712
+ ];
1713
+
1714
+ // Return a 3 character hex if possible
1715
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1716
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1717
+ }
1718
+
1719
+ return hex.join("");
1720
+ }
1721
+ // `rgbaToHex`
1722
+ // Converts an RGBA color plus alpha transparency to hex
1723
+ // Assumes r, g, b and a are contained in the set [0, 255]
1724
+ // Returns an 8 character hex
1725
+ function rgbaToHex(r, g, b, a) {
1726
+
1727
+ var hex = [
1728
+ pad2(convertDecimalToHex(a)),
1729
+ pad2(mathRound(r).toString(16)),
1730
+ pad2(mathRound(g).toString(16)),
1731
+ pad2(mathRound(b).toString(16))
1732
+ ];
1733
+
1734
+ return hex.join("");
1735
+ }
1736
+
1737
+ // `equals`
1738
+ // Can be called with any tinycolor input
1739
+ tinycolor.equals = function (color1, color2) {
1740
+ if (!color1 || !color2) { return false; }
1741
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1742
+ };
1743
+ tinycolor.random = function() {
1744
+ return tinycolor.fromRatio({
1745
+ r: mathRandom(),
1746
+ g: mathRandom(),
1747
+ b: mathRandom()
1748
+ });
1749
+ };
1750
+
1751
+
1752
+ // Modification Functions
1753
+ // ----------------------
1754
+ // Thanks to less.js for some of the basics here
1755
+ // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1756
+
1757
+ function desaturate(color, amount) {
1758
+ amount = (amount === 0) ? 0 : (amount || 10);
1759
+ var hsl = tinycolor(color).toHsl();
1760
+ hsl.s -= amount / 100;
1761
+ hsl.s = clamp01(hsl.s);
1762
+ return tinycolor(hsl);
1763
+ }
1764
+
1765
+ function saturate(color, amount) {
1766
+ amount = (amount === 0) ? 0 : (amount || 10);
1767
+ var hsl = tinycolor(color).toHsl();
1768
+ hsl.s += amount / 100;
1769
+ hsl.s = clamp01(hsl.s);
1770
+ return tinycolor(hsl);
1771
+ }
1772
+
1773
+ function greyscale(color) {
1774
+ return tinycolor(color).desaturate(100);
1775
+ }
1776
+
1777
+ function lighten (color, amount) {
1778
+ amount = (amount === 0) ? 0 : (amount || 10);
1779
+ var hsl = tinycolor(color).toHsl();
1780
+ hsl.l += amount / 100;
1781
+ hsl.l = clamp01(hsl.l);
1782
+ return tinycolor(hsl);
1783
+ }
1784
+
1785
+ function brighten(color, amount) {
1786
+ amount = (amount === 0) ? 0 : (amount || 10);
1787
+ var rgb = tinycolor(color).toRgb();
1788
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
1789
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
1790
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
1791
+ return tinycolor(rgb);
1792
+ }
1793
+
1794
+ function darken (color, amount) {
1795
+ amount = (amount === 0) ? 0 : (amount || 10);
1796
+ var hsl = tinycolor(color).toHsl();
1797
+ hsl.l -= amount / 100;
1798
+ hsl.l = clamp01(hsl.l);
1799
+ return tinycolor(hsl);
1800
+ }
1801
+
1802
+ // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
1803
+ // Values outside of this range will be wrapped into this range.
1804
+ function spin(color, amount) {
1805
+ var hsl = tinycolor(color).toHsl();
1806
+ var hue = (mathRound(hsl.h) + amount) % 360;
1807
+ hsl.h = hue < 0 ? 360 + hue : hue;
1808
+ return tinycolor(hsl);
1809
+ }
1810
+
1811
+ // Combination Functions
1812
+ // ---------------------
1813
+ // Thanks to jQuery xColor for some of the ideas behind these
1814
+ // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1815
+
1816
+ function complement(color) {
1817
+ var hsl = tinycolor(color).toHsl();
1818
+ hsl.h = (hsl.h + 180) % 360;
1819
+ return tinycolor(hsl);
1820
+ }
1821
+
1822
+ function triad(color) {
1823
+ var hsl = tinycolor(color).toHsl();
1824
+ var h = hsl.h;
1825
+ return [
1826
+ tinycolor(color),
1827
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1828
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1829
+ ];
1830
+ }
1831
+
1832
+ function tetrad(color) {
1833
+ var hsl = tinycolor(color).toHsl();
1834
+ var h = hsl.h;
1835
+ return [
1836
+ tinycolor(color),
1837
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1838
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1839
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1840
+ ];
1841
+ }
1842
+
1843
+ function splitcomplement(color) {
1844
+ var hsl = tinycolor(color).toHsl();
1845
+ var h = hsl.h;
1846
+ return [
1847
+ tinycolor(color),
1848
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1849
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1850
+ ];
1851
+ }
1852
+
1853
+ function analogous(color, results, slices) {
1854
+ results = results || 6;
1855
+ slices = slices || 30;
1856
+
1857
+ var hsl = tinycolor(color).toHsl();
1858
+ var part = 360 / slices;
1859
+ var ret = [tinycolor(color)];
1860
+
1861
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1862
+ hsl.h = (hsl.h + part) % 360;
1863
+ ret.push(tinycolor(hsl));
1864
+ }
1865
+ return ret;
1866
+ }
1867
+
1868
+ function monochromatic(color, results) {
1869
+ results = results || 6;
1870
+ var hsv = tinycolor(color).toHsv();
1871
+ var h = hsv.h, s = hsv.s, v = hsv.v;
1872
+ var ret = [];
1873
+ var modification = 1 / results;
1874
+
1875
+ while (results--) {
1876
+ ret.push(tinycolor({ h: h, s: s, v: v}));
1877
+ v = (v + modification) % 1;
1878
+ }
1879
+
1880
+ return ret;
1881
+ }
1882
+
1883
+ // Utility Functions
1884
+ // ---------------------
1885
+
1886
+ tinycolor.mix = function(color1, color2, amount) {
1887
+ amount = (amount === 0) ? 0 : (amount || 50);
1888
+
1889
+ var rgb1 = tinycolor(color1).toRgb();
1890
+ var rgb2 = tinycolor(color2).toRgb();
1891
+
1892
+ var p = amount / 100;
1893
+ var w = p * 2 - 1;
1894
+ var a = rgb2.a - rgb1.a;
1895
+
1896
+ var w1;
1897
+
1898
+ if (w * a == -1) {
1899
+ w1 = w;
1900
+ } else {
1901
+ w1 = (w + a) / (1 + w * a);
1902
+ }
1903
+
1904
+ w1 = (w1 + 1) / 2;
1905
+
1906
+ var w2 = 1 - w1;
1907
+
1908
+ var rgba = {
1909
+ r: rgb2.r * w1 + rgb1.r * w2,
1910
+ g: rgb2.g * w1 + rgb1.g * w2,
1911
+ b: rgb2.b * w1 + rgb1.b * w2,
1912
+ a: rgb2.a * p + rgb1.a * (1 - p)
1913
+ };
1914
+
1915
+ return tinycolor(rgba);
1916
+ };
1917
+
1918
+
1919
+ // Readability Functions
1920
+ // ---------------------
1921
+ // <http://www.w3.org/TR/AERT#color-contrast>
1922
+
1923
+ // `readability`
1924
+ // Analyze the 2 colors and returns an object with the following properties:
1925
+ // `brightness`: difference in brightness between the two colors
1926
+ // `color`: difference in color/hue between the two colors
1927
+ tinycolor.readability = function(color1, color2) {
1928
+ var c1 = tinycolor(color1);
1929
+ var c2 = tinycolor(color2);
1930
+ var rgb1 = c1.toRgb();
1931
+ var rgb2 = c2.toRgb();
1932
+ var brightnessA = c1.getBrightness();
1933
+ var brightnessB = c2.getBrightness();
1934
+ var colorDiff = (
1935
+ Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +
1936
+ Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +
1937
+ Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)
1938
+ );
1939
+
1940
+ return {
1941
+ brightness: Math.abs(brightnessA - brightnessB),
1942
+ color: colorDiff
1943
+ };
1944
+ };
1945
+
1946
+ // `readable`
1947
+ // http://www.w3.org/TR/AERT#color-contrast
1948
+ // Ensure that foreground and background color combinations provide sufficient contrast.
1949
+ // *Example*
1950
+ // tinycolor.isReadable("#000", "#111") => false
1951
+ tinycolor.isReadable = function(color1, color2) {
1952
+ var readability = tinycolor.readability(color1, color2);
1953
+ return readability.brightness > 125 && readability.color > 500;
1954
+ };
1955
+
1956
+ // `mostReadable`
1957
+ // Given a base color and a list of possible foreground or background
1958
+ // colors for that base, returns the most readable color.
1959
+ // *Example*
1960
+ // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1961
+ tinycolor.mostReadable = function(baseColor, colorList) {
1962
+ var bestColor = null;
1963
+ var bestScore = 0;
1964
+ var bestIsReadable = false;
1965
+ for (var i=0; i < colorList.length; i++) {
1966
+
1967
+ // We normalize both around the "acceptable" breaking point,
1968
+ // but rank brightness constrast higher than hue.
1969
+
1970
+ var readability = tinycolor.readability(baseColor, colorList[i]);
1971
+ var readable = readability.brightness > 125 && readability.color > 500;
1972
+ var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1973
+
1974
+ if ((readable && ! bestIsReadable) ||
1975
+ (readable && bestIsReadable && score > bestScore) ||
1976
+ ((! readable) && (! bestIsReadable) && score > bestScore)) {
1977
+ bestIsReadable = readable;
1978
+ bestScore = score;
1979
+ bestColor = tinycolor(colorList[i]);
1980
+ }
1981
+ }
1982
+ return bestColor;
1983
+ };
1984
+
1985
+
1986
+ // Big List of Colors
1987
+ // ------------------
1988
+ // <http://www.w3.org/TR/css3-color/#svg-color>
1989
+ var names = tinycolor.names = {
1990
+ aliceblue: "f0f8ff",
1991
+ antiquewhite: "faebd7",
1992
+ aqua: "0ff",
1993
+ aquamarine: "7fffd4",
1994
+ azure: "f0ffff",
1995
+ beige: "f5f5dc",
1996
+ bisque: "ffe4c4",
1997
+ black: "000",
1998
+ blanchedalmond: "ffebcd",
1999
+ blue: "00f",
2000
+ blueviolet: "8a2be2",
2001
+ brown: "a52a2a",
2002
+ burlywood: "deb887",
2003
+ burntsienna: "ea7e5d",
2004
+ cadetblue: "5f9ea0",
2005
+ chartreuse: "7fff00",
2006
+ chocolate: "d2691e",
2007
+ coral: "ff7f50",
2008
+ cornflowerblue: "6495ed",
2009
+ cornsilk: "fff8dc",
2010
+ crimson: "dc143c",
2011
+ cyan: "0ff",
2012
+ darkblue: "00008b",
2013
+ darkcyan: "008b8b",
2014
+ darkgoldenrod: "b8860b",
2015
+ darkgray: "a9a9a9",
2016
+ darkgreen: "006400",
2017
+ darkgrey: "a9a9a9",
2018
+ darkkhaki: "bdb76b",
2019
+ darkmagenta: "8b008b",
2020
+ darkolivegreen: "556b2f",
2021
+ darkorange: "ff8c00",
2022
+ darkorchid: "9932cc",
2023
+ darkred: "8b0000",
2024
+ darksalmon: "e9967a",
2025
+ darkseagreen: "8fbc8f",
2026
+ darkslateblue: "483d8b",
2027
+ darkslategray: "2f4f4f",
2028
+ darkslategrey: "2f4f4f",
2029
+ darkturquoise: "00ced1",
2030
+ darkviolet: "9400d3",
2031
+ deeppink: "ff1493",
2032
+ deepskyblue: "00bfff",
2033
+ dimgray: "696969",
2034
+ dimgrey: "696969",
2035
+ dodgerblue: "1e90ff",
2036
+ firebrick: "b22222",
2037
+ floralwhite: "fffaf0",
2038
+ forestgreen: "228b22",
2039
+ fuchsia: "f0f",
2040
+ gainsboro: "dcdcdc",
2041
+ ghostwhite: "f8f8ff",
2042
+ gold: "ffd700",
2043
+ goldenrod: "daa520",
2044
+ gray: "808080",
2045
+ green: "008000",
2046
+ greenyellow: "adff2f",
2047
+ grey: "808080",
2048
+ honeydew: "f0fff0",
2049
+ hotpink: "ff69b4",
2050
+ indianred: "cd5c5c",
2051
+ indigo: "4b0082",
2052
+ ivory: "fffff0",
2053
+ khaki: "f0e68c",
2054
+ lavender: "e6e6fa",
2055
+ lavenderblush: "fff0f5",
2056
+ lawngreen: "7cfc00",
2057
+ lemonchiffon: "fffacd",
2058
+ lightblue: "add8e6",
2059
+ lightcoral: "f08080",
2060
+ lightcyan: "e0ffff",
2061
+ lightgoldenrodyellow: "fafad2",
2062
+ lightgray: "d3d3d3",
2063
+ lightgreen: "90ee90",
2064
+ lightgrey: "d3d3d3",
2065
+ lightpink: "ffb6c1",
2066
+ lightsalmon: "ffa07a",
2067
+ lightseagreen: "20b2aa",
2068
+ lightskyblue: "87cefa",
2069
+ lightslategray: "789",
2070
+ lightslategrey: "789",
2071
+ lightsteelblue: "b0c4de",
2072
+ lightyellow: "ffffe0",
2073
+ lime: "0f0",
2074
+ limegreen: "32cd32",
2075
+ linen: "faf0e6",
2076
+ magenta: "f0f",
2077
+ maroon: "800000",
2078
+ mediumaquamarine: "66cdaa",
2079
+ mediumblue: "0000cd",
2080
+ mediumorchid: "ba55d3",
2081
+ mediumpurple: "9370db",
2082
+ mediumseagreen: "3cb371",
2083
+ mediumslateblue: "7b68ee",
2084
+ mediumspringgreen: "00fa9a",
2085
+ mediumturquoise: "48d1cc",
2086
+ mediumvioletred: "c71585",
2087
+ midnightblue: "191970",
2088
+ mintcream: "f5fffa",
2089
+ mistyrose: "ffe4e1",
2090
+ moccasin: "ffe4b5",
2091
+ navajowhite: "ffdead",
2092
+ navy: "000080",
2093
+ oldlace: "fdf5e6",
2094
+ olive: "808000",
2095
+ olivedrab: "6b8e23",
2096
+ orange: "ffa500",
2097
+ orangered: "ff4500",
2098
+ orchid: "da70d6",
2099
+ palegoldenrod: "eee8aa",
2100
+ palegreen: "98fb98",
2101
+ paleturquoise: "afeeee",
2102
+ palevioletred: "db7093",
2103
+ papayawhip: "ffefd5",
2104
+ peachpuff: "ffdab9",
2105
+ peru: "cd853f",
2106
+ pink: "ffc0cb",
2107
+ plum: "dda0dd",
2108
+ powderblue: "b0e0e6",
2109
+ purple: "800080",
2110
+ rebeccapurple: "663399",
2111
+ red: "f00",
2112
+ rosybrown: "bc8f8f",
2113
+ royalblue: "4169e1",
2114
+ saddlebrown: "8b4513",
2115
+ salmon: "fa8072",
2116
+ sandybrown: "f4a460",
2117
+ seagreen: "2e8b57",
2118
+ seashell: "fff5ee",
2119
+ sienna: "a0522d",
2120
+ silver: "c0c0c0",
2121
+ skyblue: "87ceeb",
2122
+ slateblue: "6a5acd",
2123
+ slategray: "708090",
2124
+ slategrey: "708090",
2125
+ snow: "fffafa",
2126
+ springgreen: "00ff7f",
2127
+ steelblue: "4682b4",
2128
+ tan: "d2b48c",
2129
+ teal: "008080",
2130
+ thistle: "d8bfd8",
2131
+ tomato: "ff6347",
2132
+ turquoise: "40e0d0",
2133
+ violet: "ee82ee",
2134
+ wheat: "f5deb3",
2135
+ white: "fff",
2136
+ whitesmoke: "f5f5f5",
2137
+ yellow: "ff0",
2138
+ yellowgreen: "9acd32"
2139
+ };
2140
+
2141
+ // Make it easy to access colors via `hexNames[hex]`
2142
+ var hexNames = tinycolor.hexNames = flip(names);
2143
+
2144
+
2145
+ // Utilities
2146
+ // ---------
2147
+
2148
+ // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
2149
+ function flip(o) {
2150
+ var flipped = { };
2151
+ for (var i in o) {
2152
+ if (o.hasOwnProperty(i)) {
2153
+ flipped[o[i]] = i;
2154
+ }
2155
+ }
2156
+ return flipped;
2157
+ }
2158
+
2159
+ // Return a valid alpha value [0,1] with all invalid values being set to 1
2160
+ function boundAlpha(a) {
2161
+ a = parseFloat(a);
2162
+
2163
+ if (isNaN(a) || a < 0 || a > 1) {
2164
+ a = 1;
2165
+ }
2166
+
2167
+ return a;
2168
+ }
2169
+
2170
+ // Take input from [0, n] and return it as [0, 1]
2171
+ function bound01(n, max) {
2172
+ if (isOnePointZero(n)) { n = "100%"; }
2173
+
2174
+ var processPercent = isPercentage(n);
2175
+ n = mathMin(max, mathMax(0, parseFloat(n)));
2176
+
2177
+ // Automatically convert percentage into number
2178
+ if (processPercent) {
2179
+ n = parseInt(n * max, 10) / 100;
2180
+ }
2181
+
2182
+ // Handle floating point rounding errors
2183
+ if ((math.abs(n - max) < 0.000001)) {
2184
+ return 1;
2185
+ }
2186
+
2187
+ // Convert into [0, 1] range if it isn't already
2188
+ return (n % max) / parseFloat(max);
2189
+ }
2190
+
2191
+ // Force a number between 0 and 1
2192
+ function clamp01(val) {
2193
+ return mathMin(1, mathMax(0, val));
2194
+ }
2195
+
2196
+ // Parse a base-16 hex value into a base-10 integer
2197
+ function parseIntFromHex(val) {
2198
+ return parseInt(val, 16);
2199
+ }
2200
+
2201
+ // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
2202
+ // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
2203
+ function isOnePointZero(n) {
2204
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
2205
+ }
2206
+
2207
+ // Check to see if string passed in is a percentage
2208
+ function isPercentage(n) {
2209
+ return typeof n === "string" && n.indexOf('%') != -1;
2210
+ }
2211
+
2212
+ // Force a hex value to have 2 characters
2213
+ function pad2(c) {
2214
+ return c.length == 1 ? '0' + c : '' + c;
2215
+ }
2216
+
2217
+ // Replace a decimal with it's percentage value
2218
+ function convertToPercentage(n) {
2219
+ if (n <= 1) {
2220
+ n = (n * 100) + "%";
2221
+ }
2222
+
2223
+ return n;
2224
+ }
2225
+
2226
+ // Converts a decimal to a hex value
2227
+ function convertDecimalToHex(d) {
2228
+ return Math.round(parseFloat(d) * 255).toString(16);
2229
+ }
2230
+ // Converts a hex value to a decimal
2231
+ function convertHexToDecimal(h) {
2232
+ return (parseIntFromHex(h) / 255);
2233
+ }
2234
+
2235
+ var matchers = (function() {
2236
+
2237
+ // <http://www.w3.org/TR/css3-values/#integers>
2238
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
2239
+
2240
+ // <http://www.w3.org/TR/css3-values/#number-value>
2241
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
2242
+
2243
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
2244
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
2245
+
2246
+ // Actual matching.
2247
+ // Parentheses and commas are optional, but not required.
2248
+ // Whitespace can take the place of commas or opening paren
2249
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2250
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2251
+
2252
+ return {
2253
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
2254
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
2255
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
2256
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
2257
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
2258
+ hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
2259
+ hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
2260
+ hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
2261
+ hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
2262
+ };
2263
+ })();
2264
+
2265
+ // `stringInputToObject`
2266
+ // Permissive string parsing. Take in a number of formats, and output an object
2267
+ // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
2268
+ function stringInputToObject(color) {
2269
+
2270
+ color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
2271
+ var named = false;
2272
+ if (names[color]) {
2273
+ color = names[color];
2274
+ named = true;
2275
+ }
2276
+ else if (color == 'transparent') {
2277
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
2278
+ }
2279
+
2280
+ // Try to match string input using regular expressions.
2281
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
2282
+ // Just return an object and let the conversion functions handle that.
2283
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
2284
+ var match;
2285
+ if ((match = matchers.rgb.exec(color))) {
2286
+ return { r: match[1], g: match[2], b: match[3] };
2287
+ }
2288
+ if ((match = matchers.rgba.exec(color))) {
2289
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
2290
+ }
2291
+ if ((match = matchers.hsl.exec(color))) {
2292
+ return { h: match[1], s: match[2], l: match[3] };
2293
+ }
2294
+ if ((match = matchers.hsla.exec(color))) {
2295
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
2296
+ }
2297
+ if ((match = matchers.hsv.exec(color))) {
2298
+ return { h: match[1], s: match[2], v: match[3] };
2299
+ }
2300
+ if ((match = matchers.hsva.exec(color))) {
2301
+ return { h: match[1], s: match[2], v: match[3], a: match[4] };
2302
+ }
2303
+ if ((match = matchers.hex8.exec(color))) {
2304
+ return {
2305
+ a: convertHexToDecimal(match[1]),
2306
+ r: parseIntFromHex(match[2]),
2307
+ g: parseIntFromHex(match[3]),
2308
+ b: parseIntFromHex(match[4]),
2309
+ format: named ? "name" : "hex8"
2310
+ };
2311
+ }
2312
+ if ((match = matchers.hex6.exec(color))) {
2313
+ return {
2314
+ r: parseIntFromHex(match[1]),
2315
+ g: parseIntFromHex(match[2]),
2316
+ b: parseIntFromHex(match[3]),
2317
+ format: named ? "name" : "hex"
2318
+ };
2319
+ }
2320
+ if ((match = matchers.hex3.exec(color))) {
2321
+ return {
2322
+ r: parseIntFromHex(match[1] + '' + match[1]),
2323
+ g: parseIntFromHex(match[2] + '' + match[2]),
2324
+ b: parseIntFromHex(match[3] + '' + match[3]),
2325
+ format: named ? "name" : "hex"
2326
+ };
2327
+ }
2328
+
2329
+ return false;
2330
+ }
2331
+
2332
+ window.tinycolor = tinycolor;
2333
+ })();
2334
+
2335
+ $(function () {
2336
+ if ($.fn.spectrum.load) {
2337
+ $.fn.spectrum.processNativeColorInputs();
2338
+ }
2339
+ });
2340
+
2341
+ });
media/js/lib/spectrum.min.js CHANGED
@@ -1,5 +1,5 @@
1
- // Spectrum Colorpicker v1.8.1
2
- // https://github.com/bgrins/spectrum
3
- // Author: Brian Grinstead
4
- // License: MIT
5
  !function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports&&"object"==typeof module?module.exports=t(require("jquery")):t(jQuery)}(function(jt,Et){"use strict";var t,Dt={beforeShow:r,move:r,change:r,show:r,hide:r,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},It=[],zt=!!/msie/i.exec(window.navigator.userAgent),Bt=((t=document.createElement("div").style).cssText="background-color:rgba(0,0,0,.5)",e(t.backgroundColor,"rgba")||e(t.backgroundColor,"hsla")),Lt=["<div class='sp-replacer'>","<div class='sp-preview'><div class='sp-preview-inner'></div></div>","<div class='sp-dd'>&#9660;</div>","</div>"].join(""),Kt=function(){var t="";if(zt)for(var e=1;e<=6;e++)t+="<div class='sp-"+e+"'></div>";return["<div class='sp-container sp-hidden'>","<div class='sp-palette-container'>","<div class='sp-palette sp-thumb sp-cf'></div>","<div class='sp-palette-button-container sp-cf'>","<button type='button' class='sp-palette-toggle'></button>","</div>","</div>","<div class='sp-picker-container'>","<div class='sp-top sp-cf'>","<div class='sp-fill'></div>","<div class='sp-top-inner'>","<div class='sp-color'>","<div class='sp-sat'>","<div class='sp-val'>","<div class='sp-dragger'></div>","</div>","</div>","</div>","<div class='sp-clear sp-clear-display'>","</div>","<div class='sp-hue'>","<div class='sp-slider'></div>",t,"</div>","</div>","<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>","</div>","<div class='sp-input-container sp-cf'>","<input class='sp-input' type='text' spellcheck='false' />","</div>","<div class='sp-initial sp-thumb sp-cf'></div>","<div class='sp-button-container sp-cf'>","<a class='sp-cancel' href='#'></a>","<button type='button' class='sp-choose'></button>","</div>","</div>","</div>"].join("")}();function e(t,e){return!!~(""+t).indexOf(e)}function Vt(t,e,r,a){for(var n=[],o=0;o<t.length;o++){var i,s,l,c,f=t[o];f?(s=(i=tinycolor(f)).toHsl().l<.5?"sp-thumb-el sp-thumb-dark":"sp-thumb-el sp-thumb-light",s+=tinycolor.equals(e,f)?" sp-thumb-active":"",l=i.toString(a.preferredFormat||"rgb"),c=Bt?"background-color:"+i.toRgbString():"filter:"+i.toFilter(),n.push('<span title="'+l+'" data-color="'+i.toRgbString()+'" class="'+s+'"><span class="sp-thumb-inner" style="'+c+';"></span></span>')):n.push(jt("<div />").append(jt('<span data-color="" style="background-color:transparent;" class="sp-clear-display"></span>').attr("title",a.noColorSelectedText)).html())}return"<div class='sp-cf "+r+"'>"+n.join("")+"</div>"}function o(t,e){var r,a,n,o,i,s,l,u=(i=e,s=t,(l=jt.extend({},Dt,i)).callbacks={move:Wt(l.move,s),change:Wt(l.change,s),show:Wt(l.show,s),hide:Wt(l.hide,s),beforeShow:Wt(l.beforeShow,s)},l),d=u.flat,c=u.showSelectionPalette,f=u.localStorageKey,h=u.theme,p=u.callbacks,g=(r=Ot,function(){var t=this,e=arguments;n&&clearTimeout(o),!n&&o||(o=setTimeout(function(){o=null,r.apply(t,e)},a))}),b=!(a=10),v=!1,m=0,y=0,w=0,_=0,x=0,k=0,S=0,C=0,P=0,A=0,M=1,R=[],H=[],F={},T=u.selectionPalette.slice(0),O=u.maxSelectionSize,q="sp-dragging",N=null,j=t.ownerDocument,E=(j.body,jt(t)),D=!1,I=jt(Kt,j).addClass(h),z=I.find(".sp-picker-container"),B=I.find(".sp-color"),L=I.find(".sp-dragger"),K=I.find(".sp-hue"),V=I.find(".sp-slider"),$=I.find(".sp-alpha-inner"),W=I.find(".sp-alpha"),X=I.find(".sp-alpha-handle"),Y=I.find(".sp-input"),G=I.find(".sp-palette"),Q=I.find(".sp-initial"),J=I.find(".sp-cancel"),U=I.find(".sp-clear"),Z=I.find(".sp-choose"),tt=I.find(".sp-palette-toggle"),et=E.is("input"),rt=et&&"color"===E.attr("type")&&Yt(),at=et&&!d,nt=at?jt(Lt).addClass(h).addClass(u.className).addClass(u.replacerClassName):jt([]),ot=at?nt:E,it=nt.find(".sp-preview-inner"),st=u.color||et&&E.val(),lt=!1,ct=u.preferredFormat,ft=!u.showButtons||u.clickoutFiresChange,ht=!st,ut=u.allowEmpty&&!rt;function dt(){if(u.showPaletteOnly&&(u.showPalette=!0),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),u.palette){R=u.palette.slice(0),H=jt.isArray(R[0])?R:[R],F={};for(var t=0;t<H.length;t++)for(var e=0;e<H[t].length;e++){var r=tinycolor(H[t][e]).toRgbString();F[r]=!0}}I.toggleClass("sp-flat",d),I.toggleClass("sp-input-disabled",!u.showInput),I.toggleClass("sp-alpha-enabled",u.showAlpha),I.toggleClass("sp-clear-enabled",ut),I.toggleClass("sp-buttons-disabled",!u.showButtons),I.toggleClass("sp-palette-buttons-disabled",!u.togglePaletteOnly),I.toggleClass("sp-palette-disabled",!u.showPalette),I.toggleClass("sp-palette-only",u.showPaletteOnly),I.toggleClass("sp-initial-disabled",!u.showInitial),I.addClass(u.className).addClass(u.containerClassName),Ot()}function pt(){if(f&&window.localStorage){try{var t=window.localStorage[f].split(",#");1<t.length&&(delete window.localStorage[f],jt.each(t,function(t,e){gt(e)}))}catch(t){}try{T=window.localStorage[f].split(";")}catch(t){}}}function gt(t){if(c){var e=tinycolor(t).toRgbString();if(!F[e]&&-1===jt.inArray(e,T))for(T.push(e);T.length>O;)T.shift();if(f&&window.localStorage)try{window.localStorage[f]=T.join(";")}catch(t){}}}function bt(){var r=Mt(),t=jt.map(H,function(t,e){return Vt(t,r,"sp-palette-row sp-palette-row-"+e,u)});pt(),T&&t.push(Vt(function(){var t=[];if(u.showPalette)for(var e=0;e<T.length;e++){var r=tinycolor(T[e]).toRgbString();F[r]||t.push(T[e])}return t.reverse().slice(0,u.maxSelectionSize)}(),r,"sp-palette-row sp-palette-row-selection",u)),G.html(t.join(""))}function vt(){var t,e;u.showInitial&&(t=lt,e=Mt(),Q.html(Vt([t,e],e,"sp-palette-row-initial",u)))}function mt(){(y<=0||m<=0||_<=0)&&Ot(),v=!0,I.addClass(q),N=null,E.trigger("dragstart.spectrum",[Mt()])}function yt(){v=!1,I.removeClass(q),E.trigger("dragstop.spectrum",[Mt()])}function wt(){var t,e=Y.val();null!==e&&""!==e||!ut?(t=tinycolor(e)).isValid()?(At(t),Rt(),Tt()):Y.addClass("sp-validation-error"):(At(null),Rt(),Tt())}function _t(){(b?Ct:xt)()}function xt(){var t=jt.Event("beforeShow.spectrum");b?Ot():(E.trigger(t,[Mt()]),!1===p.beforeShow(Mt())||t.isDefaultPrevented()||(function(){for(var t=0;t<It.length;t++)It[t]&&It[t].hide()}(),b=!0,jt(j).on("keydown.spectrum",kt),jt(j).on("click.spectrum",St),jt(window).on("resize.spectrum",g),nt.addClass("sp-active"),I.removeClass("sp-hidden"),Ot(),Ht(),lt=Mt(),vt(),p.show(lt),E.trigger("show.spectrum",[lt])))}function kt(t){27===t.keyCode&&Ct()}function St(t){2!=t.button&&(v||(ft?Tt(!0):Pt(),Ct()))}function Ct(){b&&!d&&(b=!1,jt(j).off("keydown.spectrum",kt),jt(j).off("click.spectrum",St),jt(window).off("resize.spectrum",g),nt.removeClass("sp-active"),I.addClass("sp-hidden"),p.hide(Mt()),E.trigger("hide.spectrum",[Mt()]))}function Pt(){At(lt,!0),Tt(!0)}function At(t,e){var r,a;tinycolor.equals(t,Mt())?Ht():(!t&&ut?ht=!0:(ht=!1,a=(r=tinycolor(t)).toHsv(),C=a.h%360/360,P=a.s,A=a.v,M=a.a),Ht(),r&&r.isValid()&&!e&&(ct=u.preferredFormat||r.getFormat()))}function Mt(t){return t=t||{},ut&&ht?null:tinycolor.fromRatio({h:C,s:P,v:A,a:Math.round(1e3*M)/1e3},{format:t.format||ct})}function Rt(){Ht(),p.move(Mt()),E.trigger("move.spectrum",[Mt()])}function Ht(){Y.removeClass("sp-validation-error"),Ft();var t=tinycolor.fromRatio({h:C,s:1,v:1});B.css("background-color",t.toHexString());var e=ct;M<1&&(0!==M||"name"!==e)&&("hex"!==e&&"hex3"!==e&&"hex6"!==e&&"name"!==e||(e="rgb"));var r,a,n,o,i,s=Mt({format:e}),l="";it.removeClass("sp-clear-display"),it.css("background-color","transparent"),!s&&ut?it.addClass("sp-clear-display"):(r=s.toHexString(),a=s.toRgbString(),Bt||1===s.alpha?it.css("background-color",a):(it.css("background-color","transparent"),it.css("filter",s.toFilter())),u.showAlpha&&((n=s.toRgb()).a=0,i="linear-gradient(left, "+(o=tinycolor(n).toRgbString())+", "+r+")",zt?$.css("filter",tinycolor(o).toFilter({gradientType:1},r)):($.css("background","-webkit-"+i),$.css("background","-moz-"+i),$.css("background","-ms-"+i),$.css("background","linear-gradient(to right, "+o+", "+r+")"))),l=s.toString(e)),u.showInput&&Y.val(l),u.showPalette&&bt(),vt()}function Ft(){var t,e,r,a,n=P,o=A;ut&&ht?(X.hide(),V.hide(),L.hide()):(X.show(),V.show(),L.show(),t=n*m,e=y-o*y,t=Math.max(-w,Math.min(m-w,t-w)),e=Math.max(-w,Math.min(y-w,e-w)),L.css({top:e+"px",left:t+"px"}),r=M*x,X.css({left:r-k/2+"px"}),a=C*_,V.css({top:a-S+"px"}))}function Tt(t){var e=Mt(),r="",a=!tinycolor.equals(e,lt);e&&(r=e.toString(ct),gt(e)),et&&E.val(r),t&&a&&(p.change(e),E.trigger("change",[e]))}function Ot(){var t,e,r,a,n,o,i,s,l,c,f,h;b&&(m=B.width(),y=B.height(),w=L.height(),K.width(),_=K.height(),S=V.height(),x=W.width(),k=X.width(),d||(I.css("position","absolute"),u.offset?I.offset(u.offset):I.offset((e=ot,r=(t=I).outerWidth(),a=t.outerHeight(),n=e.outerHeight(),o=t[0].ownerDocument,i=o.documentElement,s=i.clientWidth+jt(o).scrollLeft(),l=i.clientHeight+jt(o).scrollTop(),c=e.offset(),f=c.left,h=c.top,h+=n,f-=Math.min(f,s<f+r&&r<s?Math.abs(f+r-s):0),{top:h-=Math.min(h,l<h+a&&a<l?Math.abs(+(a+n)):0),bottom:c.bottom,left:f,right:c.right,width:c.width,height:c.height}))),Ft(),u.showPalette&&bt(),E.trigger("reflow.spectrum"))}function qt(){Ct(),D=!0,E.attr("disabled",!0),ot.addClass("sp-disabled")}!function(){var t;function e(t){return t.data&&t.data.ignore?(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt()):(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt(),u.hideAfterPaletteSelect?(Tt(!0),Ct()):Tt()),!1}zt&&I.find("*:not(input)").attr("unselectable","on"),dt(),at&&E.after(nt).hide(),ut||U.hide(),d?E.after(I).hide():(1!==(t="parent"===u.appendTo?E.parent():jt(u.appendTo)).length&&(t=jt("body")),t.append(I)),pt(),ot.on("click.spectrum touchstart.spectrum",function(t){D||_t(),t.stopPropagation(),jt(t.target).is("input")||t.preventDefault()}),!E.is(":disabled")&&!0!==u.disabled||qt(),I.click($t),Y.change(wt),Y.on("paste",function(){setTimeout(wt,1)}),Y.keydown(function(t){13==t.keyCode&&wt()}),J.text(u.cancelText),J.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),Pt(),Ct()}),U.attr("title",u.clearText),U.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),ht=!0,Rt(),d&&Tt(!0)}),Z.text(u.chooseText),Z.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),zt&&Y.is(":focus")&&Y.trigger("change"),Y.hasClass("sp-validation-error")||(Tt(!0),Ct())}),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),tt.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),u.showPaletteOnly=!u.showPaletteOnly,u.showPaletteOnly||d||I.css("left","-="+(z.outerWidth(!0)+5)),dt()}),Xt(W,function(t,e,r){M=t/x,ht=!1,r.shiftKey&&(M=Math.round(10*M)/10),Rt()},mt,yt),Xt(K,function(t,e){C=parseFloat(e/_),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),Xt(B,function(t,e,r){var a,n,o;r.shiftKey?N||(a=P*m,n=y-A*y,o=Math.abs(t-a)>Math.abs(e-n),N=o?"x":"y"):N=null;var i=!N||"y"===N;N&&"x"!==N||(P=parseFloat(t/m)),i&&(A=parseFloat((y-e)/y)),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),st?(At(st),Ht(),ct=u.preferredFormat||tinycolor(st).format,gt(st)):Ht(),d&&xt();var r=zt?"mousedown.spectrum":"click.spectrum touchstart.spectrum";G.on(r,".sp-thumb-el",e),Q.on(r,".sp-thumb-el:nth-child(1)",{ignore:!0},e)}();var Nt={show:xt,hide:Ct,toggle:_t,reflow:Ot,option:function(t,e){return t===Et?jt.extend({},u):e===Et?u[t]:(u[t]=e,"preferredFormat"===t&&(ct=u.preferredFormat),void dt())},enable:function(){D=!1,E.attr("disabled",!1),ot.removeClass("sp-disabled")},disable:qt,offset:function(t){u.offset=t,Ot()},set:function(t){At(t),Tt()},get:Mt,destroy:function(){E.show(),ot.off("click.spectrum touchstart.spectrum"),I.remove(),nt.remove(),It[Nt.id]=null},container:I};return Nt.id=It.push(Nt)-1,Nt}function r(){}function $t(t){t.stopPropagation()}function Wt(t,e){var r=Array.prototype.slice,a=r.call(arguments,2);return function(){return t.apply(e,a.concat(r.call(arguments)))}}function Xt(i,s,e,t){s=s||function(){},e=e||function(){},t=t||function(){};var l=document,c=!1,f={},h=0,u=0,d="ontouchstart"in window,r={};function p(t){t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.returnValue=!1}function a(t){if(c){if(zt&&l.documentMode<9&&!t.button)return g();var e=t.originalEvent&&t.originalEvent.touches&&t.originalEvent.touches[0],r=e&&e.pageX||t.pageX,a=e&&e.pageY||t.pageY,n=Math.max(0,Math.min(r-f.left,u)),o=Math.max(0,Math.min(a-f.top,h));d&&p(t),s.apply(i,[n,o,t])}}function g(){c&&(jt(l).off(r),jt(l.body).removeClass("sp-dragging"),setTimeout(function(){t.apply(i,arguments)},0)),c=!1}r.selectstart=p,r.dragstart=p,r["touchmove mousemove"]=a,r["touchend mouseup"]=g,jt(i).on("touchstart mousedown",function(t){(t.which?3==t.which:2==t.button)||c||!1!==e.apply(i,arguments)&&(c=!0,h=jt(i).height(),u=jt(i).width(),f=jt(i).offset(),jt(l).on(r),jt(l.body).addClass("sp-dragging"),a(t),p(t))})}function Yt(){return jt.fn.spectrum.inputTypeColorSupport()}var i="spectrum.id";jt.fn.spectrum=function(r,t){if("string"!=typeof r)return this.spectrum("destroy").each(function(){var t=o(this,jt.extend({},jt(this).data(),r));jt(this).data(i,t.id)});var a=this,n=Array.prototype.slice.call(arguments,1);return this.each(function(){var t=It[jt(this).data(i)];if(t){var e=t[r];if(!e)throw new Error("Spectrum: no such method: '"+r+"'");"get"==r?a=t.get():"container"==r?a=t.container:"option"==r?a=t.option.apply(t,n):"destroy"==r?(t.destroy(),jt(this).removeData(i)):e.apply(t,n)}}),a},jt.fn.spectrum.load=!0,jt.fn.spectrum.loadOpts={},jt.fn.spectrum.draggable=Xt,jt.fn.spectrum.defaults=Dt,jt.fn.spectrum.inputTypeColorSupport=function t(){var e;return void 0===t._cachedResult&&(e=jt("<input type='color'/>")[0],t._cachedResult="color"===e.type&&""!==e.value),t._cachedResult},jt.spectrum={},jt.spectrum.localization={},jt.spectrum.palettes={},jt.fn.spectrum.processNativeColorInputs=function(){var t=jt("input[type=color]");t.length&&!Yt()&&t.spectrum({preferredFormat:"hex6"})},function(){var o=/^[\s,#]+/,i=/\s+$/,a=0,c=Math,s=c.round,f=c.min,h=c.max,t=c.random,u=function(t,e){if(e=e||{},(t=t||"")instanceof u)return t;if(!(this instanceof u))return new u(t,e);var r=function(t){var e={r:0,g:0,b:0},r=1,a=!1,n=!1;"string"==typeof t&&(t=function(t){t=t.replace(o,"").replace(i,"").toLowerCase();var e,r=!1;if(P[t])t=P[t],r=!0;else if("transparent"==t)return{r:0,g:0,b:0,a:0,format:"name"};if(e=E.rgb.exec(t))return{r:e[1],g:e[2],b:e[3]};if(e=E.rgba.exec(t))return{r:e[1],g:e[2],b:e[3],a:e[4]};if(e=E.hsl.exec(t))return{h:e[1],s:e[2],l:e[3]};if(e=E.hsla.exec(t))return{h:e[1],s:e[2],l:e[3],a:e[4]};if(e=E.hsv.exec(t))return{h:e[1],s:e[2],v:e[3]};if(e=E.hsva.exec(t))return{h:e[1],s:e[2],v:e[3],a:e[4]};if(e=E.hex8.exec(t))return{a:function(t){return F(t)/255}(e[1]),r:F(e[2]),g:F(e[3]),b:F(e[4]),format:r?"name":"hex8"};if(e=E.hex6.exec(t))return{r:F(e[1]),g:F(e[2]),b:F(e[3]),format:r?"name":"hex"};if(e=E.hex3.exec(t))return{r:F(e[1]+""+e[1]),g:F(e[2]+""+e[2]),b:F(e[3]+""+e[3]),format:r?"name":"hex"};return!1}(t));"object"==typeof t&&(t.hasOwnProperty("r")&&t.hasOwnProperty("g")&&t.hasOwnProperty("b")?(e=function(t,e,r){return{r:255*R(t,255),g:255*R(e,255),b:255*R(r,255)}}(t.r,t.g,t.b),a=!0,n="%"===String(t.r).substr(-1)?"prgb":"rgb"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("v")?(t.s=O(t.s),t.v=O(t.v),e=function(t,e,r){t=6*R(t,360),e=R(e,100),r=R(r,100);var a=c.floor(t),n=t-a,o=r*(1-e),i=r*(1-n*e),s=r*(1-(1-n)*e),l=a%6;return{r:255*[r,i,o,o,s,r][l],g:255*[s,r,r,i,o,o][l],b:255*[o,o,s,r,r,i][l]}}(t.h,t.s,t.v),a=!0,n="hsv"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("l")&&(t.s=O(t.s),t.l=O(t.l),e=function(t,e,r){var a,n,o;function i(t,e,r){return r<0&&(r+=1),1<r&&--r,r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}{var s,l;t=R(t,360),e=R(e,100),r=R(r,100),0===e?a=n=o=r:(a=i(l=2*r-(s=r<.5?r*(1+e):r+e-r*e),s,t+1/3),n=i(l,s,t),o=i(l,s,t-1/3))}return{r:255*a,g:255*n,b:255*o}}(t.h,t.s,t.l),a=!0,n="hsl"),t.hasOwnProperty("a")&&(r=t.a));return r=M(r),{ok:a,format:t.format||n,r:f(255,h(e.r,0)),g:f(255,h(e.g,0)),b:f(255,h(e.b,0)),a:r}}(t);this._originalInput=t,this._r=r.r,this._g=r.g,this._b=r.b,this._a=r.a,this._roundA=s(1e3*this._a)/1e3,this._format=e.format||r.format,this._gradientType=e.gradientType,this._r<1&&(this._r=s(this._r)),this._g<1&&(this._g=s(this._g)),this._b<1&&(this._b=s(this._b)),this._ok=r.ok,this._tc_id=a++};function n(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=(n+o)/2;if(n==o)a=l=0;else{var s=n-o,l=.5<i?s/(2-n-o):s/(n+o);switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,l:i}}function l(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=n,s=n-o,l=0===n?0:s/n;if(n==o)a=0;else{switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,v:i}}function e(t,e,r,a){var n=[T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))];return a&&n[0].charAt(0)==n[0].charAt(1)&&n[1].charAt(0)==n[1].charAt(1)&&n[2].charAt(0)==n[2].charAt(1)?n[0].charAt(0)+n[1].charAt(0)+n[2].charAt(0):n.join("")}function d(t,e,r,a){var n;return[T((n=a,Math.round(255*parseFloat(n)).toString(16))),T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))].join("")}function r(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s-=e/100,r.s=H(r.s),u(r)}function p(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s+=e/100,r.s=H(r.s),u(r)}function g(t){return u(t).desaturate(100)}function b(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l+=e/100,r.l=H(r.l),u(r)}function v(t,e){e=0===e?0:e||10;var r=u(t).toRgb();return r.r=h(0,f(255,r.r-s(-e/100*255))),r.g=h(0,f(255,r.g-s(-e/100*255))),r.b=h(0,f(255,r.b-s(-e/100*255))),u(r)}function m(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l-=e/100,r.l=H(r.l),u(r)}function y(t,e){var r=u(t).toHsl(),a=(s(r.h)+e)%360;return r.h=a<0?360+a:a,u(r)}function w(t){var e=u(t).toHsl();return e.h=(e.h+180)%360,u(e)}function _(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+120)%360,s:e.s,l:e.l}),u({h:(r+240)%360,s:e.s,l:e.l})]}function x(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+90)%360,s:e.s,l:e.l}),u({h:(r+180)%360,s:e.s,l:e.l}),u({h:(r+270)%360,s:e.s,l:e.l})]}function k(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+72)%360,s:e.s,l:e.l}),u({h:(r+216)%360,s:e.s,l:e.l})]}function S(t,e,r){e=e||6,r=r||30;var a=u(t).toHsl(),n=360/r,o=[u(t)];for(a.h=(a.h-(n*e>>1)+720)%360;--e;)a.h=(a.h+n)%360,o.push(u(a));return o}function C(t,e){e=e||6;for(var r=u(t).toHsv(),a=r.h,n=r.s,o=r.v,i=[],s=1/e;e--;)i.push(u({h:a,s:n,v:o})),o=(o+s)%1;return i}u.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},setAlpha:function(t){return this._a=M(t),this._roundA=s(1e3*this._a)/1e3,this},toHsv:function(){var t=l(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=l(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.v);return 1==this._a?"hsv("+e+", "+r+"%, "+a+"%)":"hsva("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHsl:function(){var t=n(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=n(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.l);return 1==this._a?"hsl("+e+", "+r+"%, "+a+"%)":"hsla("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHex:function(t){return e(this._r,this._g,this._b,t)},toHexString:function(t){return"#"+this.toHex(t)},toHex8:function(){return d(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:s(this._r),g:s(this._g),b:s(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+s(this._r)+", "+s(this._g)+", "+s(this._b)+")":"rgba("+s(this._r)+", "+s(this._g)+", "+s(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:s(100*R(this._r,255))+"%",g:s(100*R(this._g,255))+"%",b:s(100*R(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%)":"rgba("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&A[e(this._r,this._g,this._b,!0)]||!1},toFilter:function(t){var e="#"+d(this._r,this._g,this._b,this._a),r=e,a=this._gradientType?"GradientType = 1, ":"";return t&&(r=u(t).toHex8String()),"progid:DXImageTransform.Microsoft.gradient("+a+"startColorstr="+e+",endColorstr="+r+")"},toString:function(t){var e=!!t;t=t||this._format;var r=!1,a=this._a<1&&0<=this._a;return e||!a||"hex"!==t&&"hex6"!==t&&"hex3"!==t&&"name"!==t?("rgb"===t&&(r=this.toRgbString()),"prgb"===t&&(r=this.toPercentageRgbString()),"hex"!==t&&"hex6"!==t||(r=this.toHexString()),"hex3"===t&&(r=this.toHexString(!0)),"hex8"===t&&(r=this.toHex8String()),"name"===t&&(r=this.toName()),"hsl"===t&&(r=this.toHslString()),"hsv"===t&&(r=this.toHsvString()),r||this.toHexString()):"name"===t&&0===this._a?this.toName():this.toRgbString()},_applyModification:function(t,e){var r=t.apply(null,[this].concat([].slice.call(e)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(m,arguments)},desaturate:function(){return this._applyModification(r,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(y,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(S,arguments)},complement:function(){return this._applyCombination(w,arguments)},monochromatic:function(){return this._applyCombination(C,arguments)},splitcomplement:function(){return this._applyCombination(k,arguments)},triad:function(){return this._applyCombination(_,arguments)},tetrad:function(){return this._applyCombination(x,arguments)}},u.fromRatio=function(t,e){if("object"==typeof t){var r={};for(var a in t)t.hasOwnProperty(a)&&(r[a]="a"===a?t[a]:O(t[a]));t=r}return u(t,e)},u.equals=function(t,e){return!(!t||!e)&&u(t).toRgbString()==u(e).toRgbString()},u.random=function(){return u.fromRatio({r:t(),g:t(),b:t()})},u.mix=function(t,e,r){r=0===r?0:r||50;var a=u(t).toRgb(),n=u(e).toRgb(),o=r/100,i=2*o-1,s=n.a-a.a,l=i*s==-1?i:(i+s)/(1+i*s),c=1-(l=(l+1)/2),f={r:n.r*l+a.r*c,g:n.g*l+a.g*c,b:n.b*l+a.b*c,a:n.a*o+a.a*(1-o)};return u(f)},u.readability=function(t,e){var r=u(t),a=u(e),n=r.toRgb(),o=a.toRgb(),i=r.getBrightness(),s=a.getBrightness(),l=Math.max(n.r,o.r)-Math.min(n.r,o.r)+Math.max(n.g,o.g)-Math.min(n.g,o.g)+Math.max(n.b,o.b)-Math.min(n.b,o.b);return{brightness:Math.abs(i-s),color:l}},u.isReadable=function(t,e){var r=u.readability(t,e);return 125<r.brightness&&500<r.color},u.mostReadable=function(t,e){for(var r=null,a=0,n=!1,o=0;o<e.length;o++){var i=u.readability(t,e[o]),s=125<i.brightness&&500<i.color,l=i.brightness/125*3+i.color/500;(s&&!n||s&&n&&a<l||!s&&!n&&a<l)&&(n=s,a=l,r=u(e[o]))}return r};var P=u.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},A=u.hexNames=function(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[t[r]]=r);return e}(P);function M(t){return t=parseFloat(t),(isNaN(t)||t<0||1<t)&&(t=1),t}function R(t,e){var r;"string"==typeof(r=t)&&-1!=r.indexOf(".")&&1===parseFloat(r)&&(t="100%");var a,n="string"==typeof(a=t)&&-1!=a.indexOf("%");return t=f(e,h(0,parseFloat(t))),n&&(t=parseInt(t*e,10)/100),c.abs(t-e)<1e-6?1:t%e/parseFloat(e)}function H(t){return f(1,h(0,t))}function F(t){return parseInt(t,16)}function T(t){return 1==t.length?"0"+t:""+t}function O(t){return t<=1&&(t=100*t+"%"),t}var q,N,j,E=(N="[\\s|\\(]+("+(q="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",j="[\\s|\\(]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",{rgb:new RegExp("rgb"+N),rgba:new RegExp("rgba"+j),hsl:new RegExp("hsl"+N),hsla:new RegExp("hsla"+j),hsv:new RegExp("hsv"+N),hsva:new RegExp("hsva"+j),hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});window.tinycolor=u}(),jt(function(){jt.fn.spectrum.load&&jt.fn.spectrum.processNativeColorInputs()})});
1
+ // Spectrum Colorpicker v1.8.1
2
+ // https://github.com/bgrins/spectrum
3
+ // Author: Brian Grinstead
4
+ // License: MIT
5
  !function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports&&"object"==typeof module?module.exports=t(require("jquery")):t(jQuery)}(function(jt,Et){"use strict";var t,Dt={beforeShow:r,move:r,change:r,show:r,hide:r,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},It=[],zt=!!/msie/i.exec(window.navigator.userAgent),Bt=((t=document.createElement("div").style).cssText="background-color:rgba(0,0,0,.5)",e(t.backgroundColor,"rgba")||e(t.backgroundColor,"hsla")),Lt=["<div class='sp-replacer'>","<div class='sp-preview'><div class='sp-preview-inner'></div></div>","<div class='sp-dd'>&#9660;</div>","</div>"].join(""),Kt=function(){var t="";if(zt)for(var e=1;e<=6;e++)t+="<div class='sp-"+e+"'></div>";return["<div class='sp-container sp-hidden'>","<div class='sp-palette-container'>","<div class='sp-palette sp-thumb sp-cf'></div>","<div class='sp-palette-button-container sp-cf'>","<button type='button' class='sp-palette-toggle'></button>","</div>","</div>","<div class='sp-picker-container'>","<div class='sp-top sp-cf'>","<div class='sp-fill'></div>","<div class='sp-top-inner'>","<div class='sp-color'>","<div class='sp-sat'>","<div class='sp-val'>","<div class='sp-dragger'></div>","</div>","</div>","</div>","<div class='sp-clear sp-clear-display'>","</div>","<div class='sp-hue'>","<div class='sp-slider'></div>",t,"</div>","</div>","<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>","</div>","<div class='sp-input-container sp-cf'>","<input class='sp-input' type='text' spellcheck='false' />","</div>","<div class='sp-initial sp-thumb sp-cf'></div>","<div class='sp-button-container sp-cf'>","<a class='sp-cancel' href='#'></a>","<button type='button' class='sp-choose'></button>","</div>","</div>","</div>"].join("")}();function e(t,e){return!!~(""+t).indexOf(e)}function Vt(t,e,r,a){for(var n=[],o=0;o<t.length;o++){var i,s,l,c,f=t[o];f?(s=(i=tinycolor(f)).toHsl().l<.5?"sp-thumb-el sp-thumb-dark":"sp-thumb-el sp-thumb-light",s+=tinycolor.equals(e,f)?" sp-thumb-active":"",l=i.toString(a.preferredFormat||"rgb"),c=Bt?"background-color:"+i.toRgbString():"filter:"+i.toFilter(),n.push('<span title="'+l+'" data-color="'+i.toRgbString()+'" class="'+s+'"><span class="sp-thumb-inner" style="'+c+';"></span></span>')):n.push(jt("<div />").append(jt('<span data-color="" style="background-color:transparent;" class="sp-clear-display"></span>').attr("title",a.noColorSelectedText)).html())}return"<div class='sp-cf "+r+"'>"+n.join("")+"</div>"}function o(t,e){var r,a,n,o,i,s,l,u=(i=e,s=t,(l=jt.extend({},Dt,i)).callbacks={move:Wt(l.move,s),change:Wt(l.change,s),show:Wt(l.show,s),hide:Wt(l.hide,s),beforeShow:Wt(l.beforeShow,s)},l),d=u.flat,c=u.showSelectionPalette,f=u.localStorageKey,h=u.theme,p=u.callbacks,g=(r=Ot,function(){var t=this,e=arguments;n&&clearTimeout(o),!n&&o||(o=setTimeout(function(){o=null,r.apply(t,e)},a))}),b=!(a=10),v=!1,m=0,y=0,w=0,_=0,x=0,k=0,S=0,C=0,P=0,A=0,M=1,R=[],H=[],F={},T=u.selectionPalette.slice(0),O=u.maxSelectionSize,q="sp-dragging",N=null,j=t.ownerDocument,E=(j.body,jt(t)),D=!1,I=jt(Kt,j).addClass(h),z=I.find(".sp-picker-container"),B=I.find(".sp-color"),L=I.find(".sp-dragger"),K=I.find(".sp-hue"),V=I.find(".sp-slider"),$=I.find(".sp-alpha-inner"),W=I.find(".sp-alpha"),X=I.find(".sp-alpha-handle"),Y=I.find(".sp-input"),G=I.find(".sp-palette"),Q=I.find(".sp-initial"),J=I.find(".sp-cancel"),U=I.find(".sp-clear"),Z=I.find(".sp-choose"),tt=I.find(".sp-palette-toggle"),et=E.is("input"),rt=et&&"color"===E.attr("type")&&Yt(),at=et&&!d,nt=at?jt(Lt).addClass(h).addClass(u.className).addClass(u.replacerClassName):jt([]),ot=at?nt:E,it=nt.find(".sp-preview-inner"),st=u.color||et&&E.val(),lt=!1,ct=u.preferredFormat,ft=!u.showButtons||u.clickoutFiresChange,ht=!st,ut=u.allowEmpty&&!rt;function dt(){if(u.showPaletteOnly&&(u.showPalette=!0),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),u.palette){R=u.palette.slice(0),H=jt.isArray(R[0])?R:[R],F={};for(var t=0;t<H.length;t++)for(var e=0;e<H[t].length;e++){var r=tinycolor(H[t][e]).toRgbString();F[r]=!0}}I.toggleClass("sp-flat",d),I.toggleClass("sp-input-disabled",!u.showInput),I.toggleClass("sp-alpha-enabled",u.showAlpha),I.toggleClass("sp-clear-enabled",ut),I.toggleClass("sp-buttons-disabled",!u.showButtons),I.toggleClass("sp-palette-buttons-disabled",!u.togglePaletteOnly),I.toggleClass("sp-palette-disabled",!u.showPalette),I.toggleClass("sp-palette-only",u.showPaletteOnly),I.toggleClass("sp-initial-disabled",!u.showInitial),I.addClass(u.className).addClass(u.containerClassName),Ot()}function pt(){if(f&&window.localStorage){try{var t=window.localStorage[f].split(",#");1<t.length&&(delete window.localStorage[f],jt.each(t,function(t,e){gt(e)}))}catch(t){}try{T=window.localStorage[f].split(";")}catch(t){}}}function gt(t){if(c){var e=tinycolor(t).toRgbString();if(!F[e]&&-1===jt.inArray(e,T))for(T.push(e);T.length>O;)T.shift();if(f&&window.localStorage)try{window.localStorage[f]=T.join(";")}catch(t){}}}function bt(){var r=Mt(),t=jt.map(H,function(t,e){return Vt(t,r,"sp-palette-row sp-palette-row-"+e,u)});pt(),T&&t.push(Vt(function(){var t=[];if(u.showPalette)for(var e=0;e<T.length;e++){var r=tinycolor(T[e]).toRgbString();F[r]||t.push(T[e])}return t.reverse().slice(0,u.maxSelectionSize)}(),r,"sp-palette-row sp-palette-row-selection",u)),G.html(t.join(""))}function vt(){var t,e;u.showInitial&&(t=lt,e=Mt(),Q.html(Vt([t,e],e,"sp-palette-row-initial",u)))}function mt(){(y<=0||m<=0||_<=0)&&Ot(),v=!0,I.addClass(q),N=null,E.trigger("dragstart.spectrum",[Mt()])}function yt(){v=!1,I.removeClass(q),E.trigger("dragstop.spectrum",[Mt()])}function wt(){var t,e=Y.val();null!==e&&""!==e||!ut?(t=tinycolor(e)).isValid()?(At(t),Rt(),Tt()):Y.addClass("sp-validation-error"):(At(null),Rt(),Tt())}function _t(){(b?Ct:xt)()}function xt(){var t=jt.Event("beforeShow.spectrum");b?Ot():(E.trigger(t,[Mt()]),!1===p.beforeShow(Mt())||t.isDefaultPrevented()||(function(){for(var t=0;t<It.length;t++)It[t]&&It[t].hide()}(),b=!0,jt(j).on("keydown.spectrum",kt),jt(j).on("click.spectrum",St),jt(window).on("resize.spectrum",g),nt.addClass("sp-active"),I.removeClass("sp-hidden"),Ot(),Ht(),lt=Mt(),vt(),p.show(lt),E.trigger("show.spectrum",[lt])))}function kt(t){27===t.keyCode&&Ct()}function St(t){2!=t.button&&(v||(ft?Tt(!0):Pt(),Ct()))}function Ct(){b&&!d&&(b=!1,jt(j).off("keydown.spectrum",kt),jt(j).off("click.spectrum",St),jt(window).off("resize.spectrum",g),nt.removeClass("sp-active"),I.addClass("sp-hidden"),p.hide(Mt()),E.trigger("hide.spectrum",[Mt()]))}function Pt(){At(lt,!0),Tt(!0)}function At(t,e){var r,a;tinycolor.equals(t,Mt())?Ht():(!t&&ut?ht=!0:(ht=!1,a=(r=tinycolor(t)).toHsv(),C=a.h%360/360,P=a.s,A=a.v,M=a.a),Ht(),r&&r.isValid()&&!e&&(ct=u.preferredFormat||r.getFormat()))}function Mt(t){return t=t||{},ut&&ht?null:tinycolor.fromRatio({h:C,s:P,v:A,a:Math.round(1e3*M)/1e3},{format:t.format||ct})}function Rt(){Ht(),p.move(Mt()),E.trigger("move.spectrum",[Mt()])}function Ht(){Y.removeClass("sp-validation-error"),Ft();var t=tinycolor.fromRatio({h:C,s:1,v:1});B.css("background-color",t.toHexString());var e=ct;M<1&&(0!==M||"name"!==e)&&("hex"!==e&&"hex3"!==e&&"hex6"!==e&&"name"!==e||(e="rgb"));var r,a,n,o,i,s=Mt({format:e}),l="";it.removeClass("sp-clear-display"),it.css("background-color","transparent"),!s&&ut?it.addClass("sp-clear-display"):(r=s.toHexString(),a=s.toRgbString(),Bt||1===s.alpha?it.css("background-color",a):(it.css("background-color","transparent"),it.css("filter",s.toFilter())),u.showAlpha&&((n=s.toRgb()).a=0,i="linear-gradient(left, "+(o=tinycolor(n).toRgbString())+", "+r+")",zt?$.css("filter",tinycolor(o).toFilter({gradientType:1},r)):($.css("background","-webkit-"+i),$.css("background","-moz-"+i),$.css("background","-ms-"+i),$.css("background","linear-gradient(to right, "+o+", "+r+")"))),l=s.toString(e)),u.showInput&&Y.val(l),u.showPalette&&bt(),vt()}function Ft(){var t,e,r,a,n=P,o=A;ut&&ht?(X.hide(),V.hide(),L.hide()):(X.show(),V.show(),L.show(),t=n*m,e=y-o*y,t=Math.max(-w,Math.min(m-w,t-w)),e=Math.max(-w,Math.min(y-w,e-w)),L.css({top:e+"px",left:t+"px"}),r=M*x,X.css({left:r-k/2+"px"}),a=C*_,V.css({top:a-S+"px"}))}function Tt(t){var e=Mt(),r="",a=!tinycolor.equals(e,lt);e&&(r=e.toString(ct),gt(e)),et&&E.val(r),t&&a&&(p.change(e),E.trigger("change",[e]))}function Ot(){var t,e,r,a,n,o,i,s,l,c,f,h;b&&(m=B.width(),y=B.height(),w=L.height(),K.width(),_=K.height(),S=V.height(),x=W.width(),k=X.width(),d||(I.css("position","absolute"),u.offset?I.offset(u.offset):I.offset((e=ot,r=(t=I).outerWidth(),a=t.outerHeight(),n=e.outerHeight(),o=t[0].ownerDocument,i=o.documentElement,s=i.clientWidth+jt(o).scrollLeft(),l=i.clientHeight+jt(o).scrollTop(),c=e.offset(),f=c.left,h=c.top,h+=n,f-=Math.min(f,s<f+r&&r<s?Math.abs(f+r-s):0),{top:h-=Math.min(h,l<h+a&&a<l?Math.abs(+(a+n)):0),bottom:c.bottom,left:f,right:c.right,width:c.width,height:c.height}))),Ft(),u.showPalette&&bt(),E.trigger("reflow.spectrum"))}function qt(){Ct(),D=!0,E.attr("disabled",!0),ot.addClass("sp-disabled")}!function(){var t;function e(t){return t.data&&t.data.ignore?(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt()):(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt(),u.hideAfterPaletteSelect?(Tt(!0),Ct()):Tt()),!1}zt&&I.find("*:not(input)").attr("unselectable","on"),dt(),at&&E.after(nt).hide(),ut||U.hide(),d?E.after(I).hide():(1!==(t="parent"===u.appendTo?E.parent():jt(u.appendTo)).length&&(t=jt("body")),t.append(I)),pt(),ot.on("click.spectrum touchstart.spectrum",function(t){D||_t(),t.stopPropagation(),jt(t.target).is("input")||t.preventDefault()}),!E.is(":disabled")&&!0!==u.disabled||qt(),I.click($t),Y.change(wt),Y.on("paste",function(){setTimeout(wt,1)}),Y.keydown(function(t){13==t.keyCode&&wt()}),J.text(u.cancelText),J.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),Pt(),Ct()}),U.attr("title",u.clearText),U.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),ht=!0,Rt(),d&&Tt(!0)}),Z.text(u.chooseText),Z.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),zt&&Y.is(":focus")&&Y.trigger("change"),Y.hasClass("sp-validation-error")||(Tt(!0),Ct())}),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),tt.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),u.showPaletteOnly=!u.showPaletteOnly,u.showPaletteOnly||d||I.css("left","-="+(z.outerWidth(!0)+5)),dt()}),Xt(W,function(t,e,r){M=t/x,ht=!1,r.shiftKey&&(M=Math.round(10*M)/10),Rt()},mt,yt),Xt(K,function(t,e){C=parseFloat(e/_),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),Xt(B,function(t,e,r){var a,n,o;r.shiftKey?N||(a=P*m,n=y-A*y,o=Math.abs(t-a)>Math.abs(e-n),N=o?"x":"y"):N=null;var i=!N||"y"===N;N&&"x"!==N||(P=parseFloat(t/m)),i&&(A=parseFloat((y-e)/y)),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),st?(At(st),Ht(),ct=u.preferredFormat||tinycolor(st).format,gt(st)):Ht(),d&&xt();var r=zt?"mousedown.spectrum":"click.spectrum touchstart.spectrum";G.on(r,".sp-thumb-el",e),Q.on(r,".sp-thumb-el:nth-child(1)",{ignore:!0},e)}();var Nt={show:xt,hide:Ct,toggle:_t,reflow:Ot,option:function(t,e){return t===Et?jt.extend({},u):e===Et?u[t]:(u[t]=e,"preferredFormat"===t&&(ct=u.preferredFormat),void dt())},enable:function(){D=!1,E.attr("disabled",!1),ot.removeClass("sp-disabled")},disable:qt,offset:function(t){u.offset=t,Ot()},set:function(t){At(t),Tt()},get:Mt,destroy:function(){E.show(),ot.off("click.spectrum touchstart.spectrum"),I.remove(),nt.remove(),It[Nt.id]=null},container:I};return Nt.id=It.push(Nt)-1,Nt}function r(){}function $t(t){t.stopPropagation()}function Wt(t,e){var r=Array.prototype.slice,a=r.call(arguments,2);return function(){return t.apply(e,a.concat(r.call(arguments)))}}function Xt(i,s,e,t){s=s||function(){},e=e||function(){},t=t||function(){};var l=document,c=!1,f={},h=0,u=0,d="ontouchstart"in window,r={};function p(t){t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.returnValue=!1}function a(t){if(c){if(zt&&l.documentMode<9&&!t.button)return g();var e=t.originalEvent&&t.originalEvent.touches&&t.originalEvent.touches[0],r=e&&e.pageX||t.pageX,a=e&&e.pageY||t.pageY,n=Math.max(0,Math.min(r-f.left,u)),o=Math.max(0,Math.min(a-f.top,h));d&&p(t),s.apply(i,[n,o,t])}}function g(){c&&(jt(l).off(r),jt(l.body).removeClass("sp-dragging"),setTimeout(function(){t.apply(i,arguments)},0)),c=!1}r.selectstart=p,r.dragstart=p,r["touchmove mousemove"]=a,r["touchend mouseup"]=g,jt(i).on("touchstart mousedown",function(t){(t.which?3==t.which:2==t.button)||c||!1!==e.apply(i,arguments)&&(c=!0,h=jt(i).height(),u=jt(i).width(),f=jt(i).offset(),jt(l).on(r),jt(l.body).addClass("sp-dragging"),a(t),p(t))})}function Yt(){return jt.fn.spectrum.inputTypeColorSupport()}var i="spectrum.id";jt.fn.spectrum=function(r,t){if("string"!=typeof r)return this.spectrum("destroy").each(function(){var t=o(this,jt.extend({},jt(this).data(),r));jt(this).data(i,t.id)});var a=this,n=Array.prototype.slice.call(arguments,1);return this.each(function(){var t=It[jt(this).data(i)];if(t){var e=t[r];if(!e)throw new Error("Spectrum: no such method: '"+r+"'");"get"==r?a=t.get():"container"==r?a=t.container:"option"==r?a=t.option.apply(t,n):"destroy"==r?(t.destroy(),jt(this).removeData(i)):e.apply(t,n)}}),a},jt.fn.spectrum.load=!0,jt.fn.spectrum.loadOpts={},jt.fn.spectrum.draggable=Xt,jt.fn.spectrum.defaults=Dt,jt.fn.spectrum.inputTypeColorSupport=function t(){var e;return void 0===t._cachedResult&&(e=jt("<input type='color'/>")[0],t._cachedResult="color"===e.type&&""!==e.value),t._cachedResult},jt.spectrum={},jt.spectrum.localization={},jt.spectrum.palettes={},jt.fn.spectrum.processNativeColorInputs=function(){var t=jt("input[type=color]");t.length&&!Yt()&&t.spectrum({preferredFormat:"hex6"})},function(){var o=/^[\s,#]+/,i=/\s+$/,a=0,c=Math,s=c.round,f=c.min,h=c.max,t=c.random,u=function(t,e){if(e=e||{},(t=t||"")instanceof u)return t;if(!(this instanceof u))return new u(t,e);var r=function(t){var e={r:0,g:0,b:0},r=1,a=!1,n=!1;"string"==typeof t&&(t=function(t){t=t.replace(o,"").replace(i,"").toLowerCase();var e,r=!1;if(P[t])t=P[t],r=!0;else if("transparent"==t)return{r:0,g:0,b:0,a:0,format:"name"};if(e=E.rgb.exec(t))return{r:e[1],g:e[2],b:e[3]};if(e=E.rgba.exec(t))return{r:e[1],g:e[2],b:e[3],a:e[4]};if(e=E.hsl.exec(t))return{h:e[1],s:e[2],l:e[3]};if(e=E.hsla.exec(t))return{h:e[1],s:e[2],l:e[3],a:e[4]};if(e=E.hsv.exec(t))return{h:e[1],s:e[2],v:e[3]};if(e=E.hsva.exec(t))return{h:e[1],s:e[2],v:e[3],a:e[4]};if(e=E.hex8.exec(t))return{a:function(t){return F(t)/255}(e[1]),r:F(e[2]),g:F(e[3]),b:F(e[4]),format:r?"name":"hex8"};if(e=E.hex6.exec(t))return{r:F(e[1]),g:F(e[2]),b:F(e[3]),format:r?"name":"hex"};if(e=E.hex3.exec(t))return{r:F(e[1]+""+e[1]),g:F(e[2]+""+e[2]),b:F(e[3]+""+e[3]),format:r?"name":"hex"};return!1}(t));"object"==typeof t&&(t.hasOwnProperty("r")&&t.hasOwnProperty("g")&&t.hasOwnProperty("b")?(e=function(t,e,r){return{r:255*R(t,255),g:255*R(e,255),b:255*R(r,255)}}(t.r,t.g,t.b),a=!0,n="%"===String(t.r).substr(-1)?"prgb":"rgb"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("v")?(t.s=O(t.s),t.v=O(t.v),e=function(t,e,r){t=6*R(t,360),e=R(e,100),r=R(r,100);var a=c.floor(t),n=t-a,o=r*(1-e),i=r*(1-n*e),s=r*(1-(1-n)*e),l=a%6;return{r:255*[r,i,o,o,s,r][l],g:255*[s,r,r,i,o,o][l],b:255*[o,o,s,r,r,i][l]}}(t.h,t.s,t.v),a=!0,n="hsv"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("l")&&(t.s=O(t.s),t.l=O(t.l),e=function(t,e,r){var a,n,o;function i(t,e,r){return r<0&&(r+=1),1<r&&--r,r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}{var s,l;t=R(t,360),e=R(e,100),r=R(r,100),0===e?a=n=o=r:(a=i(l=2*r-(s=r<.5?r*(1+e):r+e-r*e),s,t+1/3),n=i(l,s,t),o=i(l,s,t-1/3))}return{r:255*a,g:255*n,b:255*o}}(t.h,t.s,t.l),a=!0,n="hsl"),t.hasOwnProperty("a")&&(r=t.a));return r=M(r),{ok:a,format:t.format||n,r:f(255,h(e.r,0)),g:f(255,h(e.g,0)),b:f(255,h(e.b,0)),a:r}}(t);this._originalInput=t,this._r=r.r,this._g=r.g,this._b=r.b,this._a=r.a,this._roundA=s(1e3*this._a)/1e3,this._format=e.format||r.format,this._gradientType=e.gradientType,this._r<1&&(this._r=s(this._r)),this._g<1&&(this._g=s(this._g)),this._b<1&&(this._b=s(this._b)),this._ok=r.ok,this._tc_id=a++};function n(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=(n+o)/2;if(n==o)a=l=0;else{var s=n-o,l=.5<i?s/(2-n-o):s/(n+o);switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,l:i}}function l(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=n,s=n-o,l=0===n?0:s/n;if(n==o)a=0;else{switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,v:i}}function e(t,e,r,a){var n=[T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))];return a&&n[0].charAt(0)==n[0].charAt(1)&&n[1].charAt(0)==n[1].charAt(1)&&n[2].charAt(0)==n[2].charAt(1)?n[0].charAt(0)+n[1].charAt(0)+n[2].charAt(0):n.join("")}function d(t,e,r,a){var n;return[T((n=a,Math.round(255*parseFloat(n)).toString(16))),T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))].join("")}function r(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s-=e/100,r.s=H(r.s),u(r)}function p(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s+=e/100,r.s=H(r.s),u(r)}function g(t){return u(t).desaturate(100)}function b(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l+=e/100,r.l=H(r.l),u(r)}function v(t,e){e=0===e?0:e||10;var r=u(t).toRgb();return r.r=h(0,f(255,r.r-s(-e/100*255))),r.g=h(0,f(255,r.g-s(-e/100*255))),r.b=h(0,f(255,r.b-s(-e/100*255))),u(r)}function m(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l-=e/100,r.l=H(r.l),u(r)}function y(t,e){var r=u(t).toHsl(),a=(s(r.h)+e)%360;return r.h=a<0?360+a:a,u(r)}function w(t){var e=u(t).toHsl();return e.h=(e.h+180)%360,u(e)}function _(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+120)%360,s:e.s,l:e.l}),u({h:(r+240)%360,s:e.s,l:e.l})]}function x(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+90)%360,s:e.s,l:e.l}),u({h:(r+180)%360,s:e.s,l:e.l}),u({h:(r+270)%360,s:e.s,l:e.l})]}function k(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+72)%360,s:e.s,l:e.l}),u({h:(r+216)%360,s:e.s,l:e.l})]}function S(t,e,r){e=e||6,r=r||30;var a=u(t).toHsl(),n=360/r,o=[u(t)];for(a.h=(a.h-(n*e>>1)+720)%360;--e;)a.h=(a.h+n)%360,o.push(u(a));return o}function C(t,e){e=e||6;for(var r=u(t).toHsv(),a=r.h,n=r.s,o=r.v,i=[],s=1/e;e--;)i.push(u({h:a,s:n,v:o})),o=(o+s)%1;return i}u.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},setAlpha:function(t){return this._a=M(t),this._roundA=s(1e3*this._a)/1e3,this},toHsv:function(){var t=l(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=l(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.v);return 1==this._a?"hsv("+e+", "+r+"%, "+a+"%)":"hsva("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHsl:function(){var t=n(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=n(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.l);return 1==this._a?"hsl("+e+", "+r+"%, "+a+"%)":"hsla("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHex:function(t){return e(this._r,this._g,this._b,t)},toHexString:function(t){return"#"+this.toHex(t)},toHex8:function(){return d(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:s(this._r),g:s(this._g),b:s(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+s(this._r)+", "+s(this._g)+", "+s(this._b)+")":"rgba("+s(this._r)+", "+s(this._g)+", "+s(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:s(100*R(this._r,255))+"%",g:s(100*R(this._g,255))+"%",b:s(100*R(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%)":"rgba("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&A[e(this._r,this._g,this._b,!0)]||!1},toFilter:function(t){var e="#"+d(this._r,this._g,this._b,this._a),r=e,a=this._gradientType?"GradientType = 1, ":"";return t&&(r=u(t).toHex8String()),"progid:DXImageTransform.Microsoft.gradient("+a+"startColorstr="+e+",endColorstr="+r+")"},toString:function(t){var e=!!t;t=t||this._format;var r=!1,a=this._a<1&&0<=this._a;return e||!a||"hex"!==t&&"hex6"!==t&&"hex3"!==t&&"name"!==t?("rgb"===t&&(r=this.toRgbString()),"prgb"===t&&(r=this.toPercentageRgbString()),"hex"!==t&&"hex6"!==t||(r=this.toHexString()),"hex3"===t&&(r=this.toHexString(!0)),"hex8"===t&&(r=this.toHex8String()),"name"===t&&(r=this.toName()),"hsl"===t&&(r=this.toHslString()),"hsv"===t&&(r=this.toHsvString()),r||this.toHexString()):"name"===t&&0===this._a?this.toName():this.toRgbString()},_applyModification:function(t,e){var r=t.apply(null,[this].concat([].slice.call(e)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(m,arguments)},desaturate:function(){return this._applyModification(r,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(y,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(S,arguments)},complement:function(){return this._applyCombination(w,arguments)},monochromatic:function(){return this._applyCombination(C,arguments)},splitcomplement:function(){return this._applyCombination(k,arguments)},triad:function(){return this._applyCombination(_,arguments)},tetrad:function(){return this._applyCombination(x,arguments)}},u.fromRatio=function(t,e){if("object"==typeof t){var r={};for(var a in t)t.hasOwnProperty(a)&&(r[a]="a"===a?t[a]:O(t[a]));t=r}return u(t,e)},u.equals=function(t,e){return!(!t||!e)&&u(t).toRgbString()==u(e).toRgbString()},u.random=function(){return u.fromRatio({r:t(),g:t(),b:t()})},u.mix=function(t,e,r){r=0===r?0:r||50;var a=u(t).toRgb(),n=u(e).toRgb(),o=r/100,i=2*o-1,s=n.a-a.a,l=i*s==-1?i:(i+s)/(1+i*s),c=1-(l=(l+1)/2),f={r:n.r*l+a.r*c,g:n.g*l+a.g*c,b:n.b*l+a.b*c,a:n.a*o+a.a*(1-o)};return u(f)},u.readability=function(t,e){var r=u(t),a=u(e),n=r.toRgb(),o=a.toRgb(),i=r.getBrightness(),s=a.getBrightness(),l=Math.max(n.r,o.r)-Math.min(n.r,o.r)+Math.max(n.g,o.g)-Math.min(n.g,o.g)+Math.max(n.b,o.b)-Math.min(n.b,o.b);return{brightness:Math.abs(i-s),color:l}},u.isReadable=function(t,e){var r=u.readability(t,e);return 125<r.brightness&&500<r.color},u.mostReadable=function(t,e){for(var r=null,a=0,n=!1,o=0;o<e.length;o++){var i=u.readability(t,e[o]),s=125<i.brightness&&500<i.color,l=i.brightness/125*3+i.color/500;(s&&!n||s&&n&&a<l||!s&&!n&&a<l)&&(n=s,a=l,r=u(e[o]))}return r};var P=u.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},A=u.hexNames=function(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[t[r]]=r);return e}(P);function M(t){return t=parseFloat(t),(isNaN(t)||t<0||1<t)&&(t=1),t}function R(t,e){var r;"string"==typeof(r=t)&&-1!=r.indexOf(".")&&1===parseFloat(r)&&(t="100%");var a,n="string"==typeof(a=t)&&-1!=a.indexOf("%");return t=f(e,h(0,parseFloat(t))),n&&(t=parseInt(t*e,10)/100),c.abs(t-e)<1e-6?1:t%e/parseFloat(e)}function H(t){return f(1,h(0,t))}function F(t){return parseInt(t,16)}function T(t){return 1==t.length?"0"+t:""+t}function O(t){return t<=1&&(t=100*t+"%"),t}var q,N,j,E=(N="[\\s|\\(]+("+(q="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",j="[\\s|\\(]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",{rgb:new RegExp("rgb"+N),rgba:new RegExp("rgba"+j),hsl:new RegExp("hsl"+N),hsla:new RegExp("hsla"+j),hsv:new RegExp("hsv"+N),hsva:new RegExp("hsva"+j),hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});window.tinycolor=u}(),jt(function(){jt.fn.spectrum.load&&jt.fn.spectrum.processNativeColorInputs()})});
media/js/mptt-functions.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([,function(e,t){window.Registry=function(){"use strict";var e={};function t(e){var t=!1;return"function"==typeof e.getInstance&&(t=!0),t}return{register:function(n,i){if(!t(i))throw new Error('Invalide module "'+n+'". The function "getInstance" is not defined.');e[n]=i},unregister:function(t){delete e[t]},_get:function(t){var n=e[t];if(!n)throw new Error('The module "'+t+'" has not been registered or it was unregistered.');if("function"!=typeof n.getInstance)throw new Error('The module "'+t+'" can not be instantiated. The function "getInstance" is not defined.');return e[t].getInstance()},registryMap:function(n){for(var i in n)if(n.hasOwnProperty(i)){if(!t(n[i]))throw new Error('Invalide module "'+i+'" inside the collection. The function "getInstance" is not defined.');e[i]=n[i]}}}}(),Registry.register("adminFunctions",function(e){"use strict";var t,n;return{getInstance:function(){return t||(t={wpAjax:function(e,t,n){e.mptt_action=e.action,delete e.action,wp.ajax.send("route_url",{success:function(e){!_.isUndefined(n)&&_.isFunction(n)&&t(e)},error:function(e){!_.isUndefined(n)&&_.isFunction(n)?n(e):console.log(e)},data:e})},initJBox:function(e,i,r){e,n=i,t.buttonEvents(r)},buttonEvents:function(t){n.find("#insert-into").off("click").on("click",(function(){t(e(this).parents("form").serializeArray())}))},callModal:function(t,n,i){var r=e(window).outerHeight()-100,o=e(window).outerWidth()-60,s=(wp.html.string({tag:"span",attrs:{class:"spinner is-active"},content:""}),{content:t,closeOnEsc:!0,animation:{open:"zoomIn",close:"zoomOut"},width:o,height:r,closeButton:"title",title:"Shortcode Settings",onOpen:function(){var t=e("#"+this.id);n.call(this,t)},onClose:function(){e("#"+this.id).remove()}});_.isUndefined(i)||e.extend(s,i),new jBox("Modal",s).open()},parseRequest:function(t){var n,i=location.search,r={};return _.isEmpty(i)||"?"===i?r:(n=(i=i.replace("?","")).split("&"),e.each(n,(function(){var e=this;e=e.split("="),r[e[0]]=e[1]})),_.isUndefined(t)?r:r[t])},generateHTML:function(n){var i,r="";if(_.isObject(n)){var o=document.createElement(n.tag);_.isUndefined(n.attrs)||e.each(n.attrs,(function(e,t){_.isUndefined(t)||""===t||o.setAttribute(e,t)})),_.isArray(n.content)?(e.each(n.content,(function(e,n){r+=t.generateHTML(n)})),e(o).html(r)):_.isObject(n.content)?(r=t.generateHTML(n.content),e(o).html(r)):_.isUndefined(n.content)?e(o).html(""):e(o).html(n.content),i=e(o).get(0).outerHTML}else i=!!_.isString(n)&&n;return i},getHtml:function(n,i){if(_.isUndefined(n))return!1;var r=!1;if(_.isUndefined(i)&&(_.isArray(n)?(r="",e.each(n,(function(e,n){r+=t.generateHTML(n)}))):r=t.generateHTML(n)),_.isObject(i)){var o=_.template(r);r=o(i)}return r}}),t}}}(jQuery)),function(e){"use strict";e(document).ready((function(){var t=function(){var t=e("body");!function(){var e=window.navigator.userAgent,t=e.indexOf("MSIE ");if(t>0)return parseInt(e.substring(t+5,e.indexOf(".",t)),10);if(e.indexOf("Trident/")>0){var n=e.indexOf("rv:");return parseInt(e.substring(n+3,e.indexOf(".",n)),10)}return!1}()?t.removeClass("mprm_ie_browser"):t.hasClass("mprm_ie_browser")||t.addClass("mprm_ie_browser");var n=e(".mptt-shortcode-wrapper");if("undefined"!=typeof typenow&&pagenow===typenow)switch(typenow){case"mp-event":Registry._get("Event").init();break;case"mp-column":Registry._get("Event").initDatePicker(),Registry._get("Event").columnRadioBox()}n.length&&(Registry._get("Event").initTableData(),Registry._get("Event").filterShortcodeEvents(),Registry._get("Event").getFilterByHash(),n.show(),n.addClass("table-init")),(e(".upcoming-events-widget").length||n.length)&&Registry._get("Event").setColorSettings()};window.mptt={},window.mptt.tableInit=t,t()}))}(jQuery)}]);
1
+ window.wp=window.wp||{},window.wp["./media/js/mptt-functions"]=function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}({2:function(e,t){window.Registry=function(){"use strict";var e={};function t(e){var t=!1;return"function"==typeof e.getInstance&&(t=!0),t}return{register:function(n,i){if(!t(i))throw new Error('Invalide module "'+n+'". The function "getInstance" is not defined.');e[n]=i},unregister:function(t){delete e[t]},_get:function(t){var n=e[t];if(!n)throw new Error('The module "'+t+'" has not been registered or it was unregistered.');if("function"!=typeof n.getInstance)throw new Error('The module "'+t+'" can not be instantiated. The function "getInstance" is not defined.');return e[t].getInstance()},registryMap:function(n){for(var i in n)if(n.hasOwnProperty(i)){if(!t(n[i]))throw new Error('Invalide module "'+i+'" inside the collection. The function "getInstance" is not defined.');e[i]=n[i]}}}}(),Registry.register("adminFunctions",function(e){"use strict";var t,n;return{getInstance:function(){return t||(t={wpAjax:function(e,t,n){e.mptt_action=e.action,delete e.action,wp.ajax.send("route_url",{success:function(e){!_.isUndefined(n)&&_.isFunction(n)&&t(e)},error:function(e){!_.isUndefined(n)&&_.isFunction(n)?n(e):console.log(e)},data:e})},initJBox:function(e,i,r){e,n=i,t.buttonEvents(r)},buttonEvents:function(t){n.find("#insert-into").off("click").on("click",(function(){t(e(this).parents("form").serializeArray())}))},callModal:function(t,n,i){var r=e(window).outerHeight()-100,o=e(window).outerWidth()-60,s=(wp.html.string({tag:"span",attrs:{class:"spinner is-active"},content:""}),{content:t,closeOnEsc:!0,animation:{open:"zoomIn",close:"zoomOut"},width:o,height:r,closeButton:"title",title:"Shortcode Settings",onOpen:function(){var t=e("#"+this.id);n.call(this,t)},onClose:function(){e("#"+this.id).remove()}});_.isUndefined(i)||e.extend(s,i),new jBox("Modal",s).open()},parseRequest:function(t){var n,i=location.search,r={};return _.isEmpty(i)||"?"===i?r:(n=(i=i.replace("?","")).split("&"),e.each(n,(function(){var e=this;e=e.split("="),r[e[0]]=e[1]})),_.isUndefined(t)?r:r[t])},generateHTML:function(n){var i,r="";if(_.isObject(n)){var o=document.createElement(n.tag);_.isUndefined(n.attrs)||e.each(n.attrs,(function(e,t){_.isUndefined(t)||""===t||o.setAttribute(e,t)})),_.isArray(n.content)?(e.each(n.content,(function(e,n){r+=t.generateHTML(n)})),e(o).html(r)):_.isObject(n.content)?(r=t.generateHTML(n.content),e(o).html(r)):_.isUndefined(n.content)?e(o).html(""):e(o).html(n.content),i=e(o).get(0).outerHTML}else i=!!_.isString(n)&&n;return i},getHtml:function(n,i){if(_.isUndefined(n))return!1;var r=!1;if(_.isUndefined(i)&&(_.isArray(n)?(r="",e.each(n,(function(e,n){r+=t.generateHTML(n)}))):r=t.generateHTML(n)),_.isObject(i)){var o=_.template(r);r=o(i)}return r}}),t}}}(jQuery)),function(e){"use strict";e(document).ready((function(){var t=function(){var t=e("body");!function(){var e=window.navigator.userAgent,t=e.indexOf("MSIE ");if(t>0)return parseInt(e.substring(t+5,e.indexOf(".",t)),10);if(e.indexOf("Trident/")>0){var n=e.indexOf("rv:");return parseInt(e.substring(n+3,e.indexOf(".",n)),10)}return!1}()?t.removeClass("mprm_ie_browser"):t.hasClass("mprm_ie_browser")||t.addClass("mprm_ie_browser");var n=e(".mptt-shortcode-wrapper");if("undefined"!=typeof typenow&&pagenow===typenow)switch(typenow){case"mp-event":Registry._get("Event").init();break;case"mp-column":Registry._get("Event").initDatePicker(),Registry._get("Event").columnRadioBox()}n.length&&(Registry._get("Event").initTableData(),Registry._get("Event").filterShortcodeEvents(),Registry._get("Event").getFilterByHash(),n.show(),n.addClass("table-init")),(e(".upcoming-events-widget").length||n.length)&&Registry._get("Event").setColorSettings()};window.mptt={},window.mptt.tableInit=t,t()}))}(jQuery)}});
media/less/block-editor.less CHANGED
@@ -1,13 +1,13 @@
1
- .wp-block[data-type="mp-timetable/timetable"] div[data-block] {
2
- overflow: auto;
3
- }
4
-
5
- /*
6
- * TODO: WordPress 5.6 Select Multiple Fix
7
- */
8
- body.branch-5-6 .components-select-control.timetable-wp56-fix .components-select-control__input {
9
- height: auto !important;
10
- }
11
- body.branch-5-6 .components-select-control.timetable-wp56-fix .components-input-control__suffix {
12
- display: none !important;
13
- }
1
+ .wp-block[data-type="mp-timetable/timetable"] div[data-block] {
2
+ overflow: auto;
3
+ }
4
+
5
+ /*
6
+ * TODO: WordPress 5.6 Select Multiple Fix
7
+ */
8
+ body.branch-5-6 .components-select-control.timetable-wp56-fix .components-select-control__input {
9
+ height: auto !important;
10
+ }
11
+ body.branch-5-6 .components-select-control.timetable-wp56-fix .components-input-control__suffix {
12
+ display: none !important;
13
+ }
mp-timetable.php CHANGED
@@ -1,273 +1,273 @@
1
- <?php
2
-
3
- /**
4
- * Plugin Name: Timetable and Event Schedule
5
- * Plugin URI: https://motopress.com/products/timetable-event-schedule/
6
- * Description: Smart time-management tool with a clean minimalist design for featuring your timetables and upcoming events.
7
- * Version: 2.3.12
8
- * Author: MotoPress
9
- * Author URI: https://motopress.com
10
- * License: GPLv2 or later
11
- * Text Domain: mp-timetable
12
- * Domain Path: /languages
13
- */
14
-
15
- /*
16
- * This plugin contains hooks that allow you to edit, add and move content without the need to edit template files.
17
- * This method protects against upgrade issues. There are several actions and filters you can use to modify content output.
18
- * You can check \mp-timetable\classes\class-hooks.php for the list of hooks.
19
- *
20
- * Alternatively in "Developer Mode", you can copy template files from '/mp-timetable/templates/' folder to '/your-theme/mp-timetable/' to override them.
21
- *
22
- * The Timetable plugin also supports default WordPress templates hierarchy:
23
- * https://developer.wordpress.org/themes/basics/template-hierarchy/#visual-overview
24
- */
25
-
26
- defined( 'ABSPATH' ) || exit;
27
-
28
- use mp_timetable\plugin_core\classes\Core;
29
-
30
- if ( ! defined( 'MP_TT_PLUGIN_NAME' ) ) {
31
- define( "MP_TT_PLUGIN_NAME", 'mp-timetable' );
32
- }
33
-
34
- if ( ! defined( 'MP_TT_DEBUG' ) ) {
35
- define( 'MP_TT_DEBUG', false );
36
- }
37
-
38
- if ( ! defined( 'MP_TT_PLUGIN_FILE' ) ) {
39
- define( 'MP_TT_PLUGIN_FILE', __FILE__ );
40
- }
41
-
42
- if ( ! defined( 'MP_TT_PLUGIN_BASENAME' ) ) {
43
- define( 'MP_TT_PLUGIN_BASENAME', plugin_basename( MP_TT_PLUGIN_FILE ) );
44
- }
45
-
46
- register_activation_hook( __FILE__, array( Mp_Time_Table::init(), 'on_activation' ) );
47
- register_deactivation_hook( __FILE__, array( 'Mp_Time_Table', 'on_deactivation' ) );
48
- register_uninstall_hook( __FILE__, array( 'Mp_Time_Table', 'on_uninstall' ) );
49
-
50
- add_action( 'plugins_loaded', array( 'Mp_Time_Table', 'init' ) );
51
- add_action( 'wpmu_new_blog', array( 'Mp_Time_Table', 'on_create_blog' ), 10, 6 );
52
- add_filter( 'wpmu_drop_tables', array( 'Mp_Time_Table', 'on_delete_blog' ) );
53
-
54
- /**
55
- * Class Mp_Time_Table
56
- */
57
- class Mp_Time_Table {
58
-
59
- protected static $instance;
60
-
61
- /**
62
- * Mp_Time_Table constructor.
63
- */
64
- public function __construct() {
65
- $this->include_all();
66
- Core::get_instance()->init_plugin( 'mp_timetable' );
67
- }
68
-
69
- /**
70
- * Include all files
71
- */
72
- public function include_all() {
73
- /**
74
- * Include Gump
75
- */
76
- require_once self::get_plugin_path() . 'classes/libs/class-gump.php';
77
- /**
78
- * Install Parsers
79
- */
80
- require_once self::get_plugin_path() . 'classes/libs/parsers.php';
81
- /**
82
- * Include Permalinks
83
- */
84
- require_once self::get_plugin_path() . 'classes/class-permalinks.php';
85
- /**
86
- * Include Core
87
- */
88
- require_once self::get_plugin_path() . 'classes/class-core.php';
89
- /**
90
- * Include module
91
- */
92
- require_once self::get_plugin_path() . 'classes/class-module.php';
93
- /**
94
- * Include Model
95
- */
96
- require_once self::get_plugin_path() . 'classes/class-model.php';
97
-
98
- /**
99
- * Include Controller
100
- */
101
- require_once self::get_plugin_path() . 'classes/class-controller.php';
102
- /**
103
- * Include State factory
104
- */
105
- require_once self::get_plugin_path() . 'classes/class-state-factory.php';
106
-
107
- /**
108
- * Include Preprocessor
109
- */
110
- require_once self::get_plugin_path() . 'classes/class-preprocessor.php';
111
-
112
- /**
113
- * include shortcodes
114
- */
115
- require_once( self::get_plugin_path() . 'classes/class-shortcode.php' );
116
- /**
117
- * include Widgets
118
- */
119
- require_once self::get_plugin_path() . 'classes/widgets/class-mp-timetable-widget.php';
120
- /**
121
- * Include view
122
- */
123
- require_once self::get_plugin_path() . 'classes/class-view.php';
124
- /**
125
- * Include hooks
126
- */
127
- require_once self::get_plugin_path() . 'classes/class-hooks.php';
128
-
129
- /**
130
- * Include blocks
131
- */
132
- require_once self::get_plugin_path() . 'classes/blocks/class-timetable-block.php';
133
- }
134
-
135
- /**
136
- * Get plugin path
137
- */
138
- public static function get_plugin_path() {
139
- return plugin_dir_path( __FILE__ );
140
- }
141
-
142
- /**
143
- * @return Mp_Time_Table
144
- */
145
- public static function init() {
146
- if ( null === self::$instance ) {
147
- self::$instance = new self();
148
- }
149
-
150
- return self::$instance;
151
- }
152
-
153
- /**
154
- * Retrieve relative to theme root path to templates.
155
- *
156
- * @return string
157
- */
158
- public static function get_template_path() {
159
- return apply_filters( 'mptt_template_path', 'mp-timetable/' );
160
- }
161
-
162
- /**
163
- * Retrieve relative to plugin root path to templates.
164
- *
165
- * @return string
166
- */
167
- public static function get_templates_path() {
168
- return self::get_plugin_path() . 'templates/';
169
- }
170
-
171
- /**
172
- * Get plugin part path
173
- *
174
- * @param string $part
175
- *
176
- * @return string
177
- */
178
- public static function get_plugin_part_path( $part = '' ) {
179
- return self::get_plugin_path() . $part;
180
- }
181
-
182
- /**
183
- * On activation
184
- */
185
- public static function on_activation() {
186
- // Register post type
187
- Core::get_instance()->register_all_post_type();
188
-
189
- // Register taxonomy all
190
- Core::get_instance()->register_all_taxonomies();
191
-
192
- flush_rewrite_rules();
193
-
194
- //Create table in not exists
195
- Core::get_instance()->create_table();
196
- }
197
-
198
- /**
199
- * On deactivation
200
- */
201
- public static function on_deactivation() {
202
- flush_rewrite_rules();
203
- }
204
-
205
- /**
206
- * On uninstall
207
- */
208
- public static function on_uninstall() {
209
- do_action( 'mptt_on_uninstall' );
210
- }
211
-
212
- /**
213
- * On create blog
214
- *
215
- * @param $blog_id
216
- * @param $user_id
217
- * @param $domain
218
- * @param $path
219
- * @param $site_id
220
- * @param $meta
221
- */
222
- public static function on_create_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
223
- if ( is_plugin_active_for_network( self::get_plugin_name() . '/' . self::get_plugin_name() . '.php' ) ) {
224
- switch_to_blog( $blog_id );
225
- //Create table in not exists
226
- Core::get_instance()->create_table();
227
- restore_current_blog();
228
- }
229
- }
230
-
231
- /**
232
- * Get plugin name
233
- *
234
- * @return string
235
- */
236
- public static function get_plugin_name() {
237
- return dirname( plugin_basename( __FILE__ ) );
238
- }
239
-
240
- /**
241
- * On blog creation
242
- */
243
- public static function on_delete_blog( $tables ) {
244
-
245
- $tables[] = self::get_datatable();
246
-
247
- return $tables;
248
- }
249
-
250
- /**
251
- * Get data table name
252
- *
253
- * @return string
254
- */
255
- public static function get_datatable() {
256
- global $wpdb;
257
-
258
- return $wpdb->prefix . "mp_timetable_data";
259
- }
260
-
261
- /**
262
- * Get plugin url
263
- *
264
- * @param bool|false $path
265
- * @param string $pluginName
266
- * @param string $sync
267
- *
268
- * @return string
269
- */
270
- static function get_plugin_url( $path = false, $pluginName = 'mp-timetable', $sync = '' ) {
271
- return plugins_url() . '/' . $pluginName . '/' . $path . $sync;
272
- }
273
- }
1
+ <?php
2
+
3
+ /**
4
+ * Plugin Name: Timetable and Event Schedule
5
+ * Plugin URI: https://motopress.com/products/timetable-event-schedule/
6
+ * Description: Smart time-management tool with a clean minimalist design for featuring your timetables and upcoming events.
7
+ * Version: 2.3.13
8
+ * Author: MotoPress
9
+ * Author URI: https://motopress.com
10
+ * License: GPLv2 or later
11
+ * Text Domain: mp-timetable
12
+ * Domain Path: /languages
13
+ */
14
+
15
+ /*
16
+ * This plugin contains hooks that allow you to edit, add and move content without the need to edit template files.
17
+ * This method protects against upgrade issues. There are several actions and filters you can use to modify content output.
18
+ * You can check \mp-timetable\classes\class-hooks.php for the list of hooks.
19
+ *
20
+ * Alternatively in "Developer Mode", you can copy template files from '/mp-timetable/templates/' folder to '/your-theme/mp-timetable/' to override them.
21
+ *
22
+ * The Timetable plugin also supports default WordPress templates hierarchy:
23
+ * https://developer.wordpress.org/themes/basics/template-hierarchy/#visual-overview
24
+ */
25
+
26
+ defined( 'ABSPATH' ) || exit;
27
+
28
+ use mp_timetable\plugin_core\classes\Core;
29
+
30
+ if ( ! defined( 'MP_TT_PLUGIN_NAME' ) ) {
31
+ define( "MP_TT_PLUGIN_NAME", 'mp-timetable' );
32
+ }
33
+
34
+ if ( ! defined( 'MP_TT_DEBUG' ) ) {
35
+ define( 'MP_TT_DEBUG', false );
36
+ }
37
+
38
+ if ( ! defined( 'MP_TT_PLUGIN_FILE' ) ) {
39
+ define( 'MP_TT_PLUGIN_FILE', __FILE__ );
40
+ }
41
+
42
+ if ( ! defined( 'MP_TT_PLUGIN_BASENAME' ) ) {
43
+ define( 'MP_TT_PLUGIN_BASENAME', plugin_basename( MP_TT_PLUGIN_FILE ) );
44
+ }
45
+
46
+ register_activation_hook( __FILE__, array( Mp_Time_Table::init(), 'on_activation' ) );
47
+ register_deactivation_hook( __FILE__, array( 'Mp_Time_Table', 'on_deactivation' ) );
48
+ register_uninstall_hook( __FILE__, array( 'Mp_Time_Table', 'on_uninstall' ) );
49
+
50
+ add_action( 'plugins_loaded', array( 'Mp_Time_Table', 'init' ) );
51
+ add_action( 'wpmu_new_blog', array( 'Mp_Time_Table', 'on_create_blog' ), 10, 6 );
52
+ add_filter( 'wpmu_drop_tables', array( 'Mp_Time_Table', 'on_delete_blog' ) );
53
+
54
+ /**
55
+ * Class Mp_Time_Table
56
+ */
57
+ class Mp_Time_Table {
58
+
59
+ protected static $instance;
60
+
61
+ /**
62
+ * Mp_Time_Table constructor.
63
+ */
64
+ public function __construct() {
65
+ $this->include_all();
66
+ Core::get_instance()->init_plugin( 'mp_timetable' );
67
+ }
68
+
69
+ /**
70
+ * Include all files
71
+ */
72
+ public function include_all() {
73
+ /**
74
+ * Include Gump
75
+ */
76
+ require_once self::get_plugin_path() . 'classes/libs/class-gump.php';
77
+ /**
78
+ * Install Parsers
79
+ */
80
+ require_once self::get_plugin_path() . 'classes/libs/parsers.php';
81
+ /**
82
+ * Include Permalinks
83
+ */
84
+ require_once self::get_plugin_path() . 'classes/class-permalinks.php';
85
+ /**
86
+ * Include Core
87
+ */
88
+ require_once self::get_plugin_path() . 'classes/class-core.php';
89
+ /**
90
+ * Include module
91
+ */
92
+ require_once self::get_plugin_path() . 'classes/class-module.php';
93
+ /**
94
+ * Include Model
95
+ */
96
+ require_once self::get_plugin_path() . 'classes/class-model.php';
97
+
98
+ /**
99
+ * Include Controller
100
+ */
101
+ require_once self::get_plugin_path() . 'classes/class-controller.php';
102
+ /**
103
+ * Include State factory
104
+ */
105
+ require_once self::get_plugin_path() . 'classes/class-state-factory.php';
106
+
107
+ /**
108
+ * Include Preprocessor
109
+ */
110
+ require_once self::get_plugin_path() . 'classes/class-preprocessor.php';
111
+
112
+ /**
113
+ * include shortcodes
114
+ */
115
+ require_once( self::get_plugin_path() . 'classes/class-shortcode.php' );
116
+ /**
117
+ * include Widgets
118
+ */
119
+ require_once self::get_plugin_path() . 'classes/widgets/class-mp-timetable-widget.php';
120
+ /**
121
+ * Include view
122
+ */
123
+ require_once self::get_plugin_path() . 'classes/class-view.php';
124
+ /**
125
+ * Include hooks
126
+ */
127
+ require_once self::get_plugin_path() . 'classes/class-hooks.php';
128
+
129
+ /**
130
+ * Include blocks
131
+ */
132
+ require_once self::get_plugin_path() . 'classes/blocks/class-timetable-block.php';
133
+ }
134
+
135
+ /**
136
+ * Get plugin path
137
+ */
138
+ public static function get_plugin_path() {
139
+ return plugin_dir_path( __FILE__ );
140
+ }
141
+
142
+ /**
143
+ * @return Mp_Time_Table
144
+ */
145
+ public static function init() {
146
+ if ( null === self::$instance ) {
147
+ self::$instance = new self();
148
+ }
149
+
150
+ return self::$instance;
151
+ }
152
+
153
+ /**
154
+ * Retrieve relative to theme root path to templates.
155
+ *
156
+ * @return string
157
+ */
158
+ public static function get_template_path() {
159
+ return apply_filters( 'mptt_template_path', 'mp-timetable/' );
160
+ }
161
+
162
+ /**
163
+ * Retrieve relative to plugin root path to templates.
164
+ *
165
+ * @return string
166
+ */
167
+ public static function get_templates_path() {
168
+ return self::get_plugin_path() . 'templates/';
169
+ }
170
+
171
+ /**
172
+ * Get plugin part path
173
+ *
174
+ * @param string $part
175
+ *
176
+ * @return string
177
+ */
178
+ public static function get_plugin_part_path( $part = '' ) {
179
+ return self::get_plugin_path() . $part;
180
+ }
181
+
182
+ /**
183
+ * On activation
184
+ */
185
+ public static function on_activation() {
186
+ // Register post type
187
+ Core::get_instance()->register_all_post_type();
188
+
189
+ // Register taxonomy all
190
+ Core::get_instance()->register_all_taxonomies();
191
+
192
+ flush_rewrite_rules();
193
+
194
+ //Create table in not exists
195
+ Core::get_instance()->create_table();
196
+ }
197
+
198
+ /**
199
+ * On deactivation
200
+ */
201
+ public static function on_deactivation() {
202
+ flush_rewrite_rules();
203
+ }
204
+
205
+ /**
206
+ * On uninstall
207
+ */
208
+ public static function on_uninstall() {
209
+ do_action( 'mptt_on_uninstall' );
210
+ }
211
+
212
+ /**
213
+ * On create blog
214
+ *
215
+ * @param $blog_id
216
+ * @param $user_id
217
+ * @param $domain
218
+ * @param $path
219
+ * @param $site_id
220
+ * @param $meta
221
+ */
222
+ public static function on_create_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
223
+ if ( is_plugin_active_for_network( self::get_plugin_name() . '/' . self::get_plugin_name() . '.php' ) ) {
224
+ switch_to_blog( $blog_id );
225
+ //Create table in not exists
226
+ Core::get_instance()->create_table();
227
+ restore_current_blog();
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Get plugin name
233
+ *
234
+ * @return string
235
+ */
236
+ public static function get_plugin_name() {
237
+ return dirname( plugin_basename( __FILE__ ) );
238
+ }
239
+
240
+ /**
241
+ * On blog creation
242
+ */
243
+ public static function on_delete_blog( $tables ) {
244
+
245
+ $tables[] = self::get_datatable();
246
+
247
+ return $tables;
248
+ }
249
+
250
+ /**
251
+ * Get data table name
252
+ *
253
+ * @return string
254
+ */
255
+ public static function get_datatable() {
256
+ global $wpdb;
257
+
258
+ return $wpdb->prefix . "mp_timetable_data";
259
+ }
260
+
261
+ /**
262
+ * Get plugin url
263
+ *
264
+ * @param bool|false $path
265
+ * @param string $pluginName
266
+ * @param string $sync
267
+ *
268
+ * @return string
269
+ */
270
+ static function get_plugin_url( $path = false, $pluginName = 'mp-timetable', $sync = '' ) {
271
+ return plugins_url() . '/' . $pluginName . '/' . $path . $sync;
272
+ }
273
+ }
readme.txt CHANGED
@@ -1,239 +1,245 @@
1
- === Timetable and Event Schedule by MotoPress ===
2
- Contributors: MotoPress
3
- Donate link: https://motopress.com/
4
- Tags: schedule, timetable, calendar, event, events calendar, dates, event organizer, booking, appointments, upcoming events
5
- Requires at least: 4.6
6
- Tested up to: 5.6
7
- Stable tag: trunk
8
- License: GPLv2 or later
9
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
-
11
- Smart event organizer and time-management tool with a clean minimalist design for featuring your timetables and upcoming events.
12
-
13
- == Description ==
14
-
15
- MotoPress Timetable and Event Schedule is an all-around organizer plugin developed to help you create and manage online schedules for a single or multiple events, customize the appearance of each event, add date, time, description and display all the needed items in a carefully-crafted timetable. It also comes with Upcoming events widget that will help you keep the sidebar clutter-free.
16
-
17
- The plugin can be used for timetabling different types of events like various lessons, gym classes, festivals, conferences, ceremonies, case-studies, formal parties, concerts, and much more. It's handy in terms of backend management and maximum easy for your audience to use.
18
-
19
- * Check [Timetable and Event Schedule Plugin Demo](https://mpttdemo.getmotopress.com/)
20
- * Please find the step-by-step [instructions of working with the plugin](https://motopress.com/files/motopress-timetable-plugin-documentation.pdf)
21
-
22
- ### Key advantages
23
-
24
- **Responsive design.** It's optimized to be viewed perfectly on different devices. A good step forward, the plugin was supplied with the ability to manually adjust the way to show your timetable on mobile devices and desktops.
25
-
26
- **A well thought-out toolkit of shortcode settings.** It eliminates the difficulties of timetabling as all preferable settings can be applied in minutes. Each setting is supplied with sufficient clarifications to ensure you coordinate and edit your events fast without additional help.
27
-
28
- **Handy event filtering.** The visitors can filter the timetable to display the only events they are interested in.
29
-
30
- **Color controls.** Highlight important activities by presenting them in different colors. Additionally, it simplifies and speeds up the search as the needed events marked with the same color can be noticed faster even without being filtered. Various color markers can become helpful in making the timetable more colorful or in customizing it to fit your website color scheme.
31
-
32
- **More precise visual time frames.** Hourly time frames are generally large enough for showing the events, but using the MotoPress Timetable plugin you still can increase them by setting the timetable to show up to 15 minutes accurate time in the left 'time' column.
33
-
34
- **Flexibility.** If any unexpected delays or total dates' changes take place, your timetable can bend easily in one direction or another thanks to a couple of qucik time edits in the backend.
35
-
36
- ### Main features
37
- * Several column types
38
- * Selecting/deselecting the preferable columns and events to be displayed in the timetable
39
- * Ability to add event tags and categories
40
- * Ability to display the events by the appropriate categories
41
- * Hour measure to be displayed in the left timetable column to show more accurate duration of each activity (event)
42
- * Several filter styles: drop-down list and tabs
43
- * Option to display/hide 'All Events' view mode, hours column and empty rows
44
- * Customizable event parameters (title, time, subtitle, etc.) and the ability to display only preferable ones in the timetable
45
- * Featured images for individual events
46
- * Opportunity to set event URL to link it any external website
47
- * Text align options for event blocks
48
- * Unique IDs for multiple timetables on a single page
49
- * Color settings for background, background hover, text, and text hover
50
- * Export/import of your data
51
-
52
- Timetable can be added to Elementor, Divi, Beaver or any other builder via shortcode. Plugin provides Timetable block for Gutenberg.
53
-
54
- Proud developers of Timetable plugin and the biggest set of blocks for Gutenberg - [Getwid WordPress Blocks](https://wordpress.org/plugins/getwid/).
55
-
56
- ### Power up your timetables with the Appointment Booking plugin
57
-
58
- Want to take automatic online appointment reservations through your website for events, classes, and any other type of services? Enable [hourly appointment booking](https://motopress.com/products/appointment-booking/?utm_source=wp_org_tt_page&utm_medium=text_link&utm_campaign=appointment_plugin) with our custom-crafted plugin optimized for easy appointment scheduling and quick online reservations.
59
-
60
- == Installation ==
61
-
62
- 1. Upload the plugin files to the /wp-content/plugins/ directory
63
- 2. Activate the plugin through the 'Plugins' menu in WordPress. You'll find 'Timetable' on your main WordPress dashboard.
64
-
65
- == Copyright ==
66
-
67
- Timetable and Event Schedule plugin, Copyright (C) 2019, MotoPress https://motopress.com/
68
- Timetable and Event Schedule plugin is distributed under the terms of the GNU GPL.
69
-
70
- == Screenshots ==
71
- 1. Timetable
72
- 2. Column
73
- 3. Timeslots
74
-
75
- == Credits ==
76
-
77
- Plugin bundles the following third-party resources:
78
-
79
- * GUMP, Copyright (c) 2015 wixelhq.com, MIT License
80
- * jQuery UI, Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT
81
- * Spectrum Colorpicker, by Brian Grinstead, MIT License
82
- * jBox, by Stephan Wagner, MIT License
83
- * jQuery UI Timepicker, Copyright 2010-2013, Francois Gelinas, Dual licensed under the MIT or GPL Version 2 licenses.
84
-
85
-
86
- == Changelog ==
87
-
88
- = 2.3.12, Dec 11 2020 =
89
- * Improved compatibility with WordPress 5.6.
90
-
91
- = 2.3.11, May 18 2020 =
92
- * Added the ability to duplicate events.
93
- * Added the ability to set table layout fixed or auto.
94
- * Bug fix: fixed an issue with an empty categories list in the widget.
95
-
96
- = 2.3.10, Apr 24 2020 =
97
- * Bug fix: fixed an issue when a user with the Editor role could not access the administration area.
98
- * Improved compatibility with PHP 7.4.
99
-
100
- = 2.3.9, Apr 21 2020 =
101
- * Added the ability to sort events in the dropdown list or tabs.
102
- * Improved user capability check.
103
-
104
- = 2.3.8, Apr 1 2020 =
105
- * Bug fix: fixed an issue with the missing Event tags field.
106
- * Bug fix: fixed an issue when a user with the read capability could access a Help menu page.
107
-
108
- = 2.3.7, Mar 10 2020 =
109
- * Bug fix: fixed an issue with the erroneous positioning of events.
110
-
111
- = 2.3.6, Feb 19 2020 =
112
- * Bug fix: fixed an issue with the missing subtitle in mobile view.
113
-
114
- = 2.3.5, Feb 19 2020 =
115
- * Bug fix: fixed an issue with slashes in event description.
116
-
117
- = 2.3.4, Sep 25 2019 =
118
- * Bug fix: fixed an issue with UTC timezone offset.
119
-
120
- = 2.3.3, Sep 20 2019 =
121
- * Bug fix: fixed the issue with events disappearing on hover in Chrome.
122
-
123
- = 2.3.2 =
124
- * Bug fix: fixed an issue in IE browser.
125
-
126
- = 2.3.1 =
127
- * Bug fix: fixed the issue with opening PHP tag.
128
-
129
- = 2.3.0 =
130
- * Added support for WordPress 5.0.
131
-
132
- = 2.2.1 =
133
- * Bug fix: fixed an issue with URL hash (not-set:all).
134
-
135
- = 2.2.0 =
136
- * Added filters for register_post_type and register_taxonomy functions.
137
- * Added permalink configuration option in Settings > Permalinks.
138
-
139
- = 2.1.12 =
140
- * Bug fix: fixed an issue in IE browser.
141
-
142
- = 2.1.11 =
143
- * Added translations into the Persian language.
144
-
145
- = 2.1.10 =
146
- * Improved compatibility with WooCommerce Memberships plugin.
147
- * Better W3C validation.
148
-
149
- = 2.1.9 =
150
- * Bug fix: fixed the issue when event was not visible in the timetable if it starts at 00:00.
151
-
152
- = 2.1.8 =
153
- * Improved compatibility with javascript-disabled browsers.
154
-
155
- = 2.1.7 =
156
- * Bug fix: fixed the issue when events were not filtered by the selected category in a widget.
157
- * Bug fix: fixed the issue when event was not visible in the timetable if it ends the next day.
158
- * Minor bugfixes and improvements.
159
-
160
- = 2.1.6 =
161
- * New dashboard icons.
162
-
163
- = 2.1.5 =
164
- * Bug fix: fixed the issue when table is not visible if events filter is set to 'none'.
165
-
166
- = 2.1.4 =
167
- * Bug fix: fixed internal issue.
168
-
169
- = 2.1.3 =
170
- * Added the ability to merge cells with common events.
171
- * Added the ability to set vertical alignment in the table.
172
- * Added the ability to set custom CSS class for table shortcode.
173
- * Added the ability to hide filter control on the top of the table.
174
- * Bug fix: fixed the issue when table ID didn't output on the site.
175
-
176
- = 2.1.2 =
177
- * Bug fix: fixed the issue when plugin overrides default archive template.
178
- * Bug fix: fixed the issue in upcoming events widget when events were not sorted by days.
179
-
180
- = 2.1.1 =
181
- * Bug fix: fixed the issue with shortcode tempalte.
182
-
183
- = 2.1.0 =
184
- * Added the ability to override templates in a theme.
185
- * Bug fix: fixed the issue on WordPress multisite when Event wasn't saving.
186
- * Bug fix: fixed the issue when timeslots didn't show if Event is in the Draft status.
187
-
188
- = 2.0.4 =
189
- * Bug fix: fixed an issue with post template on search results page.
190
-
191
- = 2.0.3 =
192
- * Bug fix: fixed a link to create new column from event screen.
193
- * Improved usernames in Event Head dropdown.
194
-
195
- = 2.0.2 =
196
- * Minor bugfixes and improvements.
197
-
198
- = 2.0.1 =
199
- * Bug fix: fixed an issue with template override.
200
-
201
- = 2.0.0 =
202
- * We improved compatibility with your theme styles in this update. If you still stick to a previous version, simply change the template mode option in the plugin settings.
203
- * Added the ability to set font size for timetable shortcode so you can make your text bigger or smaller.
204
-
205
- = 1.1.6 =
206
- * Bug fix: fixed an issue with empty rows.
207
-
208
- = 1.1.5 =
209
- * Bug fix: fixed an issue with post view in search results.
210
-
211
- = 1.1.4 =
212
- * Improved compatibility with Polylang plugin.
213
-
214
- = 1.1.3 =
215
- * Fixed an issue with categories filter in widget.
216
-
217
- = 1.1.2 =
218
- * Fixed an issue with posts order.
219
-
220
- = 1.1.0 =
221
- * Improved events sorting.
222
- * Minor bugfixes and improvements.
223
-
224
- = 1.0.7 =
225
- * Improved events and columns sorting by date.
226
- * Comments section added to event.
227
- * Minor bugfixes and improvements.
228
-
229
- = 1.0.6 =
230
- * Fixed an issue in column view.
231
-
232
- = 1.0.5 =
233
- * Improved compatibility with IE10+
234
-
235
- = 1.0.4 =
236
- * Minor bugfixes and improvements.
237
-
238
- = 1.0.3 =
239
- * Minor bugfixes and improvements.
 
 
 
 
 
 
1
+ === Timetable and Event Schedule by MotoPress ===
2
+ Contributors: MotoPress
3
+ Donate link: https://motopress.com/
4
+ Tags: schedule, timetable, calendar, event, events calendar, dates, event organizer, booking, appointments, upcoming events
5
+ Requires at least: 4.6
6
+ Tested up to: 5.6
7
+ Stable tag: trunk
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Smart event organizer and time-management tool with a clean minimalist design for featuring your timetables and upcoming events.
12
+
13
+ == Description ==
14
+
15
+ MotoPress Timetable and Event Schedule is an all-around organizer plugin developed to help you create and manage online schedules for a single or multiple events, customize the appearance of each event, add date, time, description and display all the needed items in a carefully-crafted timetable. It also comes with Upcoming events widget that will help you keep the sidebar clutter-free.
16
+
17
+ The plugin can be used for timetabling different types of events like various lessons, gym classes, festivals, conferences, ceremonies, case-studies, formal parties, concerts, and much more. It's handy in terms of backend management and maximum easy for your audience to use.
18
+
19
+ * Check [Timetable and Event Schedule Plugin Demo](https://mpttdemo.getmotopress.com/)
20
+ * Please find the step-by-step [instructions of working with the plugin](https://motopress.com/files/motopress-timetable-plugin-documentation.pdf)
21
+
22
+ ### Key advantages
23
+
24
+ **Responsive design.** It's optimized to be viewed perfectly on different devices. A good step forward, the plugin was supplied with the ability to manually adjust the way to show your timetable on mobile devices and desktops.
25
+
26
+ **A well thought-out toolkit of shortcode settings.** It eliminates the difficulties of timetabling as all preferable settings can be applied in minutes. Each setting is supplied with sufficient clarifications to ensure you coordinate and edit your events fast without additional help.
27
+
28
+ **Handy event filtering.** The visitors can filter the timetable to display the only events they are interested in.
29
+
30
+ **Color controls.** Highlight important activities by presenting them in different colors. Additionally, it simplifies and speeds up the search as the needed events marked with the same color can be noticed faster even without being filtered. Various color markers can become helpful in making the timetable more colorful or in customizing it to fit your website color scheme.
31
+
32
+ **More precise visual time frames.** Hourly time frames are generally large enough for showing the events, but using the MotoPress Timetable plugin you still can increase them by setting the timetable to show up to 15 minutes accurate time in the left 'time' column.
33
+
34
+ **Flexibility.** If any unexpected delays or total dates' changes take place, your timetable can bend easily in one direction or another thanks to a couple of qucik time edits in the backend.
35
+
36
+ ### Main features
37
+ * Several column types
38
+ * Selecting/deselecting the preferable columns and events to be displayed in the timetable
39
+ * Ability to add event tags and categories
40
+ * Ability to display the events by the appropriate categories
41
+ * Hour measure to be displayed in the left timetable column to show more accurate duration of each activity (event)
42
+ * Several filter styles: drop-down list and tabs
43
+ * Option to display/hide 'All Events' view mode, hours column and empty rows
44
+ * Customizable event parameters (title, time, subtitle, etc.) and the ability to display only preferable ones in the timetable
45
+ * Featured images for individual events
46
+ * Opportunity to set event URL to link it any external website
47
+ * Text align options for event blocks
48
+ * Unique IDs for multiple timetables on a single page
49
+ * Color settings for background, background hover, text, and text hover
50
+ * Export/import of your data
51
+
52
+ Timetable can be added to Elementor, Divi, Beaver or any other builder via shortcode. Plugin provides Timetable block for Gutenberg.
53
+
54
+ Proud developers of Timetable plugin and the biggest set of blocks for Gutenberg - [Getwid WordPress Blocks](https://wordpress.org/plugins/getwid/).
55
+
56
+ ### Appointment Booking plugin
57
+
58
+ Want to take automatic online appointment reservations through your website for events, classes, and any other type of services?
59
+
60
+ Enable [Hourly Appointment Booking](https://motopress.com/products/appointment-booking/?utm_source=wp_org_tt_page&utm_medium=text_link&utm_campaign=appointment_plugin) with our custom-crafted plugin optimized for easy appointment scheduling and quick online reservations.
61
+
62
+ == Installation ==
63
+
64
+ 1. Upload the plugin files to the /wp-content/plugins/ directory
65
+ 2. Activate the plugin through the 'Plugins' menu in WordPress. You'll find 'Timetable' on your main WordPress dashboard.
66
+
67
+ == Copyright ==
68
+
69
+ Timetable and Event Schedule plugin, Copyright (C) 2019, MotoPress https://motopress.com/
70
+ Timetable and Event Schedule plugin is distributed under the terms of the GNU GPL.
71
+
72
+ == Screenshots ==
73
+ 1. Timetable
74
+ 2. Column
75
+ 3. Timeslots
76
+
77
+ == Credits ==
78
+
79
+ Plugin bundles the following third-party resources:
80
+
81
+ * GUMP, Copyright (c) 2015 wixelhq.com, MIT License
82
+ * jQuery UI, Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT
83
+ * Spectrum Colorpicker, by Brian Grinstead, MIT License
84
+ * jBox, by Stephan Wagner, MIT License
85
+ * jQuery UI Timepicker, Copyright 2010-2013, Francois Gelinas, Dual licensed under the MIT or GPL Version 2 licenses.
86
+
87
+
88
+ == Changelog ==
89
+
90
+ = 2.3.13, Feb 3 2021 =
91
+ * Bug fix: fixed an issue with double slashes in the assets' URLs.
92
+ * Improved plugin internalization.
93
+
94
+ = 2.3.12, Dec 11 2020 =
95
+ * Improved compatibility with WordPress 5.6.
96
+
97
+ = 2.3.11, May 18 2020 =
98
+ * Added the ability to duplicate events.
99
+ * Added the ability to set table layout fixed or auto.
100
+ * Bug fix: fixed an issue with an empty categories list in the widget.
101
+
102
+ = 2.3.10, Apr 24 2020 =
103
+ * Bug fix: fixed an issue when a user with the Editor role could not access the administration area.
104
+ * Improved compatibility with PHP 7.4.
105
+
106
+ = 2.3.9, Apr 21 2020 =
107
+ * Added the ability to sort events in the dropdown list or tabs.
108
+ * Improved user capability check.
109
+
110
+ = 2.3.8, Apr 1 2020 =
111
+ * Bug fix: fixed an issue with the missing Event tags field.
112
+ * Bug fix: fixed an issue when a user with the read capability could access a Help menu page.
113
+
114
+ = 2.3.7, Mar 10 2020 =
115
+ * Bug fix: fixed an issue with the erroneous positioning of events.
116
+
117
+ = 2.3.6, Feb 19 2020 =
118
+ * Bug fix: fixed an issue with the missing subtitle in mobile view.
119
+
120
+ = 2.3.5, Feb 19 2020 =
121
+ * Bug fix: fixed an issue with slashes in event description.
122
+
123
+ = 2.3.4, Sep 25 2019 =
124
+ * Bug fix: fixed an issue with UTC timezone offset.
125
+
126
+ = 2.3.3, Sep 20 2019 =
127
+ * Bug fix: fixed the issue with events disappearing on hover in Chrome.
128
+
129
+ = 2.3.2 =
130
+ * Bug fix: fixed an issue in IE browser.
131
+
132
+ = 2.3.1 =
133
+ * Bug fix: fixed the issue with opening PHP tag.
134
+
135
+ = 2.3.0 =
136
+ * Added support for WordPress 5.0.
137
+
138
+ = 2.2.1 =
139
+ * Bug fix: fixed an issue with URL hash (not-set:all).
140
+
141
+ = 2.2.0 =
142
+ * Added filters for register_post_type and register_taxonomy functions.
143
+ * Added permalink configuration option in Settings > Permalinks.
144
+
145
+ = 2.1.12 =
146
+ * Bug fix: fixed an issue in IE browser.
147
+
148
+ = 2.1.11 =
149
+ * Added translations into the Persian language.
150
+
151
+ = 2.1.10 =
152
+ * Improved compatibility with WooCommerce Memberships plugin.
153
+ * Better W3C validation.
154
+
155
+ = 2.1.9 =
156
+ * Bug fix: fixed the issue when event was not visible in the timetable if it starts at 00:00.
157
+
158
+ = 2.1.8 =
159
+ * Improved compatibility with javascript-disabled browsers.
160
+
161
+ = 2.1.7 =
162
+ * Bug fix: fixed the issue when events were not filtered by the selected category in a widget.
163
+ * Bug fix: fixed the issue when event was not visible in the timetable if it ends the next day.
164
+ * Minor bugfixes and improvements.
165
+
166
+ = 2.1.6 =
167
+ * New dashboard icons.
168
+
169
+ = 2.1.5 =
170
+ * Bug fix: fixed the issue when table is not visible if events filter is set to 'none'.
171
+
172
+ = 2.1.4 =
173
+ * Bug fix: fixed internal issue.
174
+
175
+ = 2.1.3 =
176
+ * Added the ability to merge cells with common events.
177
+ * Added the ability to set vertical alignment in the table.
178
+ * Added the ability to set custom CSS class for table shortcode.
179
+ * Added the ability to hide filter control on the top of the table.
180
+ * Bug fix: fixed the issue when table ID didn't output on the site.
181
+
182
+ = 2.1.2 =
183
+ * Bug fix: fixed the issue when plugin overrides default archive template.
184
+ * Bug fix: fixed the issue in upcoming events widget when events were not sorted by days.
185
+
186
+ = 2.1.1 =
187
+ * Bug fix: fixed the issue with shortcode tempalte.
188
+
189
+ = 2.1.0 =
190
+ * Added the ability to override templates in a theme.
191
+ * Bug fix: fixed the issue on WordPress multisite when Event wasn't saving.
192
+ * Bug fix: fixed the issue when timeslots didn't show if Event is in the Draft status.
193
+
194
+ = 2.0.4 =
195
+ * Bug fix: fixed an issue with post template on search results page.
196
+
197
+ = 2.0.3 =
198
+ * Bug fix: fixed a link to create new column from event screen.
199
+ * Improved usernames in Event Head dropdown.
200
+
201
+ = 2.0.2 =
202
+ * Minor bugfixes and improvements.
203
+
204
+ = 2.0.1 =
205
+ * Bug fix: fixed an issue with template override.
206
+
207
+ = 2.0.0 =
208
+ * We improved compatibility with your theme styles in this update. If you still stick to a previous version, simply change the template mode option in the plugin settings.
209
+ * Added the ability to set font size for timetable shortcode so you can make your text bigger or smaller.
210
+
211
+ = 1.1.6 =
212
+ * Bug fix: fixed an issue with empty rows.
213
+
214
+ = 1.1.5 =
215
+ * Bug fix: fixed an issue with post view in search results.
216
+
217
+ = 1.1.4 =
218
+ * Improved compatibility with Polylang plugin.
219
+
220
+ = 1.1.3 =
221
+ * Fixed an issue with categories filter in widget.
222
+
223
+ = 1.1.2 =
224
+ * Fixed an issue with posts order.
225
+
226
+ = 1.1.0 =
227
+ * Improved events sorting.
228
+ * Minor bugfixes and improvements.
229
+
230
+ = 1.0.7 =
231
+ * Improved events and columns sorting by date.
232
+ * Comments section added to event.
233
+ * Minor bugfixes and improvements.
234
+
235
+ = 1.0.6 =
236
+ * Fixed an issue in column view.
237
+
238
+ = 1.0.5 =
239
+ * Improved compatibility with IE10+
240
+
241
+ = 1.0.4 =
242
+ * Minor bugfixes and improvements.
243
+
244
+ = 1.0.3 =
245
+ * Minor bugfixes and improvements.
templates-functions/action-shortcode-functions.php CHANGED
@@ -1,726 +1,726 @@
1
- <?php
2
- use mp_timetable\classes\models\Settings;
3
- use mp_timetable\plugin_core\classes\View;
4
-
5
- /**
6
- * Before content
7
- */
8
- function mptt_shortcode_template_before_content() {
9
- global $mptt_shortcode_data;
10
- $wrapper_class = mptt_popular_theme_class();
11
- $id = empty( $mptt_shortcode_data[ 'params' ][ 'id' ] ) ? '' : $mptt_shortcode_data[ 'params' ][ 'id' ];
12
- ?>
13
- <div <?php if ( !empty($id) ) echo 'id="' . $id . '" '; ?>class="<?php echo apply_filters( 'mptt_shortcode_wrapper_class', 'mptt-shortcode-wrapper' . $wrapper_class . ( $mptt_shortcode_data[ 'params' ][ 'responsive' ] == '0' ? ' mptt-table-fixed' : ' mptt-table-responsive' ) ) ?>">
14
- <?php
15
- }
16
-
17
- /**
18
- * After content
19
- */
20
- function mptt_shortcode_template_after_content() { ?>
21
- </div>
22
- <?php }
23
-
24
- /**
25
- * Filter contents
26
- */
27
- function mptt_shortcode_template_content_filter() {
28
-
29
- global $mptt_shortcode_data;
30
-
31
- $unique_events = empty( $mptt_shortcode_data[ 'unique_events' ] ) ? array() : $mptt_shortcode_data[ 'unique_events' ];
32
- $style = '';
33
- $params = $mptt_shortcode_data[ 'params' ];
34
-
35
- //sort events in filter
36
- if ( !empty( $unique_events ) && function_exists('usort') && !empty($params['view_sort']) ) {
37
- if ( $params['view_sort'] == 'menu_order' ) {
38
- usort($unique_events, function($a, $b) {
39
- return ($a->post->menu_order > $b->post->menu_order);
40
- });
41
- } elseif ( $params['view_sort'] == 'post_title' ) {
42
- usort($unique_events, function($a, $b) {
43
- return strcmp($a->post->post_title, $b->post->post_title);
44
- });
45
- }
46
- }
47
-
48
- if ( isset( $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ]) && count( $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ] ) < 2 ) {
49
- $style = ' style="display:none;"';
50
- }
51
- $display_label = $params[ 'hide_label' ] ? 'display: none' : '';
52
-
53
- if ( $params[ 'view' ] == 'dropdown_list' ) { ?>
54
- <select class="<?php echo apply_filters( 'mptt_shortcode_navigation_select_class', 'mptt-menu mptt-navigation-select' ) ?>"<?php echo $style ?>>
55
- <?php if ( ! $params[ 'hide_label' ] ) { ?>
56
- <option value="all"><?php echo ( strlen( trim( $params[ 'label' ] ) ) ) ?
57
- trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?></option>
58
- <?php } else { ?>
59
- <option value="all"></option>
60
- <?php }
61
- if ( ! empty( $unique_events ) ):
62
- foreach ( $unique_events as $event ): ?>
63
- <option value="<?php echo esc_attr( $event->post->post_name); ?>"><?php echo esc_html($event->post->post_title); ?></option>
64
- <?php endforeach;
65
- endif; ?>
66
- </select>
67
- <?php } elseif ( $params[ 'view' ] == 'tabs' ) { ?>
68
- <ul class="<?php echo apply_filters( 'mptt_shortcode_navigation_tabs_class', 'mptt-menu mptt-navigation-tabs' ) ?>" <?php echo $style ?>>
69
- <li style="<?php echo $display_label ?>">
70
- <a title="<?php echo ( strlen( trim( $params[ 'label' ] ) ) ) ?
71
- trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?>" href="#all" onclick="event.preventDefault();"><?php
72
- echo ( strlen( trim( $params[ 'label' ] ) ) ) ? trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?>
73
- </a>
74
- </li>
75
- <?php if ( ! empty( $unique_events ) ): ?>
76
- <?php foreach ( $unique_events as $event ): ?>
77
- <li><a title="<?php echo esc_attr($event->post->post_title); ?>" href="#<?php
78
- echo esc_attr($event->post->post_name); ?>" onclick="event.preventDefault();"><?php
79
- echo esc_html($event->post->post_title); ?></a></li>
80
- <?php endforeach;
81
- endif; ?>
82
- </ul>
83
- <?php }
84
- }
85
-
86
- /**
87
- * Content static table
88
- */
89
- function mptt_shortcode_template_content_static_table() {
90
- global $mptt_shortcode_data;
91
-
92
- mptt_shortcode_template_event( $mptt_shortcode_data );
93
-
94
- if ( isset( $mptt_shortcode_data[ 'unique_events' ] ) && is_array( $mptt_shortcode_data[ 'unique_events' ] ) ) {
95
- foreach ( $mptt_shortcode_data[ 'unique_events' ] as $ev ) {
96
- mptt_shortcode_template_event( $mptt_shortcode_data, $ev->post );
97
- }
98
- }
99
- }
100
-
101
- /**
102
- * Event template
103
- *
104
- * @param $mptt_shortcode_data
105
- * @param mixed $post
106
- */
107
- function mptt_shortcode_template_event( $mptt_shortcode_data, $post = 'all' ) {
108
- $params = $mptt_shortcode_data[ 'params' ];
109
-
110
- $column_events = mptt_get_columns_events( $mptt_shortcode_data, $post );
111
-
112
- // Get start / end row index
113
- $bounds = mptt_shortcode_get_table_cell_bounds( $column_events, $params );
114
-
115
- $hide_empty_rows = $params[ 'hide_empty_rows' ];
116
- $font_size = ! empty( $params[ 'font_size' ] ) ? ' font-size:' . $params[ 'font_size' ] . ';' : '';
117
- $row_height = $params[ 'row_height' ];
118
- $table_class = apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) . ' ' . $params[ 'custom_class' ];
119
- $table_class .= Settings::get_instance()->is_plugin_template_mode() ? '' : ' mptt-theme-mode';
120
-
121
- $table_layout = $params['table_layout'];
122
- if ( !empty($table_layout) && ($table_layout == 'fixed' || $table_layout == 'auto') ) {
123
- $table_class .= ' mptt-table-layout-' . $table_layout;
124
- }
125
-
126
- $data_grouped_by_row = mptt_make_data_shortcode( $bounds, $mptt_shortcode_data, $column_events );
127
-
128
- ?>
129
- <table class="<?php echo ! empty( $table_class ) ? $table_class : ''; ?>" id="#<?php echo is_object( $post ) ? $post->post_name : $post; ?>" style="display:none; <?php echo $font_size; ?>" data-hide_empty_row="<?php echo $hide_empty_rows; ?>">
130
- <?php echo View::get_instance()->get_template_html( 'shortcodes/table-header', array( 'header_items' => $data_grouped_by_row[ 'table_header' ], 'params' => $params ) ); ?>
131
- <tbody>
132
- <?php if ( isset( $data_grouped_by_row[ 'rows' ] ) && is_array( $data_grouped_by_row[ 'rows' ] ) ) {
133
-
134
- foreach ( $data_grouped_by_row[ 'rows' ] as $row_key => $row ) {
135
- if ( ! $row[ 'show' ] && $params[ 'hide_empty_rows' ] ) {
136
- continue;
137
- } ?>
138
- <tr class="mptt-shortcode-row-<?php echo $row_key ?>" data-index="<?php echo $row_key ?>">
139
- <?php $cells = $data_grouped_by_row[ 'rows' ][ $row_key ][ 'cells' ];
140
-
141
- foreach ( $cells as $key_event => $cell ) {
142
-
143
- if ( isset( $cell[ 'time_cell' ] ) && filter_var( $cell[ 'time_cell' ], FILTER_VALIDATE_BOOLEAN, array( 'options' => array( 'default' => false ) ) ) ) { ?>
144
- <td class="mptt-shortcode-hours" style="<?php echo 'height:' . $row_height . 'px;'; ?>"><?php echo $cell[ 'title' ] ?></td>
145
- <?php continue;
146
- }
147
-
148
- if ( ! $cell[ 'hide' ] ) { ?>
149
- <td class="mptt-shortcode-event <?php echo mptt_is_grouped_event_class( $cell ) ?> mptt-event-vertical-<?php echo $params[ 'text_align_vertical' ] ?>" data-column-id="<?php echo $cell[ 'column_id' ] ?>" colspan="<?php echo ! isset( $cell[ 'count' ] ) ? '' : $cell[ 'count' ] ?>" data-row_height="<?php echo $row_height; ?>" style="<?php echo 'height:' . $row_height . 'px;'; ?>">
150
- <?php
151
- $height = 100 / count( $cell[ 'events' ] );
152
- $top = 0;
153
- foreach ( $cell[ 'events' ] as $event ) {
154
-
155
- if ( ! empty( $event[ 'id' ] ) && filter_var( $event[ 'id' ], FILTER_VALIDATE_INT ) ) {
156
- View::get_instance()->get_template( 'shortcodes/event-container', array( 'item' => $event, 'params' => $params, 'height' => $height, 'top' => $top ) );
157
- $top += $height;
158
- }
159
-
160
- } ?>
161
- </td>
162
- <?php }
163
- } ?>
164
- </tr>
165
- <?php }
166
-
167
- } ?>
168
- </tbody>
169
- </table>
170
- <?php
171
- }
172
-
173
- /**
174
- * Check row has items
175
- *
176
- * @param $i
177
- *
178
- * @param $column_events
179
- *
180
- * @return bool
181
- */
182
- function mptt_shortcode_row_has_items( $i, $column_events ) {
183
-
184
- foreach ( $column_events as $column_id => $events_list ) {
185
-
186
- if ( ! empty( $column_events[ $column_id ] ) ) {
187
- foreach ( $events_list as $key_events => $item ) {
188
- if ( $item->start_index <= $i && $i < $item->end_index ) {
189
- return true;
190
- }
191
- }
192
- }
193
-
194
- }
195
-
196
- return false;
197
- }
198
-
199
- /**
200
- * Get table cell bounds
201
- *
202
- * @param $column_events
203
- * @param $params
204
- *
205
- * @return array
206
- */
207
- function mptt_shortcode_get_table_cell_bounds( $column_events, $params ) {
208
- $hide_empty_rows = $params[ 'hide_empty_rows' ];
209
-
210
- if ( $hide_empty_rows ) {
211
- $min = - 1;
212
- $max = - 1;
213
- foreach ( $column_events as $events ) {
214
- foreach ( $events as $item ) {
215
- if ( isset($item->start_index) && isset($item->end_index) ) {
216
- $min = ( $min === - 1 ) ? $item->start_index : $min;
217
- $max = ( $max === - 1 ) ? $item->end_index : $max;
218
- $min = ( $item->start_index < $min ) ? $item->start_index : $min;
219
- $max = ( $item->end_index > $max ) ? $item->end_index : $max;
220
- }
221
- }
222
- }
223
- } else {
224
- $min = 0;
225
- $max = 23 / $params[ 'increment' ];
226
- }
227
-
228
- return array( 'start' => $min, 'end' => $max );
229
- }
230
-
231
- /**
232
- * Content responsive table
233
- */
234
- function mptt_shortcode_template_content_responsive_table() {
235
- global $mptt_shortcode_data;
236
- if ( $mptt_shortcode_data[ 'params' ][ 'responsive' ] ) { ?>
237
- <div class="<?php echo apply_filters( 'mptt_shortcode_list_view_class', 'mptt-shortcode-list' ) . ' ' . $mptt_shortcode_data[ 'params' ][ 'custom_class' ] ?>">
238
- <?php if ( ! empty( $mptt_shortcode_data[ 'events_data' ] ) ):
239
- foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column' ] as $column ): ?>
240
- <div class="mptt-column">
241
- <h3 class="mptt-column-title"><?php echo $column->post_title ?></h3>
242
- <ul class="mptt-events-list">
243
- <?php if ( ! empty( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ][ $column->ID ] ) ):
244
- foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ][ $column->ID ] as $event ) : ?>
245
- <li class="mptt-list-event" data-event-id="<?php echo $event->post->post_name ?>"
246
- <?php if ( ! empty( $event->post->color ) ) {
247
- echo 'style="border-left-color:' . $event->post->color . ';"';
248
- } ?>>
249
- <?php if ( $mptt_shortcode_data[ 'params' ][ 'title' ] ):
250
- $disable_url = (bool) $event->post->timetable_disable_url || (bool) $mptt_shortcode_data[ 'params' ][ 'disable_event_url' ];
251
- if ( ! $disable_url ) { ?>
252
- <a title="<?php echo $event->post->post_title; ?>"
253
- href="<?php echo ( $event->post->timetable_custom_url != "" ) ? $event->post->timetable_custom_url : get_permalink( $event->event_id ); ?>"
254
- class="mptt-event-title">
255
- <?php }
256
- echo $event->post->post_title;
257
-
258
- if ( ! $disable_url ) { ?>
259
- </a>
260
- <?php }
261
-
262
- endif;
263
- if ( $mptt_shortcode_data[ 'params' ][ 'time' ] ): ?>
264
- <p class="timeslot">
265
- <time datetime="<?php echo $event->event_start; ?>" class="timeslot-start"><?php echo date( get_option( 'time_format' ), strtotime( $event->event_start ) ); ?></time>
266
- <span class="timeslot-delimiter"><?php echo apply_filters( 'mptt_timeslot_delimiter', ' - ' ); ?></span>
267
- <time datetime="<?php echo $event->event_end; ?>" class="timeslot-end"><?php echo date( get_option( 'time_format' ), strtotime( $event->event_end ) ); ?></time>
268
- </p>
269
- <?php endif;
270
- if ( $mptt_shortcode_data[ 'params' ][ 'sub-title' ] && ! empty( $event->post->sub_title ) ): ?>
271
- <p class="event-subtitle"><?php echo $event->post->sub_title; ?></p>
272
- <?php endif;
273
- if ( $mptt_shortcode_data[ 'params' ][ 'description' ] ): ?>
274
- <p class="event-description"><?php
275
- echo stripslashes( $event->description );
276
- ?></p>
277
- <?php endif;
278
- if ( $mptt_shortcode_data[ 'params' ][ 'user' ] && ( $event->user_id != '-1' ) ): ?>
279
- <p class="event-user"><?php $user_info = get_userdata( $event->user_id );
280
- if ( $user_info ) {
281
- echo get_avatar( $event->user_id, apply_filters( 'mptt-event-user-avatar-size', 24 ), '', $user_info->data->display_name ) . ' ';
282
- echo $user_info->data->display_name;
283
- } ?></p>
284
- <?php endif; ?>
285
- </li>
286
- <?php endforeach;
287
- endif; ?>
288
- </ul>
289
- </div>
290
- <?php endforeach;
291
- endif; ?>
292
- </div>
293
- <?php }
294
- }
295
-
296
- /**
297
- * Sidebar
298
- */
299
- function mptt_sidebar() {
300
- global $post;
301
- View::get_instance()->get_template( 'templates-actions/action-sidebar', array( 'post' => $post ) );
302
- }
303
-
304
- /**
305
- * Make data shortcode
306
- *
307
- * @param $bounds
308
- * @param $mptt_shortcode_data
309
- * @param $column_events
310
- *
311
- * @return array
312
- */
313
- function mptt_make_data_shortcode( $bounds, $mptt_shortcode_data, $column_events ) {
314
- $data = array( 'rows' => array() );
315
- $amount_rows = 23 / $mptt_shortcode_data[ 'params' ][ 'increment' ];
316
-
317
- $data[ 'table_header' ] = mptt_get_header_row( $mptt_shortcode_data );
318
-
319
- foreach ( $column_events as $column_id => $events_list ) {
320
-
321
- foreach ( $events_list as $event_key => $item ) {
322
- if ( isset( $item->resolve ) ) {
323
- unset( $item->resolve );
324
- }
325
- }
326
- }
327
-
328
- for ( $row_index = $bounds[ 'start' ]; $row_index <= $bounds[ 'end' ]; $row_index ++ ) {
329
-
330
- $table_time_cell = get_time_cell( $row_index, $amount_rows, $mptt_shortcode_data[ 'params' ][ 'increment' ] );
331
-
332
- list( $row_cells, $column_events ) = mptt_get_row_events( $column_events, $row_index );
333
-
334
- if ( $mptt_shortcode_data[ 'params' ][ 'group' ] ) {
335
- $row_cells = mptt_group_identical_row_events( $row_cells );
336
- }
337
-
338
- $data[ 'rows' ][ $row_index ][ 'cells' ] = $row_cells;
339
- $data[ 'rows' ][ $row_index ][ 'show' ] = mptt_shortcode_row_has_items( $row_index, $column_events );
340
-
341
- if ( ! $mptt_shortcode_data[ 'params' ][ 'hide_hrs' ] ) {
342
- array_unshift( $data[ 'rows' ][ $row_index ][ 'cells' ], array( 'time_cell' => true, 'title' => date( get_option( 'time_format' ), strtotime( $table_time_cell ) ) ) );
343
- }
344
- }
345
-
346
- return $data;
347
- }
348
-
349
- /**
350
- * Get time cell
351
- *
352
- * @param $row_index
353
- * @param $amount_rows
354
- * @param $increment
355
- *
356
- * @return string
357
- */
358
- function get_time_cell( $row_index, $amount_rows, $increment ) {
359
- $tm = $row_index * $increment;
360
-
361
- if ( floor( $tm ) == $tm ) {
362
- $time = $tm . ':00';
363
-
364
- return $time;
365
- } else {
366
- if ( $amount_rows == 46 ) {
367
- $time = floor( $tm ) . ':30';
368
-
369
- return $time;
370
- } else {
371
- $tm_position = explode( '.', $tm );
372
-
373
- if ( $tm_position[ 1 ] == 25 ) {
374
- $mnts = ':15';
375
- } elseif ( $tm_position[ 1 ] == 5 ) {
376
- $mnts = ':30';
377
- } else {
378
- $mnts = ':45';
379
- }
380
-
381
- $time = floor( $tm ) . $mnts;
382
-
383
- return $time;
384
- }
385
- }
386
- }
387
-
388
- /**
389
- * Add group attribute to event
390
- *
391
- * @param $bounds
392
- * @param $events_array
393
- *
394
- * @return mixed
395
- */
396
- function group_events( $bounds, $events_array ) {
397
- $output_array = array();
398
-
399
- foreach ( $events_array as $column_id => $events_list ) {
400
-
401
- if ( ! empty( $events_array[ $column_id ] ) ) {
402
-
403
- foreach ( $events_list as $key_events => $item ) {
404
-
405
- if ( $bounds[ 'end' ] <= $item->end_index && $bounds[ 'start' ] >= $item->start_index ) {
406
- continue;
407
- } else {
408
- $key_count = $item->start_index . '_' . $item->event_id . '_' . $item->end_index;
409
-
410
- if ( ! isset( $output_array[ $key_count ] ) ) {
411
- $output_array[ $key_count ] = array( 'count' => 0, 'output' => false );
412
- $output_array[ $key_count ][ 'count' ] ++;
413
- } else {
414
- $output_array[ $key_count ][ 'count' ] ++;
415
- }
416
-
417
- }
418
- }
419
- }
420
- }
421
-
422
- return $output_array;
423
- }
424
-
425
- /**
426
- * Header row
427
- *
428
- * @param $mptt_shortcode_data
429
- *
430
- * @return array
431
- */
432
- function mptt_get_header_row( $mptt_shortcode_data ) {
433
- $header_array = array( '0' => array( 'output' => false ) );
434
- $show_hrs = ! $mptt_shortcode_data[ 'params' ][ 'hide_hrs' ];
435
-
436
- if ( $show_hrs ):
437
- $header_array[ 0 ] = array( 'output' => true, 'id' => '', 'title' => '' );
438
- endif;
439
-
440
- if ( ! empty( $mptt_shortcode_data[ 'events_data' ][ 'column' ] ) ) {
441
- foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column' ] as $column ):
442
- $header_array[] = array( 'output' => true, 'id' => $column->ID, 'title' => $column->post_title );
443
- endforeach;
444
- }
445
-
446
- return $header_array;
447
- }
448
-
449
- /**
450
- * Row events
451
- *
452
- * @param $column_events
453
- * @param $row_index
454
- *
455
- * @return array
456
- */
457
- function mptt_get_row_events( $column_events, $row_index ) {
458
- $events = array();
459
- $default_count = 1;
460
- $i = 0;
461
-
462
- foreach ( $column_events as $column_id => $events_list ) {
463
- $empty = true;
464
-
465
- foreach ( $events_list as $event_key => $item ) {
466
- if ( isset( $item->resolve ) && $item->resolve ) {
467
-
468
- continue;
469
- }
470
- $group = false;
471
- if ( ! empty( $current ) ) {
472
- if ( ( $item->end_index <= $current[ 'end_index' ] )
473
- //&& $item->end_index == $row_index
474
- && $item->start_index == $row_index
475
- ) {
476
- $group = true;
477
- }
478
- }
479
-
480
- if ( $item->start_index == $row_index || $group ) {
481
-
482
- //create temp event data for generate hash
483
- $temp = (array) $item;
484
-
485
- //clear data before make hash to compare
486
- if ( $temp[ 'id' ] ) {
487
- unset( $temp[ 'id' ] );
488
- unset( $temp[ 'column_id' ] );
489
- }
490
-
491
- $event = array(
492
- 'id' => $item->id,
493
- 'hash' => md5( serialize( $temp ) ),
494
- 'start_index' => $item->start_index,
495
- 'end_index' => $item->end_index,
496
- 'event_start' => $item->event_start,
497
- 'event_end' => $item->event_end,
498
- 'column_id' => $item->column_id,
499
- 'event_id' => $item->event_id,
500
- 'event' => true,
501
- 'user_id' => $item->user_id,
502
- 'description' => trim( $item->description ),
503
- 'order' => $event_key,
504
- 'hide' => $group ? true : false
505
- );
506
-
507
- if ( ! $group ) {
508
- $events[ $i ][ 'events' ][ $event[ 'hash' ] ] = $event;
509
- $events[ $i ][ 'count' ] = $default_count;
510
- $events[ $i ][ 'grouped' ] = false;
511
- $events[ $i ][ 'column_id' ] = $column_id;
512
- $events[ $i ][ 'hide' ] = false;
513
- } else {
514
-
515
- $events[ $i ][ 'hide' ] = false;
516
- $events[ $i ][ 'column_id' ] = $column_id;
517
- $events[ $i ][ 'events' ][ $event[ 'hash' ] ] = $event;
518
-
519
- }
520
-
521
- $column_events[ $column_id ][ $event_key ]->resolve = true;
522
-
523
- $empty = false;
524
-
525
- if ( empty( $current ) ) {
526
- $current = array( 'start_index' => $item->start_index, 'end_index' => $item->end_index );
527
- } else {
528
- $current[ 'start_index' ] = $current[ 'start_index' ] >= $item->start_index ? $item->start_index : $current[ 'start_index' ];
529
- $current[ 'end_index' ] = $current[ 'end_index' ] <= $item->end_index ? $item->end_index : $current[ 'end_index' ];
530
- }
531
- }
532
- }
533
-
534
-
535
- if ( $empty ) {
536
-
537
- $events[ $i ][ 'events' ][] = array(
538
- 'id' => false,
539
- 'start_index' => $row_index,
540
- 'end_index' => $row_index,
541
- 'column_id' => $column_id,
542
- 'event' => true,
543
- );
544
-
545
- $events[ $i ][ 'count' ] = $default_count;
546
- $events[ $i ][ 'column_id' ] = $column_id;
547
- $events[ $i ][ 'hide' ] = false;
548
-
549
- }
550
- unset( $current );
551
- $i ++;
552
- }
553
-
554
- $events = sort_events_data_by_order( $events );
555
-
556
- return array( $events, $column_events );
557
- }
558
-
559
- /**
560
- * Sort events by order
561
- *
562
- * @param $events
563
- *
564
- * @return mixed
565
- */
566
- function sort_events_data_by_order( $events ) {
567
- foreach ( $events as $cell => $event_data ) {
568
- usort( $event_data[ 'events' ], function ( $a, $b ) {
569
- if ( $a[ 'order' ] == $b[ 'order' ] ) {
570
- return 0;
571
- }
572
-
573
- return ( $a[ 'order' ] < $b[ 'order' ] ) ? - 1 : 1;
574
- } );
575
- $events[ $cell ][ 'events' ] = $event_data[ 'events' ];
576
- }
577
-
578
- return $events;
579
- }
580
-
581
- /**
582
- * Get columns events
583
- *
584
- * @param $mptt_shortcode_data
585
- *
586
- * @param $post
587
- *
588
- * @return array
589
- */
590
- function mptt_get_columns_events( $mptt_shortcode_data, $post ) {
591
- if ( $post === 'all' ) {
592
- $column_events = $mptt_shortcode_data[ 'events_data' ][ 'column_events' ];
593
-
594
- return $column_events;
595
- } else {
596
- $column_events = array();
597
-
598
- foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ] as $col_id => $col_events ) {
599
- $column_events[ $col_id ] = array_filter(
600
- $col_events,
601
- function ( $val ) use ( $post ) {
602
- return $post->ID == $val->event_id;
603
- } );
604
- }
605
-
606
- return $column_events;
607
- }
608
- }
609
-
610
- /**
611
- * Checking identical event in cell
612
- *
613
- * @param $needle
614
- * @param $events
615
- *
616
- * @return bool
617
- */
618
- function mptt_check_exists_column( $needle, $events ) {
619
- $exist = false;
620
- $const_available_difference = 1;
621
-
622
- foreach ( $events as $key => $event ) {
623
- $difference_data = array_diff( $needle, $event );
624
- if ( isset( $difference_data[ 'id' ] ) && ( count( $difference_data ) === $const_available_difference ) ) {
625
- $exist = true;
626
- break;
627
- }
628
- }
629
-
630
- return $exist;
631
- }
632
-
633
- /**
634
- * Group event in row
635
- *
636
- * @param $events_row_data
637
- *
638
- * @return array|mixed
639
- */
640
- function mptt_group_identical_row_events( $events_row_data ) {
641
-
642
- $length = count( $events_row_data );
643
-
644
- for ( $i = 0; $i < $length - 1; $i ++ ) {
645
- if ( ! isset( $events_row_data[ ( $i + 1 ) ] ) ) {
646
- continue;
647
- }
648
-
649
- $events_current_data = $events_row_data[ $i ];
650
- $events_current_count = count( $events_current_data[ 'events' ] );
651
-
652
- $events_next_data = $events_row_data[ ( $i + 1 ) ];
653
- $events_next_count = count( $events_next_data[ 'events' ] );
654
-
655
-
656
- if ( $events_next_count > 1 || $events_current_count > 1 ) {
657
- continue;
658
- } else {
659
- if ( filter_var( $events_current_data[ 'events' ][ 0 ][ 'id' ], FILTER_VALIDATE_INT ) && filter_var( $events_next_data[ 'events' ][ 0 ][ 'id' ], FILTER_VALIDATE_INT ) ) {
660
-
661
- $hash_current = $events_current_data[ 'events' ][ 0 ][ 'hash' ];
662
- $hash_next = $events_next_data[ 'events' ][ 0 ][ 'hash' ];
663
-
664
- if ( ! isset( $current_data ) ) {
665
- $current_data = array( 'key' => $i, 'hash' => $hash_current );
666
- }
667
-
668
- if ( $hash_current === $hash_next ) {
669
-
670
- if ( $current_data[ 'hash' ] !== $hash_current ) {
671
- $current_data = array( 'key' => $i, 'hash' => $hash_current );
672
- }
673
-
674
- if ( $current_data[ 'key' ] === $i ) {
675
- $events_current_data[ 'count' ] ++;
676
- $events_current_data[ 'grouped' ] = true;
677
- $events_row_data[ $i ] = $events_current_data;
678
- $events_row_data[ $i + 1 ][ 'hide' ] = true;
679
- } else {
680
- $events_row_data[ $current_data[ 'key' ] ][ 'count' ] ++;
681
- $events_row_data[ $i + 1 ][ 'hide' ] = true;
682
- }
683
-
684
- }
685
- }
686
- }
687
- }
688
-
689
- return $events_row_data;
690
- }
691
-
692
- /**
693
- * Check exists grouped attribute
694
- *
695
- * @param $event_item
696
- *
697
- * @return string
698
- */
699
- function mptt_is_grouped_event_class( $event_item ) {
700
- return ( isset( $event_item[ 'grouped' ] ) && $event_item[ 'grouped' ] ) ? 'mptt-grouped-event' : '';
701
- }
702
-
703
- /**
704
- * Grouped by column
705
- *
706
- * @param $events
707
- *
708
- * @return array
709
- */
710
- function grouped_by_column( $events ) {
711
- $data = array();
712
-
713
- foreach ( $events as $key => $event ) {
714
- if ( ! $event[ 'event' ] ) {
715
- $data[] = $event;
716
- continue;
717
- }
718
- if ( isset( $data[ $event[ 'column_id' ] ] ) ) {
719
- $data[ $event[ 'column_id' ] ][ 'related_by_column' ][] = $event;
720
- } else {
721
- $data[ $event[ 'column_id' ] ] = $event;
722
- }
723
- }
724
-
725
- return $data;
726
  }
1
+ <?php
2
+ use mp_timetable\classes\models\Settings;
3
+ use mp_timetable\plugin_core\classes\View;
4
+
5
+ /**
6
+ * Before content
7
+ */
8
+ function mptt_shortcode_template_before_content() {
9
+ global $mptt_shortcode_data;
10
+ $wrapper_class = mptt_popular_theme_class();
11
+ $id = empty( $mptt_shortcode_data[ 'params' ][ 'id' ] ) ? '' : $mptt_shortcode_data[ 'params' ][ 'id' ];
12
+ ?>
13
+ <div <?php if ( !empty($id) ) echo 'id="' . $id . '" '; ?>class="<?php echo apply_filters( 'mptt_shortcode_wrapper_class', 'mptt-shortcode-wrapper' . $wrapper_class . ( $mptt_shortcode_data[ 'params' ][ 'responsive' ] == '0' ? ' mptt-table-fixed' : ' mptt-table-responsive' ) ) ?>">
14
+ <?php
15
+ }
16
+
17
+ /**
18
+ * After content
19
+ */
20
+ function mptt_shortcode_template_after_content() { ?>
21
+ </div>
22
+ <?php }
23
+
24
+ /**
25
+ * Filter contents
26
+ */
27
+ function mptt_shortcode_template_content_filter() {
28
+
29
+ global $mptt_shortcode_data;
30
+
31
+ $unique_events = empty( $mptt_shortcode_data[ 'unique_events' ] ) ? array() : $mptt_shortcode_data[ 'unique_events' ];
32
+ $style = '';
33
+ $params = $mptt_shortcode_data[ 'params' ];
34
+
35
+ //sort events in filter
36
+ if ( !empty( $unique_events ) && function_exists('usort') && !empty($params['view_sort']) ) {
37
+ if ( $params['view_sort'] == 'menu_order' ) {
38
+ usort($unique_events, function($a, $b) {
39
+ return ($a->post->menu_order > $b->post->menu_order);
40
+ });
41
+ } elseif ( $params['view_sort'] == 'post_title' ) {
42
+ usort($unique_events, function($a, $b) {
43
+ return strcmp($a->post->post_title, $b->post->post_title);
44
+ });
45
+ }
46
+ }
47
+
48
+ if ( isset( $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ]) && count( $mptt_shortcode_data[ 'events_data' ][ 'unique_events' ] ) < 2 ) {
49
+ $style = ' style="display:none;"';
50
+ }
51
+ $display_label = $params[ 'hide_label' ] ? 'display: none' : '';
52
+
53
+ if ( $params[ 'view' ] == 'dropdown_list' ) { ?>
54
+ <select class="<?php echo apply_filters( 'mptt_shortcode_navigation_select_class', 'mptt-menu mptt-navigation-select' ) ?>"<?php echo $style ?>>
55
+ <?php if ( ! $params[ 'hide_label' ] ) { ?>
56
+ <option value="all"><?php echo ( strlen( trim( $params[ 'label' ] ) ) ) ?
57
+ trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?></option>
58
+ <?php } else { ?>
59
+ <option value="all"></option>
60
+ <?php }
61
+ if ( ! empty( $unique_events ) ):
62
+ foreach ( $unique_events as $event ): ?>
63
+ <option value="<?php echo esc_attr( $event->post->post_name); ?>"><?php echo esc_html($event->post->post_title); ?></option>
64
+ <?php endforeach;
65
+ endif; ?>
66
+ </select>
67
+ <?php } elseif ( $params[ 'view' ] == 'tabs' ) { ?>
68
+ <ul class="<?php echo apply_filters( 'mptt_shortcode_navigation_tabs_class', 'mptt-menu mptt-navigation-tabs' ) ?>" <?php echo $style ?>>
69
+ <li style="<?php echo $display_label ?>">
70
+ <a title="<?php echo ( strlen( trim( $params[ 'label' ] ) ) ) ?
71
+ trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?>" href="#all" onclick="event.preventDefault();"><?php
72
+ echo ( strlen( trim( $params[ 'label' ] ) ) ) ? trim( $params[ 'label' ] ) : __( 'All Events', 'mp-timetable' ) ?>
73
+ </a>
74
+ </li>
75
+ <?php if ( ! empty( $unique_events ) ): ?>
76
+ <?php foreach ( $unique_events as $event ): ?>
77
+ <li><a title="<?php echo esc_attr($event->post->post_title); ?>" href="#<?php
78
+ echo esc_attr($event->post->post_name); ?>" onclick="event.preventDefault();"><?php
79
+ echo esc_html($event->post->post_title); ?></a></li>
80
+ <?php endforeach;
81
+ endif; ?>
82
+ </ul>
83
+ <?php }
84
+ }
85
+
86
+ /**
87
+ * Content static table
88
+ */
89
+ function mptt_shortcode_template_content_static_table() {
90
+ global $mptt_shortcode_data;
91
+
92
+ mptt_shortcode_template_event( $mptt_shortcode_data );
93
+
94
+ if ( isset( $mptt_shortcode_data[ 'unique_events' ] ) && is_array( $mptt_shortcode_data[ 'unique_events' ] ) ) {
95
+ foreach ( $mptt_shortcode_data[ 'unique_events' ] as $ev ) {
96
+ mptt_shortcode_template_event( $mptt_shortcode_data, $ev->post );
97
+ }
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Event template
103
+ *
104
+ * @param $mptt_shortcode_data
105
+ * @param mixed $post
106
+ */
107
+ function mptt_shortcode_template_event( $mptt_shortcode_data, $post = 'all' ) {
108
+ $params = $mptt_shortcode_data[ 'params' ];
109
+
110
+ $column_events = mptt_get_columns_events( $mptt_shortcode_data, $post );
111
+
112
+ // Get start / end row index
113
+ $bounds = mptt_shortcode_get_table_cell_bounds( $column_events, $params );
114
+
115
+ $hide_empty_rows = $params[ 'hide_empty_rows' ];
116
+ $font_size = ! empty( $params[ 'font_size' ] ) ? ' font-size:' . $params[ 'font_size' ] . ';' : '';
117
+ $row_height = $params[ 'row_height' ];
118
+ $table_class = apply_filters( 'mptt_shortcode_static_table_class', 'mptt-shortcode-table' ) . ' ' . $params[ 'custom_class' ];
119
+ $table_class .= Settings::get_instance()->is_plugin_template_mode() ? '' : ' mptt-theme-mode';
120
+
121
+ $table_layout = $params['table_layout'];
122
+ if ( !empty($table_layout) && ($table_layout == 'fixed' || $table_layout == 'auto') ) {
123
+ $table_class .= ' mptt-table-layout-' . $table_layout;
124
+ }
125
+
126
+ $data_grouped_by_row = mptt_make_data_shortcode( $bounds, $mptt_shortcode_data, $column_events );
127
+
128
+ ?>
129
+ <table class="<?php echo ! empty( $table_class ) ? $table_class : ''; ?>" id="#<?php echo is_object( $post ) ? $post->post_name : $post; ?>" style="display:none; <?php echo $font_size; ?>" data-hide_empty_row="<?php echo $hide_empty_rows; ?>">
130
+ <?php echo View::get_instance()->get_template_html( 'shortcodes/table-header', array( 'header_items' => $data_grouped_by_row[ 'table_header' ], 'params' => $params ) ); ?>
131
+ <tbody>
132
+ <?php if ( isset( $data_grouped_by_row[ 'rows' ] ) && is_array( $data_grouped_by_row[ 'rows' ] ) ) {
133
+
134
+ foreach ( $data_grouped_by_row[ 'rows' ] as $row_key => $row ) {
135
+ if ( ! $row[ 'show' ] && $params[ 'hide_empty_rows' ] ) {
136
+ continue;
137
+ } ?>
138
+ <tr class="mptt-shortcode-row-<?php echo $row_key ?>" data-index="<?php echo $row_key ?>">
139
+ <?php $cells = $data_grouped_by_row[ 'rows' ][ $row_key ][ 'cells' ];
140
+
141
+ foreach ( $cells as $key_event => $cell ) {
142
+
143
+ if ( isset( $cell[ 'time_cell' ] ) && filter_var( $cell[ 'time_cell' ], FILTER_VALIDATE_BOOLEAN, array( 'options' => array( 'default' => false ) ) ) ) { ?>
144
+ <td class="mptt-shortcode-hours" style="<?php echo 'height:' . $row_height . 'px;'; ?>"><?php echo $cell[ 'title' ] ?></td>
145
+ <?php continue;
146
+ }
147
+
148
+ if ( ! $cell[ 'hide' ] ) { ?>
149
+ <td class="mptt-shortcode-event <?php echo mptt_is_grouped_event_class( $cell ) ?> mptt-event-vertical-<?php echo $params[ 'text_align_vertical' ] ?>" data-column-id="<?php echo $cell[ 'column_id' ] ?>" colspan="<?php echo ! isset( $cell[ 'count' ] ) ? '' : $cell[ 'count' ] ?>" data-row_height="<?php echo $row_height; ?>" style="<?php echo 'height:' . $row_height . 'px;'; ?>">
150
+ <?php
151
+ $height = 100 / count( $cell[ 'events' ] );
152
+ $top = 0;
153
+ foreach ( $cell[ 'events' ] as $event ) {
154
+
155
+ if ( ! empty( $event[ 'id' ] ) && filter_var( $event[ 'id' ], FILTER_VALIDATE_INT ) ) {
156
+ View::get_instance()->get_template( 'shortcodes/event-container', array( 'item' => $event, 'params' => $params, 'height' => $height, 'top' => $top ) );
157
+ $top += $height;
158
+ }
159
+
160
+ } ?>
161
+ </td>
162
+ <?php }
163
+ } ?>
164
+ </tr>
165
+ <?php }
166
+
167
+ } ?>
168
+ </tbody>
169
+ </table>
170
+ <?php
171
+ }
172
+
173
+ /**
174
+ * Check row has items
175
+ *
176
+ * @param $i
177
+ *
178
+ * @param $column_events
179
+ *
180
+ * @return bool
181
+ */
182
+ function mptt_shortcode_row_has_items( $i, $column_events ) {
183
+
184
+ foreach ( $column_events as $column_id => $events_list ) {
185
+
186
+ if ( ! empty( $column_events[ $column_id ] ) ) {
187
+ foreach ( $events_list as $key_events => $item ) {
188
+ if ( $item->start_index <= $i && $i < $item->end_index ) {
189
+ return true;
190
+ }
191
+ }
192
+ }
193
+
194
+ }
195
+
196
+ return false;
197
+ }
198
+
199
+ /**
200
+ * Get table cell bounds
201
+ *
202
+ * @param $column_events
203
+ * @param $params
204
+ *
205
+ * @return array
206
+ */
207
+ function mptt_shortcode_get_table_cell_bounds( $column_events, $params ) {
208
+ $hide_empty_rows = $params[ 'hide_empty_rows' ];
209
+
210
+ if ( $hide_empty_rows ) {
211
+ $min = - 1;
212
+ $max = - 1;
213
+ foreach ( $column_events as $events ) {
214
+ foreach ( $events as $item ) {
215
+ if ( isset($item->start_index) && isset($item->end_index) ) {
216
+ $min = ( $min === - 1 ) ? $item->start_index : $min;
217
+ $max = ( $max === - 1 ) ? $item->end_index : $max;
218
+ $min = ( $item->start_index < $min ) ? $item->start_index : $min;
219
+ $max = ( $item->end_index > $max ) ? $item->end_index : $max;
220
+ }
221
+ }
222
+ }
223
+ } else {
224
+ $min = 0;
225
+ $max = 23 / $params[ 'increment' ];
226
+ }
227
+
228
+ return array( 'start' => $min, 'end' => $max );
229
+ }
230
+
231
+ /**
232
+ * Content responsive table
233
+ */
234
+ function mptt_shortcode_template_content_responsive_table() {
235
+ global $mptt_shortcode_data;
236
+ if ( $mptt_shortcode_data[ 'params' ][ 'responsive' ] ) { ?>
237
+ <div class="<?php echo apply_filters( 'mptt_shortcode_list_view_class', 'mptt-shortcode-list' ) . ' ' . $mptt_shortcode_data[ 'params' ][ 'custom_class' ] ?>">
238
+ <?php if ( ! empty( $mptt_shortcode_data[ 'events_data' ] ) ):
239
+ foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column' ] as $column ): ?>
240
+ <div class="mptt-column">
241
+ <h3 class="mptt-column-title"><?php echo $column->post_title ?></h3>
242
+ <ul class="mptt-events-list">
243
+ <?php if ( ! empty( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ][ $column->ID ] ) ):
244
+ foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ][ $column->ID ] as $event ) : ?>
245
+ <li class="mptt-list-event" data-event-id="<?php echo $event->post->post_name ?>"
246
+ <?php if ( ! empty( $event->post->color ) ) {
247
+ echo 'style="border-left-color:' . $event->post->color . ';"';
248
+ } ?>>
249
+ <?php if ( $mptt_shortcode_data[ 'params' ][ 'title' ] ):
250
+ $disable_url = (bool) $event->post->timetable_disable_url || (bool) $mptt_shortcode_data[ 'params' ][ 'disable_event_url' ];
251
+ if ( ! $disable_url ) { ?>
252
+ <a title="<?php echo $event->post->post_title; ?>"
253
+ href="<?php echo ( $event->post->timetable_custom_url != "" ) ? $event->post->timetable_custom_url : get_permalink( $event->event_id ); ?>"
254
+ class="mptt-event-title">
255
+ <?php }
256
+ echo $event->post->post_title;
257
+
258
+ if ( ! $disable_url ) { ?>
259
+ </a>
260
+ <?php }
261
+
262
+ endif;
263
+ if ( $mptt_shortcode_data[ 'params' ][ 'time' ] ): ?>
264
+ <p class="timeslot">
265
+ <time datetime="<?php echo $event->event_start; ?>" class="timeslot-start"><?php echo date( get_option( 'time_format' ), strtotime( $event->event_start ) ); ?></time>
266
+ <span class="timeslot-delimiter"><?php echo apply_filters( 'mptt_timeslot_delimiter', ' - ' ); ?></span>
267
+ <time datetime="<?php echo $event->event_end; ?>" class="timeslot-end"><?php echo date( get_option( 'time_format' ), strtotime( $event->event_end ) ); ?></time>
268
+ </p>
269
+ <?php endif;
270
+ if ( $mptt_shortcode_data[ 'params' ][ 'sub-title' ] && ! empty( $event->post->sub_title ) ): ?>
271
+ <p class="event-subtitle"><?php echo $event->post->sub_title; ?></p>
272
+ <?php endif;
273
+ if ( $mptt_shortcode_data[ 'params' ][ 'description' ] ): ?>
274
+ <p class="event-description"><?php
275
+ echo stripslashes( $event->description );
276
+ ?></p>
277
+ <?php endif;
278
+ if ( $mptt_shortcode_data[ 'params' ][ 'user' ] && ( $event->user_id != '-1' ) ): ?>
279
+ <p class="event-user"><?php $user_info = get_userdata( $event->user_id );
280
+ if ( $user_info ) {
281
+ echo get_avatar( $event->user_id, apply_filters( 'mptt-event-user-avatar-size', 24 ), '', $user_info->data->display_name ) . ' ';
282
+ echo $user_info->data->display_name;
283
+ } ?></p>
284
+ <?php endif; ?>
285
+ </li>
286
+ <?php endforeach;
287
+ endif; ?>
288
+ </ul>
289
+ </div>
290
+ <?php endforeach;
291
+ endif; ?>
292
+ </div>
293
+ <?php }
294
+ }
295
+
296
+ /**
297
+ * Sidebar
298
+ */
299
+ function mptt_sidebar() {
300
+ global $post;
301
+ View::get_instance()->get_template( 'templates-actions/action-sidebar', array( 'post' => $post ) );
302
+ }
303
+
304
+ /**
305
+ * Make data shortcode
306
+ *
307
+ * @param $bounds
308
+ * @param $mptt_shortcode_data
309
+ * @param $column_events
310
+ *
311
+ * @return array
312
+ */
313
+ function mptt_make_data_shortcode( $bounds, $mptt_shortcode_data, $column_events ) {
314
+ $data = array( 'rows' => array() );
315
+ $amount_rows = 23 / $mptt_shortcode_data[ 'params' ][ 'increment' ];
316
+
317
+ $data[ 'table_header' ] = mptt_get_header_row( $mptt_shortcode_data );
318
+
319
+ foreach ( $column_events as $column_id => $events_list ) {
320
+
321
+ foreach ( $events_list as $event_key => $item ) {
322
+ if ( isset( $item->resolve ) ) {
323
+ unset( $item->resolve );
324
+ }
325
+ }
326
+ }
327
+
328
+ for ( $row_index = $bounds[ 'start' ]; $row_index <= $bounds[ 'end' ]; $row_index ++ ) {
329
+
330
+ $table_time_cell = get_time_cell( $row_index, $amount_rows, $mptt_shortcode_data[ 'params' ][ 'increment' ] );
331
+
332
+ list( $row_cells, $column_events ) = mptt_get_row_events( $column_events, $row_index );
333
+
334
+ if ( $mptt_shortcode_data[ 'params' ][ 'group' ] ) {
335
+ $row_cells = mptt_group_identical_row_events( $row_cells );
336
+ }
337
+
338
+ $data[ 'rows' ][ $row_index ][ 'cells' ] = $row_cells;
339
+ $data[ 'rows' ][ $row_index ][ 'show' ] = mptt_shortcode_row_has_items( $row_index, $column_events );
340
+
341
+ if ( ! $mptt_shortcode_data[ 'params' ][ 'hide_hrs' ] ) {
342
+ array_unshift( $data[ 'rows' ][ $row_index ][ 'cells' ], array( 'time_cell' => true, 'title' => date( get_option( 'time_format' ), strtotime( $table_time_cell ) ) ) );
343
+ }
344
+ }
345
+
346
+ return $data;
347
+ }
348
+
349
+ /**
350
+ * Get time cell
351
+ *
352
+ * @param $row_index
353
+ * @param $amount_rows
354
+ * @param $increment
355
+ *
356
+ * @return string
357
+ */
358
+ function get_time_cell( $row_index, $amount_rows, $increment ) {
359
+ $tm = $row_index * $increment;
360
+
361
+ if ( floor( $tm ) == $tm ) {
362
+ $time = $tm . ':00';
363
+
364
+ return $time;
365
+ } else {
366
+ if ( $amount_rows == 46 ) {
367
+ $time = floor( $tm ) . ':30';
368
+
369
+ return $time;
370
+ } else {
371
+ $tm_position = explode( '.', $tm );
372
+
373
+ if ( $tm_position[ 1 ] == 25 ) {
374
+ $mnts = ':15';
375
+ } elseif ( $tm_position[ 1 ] == 5 ) {
376
+ $mnts = ':30';
377
+ } else {
378
+ $mnts = ':45';
379
+ }
380
+
381
+ $time = floor( $tm ) . $mnts;
382
+
383
+ return $time;
384
+ }
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Add group attribute to event
390
+ *
391
+ * @param $bounds
392
+ * @param $events_array
393
+ *
394
+ * @return mixed
395
+ */
396
+ function group_events( $bounds, $events_array ) {
397
+ $output_array = array();
398
+
399
+ foreach ( $events_array as $column_id => $events_list ) {
400
+
401
+ if ( ! empty( $events_array[ $column_id ] ) ) {
402
+
403
+ foreach ( $events_list as $key_events => $item ) {
404
+
405
+ if ( $bounds[ 'end' ] <= $item->end_index && $bounds[ 'start' ] >= $item->start_index ) {
406
+ continue;
407
+ } else {
408
+ $key_count = $item->start_index . '_' . $item->event_id . '_' . $item->end_index;
409
+
410
+ if ( ! isset( $output_array[ $key_count ] ) ) {
411
+ $output_array[ $key_count ] = array( 'count' => 0, 'output' => false );
412
+ $output_array[ $key_count ][ 'count' ] ++;
413
+ } else {
414
+ $output_array[ $key_count ][ 'count' ] ++;
415
+ }
416
+
417
+ }
418
+ }
419
+ }
420
+ }
421
+
422
+ return $output_array;
423
+ }
424
+
425
+ /**
426
+ * Header row
427
+ *
428
+ * @param $mptt_shortcode_data
429
+ *
430
+ * @return array
431
+ */
432
+ function mptt_get_header_row( $mptt_shortcode_data ) {
433
+ $header_array = array( '0' => array( 'output' => false ) );
434
+ $show_hrs = ! $mptt_shortcode_data[ 'params' ][ 'hide_hrs' ];
435
+
436
+ if ( $show_hrs ):
437
+ $header_array[ 0 ] = array( 'output' => true, 'id' => '', 'title' => '' );
438
+ endif;
439
+
440
+ if ( ! empty( $mptt_shortcode_data[ 'events_data' ][ 'column' ] ) ) {
441
+ foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column' ] as $column ):
442
+ $header_array[] = array( 'output' => true, 'id' => $column->ID, 'title' => $column->post_title );
443
+ endforeach;
444
+ }
445
+
446
+ return $header_array;
447
+ }
448
+
449
+ /**
450
+ * Row events
451
+ *
452
+ * @param $column_events
453
+ * @param $row_index
454
+ *
455
+ * @return array
456
+ */
457
+ function mptt_get_row_events( $column_events, $row_index ) {
458
+ $events = array();
459
+ $default_count = 1;
460
+ $i = 0;
461
+
462
+ foreach ( $column_events as $column_id => $events_list ) {
463
+ $empty = true;
464
+
465
+ foreach ( $events_list as $event_key => $item ) {
466
+ if ( isset( $item->resolve ) && $item->resolve ) {
467
+
468
+ continue;
469
+ }
470
+ $group = false;
471
+ if ( ! empty( $current ) ) {
472
+ if ( ( $item->end_index <= $current[ 'end_index' ] )
473
+ //&& $item->end_index == $row_index
474
+ && $item->start_index == $row_index
475
+ ) {
476
+ $group = true;
477
+ }
478
+ }
479
+
480
+ if ( $item->start_index == $row_index || $group ) {
481
+
482
+ //create temp event data for generate hash
483
+ $temp = (array) $item;
484
+
485
+ //clear data before make hash to compare
486
+ if ( $temp[ 'id' ] ) {
487
+ unset( $temp[ 'id' ] );
488
+ unset( $temp[ 'column_id' ] );
489
+ }
490
+
491
+ $event = array(
492
+ 'id' => $item->id,
493
+ 'hash' => md5( serialize( $temp ) ),
494
+ 'start_index' => $item->start_index,
495
+ 'end_index' => $item->end_index,
496
+ 'event_start' => $item->event_start,
497
+ 'event_end' => $item->event_end,
498
+ 'column_id' => $item->column_id,
499
+ 'event_id' => $item->event_id,
500
+ 'event' => true,
501
+ 'user_id' => $item->user_id,
502
+ 'description' => trim( $item->description ),
503
+ 'order' => $event_key,
504
+ 'hide' => $group ? true : false
505
+ );
506
+
507
+ if ( ! $group ) {
508
+ $events[ $i ][ 'events' ][ $event[ 'hash' ] ] = $event;
509
+ $events[ $i ][ 'count' ] = $default_count;
510
+ $events[ $i ][ 'grouped' ] = false;
511
+ $events[ $i ][ 'column_id' ] = $column_id;
512
+ $events[ $i ][ 'hide' ] = false;
513
+ } else {
514
+
515
+ $events[ $i ][ 'hide' ] = false;
516
+ $events[ $i ][ 'column_id' ] = $column_id;
517
+ $events[ $i ][ 'events' ][ $event[ 'hash' ] ] = $event;
518
+
519
+ }
520
+
521
+ $column_events[ $column_id ][ $event_key ]->resolve = true;
522
+
523
+ $empty = false;
524
+
525
+ if ( empty( $current ) ) {
526
+ $current = array( 'start_index' => $item->start_index, 'end_index' => $item->end_index );
527
+ } else {
528
+ $current[ 'start_index' ] = $current[ 'start_index' ] >= $item->start_index ? $item->start_index : $current[ 'start_index' ];
529
+ $current[ 'end_index' ] = $current[ 'end_index' ] <= $item->end_index ? $item->end_index : $current[ 'end_index' ];
530
+ }
531
+ }
532
+ }
533
+
534
+
535
+ if ( $empty ) {
536
+
537
+ $events[ $i ][ 'events' ][] = array(
538
+ 'id' => false,
539
+ 'start_index' => $row_index,
540
+ 'end_index' => $row_index,
541
+ 'column_id' => $column_id,
542
+ 'event' => true,
543
+ );
544
+
545
+ $events[ $i ][ 'count' ] = $default_count;
546
+ $events[ $i ][ 'column_id' ] = $column_id;
547
+ $events[ $i ][ 'hide' ] = false;
548
+
549
+ }
550
+ unset( $current );
551
+ $i ++;
552
+ }
553
+
554
+ $events = sort_events_data_by_order( $events );
555
+
556
+ return array( $events, $column_events );
557
+ }
558
+
559
+ /**
560
+ * Sort events by order
561
+ *
562
+ * @param $events
563
+ *
564
+ * @return mixed
565
+ */
566
+ function sort_events_data_by_order( $events ) {
567
+ foreach ( $events as $cell => $event_data ) {
568
+ usort( $event_data[ 'events' ], function ( $a, $b ) {
569
+ if ( $a[ 'order' ] == $b[ 'order' ] ) {
570
+ return 0;
571
+ }
572
+
573
+ return ( $a[ 'order' ] < $b[ 'order' ] ) ? - 1 : 1;
574
+ } );
575
+ $events[ $cell ][ 'events' ] = $event_data[ 'events' ];
576
+ }
577
+
578
+ return $events;
579
+ }
580
+
581
+ /**
582
+ * Get columns events
583
+ *
584
+ * @param $mptt_shortcode_data
585
+ *
586
+ * @param $post
587
+ *
588
+ * @return array
589
+ */
590
+ function mptt_get_columns_events( $mptt_shortcode_data, $post ) {
591
+ if ( $post === 'all' ) {
592
+ $column_events = $mptt_shortcode_data[ 'events_data' ][ 'column_events' ];
593
+
594
+ return $column_events;
595
+ } else {
596
+ $column_events = array();
597
+
598
+ foreach ( $mptt_shortcode_data[ 'events_data' ][ 'column_events' ] as $col_id => $col_events ) {
599
+ $column_events[ $col_id ] = array_filter(
600
+ $col_events,
601
+ function ( $val ) use ( $post ) {
602
+ return $post->ID == $val->event_id;
603
+ } );
604
+ }
605
+
606
+ return $column_events;
607
+ }
608
+ }
609
+
610
+ /**
611
+ * Checking identical event in cell
612
+ *
613
+ * @param $needle
614
+ * @param $events
615
+ *
616
+ * @return bool
617
+ */
618
+ function mptt_check_exists_column( $needle, $events ) {
619
+ $exist = false;
620
+ $const_available_difference = 1;
621
+
622
+ foreach ( $events as $key => $event ) {
623
+ $difference_data = array_diff( $needle, $event );
624
+ if ( isset( $difference_data[ 'id' ] ) && ( count( $difference_data ) === $const_available_difference ) ) {
625
+ $exist = true;
626
+ break;
627
+ }
628
+ }
629
+
630
+ return $exist;
631
+ }
632
+
633
+ /**
634
+ * Group event in row
635
+ *
636
+ * @param $events_row_data
637
+ *
638
+ * @return array|mixed
639
+ */
640
+ function mptt_group_identical_row_events( $events_row_data ) {
641
+
642
+ $length = count( $events_row_data );
643
+
644
+ for ( $i = 0; $i < $length - 1; $i ++ ) {
645
+ if ( ! isset( $events_row_data[ ( $i + 1 ) ] ) ) {
646
+ continue;
647
+ }
648
+
649
+ $events_current_data = $events_row_data[ $i ];
650
+ $events_current_count = count( $events_current_data[ 'events' ] );
651
+
652
+ $events_next_data = $events_row_data[ ( $i + 1 ) ];
653
+ $events_next_count = count( $events_next_data[ 'events' ] );
654
+
655
+
656
+ if ( $events_next_count > 1 || $events_current_count > 1 ) {
657
+ continue;
658
+ } else {
659
+ if ( filter_var( $events_current_data[ 'events' ][ 0 ][ 'id' ], FILTER_VALIDATE_INT ) && filter_var( $events_next_data[ 'events' ][ 0 ][ 'id' ], FILTER_VALIDATE_INT ) ) {
660
+
661
+ $hash_current = $events_current_data[ 'events' ][ 0 ][ 'hash' ];
662
+ $hash_next = $events_next_data[ 'events' ][ 0 ][ 'hash' ];
663
+
664
+ if ( ! isset( $current_data ) ) {
665
+ $current_data = array( 'key' => $i, 'hash' => $hash_current );
666
+ }
667
+
668
+ if ( $hash_current === $hash_next ) {
669
+
670
+ if ( $current_data[ 'hash' ] !== $hash_current ) {
671
+ $current_data = array( 'key' => $i, 'hash' => $hash_current );
672
+ }
673
+
674
+ if ( $current_data[ 'key' ] === $i ) {
675
+ $events_current_data[ 'count' ] ++;
676
+ $events_current_data[ 'grouped' ] = true;
677
+ $events_row_data[ $i ] = $events_current_data;
678
+ $events_row_data[ $i + 1 ][ 'hide' ] = true;
679
+ } else {
680
+ $events_row_data[ $current_data[ 'key' ] ][ 'count' ] ++;
681
+ $events_row_data[ $i + 1 ][ 'hide' ] = true;
682
+ }
683
+
684
+ }
685
+ }
686
+ }
687
+ }
688
+
689
+ return $events_row_data;
690
+ }
691
+
692
+ /**
693
+ * Check exists grouped attribute
694
+ *
695
+ * @param $event_item
696
+ *
697
+ * @return string
698
+ */
699
+ function mptt_is_grouped_event_class( $event_item ) {
700
+ return ( isset( $event_item[ 'grouped' ] ) && $event_item[ 'grouped' ] ) ? 'mptt-grouped-event' : '';
701
+ }
702
+
703
+ /**
704
+ * Grouped by column
705
+ *
706
+ * @param $events
707
+ *
708
+ * @return array
709
+ */
710
+ function grouped_by_column( $events ) {
711
+ $data = array();
712
+
713
+ foreach ( $events as $key => $event ) {
714
+ if ( ! $event[ 'event' ] ) {
715
+ $data[] = $event;
716
+ continue;
717
+ }
718
+ if ( isset( $data[ $event[ 'column_id' ] ] ) ) {
719
+ $data[ $event[ 'column_id' ] ][ 'related_by_column' ][] = $event;
720
+ } else {
721
+ $data[ $event[ 'column_id' ] ] = $event;
722
+ }
723
+ }
724
+
725
+ return $data;
726
  }
templates/events/event-data.php CHANGED
@@ -1,41 +1,44 @@
1
- <table class="widefat fixed">
2
- <thead>
3
- <tr>
4
- <th><?php _e('Column', 'mp-timetable') ?></th>
5
- <th><?php _e('Start', 'mp-timetable') ?></th>
6
- <th><?php _e('End', 'mp-timetable') ?></th>
7
- <th><?php _e('Description', 'mp-timetable') ?></th>
8
- <th><?php _e('Head', 'mp-timetable') ?></th>
9
- <th><?php _e('Actions', 'mp-timetable') ?></th>
10
- </tr>
11
- </thead>
12
- <tbody>
13
- </tbody>
14
- </table>
15
- <div class="events-list-wrapper">
16
- <table id="events-list" class="widefat fixed striped">
17
- <tbody>
18
- <?php if (!empty($event_data)): ?>
19
- <?php foreach ($event_data as $data): ?>
20
- <tr data-id="<?php echo $data->id ?>">
21
- <td class="event-column"><?php echo get_the_title($data->column_id); ?></td>
22
- <td class="event-start"><?php echo date(get_option('time_format'), strtotime($data->event_start)); ?></td>
23
- <td class="event-end"><?php echo date(get_option('time_format'), strtotime($data->event_end)); ?></td>
24
- <td class="event-description"><?php echo $data->description; ?></td>
25
- <td class="event-user-id"><?php
26
- $user = ($data->user_id != '-1') ? get_userdata($data->user_id) : false;
27
- if ($user) {
28
- echo $user->display_name;
29
- } ?>
30
- </td>
31
- <td>
32
- <a class="button icon dashicons-edit edit-event-button" data-id="<?php echo $data->id ?>" title="<?php _e('Edit event in the form below', 'mp-timetable') ?>"></a>
33
- <a class="button icon dashicons-trash delete-event-button" data-id="<?php echo $data->id ?>" title="<?php _e('Delete', 'mp-timetable') ?>"></a>
34
- <span class="spinner left"></span>
35
- </td>
36
- </tr>
37
- <?php endforeach; ?>
38
- <?php endif; ?>
39
- </tbody>
40
- </table>
 
 
 
41
  </div>
1
+ <table class="widefat fixed">
2
+ <thead>
3
+ <tr>
4
+ <th><?php _e('Column', 'mp-timetable'); ?></th>
5
+ <th><?php _e('Start', 'mp-timetable'); ?></th>
6
+ <th><?php _e('End', 'mp-timetable'); ?></th>
7
+ <th><?php _e('Description', 'mp-timetable'); ?></th>
8
+ <th><?php
9
+ //translators: Head means the leader of the event.
10
+ _e('Head', 'mp-timetable');
11
+ ?></th>
12
+ <th><?php _e('Actions', 'mp-timetable'); ?></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ </tbody>
17
+ </table>
18
+ <div class="events-list-wrapper">
19
+ <table id="events-list" class="widefat fixed striped">
20
+ <tbody>
21
+ <?php if (!empty($event_data)): ?>
22
+ <?php foreach ($event_data as $data): ?>
23
+ <tr data-id="<?php echo $data->id ?>">
24
+ <td class="event-column"><?php echo get_the_title($data->column_id); ?></td>
25
+ <td class="event-start"><?php echo date(get_option('time_format'), strtotime($data->event_start)); ?></td>
26
+ <td class="event-end"><?php echo date(get_option('time_format'), strtotime($data->event_end)); ?></td>
27
+ <td class="event-description"><?php echo $data->description; ?></td>
28
+ <td class="event-user-id"><?php
29
+ $user = ($data->user_id != '-1') ? get_userdata($data->user_id) : false;
30
+ if ($user) {
31
+ echo $user->display_name;
32
+ } ?>
33
+ </td>
34
+ <td>
35
+ <a class="button icon dashicons-edit edit-event-button" data-id="<?php echo $data->id ?>" title="<?php _e('Edit event in the form below', 'mp-timetable') ?>"></a>
36
+ <a class="button icon dashicons-trash delete-event-button" data-id="<?php echo $data->id ?>" title="<?php _e('Delete', 'mp-timetable') ?>"></a>
37
+ <span class="spinner left"></span>
38
+ </td>
39
+ </tr>
40
+ <?php endforeach; ?>
41
+ <?php endif; ?>
42
+ </tbody>
43
+ </table>
44
  </div>
templates/events/metabox-event-data.php CHANGED
@@ -1,82 +1,88 @@
1
- <input type="hidden" name="<?php echo Mp_Time_Table::get_plugin_name() . '_noncename' ?>" id="eventmeta_noncename" value="<?php echo wp_create_nonce(Mp_Time_Table::get_plugin_path()) ?>"/>
2
- <input type="hidden" name="events[place]" id="eventmeta_place" value=""/>
3
- <input type="hidden" name="events[leading_event]" id="eventmeta_leading_event" value="'.<?php wp_create_nonce(plugin_basename(__FILE__)) ?>.'"/>
4
- <input type="hidden" id="time_format" value="<?php echo $date["time_format"]["am_pm"] === true ? '1' : '0' ?>"/>
5
- <?php
6
-
7
- \mp_timetable\plugin_core\classes\View::get_instance()->render_html('events/event-data', array('event_data' => $event_data), true);
8
-
9
- ?>
10
- <h4><?php _e('Add New / Edit Timeslot', 'mp-timetable'); ?></h4>
11
- <table id="add_event_table" class="widefat">
12
- <tr>
13
- <td><label for="weekday_id"><?php _e('Column:', 'mp-timetable') ?></label></td>
14
- <td>
15
- <?php if (count($columns)) { ?>
16
- <select id="weekday_id" name="events[weekday_id]">
17
- <?php foreach ($columns as $column) { ?>
18
- <option value="<?php echo $column->ID ?>"><?php echo $column->post_title ?></option>
19
- <?php } ?>
20
- </select>
21
- <span class="description"><?php printf(__('Select column or <a target="_blank" href="%s">Add New</a>.', 'mp-timetable'), admin_url('post-new.php?post_type=mp-column') ); ?></span>
22
- <?php } else {
23
- printf(__('No columns found. <a href="%s">Create at least one column first.</a>', 'mp-timetable'), admin_url('post-new.php?post_type=mp-column'));
24
- }
25
- ?>
26
- </td>
27
- </tr>
28
- <tr>
29
- <td><label for="event_start"><?php _e('Start Time:', 'mp-timetable') ?></label></td>
30
- <td>
31
- <input id="event_start" type="text" value="" name="events[start_hour]" maxlength="5" size="5">
32
- <span class="description"><?php _e('hh:mm', 'mp-timetable') ?></span>
33
- </td>
34
- </tr>
35
- <tr>
36
- <td><label for="event_end"><?php _e('End Time:', 'mp-timetable') ?></label></td>
37
- <td>
38
- <input id="event_end" type="text" value="" name="events[end_hour]" maxlength="5" size="5">
39
- <span class="description"><?php _e('hh:mm', 'mp-timetable') ?></span>
40
- </td>
41
- </tr>
42
- <tr>
43
- <td><label for="description"><?php _e('Description:', 'mp-timetable') ?></label></td>
44
- <td><textarea id="description" class="widefat" name="events[description]" rows="2"></textarea></td>
45
- </tr>
46
- <tr>
47
- <td><label for="user_id"><?php _e('Event Head:', 'mp-timetable') ?></label></td>
48
- <td>
49
- <?php
50
-
51
- global $wp_version;
52
- $wp_dropdown_users_show = (version_compare($wp_version, '4.5', '<')) ? 'user_login' : 'display_name_with_login';
53
-
54
- wp_dropdown_users(array(
55
- 'show_option_none' => __('none', 'mp-timetable'),
56
- 'show_option_all' => null,
57
- 'hide_if_only_one_author' => null,
58
- 'orderby' => 'display_name',
59
- 'order' => 'ASC',
60
- 'include' => null,
61
- 'exclude' => null,
62
- 'multi' => false,
63
- 'show' => $wp_dropdown_users_show,
64
- 'echo' => true,
65
- 'selected' => false,
66
- 'include_selected' => false,
67
- 'name' => 'user_id',
68
- 'id' => null,
69
- 'class' => null,
70
- 'blog_id' => $GLOBALS['blog_id'],
71
- 'who' => null
72
- )); ?>
73
- </td>
74
- </tr>
75
- <tr>
76
- <td></td>
77
- <td>
78
- <input id="add_mp_event" type="button" class="button button-primary" value="<?php _e('Add New', 'mp-timetable'); ?>">
79
- <span class="spinner left"></span>
80
- </td>
81
- </tr>
82
- </table>
 
 
 
 
 
 
1
+ <input type="hidden" name="<?php echo Mp_Time_Table::get_plugin_name() . '_noncename' ?>" id="eventmeta_noncename" value="<?php echo wp_create_nonce(Mp_Time_Table::get_plugin_path()) ?>"/>
2
+ <input type="hidden" name="events[place]" id="eventmeta_place" value=""/>
3
+ <input type="hidden" name="events[leading_event]" id="eventmeta_leading_event" value="'.<?php wp_create_nonce(plugin_basename(__FILE__)) ?>.'"/>
4
+ <input type="hidden" id="time_format" value="<?php echo $date["time_format"]["am_pm"] === true ? '1' : '0' ?>"/>
5
+ <?php
6
+
7
+ \mp_timetable\plugin_core\classes\View::get_instance()->render_html('events/event-data', array('event_data' => $event_data), true);
8
+
9
+ ?>
10
+ <h4><?php _e('Add New / Edit Timeslot', 'mp-timetable'); ?></h4>
11
+ <table id="add_event_table" class="widefat">
12
+ <tr>
13
+ <td><label for="weekday_id"><?php _e('Column:', 'mp-timetable') ?></label></td>
14
+ <td>
15
+ <?php if (count($columns)) { ?>
16
+ <select id="weekday_id" name="events[weekday_id]">
17
+ <?php foreach ($columns as $column) { ?>
18
+ <option value="<?php echo $column->ID ?>"><?php echo $column->post_title ?></option>
19
+ <?php } ?>
20
+ </select>
21
+ <span class="description"><?php printf(__('Select column or <a target="_blank" href="%s">Add New</a>.', 'mp-timetable'), admin_url('post-new.php?post_type=mp-column') ); ?></span>
22
+ <?php } else {
23
+ printf(__('No columns found. <a href="%s">Create at least one column first.</a>', 'mp-timetable'), admin_url('post-new.php?post_type=mp-column'));
24
+ }
25
+ ?>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td><label for="event_start"><?php _e('Start Time:', 'mp-timetable') ?></label></td>
30
+ <td>
31
+ <input id="event_start" type="text" value="" name="events[start_hour]" maxlength="5" size="5">
32
+ <span class="description"><?php _e('hh:mm', 'mp-timetable') ?></span>
33
+ </td>
34
+ </tr>
35
+ <tr>
36
+ <td><label for="event_end"><?php _e('End Time:', 'mp-timetable') ?></label></td>
37
+ <td>
38
+ <input id="event_end" type="text" value="" name="events[end_hour]" maxlength="5" size="5">
39
+ <span class="description"><?php _e('hh:mm', 'mp-timetable') ?></span>
40
+ </td>
41
+ </tr>
42
+ <tr>
43
+ <td><label for="description"><?php _e('Description:', 'mp-timetable') ?></label></td>
44
+ <td><textarea id="description" class="widefat" name="events[description]" rows="2"></textarea></td>
45
+ </tr>
46
+ <tr>
47
+ <td><label for="user_id"><?php
48
+ //translators: Head means the leader of the event.
49
+ _e('Event Head:', 'mp-timetable')
50
+ ?></label></td>
51
+ <td>
52
+ <?php
53
+
54
+ global $wp_version;
55
+ $wp_dropdown_users_show = (version_compare($wp_version, '4.5', '<')) ? 'user_login' : 'display_name_with_login';
56
+
57
+ wp_dropdown_users(array(
58
+ 'show_option_none' => __('none', 'mp-timetable'),
59
+ 'show_option_all' => null,
60
+ 'hide_if_only_one_author' => null,
61
+ 'orderby' => 'display_name',
62
+ 'order' => 'ASC',
63
+ 'include' => null,
64
+ 'exclude' => null,
65
+ 'multi' => false,
66
+ 'show' => $wp_dropdown_users_show,
67
+ 'echo' => true,
68
+ 'selected' => false,
69
+ 'include_selected' => false,
70
+ 'name' => 'user_id',
71
+ 'id' => null,
72
+ 'class' => null,
73
+ 'blog_id' => $GLOBALS['blog_id'],
74
+ 'who' => null
75
+ )); ?>
76
+ </td>
77
+ </tr>
78
+ <tr>
79
+ <td></td>
80
+ <td>
81
+ <input id="add_mp_event" type="button" class="button button-primary" value="<?php
82
+ //translators: Button to add a new event.
83
+ _e('Add New', 'mp-timetable');
84
+ ?>">
85
+ <span class="spinner left"></span>
86
+ </td>
87
+ </tr>
88
+ </table>
templates/popup/index.php CHANGED
@@ -1,201 +1,206 @@
1
- <form id="mptt-settings" method="post">
2
- <div class="mptt-shortcode-settings-wrapper">
3
- <table class="form-table striped">
4
- <tr>
5
- <td><label for="weekday"><?php _e('Columns', 'mp-timetable') ?></label></td>
6
- <td>
7
- <select multiple="multiple" id="weekday" name="weekday" class="widefat mptt-resize-vertical">
8
- <?php foreach ($data[ 'column' ] as $column): ?>
9
- <option value="<?php echo $column->ID; ?>"><?php echo $column->post_title; ?></option>
10
- <?php endforeach; ?>
11
- </select>
12
- <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable') ?></p>
13
- </td>
14
- </tr>
15
- <tr>
16
- <td><label for="event"><?php _e('Specific events', 'mp-timetable') ?></label></td>
17
- <td>
18
- <select multiple="multiple" id="event" name="event" class="widefat mptt-resize-vertical">
19
- <?php foreach ($data[ 'events' ] as $events): ?>
20
- <option value="<?php echo $events->ID; ?>"><?php echo $events->post_title; ?></option>
21
- <?php endforeach; ?>
22
- </select>
23
- <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable') ?></p>
24
- </td>
25
- </tr>
26
- <tr>
27
- <td><label for="event_category"><?php _e('Event categories', 'mp-timetable'); ?></label></td>
28
- <td>
29
- <select multiple="multiple" id="event_category" name="event_category" class="widefat mptt-resize-vertical">
30
- <?php foreach ($data[ 'category' ] as $category): ?>
31
- <option value="<?php echo $category->term_id; ?>"><?php echo $category->name; ?></option>
32
- <?php endforeach; ?>
33
- </select>
34
- <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable'); ?></p>
35
- </td>
36
- </tr>
37
- <tr>
38
- <td><label><?php _e('Fields to display:', 'mp-timetable'); ?></label></td>
39
- <td>
40
- <label for="title" class="label_width"><input type="checkbox" name="title" checked value="1"/><?php _e('Title', 'mp-timetable'); ?></label><br/>
41
- <label for="time" class="label_width"><input type="checkbox" name="time" checked value="1"/><?php _e('Time', 'mp-timetable'); ?></label><br/>
42
- <label for="sub-title" class="label_width"><input type="checkbox" name="sub-title" checked value="1"/><?php _e('Subtitle', 'mp-timetable'); ?></label><br/>
43
- <label for="description" class="label_width"><input type="checkbox" name="description" value="1"/><?php _e('Description', 'mp-timetable'); ?></label><br/>
44
- <label for="user" class="label_width"><input type="checkbox" name="user" value="1"/><?php _e('Event Head', 'mp-timetable'); ?></label>
45
- <p class="description"><?php _e('Check the event parameter(s) to be displayed in the timetable.', 'mp-timetable'); ?></p>
46
- </td>
47
- </tr>
48
- <tr>
49
- <td><label for="row_height"><?php _e('Block height in pixels', 'mp-timetable'); ?></label></td>
50
- <td>
51
- <input type="text" name="row_height" id="row_height" value="45" class="regular-text">
52
- <p class="description"><?php _e('Set height of the block', 'mp-timetable'); ?></p>
53
- </td>
54
- </tr>
55
- <tr>
56
- <td><label for="font_size"><?php _e('Base font size', 'mp-timetable'); ?></label></td>
57
- <td>
58
- <input type="text" name="font_size" id="font_size" value="" class="regular-text">
59
- <p class="description"><?php _e('Base font size for the table. Example 12px, 2em, 80%.', 'mp-timetable'); ?></p>
60
- </td>
61
- </tr>
62
- <tr>
63
- <td><label for="measure"><?php _e('Time frame for event', 'mp-timetable'); ?></label></td>
64
- <td>
65
- <select id="measure" name="measure">
66
- <option value="1"><?php _e('Hour (1h)', 'mp-timetable'); ?></option>
67
- <option value="0.5"><?php _e('Half hour (30min)', 'mp-timetable'); ?></option>
68
- <option value="0.25"><?php _e('Quarter hour (15min)', 'mp-timetable'); ?></option>
69
- </select>
70
- </td>
71
- </tr>
72
- <tr>
73
- <td><label for="filter_style"><?php _e('Filter events style', 'mp-timetable'); ?> </label></td>
74
- <td>
75
- <select id="filter_style" name="filter_style">
76
- <option value="dropdown_list"><?php _e('Dropdown', 'mp-timetable'); ?></option>
77
- <option value="tabs"><?php _e('Tabs', 'mp-timetable'); ?></option>
78
- <option value="none"><?php _e('None', 'mp-timetable'); ?></option>
79
- </select>
80
- </td>
81
- </tr>
82
- <tr>
83
- <td><label for="filter_style_sort"><?php _e('Order of items in filter', 'mp-timetable'); ?> </label></td>
84
- <td>
85
- <select id="filter_style_sort" name="filter_style_sort">
86
- <option value=""><?php _e('Default', 'mp-timetable'); ?></option>
87
- <option value="menu_order"><?php _e('Menu Order', 'mp-timetable'); ?></option>
88
- <option value="post_title"><?php _e('Title', 'mp-timetable'); ?></option>
89
- </select>
90
- </td>
91
- </tr>
92
- <tr>
93
- <td><label for="filter_label"><?php _e('Filter title to display all events', 'mp-timetable'); ?></label></td>
94
- <td>
95
- <input type="text" name="filter_label" id="filter_label" value="All Events" class="regular-text">
96
- </td>
97
- </tr>
98
- <tr>
99
- <td><label for="hide_all_events_view"><?php _e('Hide \'All Events\' option', 'mp-timetable'); ?></label>
100
- </td>
101
- <td>
102
- <select id="hide_all_events_view" name="hide_all_events_view">
103
- <option value="0"><?php _e('No', 'mp-timetable') ?></option>
104
- <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
105
- </select>
106
- </td>
107
- </tr>
108
- <tr>
109
- <td><label for="hide_hours_column"><?php _e('Hide column with hours', 'mp-timetable'); ?></label></td>
110
- <td>
111
- <select id="hide_hours_column" name="hide_hours_column">
112
- <option value="0"><?php _e('No', 'mp-timetable') ?></option>
113
- <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
114
- </select>
115
- </td>
116
- </tr>
117
- <tr>
118
- <td><label for="hide_empty"><?php _e('Do not display empty rows', 'mp-timetable'); ?></label></td>
119
- <td>
120
- <select id="hide_empty" name="hide_empty">
121
- <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
122
- <option value="0"><?php _e('No', 'mp-timetable') ?></option>
123
- </select>
124
- </td>
125
- </tr>
126
- <tr>
127
- <td><label for="group_events"><?php _e('Merge cells with common events', 'mp-timetable'); ?></label></td>
128
- <td>
129
- <select id="group_events" name="group_events">
130
- <option value="0"><?php _e('No', 'mp-timetable') ?></option>
131
- <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
132
- </select>
133
- </td>
134
- </tr>
135
- <tr>
136
- <td><label for="disable_event_url"><?php _e('Disable event link', 'mp-timetable'); ?></label></td>
137
- <td>
138
- <select id="disable_event_url" name="disable_event_url">
139
- <option value="0"><?php _e('No', 'mp-timetable') ?></option>
140
- <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
141
- </select>
142
- </td>
143
- </tr>
144
- <tr>
145
- <td><label for="text_align"><?php _e('Horizontal align', 'mp-timetable') ?> </label></td>
146
- <td><select id="text_align" name="text_align">
147
- <option value="center"><?php _e('center', 'mp-timetable') ?></option>
148
- <option value="left"><?php _e('left', 'mp-timetable') ?></option>
149
- <option value="right"><?php _e('right', 'mp-timetable') ?></option>
150
- </select>
151
- </td>
152
- </tr>
153
- <tr>
154
- <td><label for="text_align_vertical"><?php _e('Vertical align', 'mp-timetable') ?> </label></td>
155
- <td><select id="text_align_vertical" name="text_align_vertical">
156
- <option value="default"><?php _e('default', 'mp-timetable') ?></option>
157
- <option value="top"><?php _e('top', 'mp-timetable') ?></option>
158
- <option value="middle"><?php _e('middle', 'mp-timetable') ?></option>
159
- <option value="bottom"><?php _e('bottom', 'mp-timetable') ?></option>
160
- </select>
161
- </td>
162
- </tr>
163
- <tr>
164
- <td><label for="table_layout"><?php _e('Table layout', 'mp-timetable'); ?> </label></td>
165
- <td>
166
- <select id="table_layout" name="table_layout">
167
- <option value=""><?php _e('Default', 'mp-timetable'); ?></option>
168
- <option value="auto"><?php _e('Auto', 'mp-timetable'); ?></option>
169
- <option value="fixed"><?php _e('Fixed', 'mp-timetable'); ?></option>
170
- </select>
171
- </td>
172
- </tr>
173
- <tr>
174
- <td><label for="id"><?php _e('Unique ID', 'mp-timetable'); ?></label></td>
175
- <td>
176
- <input type="text" name="id" id="id" value="" class="regular-text">
177
- <p class="description"><?php _e('If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'mp-timetable'); ?></p>
178
- </td>
179
- </tr>
180
- <tr>
181
- <td><label for="custom_class"><?php _e('CSS class', 'mp-timetable'); ?></label></td>
182
- <td>
183
- <input type="text" name="custom_class" id="custom_class" value="" class="regular-text">
184
- </td>
185
- </tr>
186
- <tr>
187
- <td><label for="responsive"><?php _e('Mobile behavior', 'mp-timetable'); ?></label></td>
188
- <td>
189
- <select id="responsive" name="responsive">
190
- <option value="1"><?php _e('List', 'mp-timetable') ?></option>
191
- <option value="0"><?php _e('Table', 'mp-timetable') ?></option>
192
- </select>
193
- <p class="description"><?php _e('Tick "List" to display events in a list view on mobile devices. Tick "Table" to display events in a table.', 'mp-timetable'); ?></p>
194
- </td>
195
- </tr>
196
- </table>
197
- </div>
198
- <div class="mptt-shortcode-submit-wrapper">
199
- <input type="button" value="<?php _e('Add Timetable', 'mp-timetable'); ?>" id="insert-into" class="button button-primary button-large" name="save">
200
- </div>
 
 
 
 
 
201
  </form>
1
+ <form id="mptt-settings" method="post">
2
+ <div class="mptt-shortcode-settings-wrapper">
3
+ <table class="form-table striped">
4
+ <tr>
5
+ <td><label for="weekday"><?php _e('Columns', 'mp-timetable') ?></label></td>
6
+ <td>
7
+ <select multiple="multiple" id="weekday" name="weekday" class="widefat mptt-resize-vertical">
8
+ <?php foreach ($data[ 'column' ] as $column): ?>
9
+ <option value="<?php echo $column->ID; ?>"><?php echo $column->post_title; ?></option>
10
+ <?php endforeach; ?>
11
+ </select>
12
+ <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable') ?></p>
13
+ </td>
14
+ </tr>
15
+ <tr>
16
+ <td><label for="event"><?php _e('Specific events', 'mp-timetable') ?></label></td>
17
+ <td>
18
+ <select multiple="multiple" id="event" name="event" class="widefat mptt-resize-vertical">
19
+ <?php foreach ($data[ 'events' ] as $events): ?>
20
+ <option value="<?php echo $events->ID; ?>"><?php echo $events->post_title; ?></option>
21
+ <?php endforeach; ?>
22
+ </select>
23
+ <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable') ?></p>
24
+ </td>
25
+ </tr>
26
+ <tr>
27
+ <td><label for="event_category"><?php _e('Event categories', 'mp-timetable'); ?></label></td>
28
+ <td>
29
+ <select multiple="multiple" id="event_category" name="event_category" class="widefat mptt-resize-vertical">
30
+ <?php foreach ($data[ 'category' ] as $category): ?>
31
+ <option value="<?php echo $category->term_id; ?>"><?php echo $category->name; ?></option>
32
+ <?php endforeach; ?>
33
+ </select>
34
+ <p class="description"><?php _e('Hold the Ctrl or Command key to select/deselect multiple options.', 'mp-timetable'); ?></p>
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <td><label><?php _e('Fields to display:', 'mp-timetable'); ?></label></td>
39
+ <td>
40
+ <label for="title" class="label_width"><input type="checkbox" name="title" checked value="1"/><?php _e('Title', 'mp-timetable'); ?></label><br/>
41
+ <label for="time" class="label_width"><input type="checkbox" name="time" checked value="1"/><?php _e('Time', 'mp-timetable'); ?></label><br/>
42
+ <label for="sub-title" class="label_width"><input type="checkbox" name="sub-title" checked value="1"/><?php _e('Subtitle', 'mp-timetable'); ?></label><br/>
43
+ <label for="description" class="label_width"><input type="checkbox" name="description" value="1"/><?php _e('Description', 'mp-timetable'); ?></label><br/>
44
+ <label for="user" class="label_width"><input type="checkbox" name="user" value="1"/>
45
+ <?php
46
+ //translators: Head means the leader of the event.
47
+ _e('Event Head', 'mp-timetable');
48
+ ?>
49
+ </label>
50
+ <p class="description"><?php _e('Check the event parameter(s) to be displayed in the timetable.', 'mp-timetable'); ?></p>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <td><label for="row_height"><?php _e('Block height in pixels', 'mp-timetable'); ?></label></td>
55
+ <td>
56
+ <input type="text" name="row_height" id="row_height" value="45" class="regular-text">
57
+ <p class="description"><?php _e('Set height of the block', 'mp-timetable'); ?></p>
58
+ </td>
59
+ </tr>
60
+ <tr>
61
+ <td><label for="font_size"><?php _e('Base font size', 'mp-timetable'); ?></label></td>
62
+ <td>
63
+ <input type="text" name="font_size" id="font_size" value="" class="regular-text">
64
+ <p class="description"><?php _e('Base font size for the table. Example 12px, 2em, 80%.', 'mp-timetable'); ?></p>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td><label for="measure"><?php _e('Time frame for event', 'mp-timetable'); ?></label></td>
69
+ <td>
70
+ <select id="measure" name="measure">
71
+ <option value="1"><?php _e('Hour (1h)', 'mp-timetable'); ?></option>
72
+ <option value="0.5"><?php _e('Half hour (30min)', 'mp-timetable'); ?></option>
73
+ <option value="0.25"><?php _e('Quarter hour (15min)', 'mp-timetable'); ?></option>
74
+ </select>
75
+ </td>
76
+ </tr>
77
+ <tr>
78
+ <td><label for="filter_style"><?php _e('Filter events style', 'mp-timetable'); ?> </label></td>
79
+ <td>
80
+ <select id="filter_style" name="filter_style">
81
+ <option value="dropdown_list"><?php _e('Dropdown', 'mp-timetable'); ?></option>
82
+ <option value="tabs"><?php _e('Tabs', 'mp-timetable'); ?></option>
83
+ <option value="none"><?php _e('None', 'mp-timetable'); ?></option>
84
+ </select>
85
+ </td>
86
+ </tr>
87
+ <tr>
88
+ <td><label for="filter_style_sort"><?php _e('Order of items in filter', 'mp-timetable'); ?> </label></td>
89
+ <td>
90
+ <select id="filter_style_sort" name="filter_style_sort">
91
+ <option value=""><?php _e('Default', 'mp-timetable'); ?></option>
92
+ <option value="menu_order"><?php _e('Menu Order', 'mp-timetable'); ?></option>
93
+ <option value="post_title"><?php _e('Title', 'mp-timetable'); ?></option>
94
+ </select>
95
+ </td>
96
+ </tr>
97
+ <tr>
98
+ <td><label for="filter_label"><?php _e('Filter title to display all events', 'mp-timetable'); ?></label></td>
99
+ <td>
100
+ <input type="text" name="filter_label" id="filter_label" value="All Events" class="regular-text">
101
+ </td>
102
+ </tr>
103
+ <tr>
104
+ <td><label for="hide_all_events_view"><?php _e('Hide \'All Events\' option', 'mp-timetable'); ?></label>
105
+ </td>
106
+ <td>
107
+ <select id="hide_all_events_view" name="hide_all_events_view">
108
+ <option value="0"><?php _e('No', 'mp-timetable') ?></option>
109
+ <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
110
+ </select>
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <td><label for="hide_hours_column"><?php _e('Hide column with hours', 'mp-timetable'); ?></label></td>
115
+ <td>
116
+ <select id="hide_hours_column" name="hide_hours_column">
117
+ <option value="0"><?php _e('No', 'mp-timetable') ?></option>
118
+ <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
119
+ </select>
120
+ </td>
121
+ </tr>
122
+ <tr>
123
+ <td><label for="hide_empty"><?php _e('Do not display empty rows', 'mp-timetable'); ?></label></td>
124
+ <td>
125
+ <select id="hide_empty" name="hide_empty">
126
+ <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
127
+ <option value="0"><?php _e('No', 'mp-timetable') ?></option>
128
+ </select>
129
+ </td>
130
+ </tr>
131
+ <tr>
132
+ <td><label for="group_events"><?php _e('Merge cells with common events', 'mp-timetable'); ?></label></td>
133
+ <td>
134
+ <select id="group_events" name="group_events">
135
+ <option value="0"><?php _e('No', 'mp-timetable') ?></option>
136
+ <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
137
+ </select>
138
+ </td>
139
+ </tr>
140
+ <tr>
141
+ <td><label for="disable_event_url"><?php _e('Disable event link', 'mp-timetable'); ?></label></td>
142
+ <td>
143
+ <select id="disable_event_url" name="disable_event_url">
144
+ <option value="0"><?php _e('No', 'mp-timetable') ?></option>
145
+ <option value="1"><?php _e('Yes', 'mp-timetable') ?></option>
146
+ </select>
147
+ </td>
148
+ </tr>
149
+ <tr>
150
+ <td><label for="text_align"><?php _e('Horizontal align', 'mp-timetable') ?> </label></td>
151
+ <td><select id="text_align" name="text_align">
152
+ <option value="center"><?php _e('center', 'mp-timetable') ?></option>
153
+ <option value="left"><?php _e('left', 'mp-timetable') ?></option>
154
+ <option value="right"><?php _e('right', 'mp-timetable') ?></option>
155
+ </select>
156
+ </td>
157
+ </tr>
158
+ <tr>
159
+ <td><label for="text_align_vertical"><?php _e('Vertical align', 'mp-timetable') ?> </label></td>
160
+ <td><select id="text_align_vertical" name="text_align_vertical">
161
+ <option value="default"><?php _e('default', 'mp-timetable') ?></option>
162
+ <option value="top"><?php _e('top', 'mp-timetable') ?></option>
163
+ <option value="middle"><?php _e('middle', 'mp-timetable') ?></option>
164
+ <option value="bottom"><?php _e('bottom', 'mp-timetable') ?></option>
165
+ </select>
166
+ </td>
167
+ </tr>
168
+ <tr>
169
+ <td><label for="table_layout"><?php _e('Column width', 'mp-timetable'); ?> </label></td>
170
+ <td>
171
+ <select id="table_layout" name="table_layout">
172
+ <option value=""><?php _e('Default', 'mp-timetable'); ?></option>
173
+ <option value="auto"><?php _e('Auto', 'mp-timetable'); ?></option>
174
+ <option value="fixed"><?php _e('Fixed', 'mp-timetable'); ?></option>
175
+ </select>
176
+ </td>
177
+ </tr>
178
+ <tr>
179
+ <td><label for="id"><?php _e('Unique ID', 'mp-timetable'); ?></label></td>
180
+ <td>
181
+ <input type="text" name="id" id="id" value="" class="regular-text">
182
+ <p class="description"><?php _e('If you use more than one table on a page specify the unique ID for a timetable. It is usually all lowercase and contains only letters, numbers, and hyphens.', 'mp-timetable'); ?></p>
183
+ </td>
184
+ </tr>
185
+ <tr>
186
+ <td><label for="custom_class"><?php _e('CSS class', 'mp-timetable'); ?></label></td>
187
+ <td>
188
+ <input type="text" name="custom_class" id="custom_class" value="" class="regular-text">
189
+ </td>
190
+ </tr>
191
+ <tr>
192
+ <td><label for="responsive"><?php _e('Mobile behavior', 'mp-timetable'); ?></label></td>
193
+ <td>
194
+ <select id="responsive" name="responsive">
195
+ <option value="1"><?php _e('List', 'mp-timetable') ?></option>
196
+ <option value="0"><?php _e('Table', 'mp-timetable') ?></option>
197
+ </select>
198
+ <p class="description"><?php _e('Tick "List" to display events in a list view on mobile devices. Tick "Table" to display events in a table.', 'mp-timetable'); ?></p>
199
+ </td>
200
+ </tr>
201
+ </table>
202
+ </div>
203
+ <div class="mptt-shortcode-submit-wrapper">
204
+ <input type="button" value="<?php _e('Add Timetable', 'mp-timetable'); ?>" id="insert-into" class="button button-primary button-large" name="save">
205
+ </div>
206
  </form>
templates/settings/general.php CHANGED
@@ -1,45 +1,45 @@
1
- <div class="wrap">
2
- <h1 class="wp-heading-inline"><?php _e('General Settings', 'mp-timetable'); ?></h1>
3
-
4
- <?php settings_errors('mpTimetableSettings', false); ?>
5
-
6
- <form method="POST">
7
- <table class="form-table">
8
- <tr>
9
- <td><label for="template_source"><?php _e('Template Mode', 'mp-timetable'); ?></label></td>
10
- <td>
11
- <?php $theme_mode = !empty($settings['theme_mode']) ? $settings['theme_mode'] : 'theme'; ?>
12
- <select id="theme_mode" name="theme_mode" <?php echo $theme_supports ? ' disabled' : ''; ?>>
13
- <option value="theme" <?php selected($theme_mode, 'theme'); ?>><?php _e('Theme Mode', 'mp-timetable'); ?></option>
14
- <option value="plugin" <?php selected($theme_mode, 'plugin'); ?>><?php _e('Developer Mode', 'mp-timetable'); ?></option>
15
- </select>
16
- <p class="description"><?php _e("Choose Theme Mode to display the content with the styles of your theme. Choose Developer Mode to control appearance of the content with custom page templates, actions and filters.", 'mp-timetable'); ?><br/><?php _e("This option can't be changed if your theme is initially integrated with the plugin.", 'mp-timetable'); ?></p>
17
- </td>
18
- </tr>
19
- <?php
20
- if ( apply_filters('mptt_permalinks_enabled', true) ) {
21
- ?>
22
- <tr>
23
- <td><?php _e('Permalink Settings'); ?></td>
24
- <td><?php echo sprintf( __('Configure permalink settings in <a href="%s">Settings > Permalinks</a>', 'mp-timetable'), admin_url('options-permalink.php') ); ?></td>
25
- </tr>
26
- <?php } ?>
27
- </table>
28
- <p class="submit">
29
- <input type="submit" name="submit" id="submit" class="button-primary" value="<?php _e('Save', 'mp-timetable') ?>"/>
30
- <input type="hidden" name="mp-timetable-save-settings" value="<?php echo wp_create_nonce('mp_timetable_nonce_settings') ?>">
31
- </p>
32
- </form>
33
- </div>
34
- <p><?php
35
-
36
- $pluginObject = get_plugin_data( MP_TT_PLUGIN_FILE );
37
- $name = $pluginObject[ 'Name' ];
38
-
39
- echo sprintf(
40
- /* translators: 1: Timetable and Event Schedule 2:: five stars rating */
41
- __( 'If you like %1$s please leave us a %2$s rating.', 'mp-timetable' ),
42
- sprintf( '<strong>%s</strong>', esc_html( $name ) ),
43
- '<a href="https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
44
- );
45
  ?></p>
1
+ <div class="wrap">
2
+ <h1 class="wp-heading-inline"><?php _e('General Settings', 'mp-timetable'); ?></h1>
3
+
4
+ <?php settings_errors('mpTimetableSettings', false); ?>
5
+
6
+ <form method="POST">
7
+ <table class="form-table">
8
+ <tr>
9
+ <td><label for="template_source"><?php _e('Template Mode', 'mp-timetable'); ?></label></td>
10
+ <td>
11
+ <?php $theme_mode = !empty($settings['theme_mode']) ? $settings['theme_mode'] : 'theme'; ?>
12
+ <select id="theme_mode" name="theme_mode" <?php echo $theme_supports ? ' disabled' : ''; ?>>
13
+ <option value="theme" <?php selected($theme_mode, 'theme'); ?>><?php _e('Theme Mode', 'mp-timetable'); ?></option>
14
+ <option value="plugin" <?php selected($theme_mode, 'plugin'); ?>><?php _e('Developer Mode', 'mp-timetable'); ?></option>
15
+ </select>
16
+ <p class="description"><?php _e("Choose Theme Mode to display the content with the styles of your theme. Choose Developer Mode to control appearance of the content with custom page templates, actions and filters.", 'mp-timetable'); ?><br/><?php _e("This option can't be changed if your theme is initially integrated with the plugin.", 'mp-timetable'); ?></p>
17
+ </td>
18
+ </tr>
19
+ <?php
20
+ if ( apply_filters('mptt_permalinks_enabled', true) ) {
21
+ ?>
22
+ <tr>
23
+ <td><?php _e('Permalink Settings', 'mp-timetable'); ?></td>
24
+ <td><?php echo sprintf( __('Configure permalink settings in <a href="%s">Settings > Permalinks</a>', 'mp-timetable'), admin_url('options-permalink.php') ); ?></td>
25
+ </tr>
26
+ <?php } ?>
27
+ </table>
28
+ <p class="submit">
29
+ <input type="submit" name="submit" id="submit" class="button-primary" value="<?php _e('Save', 'mp-timetable') ?>"/>
30
+ <input type="hidden" name="mp-timetable-save-settings" value="<?php echo wp_create_nonce('mp_timetable_nonce_settings') ?>">
31
+ </p>
32
+ </form>
33
+ </div>
34
+ <p><?php
35
+
36
+ $pluginObject = get_plugin_data( MP_TT_PLUGIN_FILE );
37
+ $name = $pluginObject[ 'Name' ];
38
+
39
+ echo sprintf(
40
+ /* translators: 1: Timetable and Event Schedule 2:: five stars rating */
41
+ __( 'If you like %1$s please leave us a %2$s rating.', 'mp-timetable' ),
42
+ sprintf( '<strong>%s</strong>', esc_html( $name ) ),
43
+ '<a href="https://wordpress.org/support/plugin/mp-timetable/reviews?rate=5#new-post" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
44
+ );
45
  ?></p>
templates/shortcodes/event-container.php CHANGED
@@ -1,54 +1,54 @@
1
- <?php $item[ 'post' ] = get_post( $item[ 'event_id' ] ); ?>
2
- <div data-event-id="<?php echo $item[ 'event_id' ] ?>" data-start="<?php echo empty( $startIndex ) ? $item[ 'start_index' ] : $startIndex ?>" data-start-item="<?php echo $item[ 'start_index' ] ?>"
3
- data-end="<?php echo $item[ 'end_index' ] ?>"
4
- class="mptt-event-container id-<?php echo $item[ 'id' ]; ?> mptt-colorized"
5
- data-type="event"
6
- data-bg_hover_color="<?php echo $item[ 'post' ]->hover_color ? $item[ 'post' ]->hover_color : '' ?>"
7
- data-bg_color="<?php echo $item[ 'post' ]->color ? $item[ 'post' ]->color : '' ?>"
8
- data-hover_color="<?php echo $item[ 'post' ]->hover_text_color ? $item[ 'post' ]->hover_text_color : '' ?>"
9
- data-color="<?php echo $item[ 'post' ]->text_color ? $item[ 'post' ]->text_color : '' ?>"
10
- data-min-height=""
11
- style="<?php echo $params[ 'text_align' ] ? 'text-align:' . $params[ 'text_align' ] . ';' : '' ?>
12
- <?php echo $item[ 'post' ]->color ? 'background-color:' . $item[ 'post' ]->color . ';' : '' ?>
13
- <?php echo $item[ 'post' ]->text_color ? 'color:' . $item[ 'post' ]->text_color . ';' : '' ?>
14
- <?php echo ! empty( $height ) ? 'height:' . $height . '%;' : '' ?>
15
- <?php echo ! empty( $top ) ? 'top:' . $top . '%;' : '' ?>">
16
- <div class="mptt-inner-event-content">
17
- <?php if ( $params[ 'title' ] ) {
18
- $disable_url = (bool) $item[ 'post' ]->timetable_disable_url || (bool) $params[ 'disable_event_url' ];
19
-
20
- if ( ! $disable_url ) { ?>
21
- <a title="<?php echo $item[ 'post' ]->post_title; ?>" href="<?php echo ( $item[ 'post' ]->timetable_custom_url != "" ) ? $item[ 'post' ]->timetable_custom_url : get_permalink( $item[ 'event_id' ] ); ?>" class="event-title"><?php echo $item[ 'post' ]->post_title; ?></a>
22
- <?php }
23
-
24
- if ( $disable_url ) { ?>
25
- <span class="event-title"><?php echo $item[ 'post' ]->post_title; ?></span>
26
- <?php }
27
- }
28
-
29
- if ( $params[ 'time' ] ): ?>
30
- <p class="timeslot">
31
- <time datetime="<?php echo $item[ 'event_start' ]; ?>" class="timeslot-start"><?php echo date( get_option( 'time_format' ), strtotime( $item[ 'event_start' ] ) ); ?></time>
32
- <span class="timeslot-delimiter"><?php echo apply_filters( 'mptt_timeslot_delimiter', ' - ' ); ?></span>
33
- <time datetime="<?php echo $item[ 'event_end' ]; ?>" class="timeslot-end"><?php echo date( get_option( 'time_format' ), strtotime( $item[ 'event_end' ] ) );; ?></time>
34
- </p>
35
- <?php endif;
36
-
37
- if ( $params[ 'sub-title' ] && ! empty( $item[ 'post' ]->sub_title ) ): ?>
38
- <p class="event-subtitle"><?php echo $item[ 'post' ]->sub_title; ?></p>
39
- <?php endif;
40
-
41
- if ( $params[ 'description' ] && ! empty( $item[ 'description' ] ) ): ?>
42
- <p class="event-description"><?php echo stripslashes( $item[ 'description' ] ); ?></p>
43
- <?php endif;
44
-
45
- if ( $params[ 'user' ] && $item[ 'user_id' ] != '-1' ): ?>
46
- <p class="event-user"><?php $user_info = get_userdata( $item[ 'user_id' ] );
47
- if ( $user_info ) {
48
- echo get_avatar( $item[ 'user_id' ], apply_filters( 'mptt-event-user-avatar-size', 24 ), '', $user_info->data->display_name );
49
- echo $user_info->data->display_name;
50
- } ?>
51
- </p>
52
- <?php endif; ?>
53
- </div>
54
  </div>
1
+ <?php $item[ 'post' ] = get_post( $item[ 'event_id' ] ); ?>
2
+ <div data-event-id="<?php echo $item[ 'event_id' ] ?>" data-start="<?php echo empty( $startIndex ) ? $item[ 'start_index' ] : $startIndex ?>" data-start-item="<?php echo $item[ 'start_index' ] ?>"
3
+ data-end="<?php echo $item[ 'end_index' ] ?>"
4
+ class="mptt-event-container id-<?php echo $item[ 'id' ]; ?> mptt-colorized"
5
+ data-type="event"
6
+ data-bg_hover_color="<?php echo $item[ 'post' ]->hover_color ? $item[ 'post' ]->hover_color : '' ?>"
7
+ data-bg_color="<?php echo $item[ 'post' ]->color ? $item[ 'post' ]->color : '' ?>"
8
+ data-hover_color="<?php echo $item[ 'post' ]->hover_text_color ? $item[ 'post' ]->hover_text_color : '' ?>"
9
+ data-color="<?php echo $item[ 'post' ]->text_color ? $item[ 'post' ]->text_color : '' ?>"
10
+ data-min-height=""
11
+ style="<?php echo $params[ 'text_align' ] ? 'text-align:' . $params[ 'text_align' ] . ';' : '' ?>
12
+ <?php echo $item[ 'post' ]->color ? 'background-color:' . $item[ 'post' ]->color . ';' : '' ?>
13
+ <?php echo $item[ 'post' ]->text_color ? 'color:' . $item[ 'post' ]->text_color . ';' : '' ?>
14
+ <?php echo ! empty( $height ) ? 'height:' . $height . '%;' : '' ?>
15
+ <?php echo ! empty( $top ) ? 'top:' . $top . '%;' : '' ?>">
16
+ <div class="mptt-inner-event-content">
17
+ <?php if ( $params[ 'title' ] ) {
18
+ $disable_url = (bool) $item[ 'post' ]->timetable_disable_url || (bool) $params[ 'disable_event_url' ];
19
+
20
+ if ( ! $disable_url ) { ?>
21
+ <a title="<?php echo $item[ 'post' ]->post_title; ?>" href="<?php echo ( $item[ 'post' ]->timetable_custom_url != "" ) ? $item[ 'post' ]->timetable_custom_url : get_permalink( $item[ 'event_id' ] ); ?>" class="event-title"><?php echo $item[ 'post' ]->post_title; ?></a>
22
+ <?php }
23
+
24
+ if ( $disable_url ) { ?>
25
+ <span class="event-title"><?php echo $item[ 'post' ]->post_title; ?></span>
26
+ <?php }
27
+ }
28
+
29
+ if ( $params[ 'time' ] ): ?>
30
+ <p class="timeslot">
31
+ <time datetime="<?php echo $item[ 'event_start' ]; ?>" class="timeslot-start"><?php echo date( get_option( 'time_format' ), strtotime( $item[ 'event_start' ] ) ); ?></time>
32
+ <span class="timeslot-delimiter"><?php echo apply_filters( 'mptt_timeslot_delimiter', ' - ' ); ?></span>
33
+ <time datetime="<?php echo $item[ 'event_end' ]; ?>" class="timeslot-end"><?php echo date( get_option( 'time_format' ), strtotime( $item[ 'event_end' ] ) );; ?></time>
34
+ </p>
35
+ <?php endif;
36
+
37
+ if ( $params[ 'sub-title' ] && ! empty( $item[ 'post' ]->sub_title ) ): ?>
38
+ <p class="event-subtitle"><?php echo $item[ 'post' ]->sub_title; ?></p>
39
+ <?php endif;
40
+
41
+ if ( $params[ 'description' ] && ! empty( $item[ 'description' ] ) ): ?>
42
+ <p class="event-description"><?php echo stripslashes( $item[ 'description' ] ); ?></p>
43
+ <?php endif;
44
+
45
+ if ( $params[ 'user' ] && $item[ 'user_id' ] != '-1' ): ?>
46
+ <p class="event-user"><?php $user_info = get_userdata( $item[ 'user_id' ] );
47
+ if ( $user_info ) {
48
+ echo get_avatar( $item[ 'user_id' ], apply_filters( 'mptt-event-user-avatar-size', 24 ), '', $user_info->data->display_name );
49
+ echo $user_info->data->display_name;
50
+ } ?>
51
+ </p>
52
+ <?php endif; ?>
53
+ </div>
54
  </div>