YITH WooCommerce Compare - Version 2.0.0

Version Description

  • Added: Added new plugin core
  • Fixed: Error in class yith-woocompare-fontend
  • Fixed: Lightbox doesn't close after click view cart
  • Fixed: minor bug fix
  • Updated: Language files
  • Removed: old default.po catalog language file
Download this release

Release Info

Developer yithemes
Plugin Icon 128x128 YITH WooCommerce Compare
Version 2.0.0
Comparing to
See all releases

Code changes from version 1.2.3 to 2.0.0

Files changed (142) hide show
  1. README.txt +26 -31
  2. assets/css/jquery.dataTables.css +420 -186
  3. assets/images/01-bg.png +0 -0
  4. assets/images/01-icon.png +0 -0
  5. assets/images/01.png +0 -0
  6. assets/images/02-bg.png +0 -0
  7. assets/images/02-icon.png +0 -0
  8. assets/images/02.png +0 -0
  9. assets/images/03-bg.png +0 -0
  10. assets/images/03-icon.png +0 -0
  11. assets/images/03.png +0 -0
  12. assets/images/04-bg.png +0 -0
  13. assets/images/04-icon.png +0 -0
  14. assets/images/04.png +0 -0
  15. assets/images/05-bg.png +0 -0
  16. assets/images/05-icon.png +0 -0
  17. assets/images/05.png +0 -0
  18. assets/images/06-bg.png +0 -0
  19. assets/images/06-icon.png +0 -0
  20. assets/images/06.png +0 -0
  21. assets/images/07-bg.png +0 -0
  22. assets/images/07-icon.png +0 -0
  23. assets/images/07.png +0 -0
  24. assets/images/08-bg.png +0 -0
  25. assets/images/08-icon.png +0 -0
  26. assets/images/08.png +0 -0
  27. assets/images/upgrade.png +0 -0
  28. assets/js/unminified/woocompare.js +2 -2
  29. assets/js/woocompare.js +234 -1
  30. class.yith-woocompare-admin.php +0 -469
  31. includes/class.yith-woocompare-admin.php +440 -0
  32. class.yith-woocompare-frontend.php → includes/class.yith-woocompare-frontend.php +92 -59
  33. class.yith-woocompare-helper.php → includes/class.yith-woocompare-helper.php +25 -13
  34. class.yith-woocompare.php → includes/class.yith-woocompare.php +19 -0
  35. functions.yith-woocompare.php → includes/functions.yith-woocompare.php +0 -0
  36. init.php +79 -25
  37. languages/default.po +0 -248
  38. languages/yit-bg_BG.mo +0 -0
  39. languages/yit-bg_BG.po +0 -248
  40. languages/yit-es_ES.mo +0 -0
  41. languages/yit-es_ES.po +0 -255
  42. languages/yit-fa_IR.mo +0 -0
  43. languages/yit-fa_IR.po +0 -246
  44. languages/yit-fr_FR.mo +0 -0
  45. languages/yit-fr_FR.po +0 -246
  46. languages/yit-it_IT.mo +0 -0
  47. languages/yit-nl_NL.mo +0 -0
  48. languages/yit-nl_NL.po +0 -247
  49. languages/yit-pt_BR.mo +0 -0
  50. languages/yit-pt_BR.po +0 -247
  51. languages/yit-tr_TR.mo +0 -0
  52. languages/yit-tr_TR.po +0 -248
  53. languages/yit.pot +0 -248
  54. languages/yith-wcmp-bg_BG.mo +0 -0
  55. languages/yith-wcmp-bg_BG.po +397 -0
  56. languages/yith-wcmp-es_ES.mo +0 -0
  57. languages/yith-wcmp-es_ES.po +440 -0
  58. languages/yith-wcmp-fa_IR.mo +0 -0
  59. languages/yith-wcmp-fa_IR.po +420 -0
  60. languages/yith-wcmp-fr_FR.mo +0 -0
  61. languages/yith-wcmp-fr_FR.po +402 -0
  62. languages/yith-wcmp-it_IT.mo +0 -0
  63. languages/{yit-it_IT.po → yith-wcmp-it_IT.po} +293 -109
  64. languages/yith-wcmp-nl_NL.mo +0 -0
  65. languages/yith-wcmp-nl_NL.po +433 -0
  66. languages/yith-wcmp-pt_BR.mo +0 -0
  67. languages/yith-wcmp-pt_BR.po +433 -0
  68. languages/yith-wcmp-tr_TR.mo +0 -0
  69. languages/yith-wcmp-tr_TR.po +434 -0
  70. languages/yith-wcmp.pot +378 -0
  71. plugin-fw/assets/css/chosen/chosen.css +435 -0
  72. plugin-fw/assets/css/codemirror/codemirror.css +260 -0
  73. plugin-fw/assets/css/metaboxes.css +609 -0
  74. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  75. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  76. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png +0 -0
  77. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png +0 -0
  78. plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  79. plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png +0 -0
  80. plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png +0 -0
  81. plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png +0 -0
  82. plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
  83. plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png +0 -0
  84. plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png +0 -0
  85. plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png +0 -0
  86. plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png +0 -0
  87. plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png +0 -0
  88. plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css +322 -0
  89. plugin-fw/assets/css/yit-plugin-panel.css +648 -0
  90. plugin-fw/assets/css/yit-upgrader.css +14 -0
  91. plugin-fw/assets/images/chosen/chosen-sprite.png +0 -0
  92. plugin-fw/assets/images/chosen/chosen-sprite@2x.png +0 -0
  93. plugin-fw/assets/images/double-sidebar.png +0 -0
  94. plugin-fw/assets/images/licence-error.png +0 -0
  95. plugin-fw/assets/images/no-sidebar.png +0 -0
  96. plugin-fw/assets/images/off.png +0 -0
  97. plugin-fw/assets/images/on.png +0 -0
  98. plugin-fw/assets/images/select.png +0 -0
  99. plugin-fw/assets/images/sidebar-left.png +0 -0
  100. plugin-fw/assets/images/sidebar-right.png +0 -0
  101. plugin-fw/assets/images/sleep.png +0 -0
  102. plugin-fw/assets/images/slider/grey.gif +0 -0
  103. plugin-fw/assets/images/slider/handle.png +0 -0
  104. plugin-fw/assets/images/slider/orange.gif +0 -0
  105. plugin-fw/assets/images/slider/tooltip.png +0 -0
  106. plugin-fw/assets/images/spinner.png +0 -0
  107. plugin-fw/assets/images/ui-icons_222222_256x240.png +0 -0
  108. plugin-fw/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  109. plugin-fw/assets/images/ui-icons_454545_256x240.png +0 -0
  110. plugin-fw/assets/images/ui-icons_888888_256x240.png +0 -0
  111. plugin-fw/assets/images/x.png +0 -0
  112. plugin-fw/assets/images/yithemes-icon.png +0 -0
  113. plugin-fw/assets/js/chosen/ajax-chosen.jquery.js +81 -0
  114. plugin-fw/assets/js/chosen/ajax-chosen.jquery.min.js +2 -0
  115. plugin-fw/assets/js/chosen/chosen.jquery.js +1211 -0
  116. plugin-fw/assets/js/codemirror/codemirror.js +5799 -0
  117. plugin-fw/assets/js/codemirror/javascript.js +630 -0
  118. plugin-fw/assets/js/metabox.js +354 -0
  119. plugin-fw/assets/js/metabox.min.js +11 -0
  120. plugin-fw/assets/js/multisite-updater.js +216 -0
  121. plugin-fw/assets/js/multisite-updater.min.js +4 -0
  122. plugin-fw/assets/js/panel.spinner.js +139 -0
  123. plugin-fw/assets/js/panel.spinner.min.js +3 -0
  124. plugin-fw/assets/js/yit-cpt-unlimited.js +79 -0
  125. plugin-fw/assets/js/yit-cpt-unlimited.min.js +2 -0
  126. plugin-fw/assets/js/yit-cptu-sortable-posts.js +32 -0
  127. plugin-fw/assets/js/yit-plugin-panel.js +313 -0
  128. plugin-fw/assets/js/yit-plugin-panel.min.js +10 -0
  129. plugin-fw/assets/js/yit-wp-pointer.js +84 -0
  130. plugin-fw/assets/js/yit-wp-pointer.min.js +3 -0
  131. plugin-fw/languages/yith-plugin-fw-it_IT.mo +0 -0
  132. plugin-fw/languages/yith-plugin-fw-it_IT.po +988 -0
  133. plugin-fw/languages/yith-plugin-fw.pot +920 -0
  134. plugin-fw/lib/yit-cpt-unlimited.php +1775 -0
  135. plugin-fw/lib/yit-metabox.php +537 -0
  136. plugin-fw/lib/yit-plugin-common.php +1260 -0
  137. plugin-fw/lib/yit-plugin-gradients.php +536 -0
  138. plugin-fw/lib/yit-plugin-panel-wc.php +333 -0
  139. plugin-fw/lib/yit-plugin-panel.php +798 -0
  140. plugin-fw/lib/yit-plugin-subpanel.php +161 -0
  141. plugin-fw/lib/yit-pointers.php +390 -0
  142. plugin-fw/lib/yit-upgrade.php +505 -0
README.txt CHANGED
@@ -3,8 +3,8 @@
3
  Contributors: yithemes
4
  Tags: woocommerce, compare, compare products, product compare, widget
5
  Requires at least: 3.5.1
6
- Tested up to: 4.1
7
- Stable tag: 1.2.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -14,7 +14,7 @@ WooCommerce Compatible up to 2.2.x
14
 
15
  == Description ==
16
 
17
- YITH WooCommerce Compare plugin is an extension of Woocommerce plugin that allow your users to compare some products of your shop.
18
  All products are saved in one complete table where the user can see the difference between the products. Each product features can be
19
  set with the woocommerce attributes in the product configuration.
20
  You can also add a simple widget with the list of products the users have added, where you can manage them.
@@ -32,37 +32,18 @@ This plugin is 100% compatible with [WPML](http://wpml.org/?aid=24889&affiliate_
32
 
33
  = Installation =
34
 
35
- Once you have installed the plugin, you just need to activate the plugin in order to enable it.
 
 
36
 
37
  = Configuration =
38
 
39
  1. Add the features in each product by setting the attributes in prouct configuration;
40
- 2. Configure the options in Woocommerce -> Settings -> Products compare;
41
  3. The user of your shop will click in the "Compare" button located in the single product page;
42
  4. Will be open a popup with the compare table inside.
43
 
44
- You can also add the widget with the product list of compare table, in Appearance -> Widgets and adding the widget "YITH Woocommerce Compare Widget".
45
-
46
- = Developer =
47
-
48
- Are you a developer? Want to customize the templates or the style of the plugin? Read on the [documentation](http://yithemes.com/docs-plugins/yith-woocommerce-compare) and discover how to do that.
49
-
50
- = Support =
51
-
52
- Hi there, we have good news here: all our plugins are released for free. Wow!
53
- Already knew it, right?! Great, but maybe you do not know that: if you're looking for how to install the plugins or how to use them within your Wordpress installations, which is the right way to ask support?
54
- That's the way:
55
-
56
- * Register on http://yithemes.com
57
- * Go to Support > Get Support
58
-
59
- Here we provide support, not on wordpress.org were, usually we do not read topics. It's better to follow us or write on our forum!
60
-
61
- == Installation ==
62
-
63
- 1. Unzip the downloaded zip file.
64
- 2. Upload the plugin folder into the `wp-content/plugins/` directory of your WordPress site.
65
- 3. Activate `YITH WooCommerce Compare` from Plugins page
66
 
67
  == Frequently Asked Questions ==
68
 
@@ -70,10 +51,10 @@ Here we provide support, not on wordpress.org were, usually we do not read topic
70
  Yes, you can copy the template from the plugin folder and paste it inside the folder "woocommerce" of your theme folder.
71
 
72
  = Can I select what fields show inside the compare table? =
73
- Yes, you can choose what fields to show in the compare table. You can do it in Woocommerce -> Settings -> Products Compare.
74
 
75
  = Can I order the fields in the compare table? =
76
- Yes, you can sort the fields in the compare table. You can do it in Woocommerce -> Settings -> Products Compare.
77
 
78
  == Screenshots ==
79
 
@@ -83,6 +64,15 @@ Yes, you can sort the fields in the compare table. You can do it in Woocommerce
83
 
84
  == Changelog ==
85
 
 
 
 
 
 
 
 
 
 
86
  = 1.2.3 =
87
 
88
  * Added: Bulgarian Translation by Joanna Mikova
@@ -180,6 +170,11 @@ Full documentation is available [here](http://yithemes.com/docs-plugins/yith-woo
180
 
181
  == Upgrade notice ==
182
 
183
- = 1.0.0 =
184
 
185
- Initial release
 
 
 
 
 
3
  Contributors: yithemes
4
  Tags: woocommerce, compare, compare products, product compare, widget
5
  Requires at least: 3.5.1
6
+ Tested up to: 4.2.2
7
+ Stable tag: 2.0.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
14
 
15
  == Description ==
16
 
17
+ YITH WooCommerce Compare plugin is an extension of WooCommerce plugin that allow your users to compare some products of your shop.
18
  All products are saved in one complete table where the user can see the difference between the products. Each product features can be
19
  set with the woocommerce attributes in the product configuration.
20
  You can also add a simple widget with the list of products the users have added, where you can manage them.
32
 
33
  = Installation =
34
 
35
+ 1. Unzip the downloaded zip file.
36
+ 2. Upload the plugin folder into the `wp-content/plugins/` directory of your WordPress site.
37
+ 3. Activate `YITH WooCommerce Compare` from Plugins page
38
 
39
  = Configuration =
40
 
41
  1. Add the features in each product by setting the attributes in prouct configuration;
42
+ 2. Configure the options in YIT Plugin -> Compare;
43
  3. The user of your shop will click in the "Compare" button located in the single product page;
44
  4. Will be open a popup with the compare table inside.
45
 
46
+ You can also add the widget with the product list of compare table, in Appearance -> Widgets and adding the widget "YITH WooCommerce Compare Widget".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
  == Frequently Asked Questions ==
49
 
51
  Yes, you can copy the template from the plugin folder and paste it inside the folder "woocommerce" of your theme folder.
52
 
53
  = Can I select what fields show inside the compare table? =
54
+ Yes, you can choose what fields to show in the compare table. You can do it in YIT Plugins -> Compare.
55
 
56
  = Can I order the fields in the compare table? =
57
+ Yes, you can sort the fields in the compare table. You can do it in YIT Plugins -> Compare.
58
 
59
  == Screenshots ==
60
 
64
 
65
  == Changelog ==
66
 
67
+ = 2.0.0 =
68
+
69
+ * Added: Added new plugin core
70
+ * Fixed: Error in class yith-woocompare-fontend
71
+ * Fixed: Lightbox doesn't close after click view cart
72
+ * Fixed: minor bug fix
73
+ * Updated: Language files
74
+ * Removed: old default.po catalog language file
75
+
76
  = 1.2.3 =
77
 
78
  * Added: Bulgarian Translation by Joanna Mikova
170
 
171
  == Upgrade notice ==
172
 
173
+ = 2.0.0 =
174
 
175
+ * Added: Added new plugin core
176
+ * Fixed: Error in class yith-woocompare-fontend
177
+ * Fixed: Lightbox doesn't close after click view cart
178
+ * Fixed: minor bug fix
179
+ * Updated: Language files
180
+ * Removed: old default.po catalog language file
assets/css/jquery.dataTables.css CHANGED
@@ -1,221 +1,455 @@
1
-
2
  /*
3
- * Table
4
  */
5
  table.dataTable {
6
- margin: 0 auto;
7
- clear: both;
8
- width: 500px;
9
- }
10
-
11
- table.dataTable thead th {
12
- padding: 3px 18px 3px 10px;
13
- border-bottom: 1px solid black;
14
- font-weight: bold;
15
- cursor: pointer;
16
- *cursor: hand;
17
  }
18
-
19
  table.dataTable tfoot th {
20
- padding: 3px 18px 3px 10px;
21
- border-top: 1px solid black;
22
- font-weight: bold;
23
  }
24
-
25
- table.dataTable td {
26
- padding: 3px 10px;
 
27
  }
28
-
29
- table.dataTable td.center,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  table.dataTable td.dataTables_empty {
31
- text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
- /*table.dataTable tr.odd { background-color: #E2E4FF; }
35
- table.dataTable tr.even { background-color: white; }
36
-
37
- table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }
38
- table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }
39
- table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }
40
- table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }
41
- table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }
42
- table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }*/
43
-
44
 
45
  /*
46
- * Table wrapper
47
  */
48
  .dataTables_wrapper {
49
- position: relative;
50
- clear: both;
51
- *zoom: 1;
 
52
  }
53
-
54
-
55
- /*
56
- * Page length menu
57
- */
58
- .dataTables_length {
59
- float: left;
60
  }
61
-
62
-
63
- /*
64
- * Filter
65
- */
66
- .dataTables_filter {
67
- float: right;
68
- text-align: right;
69
  }
70
-
71
-
72
- /*
73
- * Table information
74
- */
75
- .dataTables_info {
76
- clear: both;
77
- float: left;
78
  }
79
-
80
-
81
- /*
82
- * Pagination
83
- */
84
- .dataTables_paginate {
85
- float: right;
86
- text-align: right;
87
  }
88
-
89
- /* Two button pagination - previous / next */
90
- .paginate_disabled_previous,
91
- .paginate_enabled_previous,
92
- .paginate_disabled_next,
93
- .paginate_enabled_next {
94
- height: 19px;
95
- float: left;
96
- cursor: pointer;
97
- *cursor: hand;
98
- color: #111 !important;
99
- }
100
- .paginate_disabled_previous:hover,
101
- .paginate_enabled_previous:hover,
102
- .paginate_disabled_next:hover,
103
- .paginate_enabled_next:hover {
104
- text-decoration: none !important;
105
- }
106
- .paginate_disabled_previous:active,
107
- .paginate_enabled_previous:active,
108
- .paginate_disabled_next:active,
109
- .paginate_enabled_next:active {
110
- outline: none;
111
  }
112
-
113
- .paginate_disabled_previous,
114
- .paginate_disabled_next {
115
- color: #666 !important;
 
 
 
 
 
 
 
 
116
  }
117
- .paginate_disabled_previous,
118
- .paginate_enabled_previous {
119
- padding-left: 23px;
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
- .paginate_disabled_next,
122
- .paginate_enabled_next {
123
- padding-right: 23px;
124
- margin-left: 10px;
 
 
125
  }
126
-
127
- /*.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; }
128
- .paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; }
129
- .paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; }
130
-
131
- .paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; }
132
- .paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; }
133
- .paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; }*/
134
-
135
- /* Full number pagination */
136
- .paging_full_numbers {
137
- height: 22px;
138
- line-height: 22px;
 
 
 
139
  }
140
- .paging_full_numbers a:active {
141
- outline: none
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
- .paging_full_numbers a:hover {
144
- text-decoration: none;
145
  }
146
-
147
- .paging_full_numbers a.paginate_button,
148
- .paging_full_numbers a.paginate_active {
149
- border: 1px solid #aaa;
150
- -webkit-border-radius: 5px;
151
- -moz-border-radius: 5px;
152
- border-radius: 5px;
153
- padding: 2px 5px;
154
- margin: 0 3px;
155
- cursor: pointer;
156
- *cursor: hand;
157
- color: #333 !important;
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
-
160
- .paging_full_numbers a.paginate_button {
161
- background-color: #ddd;
 
 
 
162
  }
163
-
164
- .paging_full_numbers a.paginate_button:hover {
165
- background-color: #ccc;
166
- text-decoration: none !important;
167
  }
168
-
169
- .paging_full_numbers a.paginate_active {
170
- background-color: #99B3FF;
171
  }
172
-
173
-
174
- /*
175
- * Processing indicator
176
- */
177
- .dataTables_processing {
178
- position: absolute;
179
- top: 50%;
180
- left: 50%;
181
- width: 250px;
182
- height: 30px;
183
- margin-left: -125px;
184
- margin-top: -15px;
185
- padding: 14px 0 2px 0;
186
- border: 1px solid #ddd;
187
- text-align: center;
188
- color: #999;
189
- font-size: 14px;
190
- background-color: white;
191
  }
192
-
193
-
194
- /*
195
- * Sorting
196
- */
197
- /*.sorting { background: url('../images/sort_both.png') no-repeat center right; }
198
- .sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }
199
- .sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }
200
-
201
- .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }
202
- .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }*/
203
-
204
- table.dataTable thead th:active,
205
- table.dataTable thead td:active {
206
- outline: none;
207
  }
208
-
209
-
210
- /*
211
- * Scrolling
212
- */
213
- .dataTables_scroll {
214
- clear: both;
215
  }
216
-
217
- .dataTables_scrollBody {
218
- *margin-top: -1px;
219
- -webkit-overflow-scrolling: touch;
 
 
220
  }
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /*
2
+ * Table styles
3
  */
4
  table.dataTable {
5
+ width: 100%;
6
+ margin: 0 auto;
7
+ clear: both;
8
+ border-collapse: separate;
9
+ border-spacing: 0;
10
+ /*
11
+ * Header and footer styles
12
+ */
13
+ /*
14
+ * Body styles
15
+ */
16
  }
17
+ table.dataTable thead th,
18
  table.dataTable tfoot th {
19
+ font-weight: bold;
 
 
20
  }
21
+ table.dataTable thead th,
22
+ table.dataTable thead td {
23
+ padding: 10px 18px;
24
+ border-bottom: 1px solid #111;
25
  }
26
+ table.dataTable thead th:active,
27
+ table.dataTable thead td:active {
28
+ outline: none;
29
+ }
30
+ table.dataTable tfoot th,
31
+ table.dataTable tfoot td {
32
+ padding: 10px 18px 6px 18px;
33
+ border-top: 1px solid #111;
34
+ }
35
+ table.dataTable thead .sorting,
36
+ table.dataTable thead .sorting_asc,
37
+ table.dataTable thead .sorting_desc {
38
+ cursor: pointer;
39
+ *cursor: hand;
40
+ }
41
+ table.dataTable thead .sorting,
42
+ table.dataTable thead .sorting_asc,
43
+ table.dataTable thead .sorting_desc,
44
+ table.dataTable thead .sorting_asc_disabled,
45
+ table.dataTable thead .sorting_desc_disabled {
46
+ background-repeat: no-repeat;
47
+ background-position: center right;
48
+ }
49
+ table.dataTable thead .sorting {
50
+ background-image: url("../images/sort_both.png");
51
+ }
52
+ table.dataTable thead .sorting_asc {
53
+ background-image: url("../images/sort_asc.png");
54
+ }
55
+ table.dataTable thead .sorting_desc {
56
+ background-image: url("../images/sort_desc.png");
57
+ }
58
+ table.dataTable thead .sorting_asc_disabled {
59
+ background-image: url("../images/sort_asc_disabled.png");
60
+ }
61
+ table.dataTable thead .sorting_desc_disabled {
62
+ background-image: url("../images/sort_desc_disabled.png");
63
+ }
64
+ table.dataTable tbody tr {
65
+ background-color: #ffffff;
66
+ }
67
+ table.dataTable tbody tr.selected {
68
+ background-color: #B0BED9;
69
+ }
70
+ table.dataTable tbody th,
71
+ table.dataTable tbody td {
72
+ padding: 8px 10px;
73
+ }
74
+ table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
75
+ border-top: 1px solid #ddd;
76
+ }
77
+ table.dataTable.row-border tbody tr:first-child th,
78
+ table.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,
79
+ table.dataTable.display tbody tr:first-child td {
80
+ border-top: none;
81
+ }
82
+ table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
83
+ border-top: 1px solid #ddd;
84
+ border-right: 1px solid #ddd;
85
+ }
86
+ table.dataTable.cell-border tbody tr th:first-child,
87
+ table.dataTable.cell-border tbody tr td:first-child {
88
+ border-left: 1px solid #ddd;
89
+ }
90
+ table.dataTable.cell-border tbody tr:first-child th,
91
+ table.dataTable.cell-border tbody tr:first-child td {
92
+ border-top: none;
93
+ }
94
+ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
95
+ background-color: #f9f9f9;
96
+ }
97
+ table.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {
98
+ background-color: #abb9d3;
99
+ }
100
+ table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
101
+ background-color: whitesmoke;
102
+ }
103
+ table.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {
104
+ background-color: #a9b7d1;
105
+ }
106
+ table.dataTable.order-column tbody tr > .sorting_1,
107
+ table.dataTable.order-column tbody tr > .sorting_2,
108
+ table.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,
109
+ table.dataTable.display tbody tr > .sorting_2,
110
+ table.dataTable.display tbody tr > .sorting_3 {
111
+ background-color: #f9f9f9;
112
+ }
113
+ table.dataTable.order-column tbody tr.selected > .sorting_1,
114
+ table.dataTable.order-column tbody tr.selected > .sorting_2,
115
+ table.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,
116
+ table.dataTable.display tbody tr.selected > .sorting_2,
117
+ table.dataTable.display tbody tr.selected > .sorting_3 {
118
+ background-color: #acbad4;
119
+ }
120
+ table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
121
+ background-color: #f1f1f1;
122
+ }
123
+ table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
124
+ background-color: #f3f3f3;
125
+ }
126
+ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
127
+ background-color: whitesmoke;
128
+ }
129
+ table.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {
130
+ background-color: #a6b3cd;
131
+ }
132
+ table.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {
133
+ background-color: #a7b5ce;
134
+ }
135
+ table.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {
136
+ background-color: #a9b6d0;
137
+ }
138
+ table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
139
+ background-color: #f9f9f9;
140
+ }
141
+ table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
142
+ background-color: #fbfbfb;
143
+ }
144
+ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
145
+ background-color: #fdfdfd;
146
+ }
147
+ table.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {
148
+ background-color: #acbad4;
149
+ }
150
+ table.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {
151
+ background-color: #adbbd6;
152
+ }
153
+ table.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {
154
+ background-color: #afbdd8;
155
+ }
156
+ table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
157
+ background-color: #eaeaea;
158
+ }
159
+ table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
160
+ background-color: #ebebeb;
161
+ }
162
+ table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
163
+ background-color: #eeeeee;
164
+ }
165
+ table.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {
166
+ background-color: #a1aec7;
167
+ }
168
+ table.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {
169
+ background-color: #a2afc8;
170
+ }
171
+ table.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {
172
+ background-color: #a4b2cb;
173
+ }
174
+ table.dataTable.no-footer {
175
+ border-bottom: 1px solid #111;
176
+ }
177
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
178
+ white-space: nowrap;
179
+ }
180
+ table.dataTable.compact thead th,
181
+ table.dataTable.compact thead td {
182
+ padding: 4px 17px 4px 4px;
183
+ }
184
+ table.dataTable.compact tfoot th,
185
+ table.dataTable.compact tfoot td {
186
+ padding: 4px;
187
+ }
188
+ table.dataTable.compact tbody th,
189
+ table.dataTable.compact tbody td {
190
+ padding: 4px;
191
+ }
192
+ table.dataTable th.dt-left,
193
+ table.dataTable td.dt-left {
194
+ text-align: left;
195
+ }
196
+ table.dataTable th.dt-center,
197
+ table.dataTable td.dt-center,
198
  table.dataTable td.dataTables_empty {
199
+ text-align: center;
200
+ }
201
+ table.dataTable th.dt-right,
202
+ table.dataTable td.dt-right {
203
+ text-align: right;
204
+ }
205
+ table.dataTable th.dt-justify,
206
+ table.dataTable td.dt-justify {
207
+ text-align: justify;
208
+ }
209
+ table.dataTable th.dt-nowrap,
210
+ table.dataTable td.dt-nowrap {
211
+ white-space: nowrap;
212
+ }
213
+ table.dataTable thead th.dt-head-left,
214
+ table.dataTable thead td.dt-head-left,
215
+ table.dataTable tfoot th.dt-head-left,
216
+ table.dataTable tfoot td.dt-head-left {
217
+ text-align: left;
218
+ }
219
+ table.dataTable thead th.dt-head-center,
220
+ table.dataTable thead td.dt-head-center,
221
+ table.dataTable tfoot th.dt-head-center,
222
+ table.dataTable tfoot td.dt-head-center {
223
+ text-align: center;
224
+ }
225
+ table.dataTable thead th.dt-head-right,
226
+ table.dataTable thead td.dt-head-right,
227
+ table.dataTable tfoot th.dt-head-right,
228
+ table.dataTable tfoot td.dt-head-right {
229
+ text-align: right;
230
+ }
231
+ table.dataTable thead th.dt-head-justify,
232
+ table.dataTable thead td.dt-head-justify,
233
+ table.dataTable tfoot th.dt-head-justify,
234
+ table.dataTable tfoot td.dt-head-justify {
235
+ text-align: justify;
236
+ }
237
+ table.dataTable thead th.dt-head-nowrap,
238
+ table.dataTable thead td.dt-head-nowrap,
239
+ table.dataTable tfoot th.dt-head-nowrap,
240
+ table.dataTable tfoot td.dt-head-nowrap {
241
+ white-space: nowrap;
242
+ }
243
+ table.dataTable tbody th.dt-body-left,
244
+ table.dataTable tbody td.dt-body-left {
245
+ text-align: left;
246
+ }
247
+ table.dataTable tbody th.dt-body-center,
248
+ table.dataTable tbody td.dt-body-center {
249
+ text-align: center;
250
+ }
251
+ table.dataTable tbody th.dt-body-right,
252
+ table.dataTable tbody td.dt-body-right {
253
+ text-align: right;
254
+ }
255
+ table.dataTable tbody th.dt-body-justify,
256
+ table.dataTable tbody td.dt-body-justify {
257
+ text-align: justify;
258
+ }
259
+ table.dataTable tbody th.dt-body-nowrap,
260
+ table.dataTable tbody td.dt-body-nowrap {
261
+ white-space: nowrap;
262
  }
263
 
264
+ table.dataTable,
265
+ table.dataTable th,
266
+ table.dataTable td {
267
+ -webkit-box-sizing: content-box;
268
+ -moz-box-sizing: content-box;
269
+ box-sizing: content-box;
270
+ }
 
 
 
271
 
272
  /*
273
+ * Control feature layout
274
  */
275
  .dataTables_wrapper {
276
+ position: relative;
277
+ clear: both;
278
+ *zoom: 1;
279
+ zoom: 1;
280
  }
281
+ .dataTables_wrapper .dataTables_length {
282
+ float: left;
 
 
 
 
 
283
  }
284
+ .dataTables_wrapper .dataTables_filter {
285
+ float: right;
286
+ text-align: right;
 
 
 
 
 
287
  }
288
+ .dataTables_wrapper .dataTables_filter input {
289
+ margin-left: 0.5em;
 
 
 
 
 
 
290
  }
291
+ .dataTables_wrapper .dataTables_info {
292
+ clear: both;
293
+ float: left;
294
+ padding-top: 0.755em;
 
 
 
 
295
  }
296
+ .dataTables_wrapper .dataTables_paginate {
297
+ float: right;
298
+ text-align: right;
299
+ padding-top: 0.25em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  }
301
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
302
+ box-sizing: border-box;
303
+ display: inline-block;
304
+ min-width: 1.5em;
305
+ padding: 0.5em 1em;
306
+ margin-left: 2px;
307
+ text-align: center;
308
+ text-decoration: none !important;
309
+ cursor: pointer;
310
+ *cursor: hand;
311
+ color: #333 !important;
312
+ border: 1px solid transparent;
313
  }
314
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
315
+ color: #333 !important;
316
+ border: 1px solid #cacaca;
317
+ background-color: white;
318
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));
319
+ /* Chrome,Safari4+ */
320
+ background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);
321
+ /* Chrome10+,Safari5.1+ */
322
+ background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);
323
+ /* FF3.6+ */
324
+ background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);
325
+ /* IE10+ */
326
+ background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);
327
+ /* Opera 11.10+ */
328
+ background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);
329
+ /* W3C */
330
  }
331
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
332
+ cursor: default;
333
+ color: #666 !important;
334
+ border: 1px solid transparent;
335
+ background: transparent;
336
+ box-shadow: none;
337
  }
338
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover {
339
+ color: white !important;
340
+ border: 1px solid #111;
341
+ background-color: #585858;
342
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));
343
+ /* Chrome,Safari4+ */
344
+ background: -webkit-linear-gradient(top, #585858 0%, #111 100%);
345
+ /* Chrome10+,Safari5.1+ */
346
+ background: -moz-linear-gradient(top, #585858 0%, #111 100%);
347
+ /* FF3.6+ */
348
+ background: -ms-linear-gradient(top, #585858 0%, #111 100%);
349
+ /* IE10+ */
350
+ background: -o-linear-gradient(top, #585858 0%, #111 100%);
351
+ /* Opera 11.10+ */
352
+ background: linear-gradient(to bottom, #585858 0%, #111 100%);
353
+ /* W3C */
354
  }
355
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
356
+ outline: none;
357
+ background-color: #2b2b2b;
358
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));
359
+ /* Chrome,Safari4+ */
360
+ background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
361
+ /* Chrome10+,Safari5.1+ */
362
+ background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
363
+ /* FF3.6+ */
364
+ background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
365
+ /* IE10+ */
366
+ background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);
367
+ /* Opera 11.10+ */
368
+ background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);
369
+ /* W3C */
370
+ box-shadow: inset 0 0 3px #111;
371
  }
372
+ .dataTables_wrapper .dataTables_paginate .ellipsis {
373
+ padding: 0 1em;
374
  }
375
+ .dataTables_wrapper .dataTables_processing {
376
+ position: absolute;
377
+ top: 50%;
378
+ left: 50%;
379
+ width: 100%;
380
+ height: 40px;
381
+ margin-left: -50%;
382
+ margin-top: -25px;
383
+ padding-top: 20px;
384
+ text-align: center;
385
+ font-size: 1.2em;
386
+ background-color: white;
387
+ background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));
388
+ /* Chrome,Safari4+ */
389
+ background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
390
+ /* Chrome10+,Safari5.1+ */
391
+ background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
392
+ /* FF3.6+ */
393
+ background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
394
+ /* IE10+ */
395
+ background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
396
+ /* Opera 11.10+ */
397
+ background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);
398
+ /* W3C */
399
  }
400
+ .dataTables_wrapper .dataTables_length,
401
+ .dataTables_wrapper .dataTables_filter,
402
+ .dataTables_wrapper .dataTables_info,
403
+ .dataTables_wrapper .dataTables_processing,
404
+ .dataTables_wrapper .dataTables_paginate {
405
+ color: #333;
406
  }
407
+ .dataTables_wrapper .dataTables_scroll {
408
+ clear: both;
 
 
409
  }
410
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
411
+ *margin-top: -1px;
412
+ -webkit-overflow-scrolling: touch;
413
  }
414
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
415
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
416
+ height: 0;
417
+ overflow: hidden;
418
+ margin: 0 !important;
419
+ padding: 0 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  }
421
+ .dataTables_wrapper.no-footer .dataTables_scrollBody {
422
+ border-bottom: 1px solid #111;
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  }
424
+ .dataTables_wrapper.no-footer div.dataTables_scrollHead table,
425
+ .dataTables_wrapper.no-footer div.dataTables_scrollBody table {
426
+ border-bottom: none;
 
 
 
 
427
  }
428
+ .dataTables_wrapper:after {
429
+ visibility: hidden;
430
+ display: block;
431
+ content: "";
432
+ clear: both;
433
+ height: 0;
434
  }
435
 
436
+ @media screen and (max-width: 767px) {
437
+ .dataTables_wrapper .dataTables_info,
438
+ .dataTables_wrapper .dataTables_paginate {
439
+ float: none;
440
+ text-align: center;
441
+ }
442
+ .dataTables_wrapper .dataTables_paginate {
443
+ margin-top: 0.5em;
444
+ }
445
+ }
446
+ @media screen and (max-width: 640px) {
447
+ .dataTables_wrapper .dataTables_length,
448
+ .dataTables_wrapper .dataTables_filter {
449
+ float: none;
450
+ text-align: center;
451
+ }
452
+ .dataTables_wrapper .dataTables_filter {
453
+ margin-top: 0.5em;
454
+ }
455
+ }
assets/images/01-bg.png ADDED
Binary file
assets/images/01-icon.png ADDED
Binary file
assets/images/01.png ADDED
Binary file
assets/images/02-bg.png ADDED
Binary file
assets/images/02-icon.png ADDED
Binary file
assets/images/02.png ADDED
Binary file
assets/images/03-bg.png ADDED
Binary file
assets/images/03-icon.png ADDED
Binary file
assets/images/03.png ADDED
Binary file
assets/images/04-bg.png ADDED
Binary file
assets/images/04-icon.png ADDED
Binary file
assets/images/04.png ADDED
Binary file
assets/images/05-bg.png ADDED
Binary file
assets/images/05-icon.png ADDED
Binary file
assets/images/05.png ADDED
Binary file
assets/images/06-bg.png ADDED
Binary file
assets/images/06-icon.png ADDED
Binary file
assets/images/06.png ADDED
Binary file
assets/images/07-bg.png ADDED
Binary file
assets/images/07-icon.png ADDED
Binary file
assets/images/07.png ADDED
Binary file
assets/images/08-bg.png ADDED
Binary file
assets/images/08-icon.png ADDED
Binary file
assets/images/08.png ADDED
Binary file
assets/images/upgrade.png ADDED
Binary file
assets/js/unminified/woocompare.js CHANGED
@@ -28,7 +28,7 @@ jQuery(document).ready(function($) {
28
  // add the product in the widget
29
  widget_list.unblock().html( response.widget_table );
30
 
31
- if (yith_woocompare.auto_open == 'yes') $('body').trigger( 'yith_woocompare_open_popup', { response: response.table_url, button: button } );
32
  }
33
  });
34
  });
@@ -37,7 +37,7 @@ jQuery(document).ready(function($) {
37
  $('body').on( 'yith_woocompare_open_popup', function( e, data ) {
38
  var response = data.response;
39
 
40
- if ($(window).width() >= 768) {
41
  $.colorbox({
42
  href: response,
43
  iframe: true,
28
  // add the product in the widget
29
  widget_list.unblock().html( response.widget_table );
30
 
31
+ if ( yith_woocompare.auto_open == 'yes') $('body').trigger( 'yith_woocompare_open_popup', { response: response.table_url, button: button } );
32
  }
33
  });
34
  });
37
  $('body').on( 'yith_woocompare_open_popup', function( e, data ) {
38
  var response = data.response;
39
 
40
+ if ( $(window).width() >= 768 ) {
41
  $.colorbox({
42
  href: response,
43
  iframe: true,
assets/js/woocompare.js CHANGED
@@ -1 +1,234 @@
1
- jQuery(document).ready(function(a){function h(a,d){a=escape(a);d=escape(d);var b=document.location.search,e=a+"="+d,b=b.replace(new RegExp("(&|\\?)"+a+"=[^&]*"),"$1"+e);RegExp.$1||(b+=(0<b.length?"&":"?")+e);return b}a(document).on("click",".product a.compare",function(c){c.preventDefault();var d=a(this);c={_yitnonce_ajax:yith_woocompare.nonceadd,action:yith_woocompare.actionadd,id:d.data("product_id"),context:"frontend"};var b=a(".yith-woocompare-widget ul.products-list");d.block({message:null,overlayCSS:{background:"#fff url("+woocommerce_params.ajax_loader_url+") no-repeat center",backgroundSize:"16px 16px",opacity:.6}});b.block({message:null,overlayCSS:{background:"#fff url("+woocommerce_params.ajax_loader_url+") no-repeat center",backgroundSize:"16px 16px",opacity:.6}});a.ajax({type:"post",url:yith_woocompare.ajaxurl,data:c,dataType:"json",success:function(c){d.unblock().addClass("added").text(yith_woocompare.added_label);b.unblock().html(c.widget_table);"yes"==yith_woocompare.auto_open&&a("body").trigger("yith_woocompare_open_popup",{response:c.table_url,button:d})}})});a("body").on("yith_woocompare_open_popup",function(c,d){var b=d.response;if(768<=a(window).width())a.colorbox({href:b,iframe:!0,width:"90%",height:"90%",onClosed:function(){var b=a(".yith-woocompare-widget ul.products-list"),c={action:yith_woocompare.actionview,context:"frontend"};b.block({message:null,overlayCSS:{background:"#fff url("+woocommerce_params.ajax_loader_url+") no-repeat center",backgroundSize:"16px 16px",opacity:.6}});a.ajax({type:"post",url:yith_woocompare.ajaxurl,data:c,success:function(a){b.unblock().html(a)}})}}),a(window).resize(function(){a.colorbox.resize({width:"90%",height:"90%"})});else{var e=b.split("?");if(2<=e.length){for(var b=encodeURIComponent("iframe")+"=",f=e[1].split(/[&;]/g),g=f.length;0<g--;)-1!==f[g].lastIndexOf(b,0)&&f.splice(g,1);b=e[0]+"?"+f.join("&")}window.open(b,yith_woocompare.table_title)}});a(document).on("click",".remove a",function(c){c.preventDefault();var d=a(this);c={_yitnonce_ajax:yith_woocompare.nonceremove,action:yith_woocompare.actionremove,id:d.data("product_id"),context:"frontend"};a("td.product_"+c.id+", th.product_"+c.id);d.block({message:null,overlayCSS:{background:"#fff url("+woocommerce_params.ajax_loader_url+") no-repeat center",backgroundSize:"16px 16px",opacity:.6}});a.ajax({type:"post",url:yith_woocompare.ajaxurl,data:c,dataType:"html",success:function(b){d.unblock();b=a(b).filter("table.compare-list");a("body > table.compare-list").replaceWith(b);a(window).trigger("yith_woocompare_product_removed")}})});a(".yith-woocompare-open a, a.yith-woocompare-open").on("click",function(c){c.preventDefault();a("body").trigger("yith_woocompare_open_popup",{response:h("action",yith_woocompare.actionview)+"&iframe=true"})});a(".yith-woocompare-widget").on("click","a.compare",function(c){c.preventDefault();a("body").trigger("yith_woocompare_open_popup",{response:a(this).attr("href")})}).on("click","li a.remove, a.clear-all",function(c){c.preventDefault();var d=a(".yith-woocompare-widget .products-list").data("lang");c=a(this);var d={_yitnonce_ajax:yith_woocompare.nonceremove,action:yith_woocompare.actionremove,id:c.data("product_id"),context:"frontend",responseType:"product_list",lang:d},b=c.parents(".yith-woocompare-widget").find("ul.products-list");b.block({message:null,overlayCSS:{background:"#fff url("+woocommerce_params.ajax_loader_url+") no-repeat center",backgroundSize:"16px 16px",opacity:.6}});a.ajax({type:"post",url:yith_woocompare.ajaxurl,data:d,dataType:"html",success:function(a){b.html(a);b.unblock()}})})});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function($) {
2
+
3
+ // add into table
4
+ $(document).on( 'click', '.product a.compare:not(.added)', function(e){
5
+ e.preventDefault();
6
+
7
+ var button = $(this),
8
+ data = {
9
+ _yitnonce_ajax: yith_woocompare.nonceadd,
10
+ action: yith_woocompare.actionadd,
11
+ id: button.data('product_id'),
12
+ context: 'frontend'
13
+ },
14
+ widget_list = $('.yith-woocompare-widget ul.products-list');
15
+
16
+ // add ajax loader
17
+ if( typeof woocommerce_params != 'undefined' ) {
18
+ button.block({message: null, overlayCSS: {background: '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6}});
19
+ widget_list.block({message: null, overlayCSS: {background: '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6}});
20
+ }
21
+
22
+ $.ajax({
23
+ type: 'post',
24
+ url: yith_woocompare.ajaxurl,
25
+ data: data,
26
+ dataType: 'json',
27
+ success: function(response){
28
+ button.unblock()
29
+ .addClass('added')
30
+ .attr( 'href', response.table_url )
31
+ .text( yith_woocompare.added_label );
32
+
33
+ // add the product in the widget
34
+ widget_list.unblock().html( response.widget_table );
35
+
36
+ if ( yith_woocompare.auto_open == 'yes')
37
+ $('body').trigger( 'yith_woocompare_open_popup', { response: response.table_url, button: button } );
38
+ }
39
+ });
40
+ });
41
+
42
+
43
+
44
+ $(document).on('click', '.product a.compare.added', function (ev) {
45
+ ev.preventDefault();
46
+
47
+ var table_url = this.href;
48
+
49
+ if (typeof table_url == 'undefined')
50
+ return;
51
+
52
+ $('body').trigger('yith_woocompare_open_popup', {response: table_url, button: $(this)});
53
+ });
54
+
55
+
56
+ // open popup
57
+ $('body').on( 'yith_woocompare_open_popup', function( e, data ) {
58
+ var response = data.response;
59
+
60
+ if ( $(window).width() >= 768 ) {
61
+ $.colorbox({
62
+ href: response,
63
+ iframe: true,
64
+ width: '90%',
65
+ height: '90%',
66
+ onClosed: function(){
67
+ var widget_list = $('.yith-woocompare-widget ul.products-list'),
68
+ data = {
69
+ action: yith_woocompare.actionview,
70
+ context: 'frontend'
71
+ };
72
+
73
+ if( typeof woocommerce_params != 'undefined' ) {
74
+ widget_list.block({message: null, overlayCSS: {background: '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6}});
75
+ }
76
+
77
+ $.ajax({
78
+ type: 'post',
79
+ url: yith_woocompare.ajaxurl,
80
+ data: data,
81
+ success: function(response){
82
+ // add the product in the widget
83
+ widget_list.unblock().html( response );
84
+ }
85
+ });
86
+ }
87
+ });
88
+
89
+ $(window).resize(function () {
90
+ $.colorbox.resize({
91
+ width: '90%',
92
+ height: '90%'
93
+ });
94
+ });
95
+
96
+ } else {
97
+ var urlparts = response.split('?');
98
+ var parameter = 'iframe';
99
+ if (urlparts.length >= 2) {
100
+ var prefix = encodeURIComponent(parameter) + '=';
101
+ var pars = urlparts[1].split(/[&;]/g);
102
+ for (var i = pars.length; i-- > 0;) {
103
+ if (pars[i].lastIndexOf(prefix, 0) !== -1) {
104
+ pars.splice(i, 1);
105
+ }
106
+ }
107
+ response = urlparts[0] + '?' + pars.join('&');
108
+ }
109
+
110
+ window.open( response, yith_woocompare.table_title);
111
+ }
112
+ });
113
+
114
+ // remove from table
115
+ $(document).on( 'click', '.remove a', function(e){
116
+ e.preventDefault();
117
+
118
+ var button = $(this),
119
+ data = {
120
+ _yitnonce_ajax: yith_woocompare.nonceremove,
121
+ action: yith_woocompare.actionremove,
122
+ id: button.data('product_id'),
123
+ context: 'frontend'
124
+ },
125
+ product_cell = $( 'td.product_' + data.id + ', th.product_' + data.id );
126
+
127
+ // add ajax loader
128
+ if( typeof woocommerce_params != 'undefined' ) {
129
+ button.block({
130
+ message: null,
131
+ overlayCSS: {
132
+ background: '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center',
133
+ backgroundSize: '16px 16px',
134
+ opacity: 0.6
135
+ }
136
+ });
137
+ }
138
+
139
+ $.ajax({
140
+ type: 'post',
141
+ url: yith_woocompare.ajaxurl,
142
+ data: data,
143
+ dataType:'html',
144
+ success: function(response){
145
+ button.unblock();
146
+
147
+ // in compare table
148
+ var table = $(response).filter('table.compare-list');
149
+ $('body > table.compare-list').replaceWith( table );
150
+
151
+ // removed trigger
152
+ $(window).trigger('yith_woocompare_product_removed');
153
+ }
154
+ });
155
+ });
156
+
157
+
158
+ // General link to open the compare table
159
+ $('.yith-woocompare-open a, a.yith-woocompare-open').on('click', function(e){
160
+ e.preventDefault();
161
+ $('body').trigger('yith_woocompare_open_popup', { response: yith_add_query_arg('action', yith_woocompare.actionview) + '&iframe=true' });
162
+ });
163
+
164
+
165
+
166
+ // ##### WIDGET ######
167
+
168
+ $('.yith-woocompare-widget')
169
+
170
+ // view table (click on compare
171
+ .on('click', 'a.compare', function (e) {
172
+ e.preventDefault();
173
+ $('body').trigger('yith_woocompare_open_popup', { response: $(this).attr('href') });
174
+ })
175
+
176
+ // remove product & clear all
177
+ .on('click', 'li a.remove, a.clear-all', function (e) {
178
+ e.preventDefault();
179
+
180
+ var lang = $( '.yith-woocompare-widget .products-list').data('lang');
181
+
182
+ var button = $(this),
183
+ data = {
184
+ _yitnonce_ajax: yith_woocompare.nonceremove,
185
+ action: yith_woocompare.actionremove,
186
+ id: button.data('product_id'),
187
+ context: 'frontend',
188
+ responseType: 'product_list',
189
+ lang: lang
190
+ },
191
+ product_list = button.parents('.yith-woocompare-widget').find('ul.products-list');
192
+
193
+ // add ajax loader
194
+ if( typeof woocommerce_params != 'undefined' ) {
195
+ product_list.block({message: null,
196
+ overlayCSS : {
197
+ background : '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center',
198
+ backgroundSize: '16px 16px',
199
+ opacity : 0.6
200
+ }
201
+ });
202
+ }
203
+
204
+ $.ajax({
205
+ type: 'post',
206
+ url: yith_woocompare.ajaxurl,
207
+ data: data,
208
+ dataType: 'html',
209
+ success: function (response) {
210
+ product_list.html(response);
211
+ product_list.unblock();
212
+ }
213
+ });
214
+ });
215
+
216
+
217
+ function yith_add_query_arg(key, value)
218
+ {
219
+ key = escape(key); value = escape(value);
220
+
221
+ var s = document.location.search;
222
+ var kvp = key+"="+value;
223
+
224
+ var r = new RegExp("(&|\\?)"+key+"=[^\&]*");
225
+
226
+ s = s.replace(r,"$1"+kvp);
227
+
228
+ if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};
229
+
230
+ //again, do what you will here
231
+ return s;
232
+ }
233
+
234
+ });
class.yith-woocompare-admin.php DELETED
@@ -1,469 +0,0 @@
1
- <?php
2
- /**
3
- * Admin class
4
- *
5
- * @author Your Inspiration Themes
6
- * @package YITH WooCommerce Magnifier
7
- * @version 1.1.4
8
- */
9
-
10
- if ( !defined( 'YITH_WOOCOMPARE' ) ) { exit; } // Exit if accessed directly
11
-
12
- if( !class_exists( 'YITH_Woocompare_Admin' ) ) {
13
- /**
14
- * Admin class.
15
- * The class manage all the admin behaviors.
16
- *
17
- * @since 1.0.0
18
- */
19
- class YITH_Woocompare_Admin {
20
- /**
21
- * Plugin version
22
- *
23
- * @var string
24
- * @since 1.0.0
25
- */
26
- public $version = YITH_WOOCOMPARE_VERSION;
27
-
28
- /**
29
- * Plugin options
30
- *
31
- * @var array
32
- * @access public
33
- * @since 1.0.0
34
- */
35
- public $options = array();
36
-
37
- /**
38
- * The standard fields
39
- *
40
- * @var array
41
- * @since 1.0.0
42
- */
43
- public $default_fields = array();
44
-
45
- /**
46
- * Various links
47
- *
48
- * @var string
49
- * @access public
50
- * @since 1.0.0
51
- */
52
- public $banner_url = 'http://cdn.yithemes.com/plugins/yith_woocommerce_compare.php?url';
53
- public $banner_img = 'http://cdn.yithemes.com/plugins/yith_woocommerce_compare.php';
54
- public $doc_url = 'http://yithemes.com/docs-plugins/yith_woocommerce_compare/';
55
-
56
-
57
- /**
58
- * Constructor
59
- *
60
- * @access public
61
- * @since 1.0.0
62
- */
63
- public function __construct() {
64
-
65
- // populate default fields for the comparison table
66
- $this->default_fields = YITH_Woocompare_Helper::standard_fields();
67
-
68
- // add image size
69
- YITH_Woocompare_Helper::set_image_size();
70
-
71
- //Actions
72
- add_action( 'init', array( $this, 'init' ) );
73
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
74
-
75
- add_action( 'woocommerce_settings_tabs_yith_woocompare', array( $this, 'print_plugin_options' ) );
76
- add_action( 'woocommerce_update_options_yith_woocompare', array( $this, 'update_options' ) );
77
- if ( !has_action('woocommerce_admin_field_slider')) add_action( 'woocommerce_admin_field_slider', array( $this, 'admin_fields_slider' ) );
78
- if ( !has_action('woocommerce_admin_field_picker')) add_action( 'woocommerce_admin_field_picker', array( $this, 'admin_fields_picker' ) );
79
- if ( !has_action('woocommerce_admin_field_attributes')) add_action( 'woocommerce_admin_field_attributes', array( $this, 'admin_fields_attributes' ) );
80
- if ( !has_action('woocommerce_admin_field_yit_wc_image_width')) add_action( 'woocommerce_admin_field_yit_wc_image_width', array( $this, 'admin_fields_yit_wc_image_width' ) );
81
- add_action( 'admin_print_footer_scripts', array( $this, 'admin_fields_image_deps' ) );
82
-
83
- add_action( 'woocommerce_update_option_slider', array( $this, 'admin_update_option' ) );
84
- add_action( 'woocommerce_update_option_picker', array( $this, 'admin_update_option' ) );
85
- add_action( 'woocommerce_update_option_attributes', array( $this, 'admin_update_option' ) );
86
-
87
- //Filters
88
- add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_tab_woocommerce' ), 30 );
89
-
90
- // YITH WCWL Loaded
91
- do_action( 'yith_woocompare_loaded' );
92
- }
93
-
94
-
95
- /**
96
- * Init method:
97
- * - default options
98
- *
99
- * @access public
100
- * @since 1.0.0
101
- */
102
- public function init() {
103
- $this->options = $this->_initOptions();
104
- $this->_default_options();
105
- }
106
-
107
-
108
- /**
109
- * Update plugin options.
110
- *
111
- * @return void
112
- * @since 1.0.0
113
- */
114
- public function update_options() {
115
- foreach( $this->options as $section_options ) {
116
- woocommerce_update_options( $section_options );
117
- }
118
- }
119
-
120
-
121
- /**
122
- * Add Magnifier's tab to Woocommerce -> Settings page
123
- *
124
- * @access public
125
- * @param array $tabs
126
- *
127
- * @return array
128
- */
129
- public function add_tab_woocommerce($tabs) {
130
- $tabs['yith_woocompare'] = __('Products Compare', 'yit');
131
-
132
- return $tabs;
133
- }
134
-
135
-
136
- /**
137
- * Print all plugin options.
138
- *
139
- * @return void
140
- * @since 1.0.0
141
- */
142
- public function print_plugin_options() {
143
- $links = apply_filters( 'yith_woocompare_tab_links', array(
144
- '<a href="#yith_woocompare_general">' . __( 'General Settings', 'yit' ) . '</a>'
145
- ) );
146
-
147
- $this->_printBanner();
148
- ?>
149
- <div class="subsubsub_section">
150
-
151
- <?php foreach( $this->options as $id => $tab ) : ?>
152
- <!-- tab #<?php echo $id ?> -->
153
- <div class="section" id="yith_woocompare_<?php echo $id ?>">
154
- <?php woocommerce_admin_fields( $this->options[$id] ) ?>
155
- </div>
156
- <?php endforeach ?>
157
- </div>
158
- <?php
159
- }
160
-
161
-
162
- /**
163
- * Initialize the options
164
- *
165
- * @access protected
166
- * @return array
167
- * @since 1.0.0
168
- */
169
- protected function _initOptions() {
170
- include dirname(__FILE__) . '/yith-woocompare-options.php';
171
- return apply_filters('yith_woocompare_tab_options', $options);
172
- }
173
-
174
-
175
- /**
176
- * Default options
177
- *
178
- * Sets up the default options used on the settings page
179
- *
180
- * @access protected
181
- * @return void
182
- * @since 1.0.0
183
- */
184
- protected function _default_options() {
185
- foreach ($this->options as $section) {
186
- foreach ( $section as $value ) {
187
- if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
188
- if ( $value['type'] == 'image_width' ) {
189
- add_option($value['id'], $value['std']);
190
- } elseif ( $value['type'] == 'attributes' ) {
191
- $value_id = str_replace( '_attrs', '', $value['id'] );
192
- if ( $value['default'] == 'all' ) {
193
- $fields = array_merge( $this->default_fields, YITH_Woocompare_Helper::attribute_taxonomies() );
194
- $all = array();
195
- foreach ( array_keys( $fields ) as $field ) $all[$field] = true;
196
- add_option( $value_id, $all );
197
- } else {
198
- add_option( $value_id, $value['std'] );
199
- }
200
- } else {
201
- add_option($value['id'], $value['std']);
202
- }
203
- }
204
- }
205
- }
206
- }
207
-
208
-
209
- /**
210
- * Create new Woocommerce admin field: slider
211
- *
212
- * @access public
213
- * @param array $value
214
- * @return void
215
- * @since 1.0.0
216
- */
217
- public function admin_fields_slider( $value ) {
218
- $slider_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
219
- esc_attr( stripslashes( get_option($value['id'] ) ) ) :
220
- esc_attr( $value['std'] );
221
-
222
- ?><tr valign="top">
223
- <th scope="row" class="titledesc">
224
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
225
- </th>
226
- <td class="forminp">
227
- <div id="<?php echo esc_attr( $value['id'] ); ?>_slider" class="yith_woocommerce_slider" style="width: 300px; float: left;"></div>
228
- <div id="<?php echo esc_attr( $value['id'] ); ?>_value" class="yith_woocommerce_slider_value ui-state-default ui-corner-all"><?php echo $slider_value ?></div>
229
- <input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="hidden" value="<?php echo $slider_value ?>" /> <?php echo $value['desc']; ?></td>
230
- </tr>
231
-
232
-
233
-
234
- <script>
235
- jQuery(document).ready(function($){
236
- $('#<?php echo esc_attr( $value['id'] ); ?>_slider').slider({
237
- min: <?php echo $value['min'] ?>,
238
- max: <?php echo $value['max'] ?>,
239
- step: <?php echo $value['step'] ?>,
240
- value: <?php echo $slider_value ?>,
241
- slide: function( event, ui ) {
242
- $( "#<?php echo esc_attr( $value['id'] ); ?>" ).val( ui.value );
243
- $( "#<?php echo esc_attr( $value['id'] ); ?>_value" ).text( ui.value );
244
- }
245
- });
246
- });
247
- </script>
248
-
249
- <?php
250
- }
251
-
252
-
253
- /**
254
- * Create new Woocommerce admin field: picker
255
- *
256
- * @access public
257
- * @param array $value
258
- * @return void
259
- * @since 1.0.0
260
- */
261
- public function admin_fields_picker( $value ) {
262
- $picker_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
263
- esc_attr( stripslashes( get_option($value['id'] ) ) ) :
264
- esc_attr( $value['std'] );
265
- ?><tr valign="top">
266
- <th scope="row" class="titledesc">
267
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
268
- </th>
269
-
270
- <td class="forminp">
271
- <div class="color_box"><strong><?php echo $value['name']; ?></strong>
272
- <input name="<?php echo esc_attr( $value['id'] ) ?>" id="<?php echo esc_attr( $value['id'] ) ?>" type="text" value="<?php echo $picker_value ?>" class="colorpick" /> <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ) ?>" class="colorpickdiv"></div>
273
- </div> <?php echo $value['desc']; ?></td>
274
- </tr>
275
- <?php
276
- }
277
-
278
- /**
279
- * Create new Woocommerce admin field: checkboxes
280
- *
281
- * @access public
282
- * @param array $value
283
- * @return void
284
- * @since 1.0.0
285
- */
286
- public function admin_fields_attributes( $value ) {
287
- $fields = array_merge( $this->default_fields, YITH_Woocompare_Helper::attribute_taxonomies() );
288
- $all = array();
289
-
290
- foreach ( array_keys( $fields ) as $field ) {
291
- $all[$field] = true;
292
- }
293
-
294
- $checkboxes = get_option( str_replace( '_attrs', '', $value['id'] ), $value['default'] == 'all' ? $all : array() );
295
-
296
- // add fields that are not still saved
297
- foreach ( $checkboxes as $k => $v ) {
298
- unset( $all[ $k ] );
299
- }
300
- $checkboxes = array_merge( $checkboxes, $all );
301
- ?>
302
- <tr valign="top">
303
- <th scope="row" class="titledesc">
304
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
305
- </th>
306
-
307
- <td class="forminp attributes">
308
- <p class="description"><?php echo $value['desc'] ?></p>
309
- <ul class="fields">
310
- <?php foreach ( $checkboxes as $slug => $checked ) { ?>
311
- <li><label><input type="checkbox" name="<?php echo $value['id'] ?>[]" id="<?php echo $value['id'] ?>_<?php echo $slug ?>" value="<?php echo $slug ?>"<?php checked( $checked ) ?> /> <?php echo $fields[$slug] ?></label></li><?php
312
- } ?>
313
- </ul>
314
- <input type="hidden" name="<?php echo $value['id'] ?>_positions" value="<?php echo implode( ',', array_keys( $checkboxes ) ) ?>" />
315
- </td>
316
- </tr>
317
- <?php
318
- }
319
-
320
- /**
321
- * Save the admin field: slider
322
- *
323
- * @access public
324
- * @param mixed $value
325
- * @return void
326
- * @since 1.0.0
327
- */
328
- public function admin_update_option($value) {
329
-
330
- global $woocommerce;
331
-
332
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
333
- $wc_clean = 'woocommerce_clean';
334
- }
335
- else {
336
- $wc_clean = 'wc_clean';
337
- }
338
-
339
- if ( $value['type'] == 'attributes' ) {
340
- $val = array();
341
- $checked_fields = isset( $_POST[$value['id']] ) ? $_POST[$value['id']] : array();
342
- $fields = array_map( 'trim', explode( ',', $_POST[ $value['id'] . '_positions' ] ) );
343
- foreach ( $fields as $field ) {
344
- $val[$field] = in_array( $field, $checked_fields );
345
- }
346
- update_option( str_replace( '_attrs', '', $value['id'] ), $val );
347
- } else{
348
- update_option( str_replace( '_attrs', '', $value['id'] ), $wc_clean($_POST[$value['id']]) );
349
- }
350
- }
351
-
352
- /**
353
- * Create new Woocommerce admin field: yit_wc_image_width
354
- *
355
- * @access public
356
- * @param array $value
357
- * @return void
358
- * @since 1.0.0
359
- */
360
- public function admin_fields_yit_wc_image_width( $value ){
361
-
362
- $width = WC_Admin_Settings::get_option( $value['id'] . '[width]', $value['default']['width'] );
363
- $height = WC_Admin_Settings::get_option( $value['id'] . '[height]', $value['default']['height'] );
364
- $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]', $value['default']['crop'] );
365
- $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]' );
366
- $crop = ( $crop == 'on' || $crop == '1' ) ? 1 : 0;
367
- $crop = checked( 1, $crop, false );
368
-
369
- ?><tr valign="top">
370
- <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?> <?php echo $value['desc'] ?></th>
371
- <td class="forminp image_width_settings">
372
-
373
- <input name="<?php echo esc_attr( $value['id'] ); ?>[width]" id="<?php echo esc_attr( $value['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> &times; <input name="<?php echo esc_attr( $value['id'] ); ?>[height]" id="<?php echo esc_attr( $value['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px
374
-
375
- <label><input name="<?php echo esc_attr( $value['id'] ); ?>[crop]" id="<?php echo esc_attr( $value['id'] ); ?>-crop" type="checkbox" <?php echo $crop; ?> /> <?php _e( 'Hard Crop?', 'woocommerce' ); ?></label>
376
-
377
- </td>
378
- </tr><?php
379
-
380
- }
381
-
382
- /**
383
- * Create new Woocommerce admin field: image deps
384
- *
385
- * @access public
386
- * @param array $value
387
- * @return void
388
- * @since 1.0.0
389
- */
390
- public function admin_fields_image_deps( $value ) {
391
- global $woocommerce;
392
-
393
- $force = get_option('yith_woocompare_force_sizes') == 'yes';
394
-
395
- if( $force ) {
396
- $value['desc'] = 'These values ??are automatically calculated based on the values ??of the Single product. If you\'d like to customize yourself the values, please disable the "Forcing Zoom Image sizes" in "Magnifier" tab.';
397
- }
398
-
399
- if( $force && isset($_GET['page']) && isset($_GET['tab']) && $_GET['page'] == 'woocommerce_settings' && $_GET['tab'] == 'catalog' ): ?>
400
- <script>
401
- jQuery(document).ready(function($){
402
- $('#woocommerce_magnifier_image-width, #woocommerce_magnifier_image-height, #woocommerce_magnifier_image-crop').attr('disabled', 'disabled');
403
-
404
- $('#shop_single_image_size-width, #shop_single_image_size-height').on('keyup', function(){
405
- var value = parseInt( $(this).val() );
406
- var input = (this.id).indexOf('width') >= 0 ? 'width' : 'height';
407
-
408
- if( !isNaN(value) ) {
409
- $('#woocommerce_magnifier_image-' + input).val( value * 2 );
410
- }
411
- });
412
-
413
- $('#shop_single_image_size-crop').on('change', function(){
414
- if( $(this).is(':checked') ) {
415
- $('#woocommerce_magnifier_image-crop').attr('checked', 'checked');
416
- } else {
417
- $('#woocommerce_magnifier_image-crop').removeAttr('checked');
418
- }
419
- });
420
-
421
- $('#mainform').on('submit', function(){
422
- $(':disabled').removeAttr('disabled');
423
- });
424
- });
425
- </script>
426
- <?php endif;
427
- }
428
-
429
-
430
- /**
431
- * Enqueue admin styles and scripts
432
- *
433
- * @access public
434
- * @return void
435
- * @since 1.0.0
436
- */
437
- public function enqueue_styles_scripts() {
438
- wp_enqueue_script( 'jquery-ui' );
439
- wp_enqueue_script( 'jquery-ui-core' );
440
- wp_enqueue_script( 'jquery-ui-mouse' );
441
- wp_enqueue_script( 'jquery-ui-slider' );
442
- wp_enqueue_script( 'jquery-ui-sortable' );
443
-
444
- if( isset( $_GET['page'] ) && ( $_GET['page'] == 'woocommerce_settings' || $_GET['page'] == 'wc-settings' ) && isset( $_GET['tab'] ) && $_GET['tab'] == 'yith_woocompare' ) {
445
- wp_enqueue_style( 'yith_woocompare_admin', YITH_WOOCOMPARE_URL . 'assets/css/admin.css' );
446
- wp_enqueue_script( 'woocompare', YITH_WOOCOMPARE_URL . 'assets/js/woocompare-admin.js', array( 'jquery', 'jquery-ui-sortable' ) );
447
- }
448
- }
449
-
450
-
451
- /**
452
- * Print the banner
453
- *
454
- * @access protected
455
- * @return void
456
- * @since 1.0.0
457
- */
458
- protected function _printBanner() {
459
- ?>
460
- <div class="yith_banner">
461
- <a href="<?php echo $this->banner_url ?>" target="_blank">
462
- <img src="<?php echo $this->banner_img ?>" alt="" />
463
- </a>
464
- </div>
465
- <?php
466
- }
467
-
468
- }
469
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class.yith-woocompare-admin.php ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Admin class
4
+ *
5
+ * @author Your Inspiration Themes
6
+ * @package YITH WooCommerce Compare
7
+ * @version 2.0.0
8
+ */
9
+
10
+ if ( ! defined( 'YITH_WOOCOMPARE' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ if ( ! class_exists( 'YITH_Woocompare_Admin' ) ) {
15
+ /**
16
+ * Admin class.
17
+ * The class manage all the admin behaviors.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+ class YITH_Woocompare_Admin {
22
+
23
+
24
+ /**
25
+ * Plugin options
26
+ *
27
+ * @var array
28
+ * @access public
29
+ * @since 1.0.0
30
+ */
31
+ public $options = array();
32
+
33
+ /**
34
+ * Plugin version
35
+ *
36
+ * @var string
37
+ * @since 1.0.0
38
+ */
39
+ public $version = YITH_WOOCOMPARE_VERSION;
40
+
41
+ /**
42
+ * @var $_panel Panel Object
43
+ */
44
+ protected $_panel;
45
+
46
+ /**
47
+ * @var $_premium string Premium tab template file name
48
+ */
49
+ protected $_premium = 'premium.php';
50
+
51
+ /**
52
+ * @var string Premium version landing link
53
+ */
54
+ protected $_premium_landing = 'https://yithemes.com/themes/plugins/yith-woocommerce-compare';
55
+
56
+ /**
57
+ * @var string Quick View panel page
58
+ */
59
+ protected $_panel_page = 'yith_woocompare_panel';
60
+
61
+ /**
62
+ * Various links
63
+ *
64
+ * @var string
65
+ * @access public
66
+ * @since 1.0.0
67
+ */
68
+ public $doc_url = 'http://yithemes.com/docs-plugins/yith-woocommerce-compare/';
69
+
70
+ /**
71
+ * Constructor
72
+ *
73
+ * @access public
74
+ * @since 1.0.0
75
+ */
76
+ public function __construct() {
77
+
78
+ add_action( 'admin_menu', array( $this, 'register_panel' ), 5) ;
79
+
80
+ //Add action links
81
+ add_filter( 'plugin_action_links_' . plugin_basename( YITH_WOOCOMPARE_DIR . '/' . basename( YITH_WOOCOMPARE_FILE ) ), array( $this, 'action_links' ) );
82
+ add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
83
+
84
+ add_action( 'yith_woocompare_premium', array( $this, 'premium_tab' ) );
85
+
86
+ add_action( 'admin_init', array( $this, 'register_pointer' ) );
87
+ add_action( 'admin_init', array( $this, 'default_options'), 99 );
88
+
89
+ // add image size
90
+ YITH_Woocompare_Helper::set_image_size();
91
+
92
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
93
+
94
+ add_action( 'woocommerce_admin_field_woocompare_image_width', array( $this, 'admin_fields_woocompare_image_width' ) );
95
+ add_action( 'woocommerce_admin_field_woocompare_attributes', array( $this, 'admin_fields_attributes' ), 10, 1 );
96
+ add_action( 'woocommerce_update_option_woocompare_attributes', array( $this, 'admin_update_custom_option' ), 10, 1 );
97
+
98
+ // YITH WCWL Loaded
99
+ do_action( 'yith_woocompare_loaded' );
100
+ }
101
+
102
+ /**
103
+ * Action Links
104
+ *
105
+ * add the action links to plugin admin page
106
+ *
107
+ * @param $links | links plugin array
108
+ *
109
+ * @return mixed Array
110
+ * @since 1.0
111
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
112
+ * @return mixed
113
+ * @use plugin_action_links_{$plugin_file_name}
114
+ */
115
+ public function action_links( $links ) {
116
+
117
+ $links[] = '<a href="' . admin_url( "admin.php?page={$this->_panel_page}" ) . '">' . __( 'Settings', 'yith-wcmp' ) . '</a>';
118
+ $links[] = '<a href="' . $this->get_premium_landing_uri() . '" target="_blank">' . __( 'Premium Version', 'yith-wcmp' ) . '</a>';
119
+
120
+ return $links;
121
+ }
122
+
123
+ /**
124
+ * Add a panel under YITH Plugins tab
125
+ *
126
+ * @return void
127
+ * @since 1.0
128
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
129
+ * @use /Yit_Plugin_Panel class
130
+ * @see plugin-fw/lib/yit-plugin-panel.php
131
+ */
132
+ public function register_panel() {
133
+
134
+ if ( ! empty( $this->_panel ) ) {
135
+ return;
136
+ }
137
+
138
+ $admin_tabs = array(
139
+ 'general' => __( 'Settings', 'yith-wcmp' ),
140
+ );
141
+
142
+ if ( ! ( defined( 'YITH_WOOCOMPARE_PREMIUM' ) && YITH_WOOCOMPARE_PREMIUM ) ) {
143
+ $admin_tabs['premium'] = __( 'Premium Version', 'yith-wcmp' );
144
+ }
145
+
146
+ $args = array(
147
+ 'create_menu_page' => true,
148
+ 'parent_slug' => '',
149
+ 'page_title' => __( 'Compare', 'yith-wcmp' ),
150
+ 'menu_title' => __( 'Compare', 'yith-wcmp' ),
151
+ 'capability' => 'manage_options',
152
+ 'parent' => '',
153
+ 'parent_page' => 'yit_plugin_panel',
154
+ 'page' => $this->_panel_page,
155
+ 'admin-tabs' => apply_filters( 'yith_woocompare_admin_tabs', $admin_tabs ),
156
+ 'options-path' => YITH_WOOCOMPARE_DIR . '/plugin-options'
157
+ );
158
+
159
+
160
+ /* === Fixed: not updated theme === */
161
+ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
162
+ require_once( YITH_WOOCOMPARE_DIR . 'plugin-fw/lib/yit-plugin-panel-wc.php' );
163
+ }
164
+
165
+ $this->_panel = new YIT_Plugin_Panel_WooCommerce( $args );
166
+ $this->options = $this->_panel->get_main_array_options();
167
+ }
168
+
169
+ /**
170
+ * Set default custom options
171
+ *
172
+ */
173
+ public function default_options() {
174
+ $this->_default_options();
175
+ }
176
+
177
+ /**
178
+ * Premium Tab Template
179
+ *
180
+ * Load the premium tab template on admin page
181
+ *
182
+ * @return void
183
+ * @since 1.0
184
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
185
+ * @return void
186
+ */
187
+ public function premium_tab() {
188
+ $premium_tab_template = YITH_WOOCOMPARE_TEMPLATE_PATH . '/admin/' . $this->_premium;
189
+ if ( file_exists( $premium_tab_template ) ) {
190
+ include_once( $premium_tab_template );
191
+ }
192
+
193
+ }
194
+
195
+ /**
196
+ * plugin_row_meta
197
+ *
198
+ * add the action links to plugin admin page
199
+ *
200
+ * @param $plugin_meta
201
+ * @param $plugin_file
202
+ * @param $plugin_data
203
+ * @param $status
204
+ *
205
+ * @return Array
206
+ * @since 1.0
207
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
208
+ * @use plugin_row_meta
209
+ */
210
+ public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
211
+
212
+ if ( defined( 'YITH_WOOCOMPARE_FREE_INIT' ) && YITH_WOOCOMPARE_FREE_INIT == $plugin_file ) {
213
+ $plugin_meta[] = '<a href="' . $this->doc_url . '" target="_blank">' . __( 'Plugin Documentation', 'yith-wcmp' ) . '</a>';
214
+ }
215
+ return $plugin_meta;
216
+ }
217
+
218
+ /**
219
+ * Register Pointer
220
+ */
221
+ public function register_pointer(){
222
+
223
+ if( ! class_exists( 'YIT_Pointers' ) ){
224
+ include_once( 'plugin-fw/lib/yit-pointers.php' );
225
+ }
226
+
227
+ $args[] = array(
228
+ 'screen_id' => 'plugins',
229
+ 'pointer_id' => 'yith_woocompare_panel',
230
+ 'target' => '#toplevel_page_yit_plugin_panel',
231
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
232
+ __( 'YITH WooCommerce Compare Activated', 'yith-wcmp' ),
233
+ apply_filters( 'yith_woocompare_activated_pointer_content', sprintf( __( 'In the YIT Plugin tab you can find the YITH WooCommerce Compare options. With this menu, you can access to all the settings of our plugins that you have activated. YITH WooCommerce Compare is available in an outstanding PREMIUM version with many new options, <a href="%s">discover it now</a>.', 'yit' ), $this->get_premium_landing_uri() ) )
234
+ ),
235
+ 'position' => array( 'edge' => 'left', 'align' => 'center' ),
236
+ 'init' => YITH_WOOCOMPARE_INIT
237
+ );
238
+
239
+ $args[] = array(
240
+ 'screen_id' => 'update',
241
+ 'pointer_id' => 'yith_woocompare_panel',
242
+ 'target' => '#toplevel_page_yit_plugin_panel',
243
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
244
+ __( 'YITH WooCommerce Compare Updated', 'yith-wcmp' ),
245
+ apply_filters( 'yith_woocompare_updated_pointer_content', sprintf( __( 'From now on, you can find all the options of YITH WooCommerce Compare under YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in the previous version. When one of our plugins is updated, a new voice will be added to this menu. YITH WooCommerce Compare has been updated with new available options, <a href="%s">discover the PREMIUM version.</a>', 'yit' ), $this->get_premium_landing_uri() ) )
246
+ ),
247
+ 'position' => array( 'edge' => 'left', 'align' => 'center' ),
248
+ 'init' => YITH_WOOCOMPARE_INIT
249
+ );
250
+
251
+ YIT_Pointers()->register( $args );
252
+ }
253
+
254
+ /**
255
+ * Get the premium landing uri
256
+ *
257
+ * @since 1.0.0
258
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
259
+ * @return string The premium landing link
260
+ */
261
+ public function get_premium_landing_uri() {
262
+ return defined( 'YITH_REFER_ID' ) ? $this->_premium_landing . '?refer_id=' . YITH_REFER_ID : $this->_premium_landing.'?refer_id=1030585';
263
+ }
264
+
265
+ /**
266
+ * Default options
267
+ *
268
+ * Sets up the default options used on the settings page
269
+ *
270
+ * @access protected
271
+ * @return void
272
+ * @since 1.0.0
273
+ */
274
+ protected function _default_options() {
275
+
276
+ foreach ( $this->options as $section ) {
277
+
278
+ foreach ( $section as $value ) {
279
+
280
+ if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
281
+
282
+ if ( $value['type'] == 'image_width' ) {
283
+ add_option( $value['id'], $value['std'] );
284
+ } elseif ( $value['type'] == 'woocompare_attributes' ) {
285
+
286
+ $value_id = str_replace( '_attrs', '', $value['id'] );
287
+
288
+ $in_db = get_option( $value_id );
289
+ $in_db_original = get_option( $value['id'] );
290
+
291
+ // if options is already in db and not reset defaults continue
292
+ if ( $in_db && $in_db_original != 'all' ) {
293
+ continue;
294
+ }
295
+
296
+ if ( $value['default'] == 'all' ) {
297
+ $fields = YITH_Woocompare_Helper::standard_fields();
298
+ $all = array();
299
+
300
+ foreach ( array_keys( $fields ) as $field ) {
301
+ $all[ $field ] = true;
302
+ }
303
+
304
+ update_option( $value_id, $all );
305
+ } else {
306
+ update_option( $value_id, $value['std'] );
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Create new Woocommerce admin field: checkboxes
316
+ *
317
+ * @access public
318
+ * @param array $value
319
+ * @return void
320
+ * @since 1.0.0
321
+ */
322
+ public function admin_fields_attributes( $value ) {
323
+ $fields = YITH_Woocompare_Helper::standard_fields();
324
+ $all = array();
325
+ $checked = get_option( str_replace( '_attrs', '', $value['id'] ), $value['default'] == 'all' ? $all : array() );
326
+
327
+ foreach ( array_keys( $fields ) as $field ) {
328
+ $all[ $field ] = true;
329
+ }
330
+ // then add fields that are not still saved
331
+ foreach ( $checked as $k => $v ) {
332
+ unset( $all[ $k ] );
333
+ }
334
+ $checkboxes = array_merge( $checked, $all );
335
+
336
+
337
+ ?>
338
+ <tr valign="top">
339
+ <th scope="row" class="titledesc">
340
+ <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
341
+ </th>
342
+
343
+ <td class="forminp attributes">
344
+ <p class="description"><?php echo $value['desc'] ?></p>
345
+ <ul class="fields">
346
+ <?php foreach ( $checkboxes as $slug => $checked ) :
347
+ if( ! isset( $fields[ $slug ] ) )
348
+ continue;
349
+ ?>
350
+ <li>
351
+ <label>
352
+ <input type="checkbox" name="<?php echo $value['id'] ?>[]" id="<?php echo $value['id'] ?>_<?php echo $slug ?>" value="<?php echo $slug ?>"<?php checked( $checked ) ?> /> <?php echo $fields[ $slug ] ?>
353
+ </label>
354
+ </li>
355
+ <?php
356
+ endforeach;
357
+ ?>
358
+ </ul>
359
+ <input type="hidden" name="<?php echo $value['id'] ?>_positions" value="<?php echo implode( ',', array_keys( $checkboxes ) ) ?>" />
360
+ </td>
361
+ </tr>
362
+ <?php
363
+ }
364
+
365
+ /**
366
+ * Create new Woocommerce admin field: yit_wc_image_width
367
+ *
368
+ * @access public
369
+ * @param array $value
370
+ * @return void
371
+ * @since 1.0.0
372
+ */
373
+ public function admin_fields_woocompare_image_width( $value ) {
374
+
375
+ $width = WC_Admin_Settings::get_option( $value['id'] . '[width]', $value['default']['width'] );
376
+ $height = WC_Admin_Settings::get_option( $value['id'] . '[height]', $value['default']['height'] );
377
+ $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]', $value['default']['crop'] );
378
+ $crop = WC_Admin_Settings::get_option( $value['id'] . '[crop]' );
379
+ $crop = ( $crop == 'on' || $crop == '1' ) ? 1 : 0;
380
+ $crop = checked( 1, $crop, false );
381
+
382
+ ?>
383
+ <tr valign="top">
384
+ <th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?></th>
385
+ <td class="forminp image_width_settings">
386
+
387
+ <input name="<?php echo esc_attr( $value['id'] ); ?>[width]" id="<?php echo esc_attr( $value['id'] ); ?>-width" type="text" size="3" value="<?php echo $width; ?>" /> &times;
388
+ <input name="<?php echo esc_attr( $value['id'] ); ?>[height]" id="<?php echo esc_attr( $value['id'] ); ?>-height" type="text" size="3" value="<?php echo $height; ?>" />px
389
+
390
+ <label><input name="<?php echo esc_attr( $value['id'] ); ?>[crop]" id="<?php echo esc_attr( $value['id'] ); ?>-crop" type="checkbox" <?php echo $crop; ?> /> <?php _e( 'Do you want to hard crop the image?', 'yith-wcmp' ); ?>
391
+ </label>
392
+ <p class="description"><?php echo $value['desc'] ?></p>
393
+
394
+ </td>
395
+ </tr><?php
396
+
397
+ }
398
+
399
+ /**
400
+ * Save the admin field: slider
401
+ *
402
+ * @access public
403
+ * @param mixed $value
404
+ * @return void
405
+ * @since 1.0.0
406
+ */
407
+ public function admin_update_custom_option( $value ) {
408
+
409
+ $val = array();
410
+ $checked_fields = isset( $_POST[ $value['id'] ] ) ? $_POST[ $value['id'] ] : array();
411
+ $fields = array_map( 'trim', explode( ',', $_POST[ $value['id'] . '_positions' ] ) );
412
+
413
+ foreach ( $fields as $field ) {
414
+ $val[ $field ] = in_array( $field, $checked_fields );
415
+ }
416
+
417
+ update_option( str_replace( '_attrs', '', $value['id'] ), $val );
418
+ }
419
+
420
+ /**
421
+ * Enqueue admin styles and scripts
422
+ *
423
+ * @access public
424
+ * @return void
425
+ * @since 1.0.0
426
+ */
427
+ public function enqueue_styles_scripts() {
428
+ wp_enqueue_script( 'jquery-ui' );
429
+ wp_enqueue_script( 'jquery-ui-core' );
430
+ wp_enqueue_script( 'jquery-ui-mouse' );
431
+ wp_enqueue_script( 'jquery-ui-slider' );
432
+ wp_enqueue_script( 'jquery-ui-sortable' );
433
+
434
+ if ( isset( $_GET['page'] ) && $_GET['page'] == 'yith_woocompare_panel' ) {
435
+ wp_enqueue_style( 'yith_woocompare_admin', YITH_WOOCOMPARE_URL . 'assets/css/admin.css' );
436
+ wp_enqueue_script( 'yith_woocompare', YITH_WOOCOMPARE_URL . 'assets/js/woocompare-admin.js', array( 'jquery', 'jquery-ui-sortable' ) );
437
+ }
438
+ }
439
+ }
440
+ }
class.yith-woocompare-frontend.php → includes/class.yith-woocompare-frontend.php RENAMED
@@ -130,7 +130,7 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
130
  public function enqueue_scripts() {
131
 
132
  // scripts
133
- wp_enqueue_script( 'yith-woocompare-main', YITH_WOOCOMPARE_URL . 'assets/js/woocompare.js', array('jquery'), $this->version, true );
134
  wp_localize_script( 'yith-woocompare-main', 'yith_woocompare', array(
135
  'nonceadd' => wp_create_nonce( $this->action_add ),
136
  'nonceremove' => wp_create_nonce( $this->action_remove ),
@@ -139,18 +139,18 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
139
  'actionadd' => $this->action_add,
140
  'actionremove' => $this->action_remove,
141
  'actionview' => $this->action_view,
142
- 'added_label' => __( 'Added', 'yit' ),
143
- 'table_title' => __( 'Product Comparison', 'yit' ),
144
  'auto_open' => get_option( 'yith_woocompare_auto_open', 'yes' )
145
  ));
146
 
147
  // colorbox
148
- wp_enqueue_style( 'jquery-colorbox', YITH_WOOCOMPARE_URL . 'assets/css/colorbox.css' );
149
- wp_enqueue_script( 'jquery-colorbox', YITH_WOOCOMPARE_URL . 'assets/js/jquery.colorbox-min.js', array('jquery'), '1.4.21', true );
150
 
151
  // widget
152
  if ( is_active_widget( false, false, 'yith-woocompare-widget', true ) && ! is_admin() ) {
153
- wp_enqueue_style( 'yith-woocompare-widget', YITH_WOOCOMPARE_URL . 'assets/css/widget.css' );
154
  }
155
  }
156
 
@@ -161,17 +161,21 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
161
  * @since 1.0.0
162
  */
163
  public function fields() {
 
164
  $fields = get_option( 'yith_woocompare_fields', array() );
 
165
  foreach ( $fields as $field => $show ) {
166
  if ( $show ) {
167
  if ( isset( $this->default_fields[$field] ) ) {
168
  $fields[$field] = $this->default_fields[$field];
169
- } else {
 
170
  if ( taxonomy_exists( $field ) ) {
171
  $fields[$field] = get_taxonomy( $field )->label;
172
  }
173
  }
174
- } else {
 
175
  unset( $fields[$field] );
176
  }
177
  }
@@ -184,6 +188,7 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
184
  *
185
  */
186
  public function compare_table_html() {
 
187
  if ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_view ) ) return;
188
 
189
  global $woocommerce;
@@ -197,13 +202,14 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
197
  remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
198
  remove_action( 'wp_head', '_admin_bar_bump_cb' );
199
 
200
- $plugin_path = plugin_dir_path(__FILE__) . 'templates/' . $this->template_file;
201
 
202
  if ( defined('WC_TEMPLATE_PATH') ) {
203
 
204
  $template_path = get_template_directory() . '/' . WC_TEMPLATE_PATH . $this->template_file;
205
  $child_path = get_stylesheet_directory() . '/' .WC_TEMPLATE_PATH . $this->template_file;
206
- }else{
 
207
  $template_path = get_template_directory() . '/' . $woocommerce->template_url . $this->template_file;
208
  $child_path = get_stylesheet_directory() . '/' . $woocommerce->template_url . $this->template_file;
209
  }
@@ -221,14 +227,19 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
221
  *
222
  * @return array The complete list of products with all attributes value
223
  */
224
- public function get_products_list() {
225
  $list = array();
226
- $products = $this->products_list;
 
 
 
227
  $fields = $this->fields();
228
 
229
  foreach ( $products as $product_id ) {
230
  $product = $this->wc_get_product( $product_id );
231
- if ( ! $product ) continue;
 
 
232
 
233
  $product->fields = array();
234
 
@@ -251,12 +262,11 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
251
  case 'stock':
252
  $availability = $product->get_availability();
253
  if ( empty( $availability['availability'] ) ) {
254
- $availability['availability'] = __( 'In stock', 'yit' );
255
  }
256
  $product->fields[$field] = sprintf( '<span class="%s">%s</span>', esc_attr( $availability['class'] ), esc_html( $availability['availability'] ) );
257
  break;
258
  default:
259
- //$taxonomy = 'pa_' . $field;
260
  if ( taxonomy_exists( $field ) ) {
261
  $product->fields[$field] = array();
262
  $terms = get_the_terms( $product_id, $field );
@@ -283,17 +293,21 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
283
  /**
284
  * The URL of product comparison table
285
  *
286
- * @param $product_id The ID of the product to add
287
  * @return string The url to add the product in the comparison table
288
  */
289
- public function view_table_url() {
290
- return add_query_arg( 'action', $this->action_view );
 
 
 
 
291
  }
292
 
293
  /**
294
  * The URL to add the product into the comparison table
295
  *
296
- * @param $product_id The ID of the product to add
297
  * @return string The url to add the product in the comparison table
298
  */
299
  public function add_product_url( $product_id ) {
@@ -301,7 +315,7 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
301
  'action' => $this->action_add,
302
  'id' => $product_id
303
  );
304
- return wp_nonce_url( add_query_arg( $url_args ), $this->action_add );
305
  }
306
 
307
  /**
@@ -315,7 +329,7 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
315
  'action' => $this->action_remove,
316
  'id' => $product_id
317
  );
318
- return wp_nonce_url( add_query_arg( $url_args ), $this->action_remove );
319
  }
320
 
321
  /**
@@ -330,12 +344,13 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
330
  }
331
 
332
  // return if product doesn't exist
333
- if ( empty( $product_id ) ) return;
 
334
 
335
- $is_button = !isset( $button_or_link ) || !$button_or_link ? get_option( 'yith_woocompare_is_button' ) : $button_or_link;
336
 
337
  if ( ! isset( $button_text ) || $button_text == 'default' ) {
338
- $button_text = get_option( 'yith_woocompare_button_text', __( 'Compare', 'yit' ) );
339
  $button_text = function_exists( 'icl_translate' ) ? icl_translate( 'Plugins', 'plugin_yit_compare_button_text', $button_text ) : $button_text;
340
  }
341
 
@@ -350,15 +365,17 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
350
 
351
  $filename = 'compare.css';
352
 
353
- $plugin_path = array( 'path' => plugin_dir_path(__FILE__) . 'assets/css/style.css', 'url' => YITH_WOOCOMPARE_URL . 'assets/css/style.css' );
354
 
355
  if ( defined('WC_TEMPLATE_PATH') ) {
356
  $template_path = array( 'path' => get_template_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_template_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename );
357
  $child_path = array( 'path' => get_stylesheet_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_stylesheet_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename );
358
- }else{
 
359
  $template_path = array( 'path' => get_template_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_template_directory_uri() . '/' . $woocommerce->template_url . $filename );
360
  $child_path = array( 'path' => get_stylesheet_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_stylesheet_directory_uri() . '/' . $woocommerce->template_url . $filename );
361
  }
 
362
  foreach ( array( 'child_path', 'template_path', 'plugin_path' ) as $var ) {
363
  if ( file_exists( ${$var}['path'] ) ) {
364
  return ${$var}['url'];
@@ -376,9 +393,9 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
376
  */
377
  protected function _vars() {
378
  $vars = array(
379
- 'products' => $this->get_products_list(),
380
- 'fields' => $this->fields(),
381
- 'repeat_price' => get_option( 'yith_woocompare_price_end' ),
382
  'repeat_add_to_cart' => get_option( 'yith_woocompare_add_to_cart_end' ),
383
  );
384
 
@@ -394,9 +411,15 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
394
  ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_add ) )
395
  return;
396
 
397
- $this->add_product_to_compare( intval( $_REQUEST['id'] ) );
 
398
 
399
- wp_redirect( remove_query_arg( array( 'id', 'action', '_wpnonce' ) ) );
 
 
 
 
 
400
  exit();
401
  }
402
 
@@ -406,16 +429,19 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
406
  public function add_product_to_compare_ajax() {
407
  check_ajax_referer( $this->action_add, '_yitnonce_ajax' );
408
 
409
- $this->add_product_to_compare( intval( $_REQUEST['id'] ) );
 
410
 
411
- $json = array(
412
- 'table_url' => add_query_arg( array(
413
- 'action' => $this->action_view,
414
- 'iframe' => 'true',
415
- 'ver' => time()
416
- ), site_url() ),
417
 
418
- 'widget_table' => $this->list_products_html()
 
 
419
  );
420
 
421
  echo json_encode( $json );
@@ -425,16 +451,14 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
425
  /**
426
  * Add a product in the products comparison table
427
  *
428
- * @param $product_id The product ID to add in the comparison table
429
  */
430
  public function add_product_to_compare( $product_id ) {
431
- $product = $this->wc_get_product( $product_id );
432
-
433
- // don't add the product if doesn't exist
434
- if ( !$product->exists() || in_array( $product_id, $this->products_list ) ) return;
435
 
436
  $this->products_list[] = $product_id;
437
- setcookie( $this->cookie_name, serialize($this->products_list), 0, COOKIEPATH, COOKIE_DOMAIN, false, true );
 
 
438
  }
439
 
440
  /**
@@ -446,12 +470,22 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
446
  ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_remove ) )
447
  return;
448
 
449
- $this->remove_product_from_compare( intval( $_REQUEST['id'] ) );
 
 
 
 
 
 
 
450
 
451
  // redirect
452
- $redirect = remove_query_arg( array( 'id', 'action', '_wpnonce' ) );
453
- if ( isset( $_REQUEST['redirect'] ) && $_REQUEST['redirect'] == 'view' ) $redirect = remove_query_arg( 'redirect', add_query_arg( 'action', $this->action_view, $redirect ) );
454
- wp_redirect( $redirect );
 
 
 
455
  exit();
456
  }
457
 
@@ -474,6 +508,8 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
474
  $this->remove_product_from_compare( intval( $_REQUEST['id'] ) );
475
  }
476
 
 
 
477
  header('Content-Type: text/html; charset=utf-8');
478
 
479
  if ( isset( $_REQUEST['responseType'] ) && $_REQUEST['responseType'] == 'product_list' ) {
@@ -509,17 +545,18 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
509
  }
510
 
511
  if ( empty( $this->products_list ) ) {
512
- echo '<li>' . __( 'No products to compare', 'yit' ) . '</li>';
513
  return ob_get_clean();
514
  }
515
 
516
  foreach ( $this->products_list as $product_id ) {
517
  $product = $this->wc_get_product( $product_id );
518
- if ( ! $product ) continue;
 
519
  ?>
520
  <li>
521
  <a class="title" href="<?php echo get_permalink( $product_id ) ?>"><?php echo $product->get_title() ?></a>
522
- <a href="<?php echo $this->remove_product_url( $product_id ) ?>" data-product_id="<?php echo $product_id; ?>" class="remove" title="<?php _e( 'Remove', 'yit' ) ?>">x</a>
523
  </li>
524
  <?php
525
  }
@@ -533,16 +570,12 @@ if( !class_exists( 'YITH_Woocompare_Frontend' ) ) {
533
  * @param $product_id The product ID to remove from the comparison table
534
  */
535
  public function remove_product_from_compare( $product_id ) {
536
- $product = $this->wc_get_product( $product_id );
537
- if ( ! $product ) return;
538
-
539
- // don't add the product if doesn't exist
540
- if ( !$product->exists() || !in_array( $product_id, $this->products_list ) ) return;
541
-
542
  foreach ( $this->products_list as $k => $id ) {
543
  if ( $product_id == $id ) unset( $this->products_list[$k] );
544
  }
545
- setcookie( $this->cookie_name, serialize($this->products_list), 0, COOKIEPATH, COOKIE_DOMAIN, false, true );
 
 
546
  }
547
 
548
  /**
130
  public function enqueue_scripts() {
131
 
132
  // scripts
133
+ wp_enqueue_script( 'yith-woocompare-main', YITH_WOOCOMPARE_ASSETS_URL . '/js/woocompare.js', array('jquery'), $this->version, true );
134
  wp_localize_script( 'yith-woocompare-main', 'yith_woocompare', array(
135
  'nonceadd' => wp_create_nonce( $this->action_add ),
136
  'nonceremove' => wp_create_nonce( $this->action_remove ),
139
  'actionadd' => $this->action_add,
140
  'actionremove' => $this->action_remove,
141
  'actionview' => $this->action_view,
142
+ 'added_label' => __( 'Added', 'yith-wcmp' ),
143
+ 'table_title' => __( 'Product Comparison', 'yith-wcmp' ),
144
  'auto_open' => get_option( 'yith_woocompare_auto_open', 'yes' )
145
  ));
146
 
147
  // colorbox
148
+ wp_enqueue_style( 'jquery-colorbox', YITH_WOOCOMPARE_ASSETS_URL . '/css/colorbox.css' );
149
+ wp_enqueue_script( 'jquery-colorbox', YITH_WOOCOMPARE_ASSETS_URL . '/js/jquery.colorbox-min.js', array('jquery'), '1.4.21', true );
150
 
151
  // widget
152
  if ( is_active_widget( false, false, 'yith-woocompare-widget', true ) && ! is_admin() ) {
153
+ wp_enqueue_style( 'yith-woocompare-widget', YITH_WOOCOMPARE_ASSETS_URL . '/css/widget.css' );
154
  }
155
  }
156
 
161
  * @since 1.0.0
162
  */
163
  public function fields() {
164
+
165
  $fields = get_option( 'yith_woocompare_fields', array() );
166
+
167
  foreach ( $fields as $field => $show ) {
168
  if ( $show ) {
169
  if ( isset( $this->default_fields[$field] ) ) {
170
  $fields[$field] = $this->default_fields[$field];
171
+ }
172
+ else {
173
  if ( taxonomy_exists( $field ) ) {
174
  $fields[$field] = get_taxonomy( $field )->label;
175
  }
176
  }
177
+ }
178
+ else {
179
  unset( $fields[$field] );
180
  }
181
  }
188
  *
189
  */
190
  public function compare_table_html() {
191
+
192
  if ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_view ) ) return;
193
 
194
  global $woocommerce;
202
  remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
203
  remove_action( 'wp_head', '_admin_bar_bump_cb' );
204
 
205
+ $plugin_path = YITH_WOOCOMPARE_TEMPLATE_PATH . '/' . $this->template_file;
206
 
207
  if ( defined('WC_TEMPLATE_PATH') ) {
208
 
209
  $template_path = get_template_directory() . '/' . WC_TEMPLATE_PATH . $this->template_file;
210
  $child_path = get_stylesheet_directory() . '/' .WC_TEMPLATE_PATH . $this->template_file;
211
+ }
212
+ else {
213
  $template_path = get_template_directory() . '/' . $woocommerce->template_url . $this->template_file;
214
  $child_path = get_stylesheet_directory() . '/' . $woocommerce->template_url . $this->template_file;
215
  }
227
  *
228
  * @return array The complete list of products with all attributes value
229
  */
230
+ public function get_products_list( $products = array() ) {
231
  $list = array();
232
+
233
+ if( empty( $products ) )
234
+ $products = apply_filters( 'yith_woocompare_exclude_products_from_list', $this->products_list );
235
+
236
  $fields = $this->fields();
237
 
238
  foreach ( $products as $product_id ) {
239
  $product = $this->wc_get_product( $product_id );
240
+
241
+ if ( ! $product )
242
+ continue;
243
 
244
  $product->fields = array();
245
 
262
  case 'stock':
263
  $availability = $product->get_availability();
264
  if ( empty( $availability['availability'] ) ) {
265
+ $availability['availability'] = __( 'In stock', 'yith-wcmp' );
266
  }
267
  $product->fields[$field] = sprintf( '<span class="%s">%s</span>', esc_attr( $availability['class'] ), esc_html( $availability['availability'] ) );
268
  break;
269
  default:
 
270
  if ( taxonomy_exists( $field ) ) {
271
  $product->fields[$field] = array();
272
  $terms = get_the_terms( $product_id, $field );
293
  /**
294
  * The URL of product comparison table
295
  *
296
+ * @param bool | int $product_id
297
  * @return string The url to add the product in the comparison table
298
  */
299
+ public function view_table_url( $product_id = false ) {
300
+ $url_args = array(
301
+ 'action' => $this->action_view,
302
+ 'iframe' => true
303
+ );
304
+ return apply_filters( 'yith_woocompare_view_table_url', esc_url_raw( add_query_arg( $url_args, site_url() ) ), $product_id );
305
  }
306
 
307
  /**
308
  * The URL to add the product into the comparison table
309
  *
310
+ * @param int $product_id ID of the product to add
311
  * @return string The url to add the product in the comparison table
312
  */
313
  public function add_product_url( $product_id ) {
315
  'action' => $this->action_add,
316
  'id' => $product_id
317
  );
318
+ return apply_filters( 'yith_woocompare_add_product_url', wp_nonce_url( esc_url_raw( add_query_arg( $url_args ) ), $this->action_add ) );
319
  }
320
 
321
  /**
329
  'action' => $this->action_remove,
330
  'id' => $product_id
331
  );
332
+ return apply_filters( 'yith_woocompare_remove_product_url', wp_nonce_url( esc_url_raw( add_query_arg( $url_args ) ), $this->action_remove ) );
333
  }
334
 
335
  /**
344
  }
345
 
346
  // return if product doesn't exist
347
+ if ( empty( $product_id ) || apply_filters( 'yith_woocompare_remove_compare_link_by_cat', false, $product_id ) )
348
+ return;
349
 
350
+ $is_button = ! isset( $button_or_link ) || ! $button_or_link ? get_option( 'yith_woocompare_is_button' ) : $button_or_link;
351
 
352
  if ( ! isset( $button_text ) || $button_text == 'default' ) {
353
+ $button_text = get_option( 'yith_woocompare_button_text', __( 'Compare', 'yith-wcmp' ) );
354
  $button_text = function_exists( 'icl_translate' ) ? icl_translate( 'Plugins', 'plugin_yit_compare_button_text', $button_text ) : $button_text;
355
  }
356
 
365
 
366
  $filename = 'compare.css';
367
 
368
+ $plugin_path = array( 'path' => YITH_WOOCOMPARE_DIR . '/assets/css/style.css', 'url' => YITH_WOOCOMPARE_ASSETS_URL . '/css/style.css' );
369
 
370
  if ( defined('WC_TEMPLATE_PATH') ) {
371
  $template_path = array( 'path' => get_template_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_template_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename );
372
  $child_path = array( 'path' => get_stylesheet_directory() . '/' . WC_TEMPLATE_PATH . $filename, 'url' => get_stylesheet_directory_uri() . '/' . WC_TEMPLATE_PATH . $filename );
373
+ }
374
+ else {
375
  $template_path = array( 'path' => get_template_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_template_directory_uri() . '/' . $woocommerce->template_url . $filename );
376
  $child_path = array( 'path' => get_stylesheet_directory() . '/' . $woocommerce->template_url . $filename, 'url' => get_stylesheet_directory_uri() . '/' . $woocommerce->template_url . $filename );
377
  }
378
+
379
  foreach ( array( 'child_path', 'template_path', 'plugin_path' ) as $var ) {
380
  if ( file_exists( ${$var}['path'] ) ) {
381
  return ${$var}['url'];
393
  */
394
  protected function _vars() {
395
  $vars = array(
396
+ 'products' => $this->get_products_list(),
397
+ 'fields' => $this->fields(),
398
+ 'repeat_price' => get_option( 'yith_woocompare_price_end' ),
399
  'repeat_add_to_cart' => get_option( 'yith_woocompare_add_to_cart_end' ),
400
  );
401
 
411
  ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_add ) )
412
  return;
413
 
414
+ $product_id = intval( $_REQUEST['id'] );
415
+ $product = $this->wc_get_product( $product_id );
416
 
417
+ // don't add the product if doesn't exist
418
+ if ( $product && ! $product->exists() && ! in_array( $product_id, $this->products_list ) ) {
419
+ $this->add_product_to_compare( $product_id );
420
+ }
421
+
422
+ wp_redirect( esc_url( remove_query_arg( array( 'id', 'action', '_wpnonce' ) ) ) );
423
  exit();
424
  }
425
 
429
  public function add_product_to_compare_ajax() {
430
  check_ajax_referer( $this->action_add, '_yitnonce_ajax' );
431
 
432
+ $product_id = intval( $_REQUEST['id'] );
433
+ $product = $this->wc_get_product( $product_id );
434
 
435
+ // don't add the product if doesn't exist
436
+ if ( $product && $product->exists() && ! in_array( $product_id, $this->products_list ) ) {
437
+ $this->add_product_to_compare( $product_id );
438
+ }
439
+
440
+ do_action( 'yith_woocompare_add_product_action_ajax' );
441
 
442
+ $json = array(
443
+ 'table_url' => $this->view_table_url( $product_id ),
444
+ 'widget_table' => $this->list_products_html()
445
  );
446
 
447
  echo json_encode( $json );
451
  /**
452
  * Add a product in the products comparison table
453
  *
454
+ * @param int $product_id product ID to add in the comparison table
455
  */
456
  public function add_product_to_compare( $product_id ) {
 
 
 
 
457
 
458
  $this->products_list[] = $product_id;
459
+ setcookie( $this->cookie_name, serialize( $this->products_list ), 0, COOKIEPATH, COOKIE_DOMAIN, false, true );
460
+
461
+ do_action( 'yith_woocompare_after_add_product', $product_id );
462
  }
463
 
464
  /**
470
  ( ! isset( $_REQUEST['action'] ) || $_REQUEST['action'] != $this->action_remove ) )
471
  return;
472
 
473
+ if ( $_REQUEST['id'] == 'all' ) {
474
+ $products = $this->products_list;
475
+ foreach ( $products as $product_id ) {
476
+ $this->remove_product_from_compare( intval( $product_id ) );
477
+ }
478
+ } else {
479
+ $this->remove_product_from_compare( intval( $_REQUEST['id'] ) );
480
+ }
481
 
482
  // redirect
483
+ $redirect = esc_url( remove_query_arg( array( 'id', 'action', '_wpnonce' ) ) );
484
+
485
+ if ( isset( $_REQUEST['redirect'] ) && $_REQUEST['redirect'] == 'view' )
486
+ $redirect = esc_url( remove_query_arg( 'redirect', add_query_arg( 'action', $this->action_view, $redirect ) ) );
487
+
488
+ wp_redirect( $redirect );
489
  exit();
490
  }
491
 
508
  $this->remove_product_from_compare( intval( $_REQUEST['id'] ) );
509
  }
510
 
511
+ do_action( 'yith_woocompare_remove_product_action_ajax' );
512
+
513
  header('Content-Type: text/html; charset=utf-8');
514
 
515
  if ( isset( $_REQUEST['responseType'] ) && $_REQUEST['responseType'] == 'product_list' ) {
545
  }
546
 
547
  if ( empty( $this->products_list ) ) {
548
+ echo '<li>' . __( 'No products to compare', 'yith-wcmp' ) . '</li>';
549
  return ob_get_clean();
550
  }
551
 
552
  foreach ( $this->products_list as $product_id ) {
553
  $product = $this->wc_get_product( $product_id );
554
+ if ( ! $product )
555
+ continue;
556
  ?>
557
  <li>
558
  <a class="title" href="<?php echo get_permalink( $product_id ) ?>"><?php echo $product->get_title() ?></a>
559
+ <a href="<?php echo $this->remove_product_url( $product_id ) ?>" data-product_id="<?php echo $product_id; ?>" class="remove" title="<?php _e( 'Remove', 'yith-wcmp' ) ?>">x</a>
560
  </li>
561
  <?php
562
  }
570
  * @param $product_id The product ID to remove from the comparison table
571
  */
572
  public function remove_product_from_compare( $product_id ) {
 
 
 
 
 
 
573
  foreach ( $this->products_list as $k => $id ) {
574
  if ( $product_id == $id ) unset( $this->products_list[$k] );
575
  }
576
+ setcookie( $this->cookie_name, serialize( $this->products_list ), 0, COOKIEPATH, COOKIE_DOMAIN, false, true );
577
+
578
+ do_action( 'yith_woocompare_after_remove_product', $product_id );
579
  }
580
 
581
  /**
class.yith-woocompare-helper.php → includes/class.yith-woocompare-helper.php RENAMED
@@ -24,6 +24,11 @@ if( !class_exists( 'YITH_Woocompare_Helper' ) ) {
24
  */
25
  public static function set_image_size() {
26
  $size = get_option( 'yith_woocompare_image_size' );
 
 
 
 
 
27
  $size['crop'] = isset( $size['crop'] ) ? true : false;
28
  add_image_size( 'yith-woocompare-image', $size['width'], $size['height'], $size['crop'] );
29
  }
@@ -34,15 +39,21 @@ if( !class_exists( 'YITH_Woocompare_Helper' ) ) {
34
  * @since 1.0.0
35
  * @access public
36
  */
37
- public static function standard_fields() {
38
- return array(
39
- 'image' => __('Image', 'yit'),
40
- 'title' => __('Title', 'yit'),
41
- 'price' => __('Price', 'yit'),
42
- 'add-to-cart' => __('Add to cart', 'yit'),
43
- 'description' => __('Description', 'yit'),
44
- 'stock' => __( 'Availability', 'yit' )
 
45
  );
 
 
 
 
 
46
  }
47
 
48
  /*
@@ -58,20 +69,21 @@ if( !class_exists( 'YITH_Woocompare_Helper' ) ) {
58
 
59
  $attributes = array();
60
 
61
-
62
-
63
  if( function_exists( 'wc_get_attribute_taxonomies' ) && function_exists( 'wc_attribute_taxonomy_name' ) ) {
64
  $attribute_taxonomies = wc_get_attribute_taxonomies();
65
- if( empty( $attribute_taxonomies ) ) return array();
 
66
  foreach( $attribute_taxonomies as $attribute ) {
67
  $tax = wc_attribute_taxonomy_name( $attribute->attribute_name );
68
  if ( taxonomy_exists( $tax ) ) {
69
  $attributes[$tax] = ucfirst( $attribute->attribute_name );
70
  }
71
  }
72
- }else{
 
73
  $attribute_taxonomies = $woocommerce->get_attribute_taxonomies();
74
- if( empty( $attribute_taxonomies ) ) return array();
 
75
  foreach( $attribute_taxonomies as $attribute ) {
76
  $tax = $woocommerce->attribute_taxonomy_name( $attribute->attribute_name );
77
  if ( taxonomy_exists( $tax ) ) {
24
  */
25
  public static function set_image_size() {
26
  $size = get_option( 'yith_woocompare_image_size' );
27
+
28
+ if( ! $size ) {
29
+ return;
30
+ }
31
+
32
  $size['crop'] = isset( $size['crop'] ) ? true : false;
33
  add_image_size( 'yith-woocompare-image', $size['width'], $size['height'], $size['crop'] );
34
  }
39
  * @since 1.0.0
40
  * @access public
41
  */
42
+ public static function standard_fields( $with_attr = true ) {
43
+
44
+ $fields = array(
45
+ 'image' => __( 'Image', 'yith-wcmp' ),
46
+ 'title' => __( 'Title', 'yith-wcmp' ),
47
+ 'price' => __( 'Price', 'yith-wcmp' ),
48
+ 'add-to-cart' => __( 'Add to cart', 'yith-wcmp' ),
49
+ 'description' => __( 'Description', 'yith-wcmp' ),
50
+ 'stock' => __( 'Availability', 'yith-wcmp' )
51
  );
52
+
53
+ if( $with_attr )
54
+ $fields = array_merge( $fields, YITH_Woocompare_Helper::attribute_taxonomies() );
55
+
56
+ return $fields;
57
  }
58
 
59
  /*
69
 
70
  $attributes = array();
71
 
 
 
72
  if( function_exists( 'wc_get_attribute_taxonomies' ) && function_exists( 'wc_attribute_taxonomy_name' ) ) {
73
  $attribute_taxonomies = wc_get_attribute_taxonomies();
74
+ if( empty( $attribute_taxonomies ) )
75
+ return array();
76
  foreach( $attribute_taxonomies as $attribute ) {
77
  $tax = wc_attribute_taxonomy_name( $attribute->attribute_name );
78
  if ( taxonomy_exists( $tax ) ) {
79
  $attributes[$tax] = ucfirst( $attribute->attribute_name );
80
  }
81
  }
82
+ }
83
+ else{
84
  $attribute_taxonomies = $woocommerce->get_attribute_taxonomies();
85
+ if( empty( $attribute_taxonomies ) )
86
+ return array();
87
  foreach( $attribute_taxonomies as $attribute ) {
88
  $tax = $woocommerce->attribute_taxonomy_name( $attribute->attribute_name );
89
  if ( taxonomy_exists( $tax ) ) {
class.yith-woocompare.php → includes/class.yith-woocompare.php RENAMED
@@ -42,6 +42,9 @@ if( !class_exists( 'YITH_Woocompare' ) ) {
42
  public function __construct() {
43
  add_action( 'widgets_init', array( $this, 'registerWidgets' ) );
44
 
 
 
 
45
  if( $this->is_frontend() ) {
46
  $this->obj = new YITH_Woocompare_Frontend();
47
  } elseif( $this->is_admin() ) {
@@ -69,6 +72,21 @@ if( !class_exists( 'YITH_Woocompare' ) ) {
69
  return (bool) ( is_admin() || $is_ajax && isset( $_REQUEST['context'] ) && $_REQUEST['context'] == 'admin' );
70
  }
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  /**
74
  * Load and register widgets
@@ -79,5 +97,6 @@ if( !class_exists( 'YITH_Woocompare' ) ) {
79
  public function registerWidgets() {
80
  register_widget( 'YITH_Woocompare_Widget' );
81
  }
 
82
  }
83
  }
42
  public function __construct() {
43
  add_action( 'widgets_init', array( $this, 'registerWidgets' ) );
44
 
45
+ // Load Plugin Framework
46
+ add_action( 'after_setup_theme', array( $this, 'plugin_fw_loader' ), 1 );
47
+
48
  if( $this->is_frontend() ) {
49
  $this->obj = new YITH_Woocompare_Frontend();
50
  } elseif( $this->is_admin() ) {
72
  return (bool) ( is_admin() || $is_ajax && isset( $_REQUEST['context'] ) && $_REQUEST['context'] == 'admin' );
73
  }
74
 
75
+ /**
76
+ * Load Plugin Framework
77
+ *
78
+ * @since 1.0
79
+ * @access public
80
+ * @return void
81
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
82
+ */
83
+ public function plugin_fw_loader() {
84
+
85
+ if ( ! defined( 'YIT' ) || ! defined( 'YIT_CORE_PLUGIN' ) ) {
86
+ require_once( YITH_WOOCOMPARE_DIR . 'plugin-fw/yit-plugin.php' );
87
+ }
88
+
89
+ }
90
 
91
  /**
92
  * Load and register widgets
97
  public function registerWidgets() {
98
  register_widget( 'YITH_Woocompare_Widget' );
99
  }
100
+
101
  }
102
  }
functions.yith-woocompare.php → includes/functions.yith-woocompare.php RENAMED
File without changes
init.php CHANGED
@@ -1,17 +1,17 @@
1
  <?php
2
  /**
3
- * Plugin Name: YITH Woocommerce Compare
4
- * Plugin URI: http://yithemes.com/
5
- * Description: YITH Woocommerce Compare allows you to compare more products with woocommerce plugin, through product attributes.
6
- * Version: 1.2.3
7
- * Author: Your Inspiration Themes
8
  * Author URI: http://yithemes.com/
9
- * Text Domain: yit
10
  * Domain Path: /languages/
11
  *
12
- * @author Your Inspiration Themes
13
- * @package YITH Woocommerce Compare
14
- * @version 1.1.4
15
  */
16
  /* Copyright 2013 Your Inspiration Themes (email : plugins@yithemes.com)
17
 
@@ -30,32 +30,86 @@
30
  */
31
  if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
32
 
33
- /* Include common functions */
34
- if( !defined('YITH_FUNCTIONS') ) {
35
- require_once( 'yit-common/yit-functions.php' );
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  function yith_woocompare_constructor() {
39
- global $woocommerce;
40
- if ( ! isset( $woocommerce ) ) return;
41
 
42
- load_plugin_textdomain( 'yit', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
 
 
 
 
 
 
 
 
 
 
43
 
44
- define( 'YITH_WOOCOMPARE', true );
45
- define( 'YITH_WOOCOMPARE_VERSION', '1.2.3' );
46
- define( 'YITH_WOOCOMPARE_URL', plugin_dir_url( __FILE__ ) );
47
- define( 'YITH_WOOCOMPARE_DIR', plugin_dir_path( __FILE__ ) );
48
 
49
  // Load required classes and functions
50
- require_once('class.yith-woocompare-helper.php');
51
- require_once('functions.yith-woocompare.php');
52
- require_once('class.yith-woocompare-admin.php');
53
- require_once('class.yith-woocompare-frontend.php');
54
  require_once('widgets/class.yith-woocompare-widget.php');
55
- require_once('class.yith-woocompare.php');
56
 
57
  // Let's start the game!
58
  global $yith_woocompare;
59
  $yith_woocompare = new YITH_Woocompare();
60
  }
61
- add_action( 'plugins_loaded', 'yith_woocompare_constructor' );
1
  <?php
2
  /**
3
+ * Plugin Name: YITH WooCommerce Compare
4
+ * Plugin URI: https://yithemes.com/
5
+ * Description: YITH WooCommerce Compare allows you to compare more products with WooCommerce plugin, through product attributes.
6
+ * Version: 2.0.0
7
+ * Author: Yithemes
8
  * Author URI: http://yithemes.com/
9
+ * Text Domain: yith-wcmp
10
  * Domain Path: /languages/
11
  *
12
+ * @author Yithemes
13
+ * @package YITH WooCommerce Compare
14
+ * @version 2.0.0
15
  */
16
  /* Copyright 2013 Your Inspiration Themes (email : plugins@yithemes.com)
17
 
30
  */
31
  if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
32
 
33
+ if ( ! function_exists( 'is_plugin_active' ) ) {
34
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 
35
  }
36
 
37
+ function yith_woocompare_install_woocommerce_admin_notice() {
38
+ ?>
39
+ <div class="error">
40
+ <p><?php _e( 'YITH WooCommerce Compare is enabled but not effective. It requires WooCommerce in order to work.', 'yith-wcmp' ); ?></p>
41
+ </div>
42
+ <?php
43
+ }
44
+
45
+ function yith_woocompare_install_free_admin_notice() {
46
+ ?>
47
+ <div class="error">
48
+ <p><?php _e( 'You can\'t activate the free version of YITH WooCommerce Compare while you are using the premium one.', 'yith-wcmp' ); ?></p>
49
+ </div>
50
+ <?php
51
+ }
52
+
53
+ if ( ! function_exists( 'yith_plugin_registration_hook' ) ) {
54
+ require_once 'plugin-fw/yit-plugin-registration-hook.php';
55
+ }
56
+ register_activation_hook( __FILE__, 'yith_plugin_registration_hook' );
57
+
58
+ if ( ! defined( 'YITH_WOOCOMPARE_VERSION' ) ){
59
+ define( 'YITH_WOOCOMPARE_VERSION', '2.0.0' );
60
+ }
61
+ if ( ! defined( 'YITH_WOOCOMPARE_FREE_INIT' ) ) {
62
+ define( 'YITH_WOOCOMPARE_FREE_INIT', plugin_basename( __FILE__ ) );
63
+ }
64
+ if ( ! defined( 'YITH_WOOCOMPARE_INIT' ) ) {
65
+ define( 'YITH_WOOCOMPARE_INIT', plugin_basename( __FILE__ ) );
66
+ }
67
+ if ( ! defined( 'YITH_WOOCOMPARE' ) ) {
68
+ define( 'YITH_WOOCOMPARE', true );
69
+ }
70
+ if ( ! defined( 'YITH_WOOCOMPARE_FILE' ) ) {
71
+ define( 'YITH_WOOCOMPARE_FILE', __FILE__ );
72
+ }
73
+ if ( ! defined( 'YITH_WOOCOMPARE_URL' ) ) {
74
+ define( 'YITH_WOOCOMPARE_URL', plugin_dir_url( __FILE__ ) );
75
+ }
76
+ if ( ! defined( 'YITH_WOOCOMPARE_DIR' ) ) {
77
+ define( 'YITH_WOOCOMPARE_DIR', plugin_dir_path( __FILE__ ) );
78
+ }
79
+ if ( ! defined( 'YITH_WOOCOMPARE_TEMPLATE_PATH' ) ) {
80
+ define( 'YITH_WOOCOMPARE_TEMPLATE_PATH', YITH_WOOCOMPARE_DIR . 'templates' );
81
+ }
82
+ if ( ! defined( 'YITH_WOOCOMPARE_ASSETS_URL' ) ) {
83
+ define( 'YITH_WOOCOMPARE_ASSETS_URL', YITH_WOOCOMPARE_URL . 'assets' );
84
+ }
85
+
86
+
87
  function yith_woocompare_constructor() {
 
 
88
 
89
+ global $woocommerce;
90
+
91
+ if ( ! isset( $woocommerce ) || ! function_exists( 'WC' ) ) {
92
+ add_action( 'admin_notices', 'yith_woocompare_install_woocommerce_admin_notice' );
93
+ return;
94
+ }
95
+ elseif ( defined( 'YITH_WOOCOMPARE_PREMIUM' ) ) {
96
+ add_action( 'admin_notices', 'yith_woocompare_install_free_admin_notice' );
97
+ deactivate_plugins( plugin_basename( __FILE__ ) );
98
+ return;
99
+ }
100
 
101
+ load_plugin_textdomain( 'yith-wcmp', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
 
 
 
102
 
103
  // Load required classes and functions
104
+ require_once('includes/class.yith-woocompare-helper.php');
105
+ require_once('includes/functions.yith-woocompare.php');
106
+ require_once('includes/class.yith-woocompare-admin.php');
107
+ require_once('includes/class.yith-woocompare-frontend.php');
108
  require_once('widgets/class.yith-woocompare-widget.php');
109
+ require_once('includes/class.yith-woocompare.php');
110
 
111
  // Let's start the game!
112
  global $yith_woocompare;
113
  $yith_woocompare = new YITH_Woocompare();
114
  }
115
+ add_action( 'plugins_loaded', 'yith_woocompare_constructor', 11 );
languages/default.po DELETED
@@ -1,248 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-12-03 12:49+0100\n"
5
- "PO-Revision-Date: 2014-12-03 12:49+0100\n"
6
- "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:130
18
- msgid "Products Compare"
19
- msgstr ""
20
-
21
- #: ../class.yith-woocompare-admin.php:144 ../yith-woocompare-options.php:24
22
- msgid "General Settings"
23
- msgstr ""
24
-
25
- #: ../class.yith-woocompare-admin.php:375
26
- msgid "Hard Crop?"
27
- msgstr ""
28
-
29
- #: ../class.yith-woocompare-frontend.php:142
30
- msgid "Added"
31
- msgstr ""
32
-
33
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:51
34
- msgid "Product Comparison"
35
- msgstr ""
36
-
37
- #: ../class.yith-woocompare-frontend.php:254
38
- msgid "In stock"
39
- msgstr ""
40
-
41
- #: ../class.yith-woocompare-frontend.php:338 ../yith-woocompare-options.php:47
42
- #: ../widgets/class.yith-woocompare-widget.php:45
43
- msgid "Compare"
44
- msgstr ""
45
-
46
- #: ../class.yith-woocompare-frontend.php:512
47
- msgid "No products to compare"
48
- msgstr ""
49
-
50
- #: ../class.yith-woocompare-frontend.php:522 ../templates/compare.php:109
51
- msgid "Remove"
52
- msgstr ""
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- msgid "Image"
56
- msgstr ""
57
-
58
- #: ../class.yith-woocompare-helper.php:40
59
- #: ../widgets/class.yith-woocompare-widget.php:62
60
- msgid "Title"
61
- msgstr ""
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Price"
65
- msgstr ""
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Add to cart"
69
- msgstr ""
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Description"
73
- msgstr ""
74
-
75
- #: ../class.yith-woocompare-helper.php:44
76
- msgid "Availability"
77
- msgstr ""
78
-
79
- #: ../yith-woocompare-options.php:31
80
- msgid "Link or Button"
81
- msgstr ""
82
-
83
- #: ../yith-woocompare-options.php:32
84
- msgid "Choose if you want to use a link or a button for the action button."
85
- msgstr ""
86
-
87
- #: ../yith-woocompare-options.php:38
88
- msgid "Link"
89
- msgstr ""
90
-
91
- #: ../yith-woocompare-options.php:39
92
- msgid "Button"
93
- msgstr ""
94
-
95
- #: ../yith-woocompare-options.php:44
96
- msgid "Link/Button text"
97
- msgstr ""
98
-
99
- #: ../yith-woocompare-options.php:45
100
- msgid "Type the text to use for the button or the link of the compare."
101
- msgstr ""
102
-
103
- #: ../yith-woocompare-options.php:52
104
- msgid "Show button in single product page"
105
- msgstr ""
106
-
107
- #: ../yith-woocompare-options.php:53
108
- msgid "Say if you want to show the button in the single product page."
109
- msgstr ""
110
-
111
- #: ../yith-woocompare-options.php:61
112
- msgid "Show button in products list"
113
- msgstr ""
114
-
115
- #: ../yith-woocompare-options.php:62
116
- msgid "Say if you want to show the button in the products list."
117
- msgstr ""
118
-
119
- #: ../yith-woocompare-options.php:70
120
- msgid "Open automatically lightbox"
121
- msgstr ""
122
-
123
- #: ../yith-woocompare-options.php:71
124
- msgid "Open link after click into \"Compare\" button\"."
125
- msgstr ""
126
-
127
- #: ../yith-woocompare-options.php:83
128
- msgid "Table Settings"
129
- msgstr ""
130
-
131
- #: ../yith-woocompare-options.php:90
132
- msgid "Table title"
133
- msgstr ""
134
-
135
- #: ../yith-woocompare-options.php:91
136
- msgid "Type the text to use for the table title."
137
- msgstr ""
138
-
139
- #: ../yith-woocompare-options.php:93
140
- msgid "Compare products"
141
- msgstr ""
142
-
143
- #: ../yith-woocompare-options.php:98
144
- msgid "Fields to show"
145
- msgstr ""
146
-
147
- #: ../yith-woocompare-options.php:99 ../yith-woocompare-options.php:108
148
- #: ../yith-woocompare-options.php:117
149
- msgid ""
150
- "Select the fields to show in the comparison table and order them by "
151
- "drag&drop (are included also the woocommerce attributes)"
152
- msgstr ""
153
-
154
- #: ../yith-woocompare-options.php:107
155
- msgid "Repeat \"Price\" field at the end of the table"
156
- msgstr ""
157
-
158
- #: ../yith-woocompare-options.php:116
159
- msgid "Repeat \"Add to cart\" field at the end of the table"
160
- msgstr ""
161
-
162
- #: ../yith-woocompare-options.php:125
163
- msgid "Image size"
164
- msgstr ""
165
-
166
- #: ../yith-woocompare-options.php:126
167
- msgid "Set the size for the images"
168
- msgstr ""
169
-
170
- #: ../templates/compare.php:76
171
- msgid "Close window [X]"
172
- msgstr ""
173
-
174
- #: ../templates/compare.php:101
175
- msgid "No products added in the compare table."
176
- msgstr ""
177
-
178
- #: ../widgets/class.yith-woocompare-widget.php:21
179
- msgid "The widget show the list of products added in the compare table."
180
- msgstr ""
181
-
182
- #: ../widgets/class.yith-woocompare-widget.php:22
183
- msgid "YITH Woocommerce Compare Widget"
184
- msgstr ""
185
-
186
- #: ../widgets/class.yith-woocompare-widget.php:44
187
- msgid "Clear all"
188
- msgstr ""
189
-
190
- #: ../yit-common/yith-panel.php:406
191
- msgid "Select a date"
192
- msgstr ""
193
-
194
- #: ../yit-common/yith-panel.php:407
195
- msgid "Hours"
196
- msgstr ""
197
-
198
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
199
- msgid "Minutes"
200
- msgstr ""
201
-
202
- #: ../yit-common/yith-panel.php:417
203
- msgid "Upload"
204
- msgstr ""
205
-
206
- #: ../yit-common/yith-panel.php:444
207
- msgid "px"
208
- msgstr ""
209
-
210
- #: ../yit-common/yith-panel.php:445
211
- msgid "em"
212
- msgstr ""
213
-
214
- #: ../yit-common/yith-panel.php:446
215
- msgid "pt"
216
- msgstr ""
217
-
218
- #: ../yit-common/yith-panel.php:447
219
- msgid "rem"
220
- msgstr ""
221
-
222
- #: ../yit-common/yith-panel.php:457
223
- msgid "Select a font family"
224
- msgstr ""
225
-
226
- #: ../yit-common/yith-panel.php:465
227
- msgid "Regular"
228
- msgstr ""
229
-
230
- #: ../yit-common/yith-panel.php:466
231
- msgid "Bold"
232
- msgstr ""
233
-
234
- #: ../yit-common/yith-panel.php:467
235
- msgid "Extra bold"
236
- msgstr ""
237
-
238
- #: ../yit-common/yith-panel.php:468
239
- msgid "Italic"
240
- msgstr ""
241
-
242
- #: ../yit-common/yith-panel.php:469
243
- msgid "Italic bold"
244
- msgstr ""
245
-
246
- #: ../yit-common/yith-panel.php:481
247
- msgid "Click to preview"
248
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-bg_BG.mo DELETED
Binary file
languages/yit-bg_BG.po DELETED
@@ -1,248 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2015-02-13 12:10+0100\n"
5
- "PO-Revision-Date: 2015-02-13 12:10+0100\n"
6
- "Last-Translator: \n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: en\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:130
18
- msgid "Products Compare"
19
- msgstr "Сравнение на продуктите"
20
-
21
- #: ../class.yith-woocompare-admin.php:144 ../yith-woocompare-options.php:24
22
- msgid "General Settings"
23
- msgstr "Общи настройки"
24
-
25
- #: ../class.yith-woocompare-admin.php:375
26
- msgid "Hard Crop?"
27
- msgstr ""
28
-
29
- #: ../class.yith-woocompare-frontend.php:142
30
- msgid "Added"
31
- msgstr "Добавено"
32
-
33
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:51
34
- msgid "Product Comparison"
35
- msgstr "Сравнение на продуктите"
36
-
37
- #: ../class.yith-woocompare-frontend.php:254
38
- msgid "In stock"
39
- msgstr "В наличност"
40
-
41
- #: ../class.yith-woocompare-frontend.php:338 ../yith-woocompare-options.php:47
42
- #: ../widgets/class.yith-woocompare-widget.php:45
43
- msgid "Compare"
44
- msgstr "Сравни"
45
-
46
- #: ../class.yith-woocompare-frontend.php:512
47
- msgid "No products to compare"
48
- msgstr "В момента нямате продукти за сравнение"
49
-
50
- #: ../class.yith-woocompare-frontend.php:522 ../templates/compare.php:109
51
- msgid "Remove"
52
- msgstr "Премахни"
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- msgid "Image"
56
- msgstr "Снимка"
57
-
58
- #: ../class.yith-woocompare-helper.php:40
59
- #: ../widgets/class.yith-woocompare-widget.php:62
60
- msgid "Title"
61
- msgstr "Заглавие"
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Price"
65
- msgstr "Цена"
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Add to cart"
69
- msgstr "КУПИ"
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Description"
73
- msgstr "Описание"
74
-
75
- #: ../class.yith-woocompare-helper.php:44
76
- msgid "Availability"
77
- msgstr "Достъпност"
78
-
79
- #: ../yith-woocompare-options.php:31
80
- msgid "Link or Button"
81
- msgstr "Свържи към бутона"
82
-
83
- #: ../yith-woocompare-options.php:32
84
- msgid "Choose if you want to use a link or a button for the action button."
85
- msgstr "Изберете дали искате да използвате линк или бутон"
86
-
87
- #: ../yith-woocompare-options.php:38
88
- msgid "Link"
89
- msgstr "Линк"
90
-
91
- #: ../yith-woocompare-options.php:39
92
- msgid "Button"
93
- msgstr "Бутон"
94
-
95
- #: ../yith-woocompare-options.php:44
96
- msgid "Link/Button text"
97
- msgstr "Текст на Линка/Бутона"
98
-
99
- #: ../yith-woocompare-options.php:45
100
- msgid "Type the text to use for the button or the link of the compare."
101
- msgstr "Напишете текста, който искате да използвате за линка или бутона"
102
-
103
- #: ../yith-woocompare-options.php:52
104
- msgid "Show button in single product page"
105
- msgstr "Покажете бутона на страницата на продукта"
106
-
107
- #: ../yith-woocompare-options.php:53
108
- msgid "Say if you want to show the button in the single product page."
109
- msgstr ""
110
-
111
- #: ../yith-woocompare-options.php:61
112
- msgid "Show button in products list"
113
- msgstr "Покажете бутона в каталога "
114
-
115
- #: ../yith-woocompare-options.php:62
116
- msgid "Say if you want to show the button in the products list."
117
- msgstr ""
118
-
119
- #: ../yith-woocompare-options.php:70
120
- msgid "Open automatically lightbox"
121
- msgstr ""
122
-
123
- #: ../yith-woocompare-options.php:71
124
- msgid "Open link after click into \"Compare\" button\"."
125
- msgstr ""
126
-
127
- #: ../yith-woocompare-options.php:83
128
- msgid "Table Settings"
129
- msgstr "Настройки на таблицата"
130
-
131
- #: ../yith-woocompare-options.php:90
132
- msgid "Table title"
133
- msgstr "Заглавие на таблицата"
134
-
135
- #: ../yith-woocompare-options.php:91
136
- msgid "Type the text to use for the table title."
137
- msgstr ""
138
-
139
- #: ../yith-woocompare-options.php:93
140
- msgid "Compare products"
141
- msgstr "Сравнете продуктите си"
142
-
143
- #: ../yith-woocompare-options.php:98
144
- msgid "Fields to show"
145
- msgstr ""
146
-
147
- #: ../yith-woocompare-options.php:99 ../yith-woocompare-options.php:108
148
- #: ../yith-woocompare-options.php:117
149
- msgid ""
150
- "Select the fields to show in the comparison table and order them by "
151
- "drag&drop (are included also the woocommerce attributes)"
152
- msgstr ""
153
-
154
- #: ../yith-woocompare-options.php:107
155
- msgid "Repeat \"Price\" field at the end of the table"
156
- msgstr ""
157
-
158
- #: ../yith-woocompare-options.php:116
159
- msgid "Repeat \"Add to cart\" field at the end of the table"
160
- msgstr ""
161
-
162
- #: ../yith-woocompare-options.php:125
163
- msgid "Image size"
164
- msgstr "Размер на изображението"
165
-
166
- #: ../yith-woocompare-options.php:126
167
- msgid "Set the size for the images"
168
- msgstr ""
169
-
170
- #: ../templates/compare.php:76
171
- msgid "Close window [X]"
172
- msgstr "Затвори"
173
-
174
- #: ../templates/compare.php:101
175
- msgid "No products added in the compare table."
176
- msgstr "Няма добавени продукти за сравнение."
177
-
178
- #: ../widgets/class.yith-woocompare-widget.php:21
179
- msgid "The widget show the list of products added in the compare table."
180
- msgstr ""
181
-
182
- #: ../widgets/class.yith-woocompare-widget.php:22
183
- msgid "YITH Woocommerce Compare Widget"
184
- msgstr ""
185
-
186
- #: ../widgets/class.yith-woocompare-widget.php:44
187
- msgid "Clear all"
188
- msgstr "Изтрий всички"
189
-
190
- #: ../yit-common/yith-panel.php:406
191
- msgid "Select a date"
192
- msgstr "Избери дата"
193
-
194
- #: ../yit-common/yith-panel.php:407
195
- msgid "Hours"
196
- msgstr "Часове"
197
-
198
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
199
- msgid "Minutes"
200
- msgstr "Минути"
201
-
202
- #: ../yit-common/yith-panel.php:417
203
- msgid "Upload"
204
- msgstr "Качи съдържание"
205
-
206
- #: ../yit-common/yith-panel.php:444
207
- msgid "px"
208
- msgstr ""
209
-
210
- #: ../yit-common/yith-panel.php:445
211
- msgid "em"
212
- msgstr ""
213
-
214
- #: ../yit-common/yith-panel.php:446
215
- msgid "pt"
216
- msgstr ""
217
-
218
- #: ../yit-common/yith-panel.php:447
219
- msgid "rem"
220
- msgstr ""
221
-
222
- #: ../yit-common/yith-panel.php:457
223
- msgid "Select a font family"
224
- msgstr "Изберете шрифт"
225
-
226
- #: ../yit-common/yith-panel.php:465
227
- msgid "Regular"
228
- msgstr ""
229
-
230
- #: ../yit-common/yith-panel.php:466
231
- msgid "Bold"
232
- msgstr ""
233
-
234
- #: ../yit-common/yith-panel.php:467
235
- msgid "Extra bold"
236
- msgstr ""
237
-
238
- #: ../yit-common/yith-panel.php:468
239
- msgid "Italic"
240
- msgstr ""
241
-
242
- #: ../yit-common/yith-panel.php:469
243
- msgid "Italic bold"
244
- msgstr ""
245
-
246
- #: ../yit-common/yith-panel.php:481
247
- msgid "Click to preview"
248
- msgstr "Предварителен преглед"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-es_ES.mo DELETED
Binary file
languages/yit-es_ES.po DELETED
@@ -1,255 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2015-02-13 12:14+0100\n"
5
- "PO-Revision-Date: 2015-02-13 12:19+0100\n"
6
- "Last-Translator: Radi Angelov <fullmetalradi@hotmail.com>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: es_ES\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
- "X-Poedit-SearchPath-0: ..\n"
17
-
18
- #: ../class.yith-woocompare-admin.php:130
19
- msgid "Products Compare"
20
- msgstr "Comparador de productos"
21
-
22
- #: ../class.yith-woocompare-admin.php:144 ../yith-woocompare-options.php:24
23
- msgid "General Settings"
24
- msgstr "Obciones generales"
25
-
26
- #: ../class.yith-woocompare-admin.php:375
27
- msgid "Hard Crop?"
28
- msgstr "Hard Crop?"
29
-
30
- #: ../class.yith-woocompare-frontend.php:142
31
- msgid "Added"
32
- msgstr "Añadido"
33
-
34
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:51
35
- msgid "Product Comparison"
36
- msgstr "Comparacion de producto"
37
-
38
- #: ../class.yith-woocompare-frontend.php:254
39
- msgid "In stock"
40
- msgstr "En stock"
41
-
42
- #: ../class.yith-woocompare-frontend.php:338 ../yith-woocompare-options.php:47
43
- #: ../widgets/class.yith-woocompare-widget.php:45
44
- msgid "Compare"
45
- msgstr "Comparar"
46
-
47
- #: ../class.yith-woocompare-frontend.php:512
48
- msgid "No products to compare"
49
- msgstr "Comparador de productos vacio"
50
-
51
- #: ../class.yith-woocompare-frontend.php:522 ../templates/compare.php:109
52
- msgid "Remove"
53
- msgstr "Eliminar"
54
-
55
- #: ../class.yith-woocompare-helper.php:39
56
- msgid "Image"
57
- msgstr "Imagen"
58
-
59
- #: ../class.yith-woocompare-helper.php:40
60
- #: ../widgets/class.yith-woocompare-widget.php:62
61
- msgid "Title"
62
- msgstr "Titulo"
63
-
64
- #: ../class.yith-woocompare-helper.php:41
65
- msgid "Price"
66
- msgstr "Precio"
67
-
68
- #: ../class.yith-woocompare-helper.php:42
69
- msgid "Add to cart"
70
- msgstr "Añadir al carrito"
71
-
72
- #: ../class.yith-woocompare-helper.php:43
73
- msgid "Description"
74
- msgstr "Descripcion"
75
-
76
- #: ../class.yith-woocompare-helper.php:44
77
- msgid "Availability"
78
- msgstr "Disponibilidad"
79
-
80
- #: ../yith-woocompare-options.php:31
81
- msgid "Link or Button"
82
- msgstr "Link o Boton"
83
-
84
- #: ../yith-woocompare-options.php:32
85
- msgid "Choose if you want to use a link or a button for the action button."
86
- msgstr "Elige si deseas usar boton o link"
87
-
88
- #: ../yith-woocompare-options.php:38
89
- msgid "Link"
90
- msgstr "Enlace"
91
-
92
- #: ../yith-woocompare-options.php:39
93
- msgid "Button"
94
- msgstr "Boton"
95
-
96
- #: ../yith-woocompare-options.php:44
97
- msgid "Link/Button text"
98
- msgstr "Texto del boton/link"
99
-
100
- #: ../yith-woocompare-options.php:45
101
- msgid "Type the text to use for the button or the link of the compare."
102
- msgstr "Escribe el texto del boton/link comparar."
103
-
104
- #: ../yith-woocompare-options.php:52
105
- msgid "Show button in single product page"
106
- msgstr "Mostrar boton en pagina de producto individual"
107
-
108
- #: ../yith-woocompare-options.php:53
109
- msgid "Say if you want to show the button in the single product page."
110
- msgstr ""
111
- "¿Quieres mostrar el boton de comparar en la pagina individual de cada "
112
- "producto?"
113
-
114
- #: ../yith-woocompare-options.php:61
115
- msgid "Show button in products list"
116
- msgstr "Mostrar boton en la lista de productos"
117
-
118
- #: ../yith-woocompare-options.php:62
119
- msgid "Say if you want to show the button in the products list."
120
- msgstr "¿Quieres mostrar el boton de comparar en la lista de productos?"
121
-
122
- #: ../yith-woocompare-options.php:70
123
- msgid "Open automatically lightbox"
124
- msgstr "Abrir lightbox (mensaje emergente) automaticamente"
125
-
126
- #: ../yith-woocompare-options.php:71
127
- msgid "Open link after click into \"Compare\" button\"."
128
- msgstr "Abrir link despues de hacer click en \"Comparar\""
129
-
130
- #: ../yith-woocompare-options.php:83
131
- msgid "Table Settings"
132
- msgstr "Opciones de tabla"
133
-
134
- #: ../yith-woocompare-options.php:90
135
- msgid "Table title"
136
- msgstr "Titulo de tabla"
137
-
138
- #: ../yith-woocompare-options.php:91
139
- msgid "Type the text to use for the table title."
140
- msgstr "Escribe el texto del boton/link comparar."
141
-
142
- #: ../yith-woocompare-options.php:93
143
- msgid "Compare products"
144
- msgstr "Comparador de productos"
145
-
146
- #: ../yith-woocompare-options.php:98
147
- msgid "Fields to show"
148
- msgstr "Mostrar boton en la lista de productos"
149
-
150
- #: ../yith-woocompare-options.php:99 ../yith-woocompare-options.php:108
151
- #: ../yith-woocompare-options.php:117
152
- msgid ""
153
- "Select the fields to show in the comparison table and order them by "
154
- "drag&drop (are included also the woocommerce attributes)"
155
- msgstr ""
156
- "Elige que campos quieres mostrar en la tabla del comparador y ordenalos "
157
- "simplemente arrastrandolos (estan incluidos los atributos de productos de "
158
- "woocommerce)"
159
-
160
- #: ../yith-woocompare-options.php:107
161
- msgid "Repeat \"Price\" field at the end of the table"
162
- msgstr "Repetir campo \"Precio\" al final de la tabla"
163
-
164
- #: ../yith-woocompare-options.php:116
165
- msgid "Repeat \"Add to cart\" field at the end of the table"
166
- msgstr "Repetir campo \"Añadir al carrito\" al final de la tabla"
167
-
168
- #: ../yith-woocompare-options.php:125
169
- msgid "Image size"
170
- msgstr "Imagen"
171
-
172
- #: ../yith-woocompare-options.php:126
173
- msgid "Set the size for the images"
174
- msgstr "Fijar el tamaño de la imagen"
175
-
176
- #: ../templates/compare.php:76
177
- msgid "Close window [X]"
178
- msgstr "Cerrar ventana [X]"
179
-
180
- #: ../templates/compare.php:101
181
- msgid "No products added in the compare table."
182
- msgstr "Comparador de productos"
183
-
184
- #: ../widgets/class.yith-woocompare-widget.php:21
185
- msgid "The widget show the list of products added in the compare table."
186
- msgstr ""
187
- "El widget muestra la lista de productos añadidos en la tabla de comparacion"
188
-
189
- #: ../widgets/class.yith-woocompare-widget.php:22
190
- msgid "YITH Woocommerce Compare Widget"
191
- msgstr "YITH Woocommerce widget de comparador"
192
-
193
- #: ../widgets/class.yith-woocompare-widget.php:44
194
- msgid "Clear all"
195
- msgstr "Eliminar todos"
196
-
197
- #: ../yit-common/yith-panel.php:406
198
- msgid "Select a date"
199
- msgstr "Seleccionar fecha"
200
-
201
- #: ../yit-common/yith-panel.php:407
202
- msgid "Hours"
203
- msgstr "Horas"
204
-
205
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
206
- msgid "Minutes"
207
- msgstr "Minutos"
208
-
209
- #: ../yit-common/yith-panel.php:417
210
- msgid "Upload"
211
- msgstr "Cargar"
212
-
213
- #: ../yit-common/yith-panel.php:444
214
- msgid "px"
215
- msgstr "px"
216
-
217
- #: ../yit-common/yith-panel.php:445
218
- msgid "em"
219
- msgstr "em"
220
-
221
- #: ../yit-common/yith-panel.php:446
222
- msgid "pt"
223
- msgstr "pt"
224
-
225
- #: ../yit-common/yith-panel.php:447
226
- msgid "rem"
227
- msgstr "rem"
228
-
229
- #: ../yit-common/yith-panel.php:457
230
- msgid "Select a font family"
231
- msgstr "Seleccionar fuente"
232
-
233
- #: ../yit-common/yith-panel.php:465
234
- msgid "Regular"
235
- msgstr "Normal"
236
-
237
- #: ../yit-common/yith-panel.php:466
238
- msgid "Bold"
239
- msgstr "Negrita"
240
-
241
- #: ../yit-common/yith-panel.php:467
242
- msgid "Extra bold"
243
- msgstr "Extra negrita"
244
-
245
- #: ../yit-common/yith-panel.php:468
246
- msgid "Italic"
247
- msgstr "Cursiva"
248
-
249
- #: ../yit-common/yith-panel.php:469
250
- msgid "Italic bold"
251
- msgstr "Cursiva negrita"
252
-
253
- #: ../yit-common/yith-panel.php:481
254
- msgid "Click to preview"
255
- msgstr "Click para previsualizar"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-fa_IR.mo DELETED
Binary file
languages/yit-fa_IR.po DELETED
@@ -1,246 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:30+0100\n"
5
- "PO-Revision-Date: 2014-02-13 09:30+0100\n"
6
- "Last-Translator: Khalil Delavaran <khalil.delavaran@gmail.com>\n"
7
- "Language-Team: Qooqnos <khalil.delavaran@gmail.com>\n"
8
- "Language: Persian\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:129
18
- msgid "Products Compare"
19
- msgstr "سنجش محصولات"
20
-
21
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
22
- msgid "General Settings"
23
- msgstr "پیکربندی همگانی"
24
-
25
- #: ../class.yith-woocompare-frontend.php:142
26
- msgid "Added"
27
- msgstr "اضافه شد"
28
-
29
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
30
- msgid "Product Comparison"
31
- msgstr "سنجش محصولات"
32
-
33
- #: ../class.yith-woocompare-frontend.php:254
34
- msgid "In stock"
35
- msgstr "داشتن در انبار"
36
-
37
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
38
- #: ../widgets/class.yith-woocompare-widget.php:38
39
- msgid "Compare"
40
- msgstr "سنجش"
41
-
42
- #: ../class.yith-woocompare-frontend.php:496
43
- msgid "No products to compare"
44
- msgstr "محصولاتی برای سنجش نیست"
45
-
46
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
47
- msgid "Remove"
48
- msgstr "پاک"
49
-
50
- #: ../class.yith-woocompare-helper.php:38
51
- msgid "Image"
52
- msgstr "نگاره"
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- #: ../widgets/class.yith-woocompare-widget.php:55
56
- msgid "Title"
57
- msgstr "جستار"
58
-
59
- #: ../class.yith-woocompare-helper.php:40
60
- msgid "Price"
61
- msgstr "قیمت"
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Add to cart"
65
- msgstr "افزودن به سبد خرید"
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Description"
69
- msgstr "روشنگری"
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Availability"
73
- msgstr "دسترس پذیری"
74
-
75
- #: ../yith-woocompare-options.php:22
76
- msgid "Link or Button"
77
- msgstr "لینک یا دکمه"
78
-
79
- #: ../yith-woocompare-options.php:23
80
- msgid "Choose if you want to use a link or a button for the action button."
81
- msgstr "گزینش بکار بردن لینک و یا دکمه برای واکنش دکمه"
82
-
83
- #: ../yith-woocompare-options.php:29
84
- msgid "Link"
85
- msgstr "لینک"
86
-
87
- #: ../yith-woocompare-options.php:30
88
- msgid "Button"
89
- msgstr "دکمه"
90
-
91
- #: ../yith-woocompare-options.php:35
92
- msgid "Link/Button text"
93
- msgstr "لینک یا دکمه"
94
-
95
- #: ../yith-woocompare-options.php:36
96
- msgid "Type the text to use for the button or the link of the compare."
97
- msgstr "نوشته ای برای بکار بردن دکمه یا لینک مقایسه بنویسید"
98
-
99
- #: ../yith-woocompare-options.php:43
100
- msgid "Show button in single product page"
101
- msgstr "نمایش دکمه در برگه محصول"
102
-
103
- #: ../yith-woocompare-options.php:44
104
- msgid "Say if you want to show the button in the single product page."
105
- msgstr "اگر می خواهید دکمه در برگه محصول نمایش داده شود"
106
-
107
- #: ../yith-woocompare-options.php:52
108
- msgid "Show button in products list"
109
- msgstr "نمایش دکمه در لیست محصولات"
110
-
111
- #: ../yith-woocompare-options.php:53
112
- msgid "Say if you want to show the button in the products list."
113
- msgstr "اگر می خواهید دکمه در لیست محصول نمایش داده شود"
114
-
115
- #: ../yith-woocompare-options.php:61
116
- msgid "Open automatically lightbox"
117
- msgstr "باز کردن اتوماتیک جعبه نور"
118
-
119
- #: ../yith-woocompare-options.php:62
120
- msgid "Open link after click into \"Compare\" button\"."
121
- msgstr " باز کردن پیوند پس از \"سنجش\" دکمه\"کلیک کنید"
122
-
123
- #: ../yith-woocompare-options.php:74
124
- msgid "Table Settings"
125
- msgstr "پیکربندی جدول"
126
-
127
- #: ../yith-woocompare-options.php:81
128
- msgid "Table title"
129
- msgstr ""
130
-
131
- #: ../yith-woocompare-options.php:82
132
- msgid "Type the text to use for the table title."
133
- msgstr ""
134
-
135
- #: ../yith-woocompare-options.php:84
136
- msgid "Compare products"
137
- msgstr "سنجش محصولات"
138
-
139
- #: ../yith-woocompare-options.php:89
140
- msgid "Fields to show"
141
- msgstr "فیلدهای نمایش"
142
-
143
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
144
- #: ../yith-woocompare-options.php:108
145
- msgid ""
146
- "Select the fields to show in the comparison table and order them by "
147
- "drag&drop (are included also the woocommerce attributes)"
148
- msgstr ""
149
- "انتخاب این گزینه برای نشان دادن در جدول سنجش و سفارش سازی آنها با کشیدن و "
150
- "رها کردن دکمه ماوس (ویژگی های ووکامرس را شامل می شود)"
151
-
152
- #: ../yith-woocompare-options.php:98
153
- msgid "Repeat \"Price\" field at the end of the table"
154
- msgstr "تکرار گزینه \"قیمت\" در پایان جدول"
155
-
156
- #: ../yith-woocompare-options.php:107
157
- msgid "Repeat \"Add to cart\" field at the end of the table"
158
- msgstr "تکرار گزینه \"افزودن به سبد خرید\" در پایان جدول"
159
-
160
- #: ../yith-woocompare-options.php:116
161
- msgid "Image size"
162
- msgstr "اندازه نگاره"
163
-
164
- #: ../yith-woocompare-options.php:117
165
- msgid "Set the size for the images"
166
- msgstr "تعیین اندازه برای نگاره"
167
-
168
- #: ../templates/compare.php:72
169
- msgid "Close window [X]"
170
- msgstr "بستن پنجره [X]"
171
-
172
- #: ../templates/compare.php:97
173
- msgid "No products added in the compare table."
174
- msgstr "هیچ محصولی افزوده نشده است برای جدول سنجش"
175
-
176
- #: ../widgets/class.yith-woocompare-widget.php:21
177
- msgid "The widget show the list of products added in the compare table."
178
- msgstr "ویجت نشان می دهد لیستی از محصولات افزوده شده در جدول سنجش"
179
-
180
- #: ../widgets/class.yith-woocompare-widget.php:22
181
- msgid "YITH Woocommerce Compare Widget"
182
- msgstr "ویجت سنجش ووکاکرس YITH"
183
-
184
- #: ../widgets/class.yith-woocompare-widget.php:37
185
- msgid "Clear all"
186
- msgstr "پاک کردن همه"
187
-
188
- #: ../yit-common/yith-panel.php:406
189
- msgid "Select a date"
190
- msgstr "انتخاب روز"
191
-
192
- #: ../yit-common/yith-panel.php:407
193
- msgid "Hours"
194
- msgstr "ساعتها"
195
-
196
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
197
- msgid "Minutes"
198
- msgstr "دقیقه ها"
199
-
200
- #: ../yit-common/yith-panel.php:417
201
- msgid "Upload"
202
- msgstr "بارگذاری"
203
-
204
- #: ../yit-common/yith-panel.php:444
205
- msgid "px"
206
- msgstr ""
207
-
208
- #: ../yit-common/yith-panel.php:445
209
- msgid "em"
210
- msgstr ""
211
-
212
- #: ../yit-common/yith-panel.php:446
213
- msgid "pt"
214
- msgstr ""
215
-
216
- #: ../yit-common/yith-panel.php:447
217
- msgid "rem"
218
- msgstr ""
219
-
220
- #: ../yit-common/yith-panel.php:457
221
- msgid "Select a font family"
222
- msgstr "گزینش قلم"
223
-
224
- #: ../yit-common/yith-panel.php:465
225
- msgid "Regular"
226
- msgstr "معمولی"
227
-
228
- #: ../yit-common/yith-panel.php:466
229
- msgid "Bold"
230
- msgstr "کلفت"
231
-
232
- #: ../yit-common/yith-panel.php:467
233
- msgid "Extra bold"
234
- msgstr "خیلی کلفت"
235
-
236
- #: ../yit-common/yith-panel.php:468
237
- msgid "Italic"
238
- msgstr "کج"
239
-
240
- #: ../yit-common/yith-panel.php:469
241
- msgid "Italic bold"
242
- msgstr "کلفت کج"
243
-
244
- #: ../yit-common/yith-panel.php:481
245
- msgid "Click to preview"
246
- msgstr "کلیک برای پیش نمایش"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-fr_FR.mo DELETED
Binary file
languages/yit-fr_FR.po DELETED
@@ -1,246 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:30+0100\n"
5
- "PO-Revision-Date: 2014-02-13 09:30+0100\n"
6
- "Last-Translator: YIThemes <support@yithemes.com>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:129
18
- msgid "Products Compare"
19
- msgstr "Comparaison de produits"
20
-
21
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
22
- msgid "General Settings"
23
- msgstr "Réglages"
24
-
25
- #: ../class.yith-woocompare-frontend.php:142
26
- msgid "Added"
27
- msgstr "Ajouté"
28
-
29
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
30
- msgid "Product Comparison"
31
- msgstr "Comparaison de produits"
32
-
33
- #: ../class.yith-woocompare-frontend.php:254
34
- msgid "In stock"
35
- msgstr "En stock"
36
-
37
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
38
- #: ../widgets/class.yith-woocompare-widget.php:38
39
- msgid "Compare"
40
- msgstr "Comparer"
41
-
42
- #: ../class.yith-woocompare-frontend.php:496
43
- msgid "No products to compare"
44
- msgstr "Aucun produits à comparer"
45
-
46
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
47
- msgid "Remove"
48
- msgstr "Retirer"
49
-
50
- #: ../class.yith-woocompare-helper.php:38
51
- msgid "Image"
52
- msgstr ""
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- #: ../widgets/class.yith-woocompare-widget.php:55
56
- msgid "Title"
57
- msgstr "Titre"
58
-
59
- #: ../class.yith-woocompare-helper.php:40
60
- msgid "Price"
61
- msgstr "Prix"
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Add to cart"
65
- msgstr "Ajouter au panier"
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Description"
69
- msgstr ""
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Availability"
73
- msgstr "Disponibilité"
74
-
75
- #: ../yith-woocompare-options.php:22
76
- msgid "Link or Button"
77
- msgstr "Lien ou bouton"
78
-
79
- #: ../yith-woocompare-options.php:23
80
- msgid "Choose if you want to use a link or a button for the action button."
81
- msgstr "utiliser un lien ou un bouton"
82
-
83
- #: ../yith-woocompare-options.php:29
84
- msgid "Link"
85
- msgstr "lien"
86
-
87
- #: ../yith-woocompare-options.php:30
88
- msgid "Button"
89
- msgstr "bouton"
90
-
91
- #: ../yith-woocompare-options.php:35
92
- msgid "Link/Button text"
93
- msgstr "texte du lien ou bouton"
94
-
95
- #: ../yith-woocompare-options.php:36
96
- msgid "Type the text to use for the button or the link of the compare."
97
- msgstr "inscriver le texte pour le bouton ou le lien pour comparer"
98
-
99
- #: ../yith-woocompare-options.php:43
100
- msgid "Show button in single product page"
101
- msgstr "montrer le bouton sur page produit"
102
-
103
- #: ../yith-woocompare-options.php:44
104
- msgid "Say if you want to show the button in the single product page."
105
- msgstr "dites si vous souhaitez montrer le bouton sur page produit"
106
-
107
- #: ../yith-woocompare-options.php:52
108
- msgid "Show button in products list"
109
- msgstr "montrer le bouton sur liste de produit"
110
-
111
- #: ../yith-woocompare-options.php:53
112
- msgid "Say if you want to show the button in the products list."
113
- msgstr "dites si vous souhaitez montrer le bouton sur liste de produit"
114
-
115
- #: ../yith-woocompare-options.php:61
116
- msgid "Open automatically lightbox"
117
- msgstr "ouverture lightbox auto"
118
-
119
- #: ../yith-woocompare-options.php:62
120
- msgid "Open link after click into \"Compare\" button\"."
121
- msgstr "ouvrir lien apres le click sur bouton"
122
-
123
- #: ../yith-woocompare-options.php:74
124
- msgid "Table Settings"
125
- msgstr "reglages panneau"
126
-
127
- #: ../yith-woocompare-options.php:81
128
- msgid "Table title"
129
- msgstr ""
130
-
131
- #: ../yith-woocompare-options.php:82
132
- msgid "Type the text to use for the table title."
133
- msgstr ""
134
-
135
- #: ../yith-woocompare-options.php:84
136
- msgid "Compare products"
137
- msgstr "Comparer les produits"
138
-
139
- #: ../yith-woocompare-options.php:89
140
- msgid "Fields to show"
141
- msgstr "champs a montrer"
142
-
143
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
144
- #: ../yith-woocompare-options.php:108
145
- msgid ""
146
- "Select the fields to show in the comparison table and order them by "
147
- "drag&drop (are included also the woocommerce attributes)"
148
- msgstr ""
149
- "selectionnez les champs a montrer dans le tabelau de comparaison (en faisant "
150
- "glisser deposer)"
151
-
152
- #: ../yith-woocompare-options.php:98
153
- msgid "Repeat \"Price\" field at the end of the table"
154
- msgstr "Repeter le prix à la fin du tabelau"
155
-
156
- #: ../yith-woocompare-options.php:107
157
- msgid "Repeat \"Add to cart\" field at the end of the table"
158
- msgstr "repeter ajout au panier a la fin du tableau"
159
-
160
- #: ../yith-woocompare-options.php:116
161
- msgid "Image size"
162
- msgstr "taille image"
163
-
164
- #: ../yith-woocompare-options.php:117
165
- msgid "Set the size for the images"
166
- msgstr "ajuster tialle image"
167
-
168
- #: ../templates/compare.php:72
169
- msgid "Close window [X]"
170
- msgstr "Fermer ce tableau"
171
-
172
- #: ../templates/compare.php:97
173
- msgid "No products added in the compare table."
174
- msgstr "Aucun produit à comparer"
175
-
176
- #: ../widgets/class.yith-woocompare-widget.php:21
177
- msgid "The widget show the list of products added in the compare table."
178
- msgstr "le widget montre les produits à comparer"
179
-
180
- #: ../widgets/class.yith-woocompare-widget.php:22
181
- msgid "YITH Woocommerce Compare Widget"
182
- msgstr ""
183
-
184
- #: ../widgets/class.yith-woocompare-widget.php:37
185
- msgid "Clear all"
186
- msgstr "Retirer tout"
187
-
188
- #: ../yit-common/yith-panel.php:406
189
- msgid "Select a date"
190
- msgstr "Choisir une date"
191
-
192
- #: ../yit-common/yith-panel.php:407
193
- msgid "Hours"
194
- msgstr "Heures"
195
-
196
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
197
- msgid "Minutes"
198
- msgstr "Minutes"
199
-
200
- #: ../yit-common/yith-panel.php:417
201
- msgid "Upload"
202
- msgstr "Mettre en ligne"
203
-
204
- #: ../yit-common/yith-panel.php:444
205
- msgid "px"
206
- msgstr ""
207
-
208
- #: ../yit-common/yith-panel.php:445
209
- msgid "em"
210
- msgstr ""
211
-
212
- #: ../yit-common/yith-panel.php:446
213
- msgid "pt"
214
- msgstr ""
215
-
216
- #: ../yit-common/yith-panel.php:447
217
- msgid "rem"
218
- msgstr ""
219
-
220
- #: ../yit-common/yith-panel.php:457
221
- msgid "Select a font family"
222
- msgstr ""
223
-
224
- #: ../yit-common/yith-panel.php:465
225
- msgid "Regular"
226
- msgstr ""
227
-
228
- #: ../yit-common/yith-panel.php:466
229
- msgid "Bold"
230
- msgstr ""
231
-
232
- #: ../yit-common/yith-panel.php:467
233
- msgid "Extra bold"
234
- msgstr ""
235
-
236
- #: ../yit-common/yith-panel.php:468
237
- msgid "Italic"
238
- msgstr ""
239
-
240
- #: ../yit-common/yith-panel.php:469
241
- msgid "Italic bold"
242
- msgstr ""
243
-
244
- #: ../yit-common/yith-panel.php:481
245
- msgid "Click to preview"
246
- msgstr "Cliquer pour previsualiser"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-it_IT.mo DELETED
Binary file
languages/yit-nl_NL.mo DELETED
Binary file
languages/yit-nl_NL.po DELETED
@@ -1,247 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:31+0100\n"
5
- "PO-Revision-Date: 2014-02-13 09:31+0100\n"
6
- "Last-Translator: Frans Pronk <beheer@ifra.nl>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:129
18
- msgid "Products Compare"
19
- msgstr "Product vergelijk"
20
-
21
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
22
- msgid "General Settings"
23
- msgstr "Algemene instellingen"
24
-
25
- #: ../class.yith-woocompare-frontend.php:142
26
- msgid "Added"
27
- msgstr "Toegevoegd"
28
-
29
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
30
- msgid "Product Comparison"
31
- msgstr "Product vergelijk"
32
-
33
- #: ../class.yith-woocompare-frontend.php:254
34
- msgid "In stock"
35
- msgstr "Op voorraad"
36
-
37
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
38
- #: ../widgets/class.yith-woocompare-widget.php:38
39
- msgid "Compare"
40
- msgstr "Vergelijk"
41
-
42
- #: ../class.yith-woocompare-frontend.php:496
43
- msgid "No products to compare"
44
- msgstr "Geen producten om te vergelijken"
45
-
46
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
47
- msgid "Remove"
48
- msgstr "Verwijder"
49
-
50
- #: ../class.yith-woocompare-helper.php:38
51
- msgid "Image"
52
- msgstr "Afbeelding"
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- #: ../widgets/class.yith-woocompare-widget.php:55
56
- msgid "Title"
57
- msgstr "Titel"
58
-
59
- #: ../class.yith-woocompare-helper.php:40
60
- msgid "Price"
61
- msgstr "Prijs"
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Add to cart"
65
- msgstr "Bestellen"
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Description"
69
- msgstr "Omschrijving"
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Availability"
73
- msgstr "Beschikbaarheid"
74
-
75
- #: ../yith-woocompare-options.php:22
76
- msgid "Link or Button"
77
- msgstr "Link of Button"
78
-
79
- #: ../yith-woocompare-options.php:23
80
- msgid "Choose if you want to use a link or a button for the action button."
81
- msgstr "Kies uit button of link als actie button."
82
-
83
- #: ../yith-woocompare-options.php:29
84
- msgid "Link"
85
- msgstr "Link"
86
-
87
- #: ../yith-woocompare-options.php:30
88
- msgid "Button"
89
- msgstr "Button"
90
-
91
- #: ../yith-woocompare-options.php:35
92
- msgid "Link/Button text"
93
- msgstr ""
94
-
95
- #: ../yith-woocompare-options.php:36
96
- msgid "Type the text to use for the button or the link of the compare."
97
- msgstr ""
98
-
99
- #: ../yith-woocompare-options.php:43
100
- msgid "Show button in single product page"
101
- msgstr "Toon button op product pagina"
102
-
103
- #: ../yith-woocompare-options.php:44
104
- msgid "Say if you want to show the button in the single product page."
105
- msgstr "Selecteer wanneer je een button op de product pagina wilt tonen."
106
-
107
- #: ../yith-woocompare-options.php:52
108
- msgid "Show button in products list"
109
- msgstr "Toon button op producten overzicht"
110
-
111
- #: ../yith-woocompare-options.php:53
112
- msgid "Say if you want to show the button in the products list."
113
- msgstr ""
114
- "Selecteer wanneer een button op de productenoverzichts pagina wilt tonen."
115
-
116
- #: ../yith-woocompare-options.php:61
117
- msgid "Open automatically lightbox"
118
- msgstr "Open automatisch in lightbox"
119
-
120
- #: ../yith-woocompare-options.php:62
121
- msgid "Open link after click into \"Compare\" button\"."
122
- msgstr "Open de link direct na aanklikken van \"Vergelijk\" button\"."
123
-
124
- #: ../yith-woocompare-options.php:74
125
- msgid "Table Settings"
126
- msgstr "Tabel instellingen"
127
-
128
- #: ../yith-woocompare-options.php:81
129
- msgid "Table title"
130
- msgstr ""
131
-
132
- #: ../yith-woocompare-options.php:82
133
- msgid "Type the text to use for the table title."
134
- msgstr ""
135
-
136
- #: ../yith-woocompare-options.php:84
137
- msgid "Compare products"
138
- msgstr "Vergelijk producten"
139
-
140
- #: ../yith-woocompare-options.php:89
141
- msgid "Fields to show"
142
- msgstr "Velden tonen"
143
-
144
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
145
- #: ../yith-woocompare-options.php:108
146
- msgid ""
147
- "Select the fields to show in the comparison table and order them by "
148
- "drag&drop (are included also the woocommerce attributes)"
149
- msgstr ""
150
- "Selecteer de velden die je in de vergelijkings tabel wilt tonen. Sleep ze "
151
- "met je muis in de gewenste volgorde."
152
-
153
- #: ../yith-woocompare-options.php:98
154
- msgid "Repeat \"Price\" field at the end of the table"
155
- msgstr "Toon \"Prijs\" veld aan het einde van de tabel"
156
-
157
- #: ../yith-woocompare-options.php:107
158
- msgid "Repeat \"Add to cart\" field at the end of the table"
159
- msgstr "Toon \"Bestel\" veld aan het einde van de tabel"
160
-
161
- #: ../yith-woocompare-options.php:116
162
- msgid "Image size"
163
- msgstr "Afbeelding formaat"
164
-
165
- #: ../yith-woocompare-options.php:117
166
- msgid "Set the size for the images"
167
- msgstr "Stel afbeeldings formaat in "
168
-
169
- #: ../templates/compare.php:72
170
- msgid "Close window [X]"
171
- msgstr "Sluit venster [X]"
172
-
173
- #: ../templates/compare.php:97
174
- msgid "No products added in the compare table."
175
- msgstr "Geen producten toegevoegd in de vergelijk tabel."
176
-
177
- #: ../widgets/class.yith-woocompare-widget.php:21
178
- msgid "The widget show the list of products added in the compare table."
179
- msgstr "Deze widget toont een lijst met producten in een vergelijkings tabel."
180
-
181
- #: ../widgets/class.yith-woocompare-widget.php:22
182
- msgid "YITH Woocommerce Compare Widget"
183
- msgstr "Een YITH Woocommerce Vergelijk Widget"
184
-
185
- #: ../widgets/class.yith-woocompare-widget.php:37
186
- msgid "Clear all"
187
- msgstr "Wis alles"
188
-
189
- #: ../yit-common/yith-panel.php:406
190
- msgid "Select a date"
191
- msgstr "Selecteer een datum"
192
-
193
- #: ../yit-common/yith-panel.php:407
194
- msgid "Hours"
195
- msgstr "Uren"
196
-
197
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
198
- msgid "Minutes"
199
- msgstr "Minuten"
200
-
201
- #: ../yit-common/yith-panel.php:417
202
- msgid "Upload"
203
- msgstr "Upload"
204
-
205
- #: ../yit-common/yith-panel.php:444
206
- msgid "px"
207
- msgstr "px"
208
-
209
- #: ../yit-common/yith-panel.php:445
210
- msgid "em"
211
- msgstr "em"
212
-
213
- #: ../yit-common/yith-panel.php:446
214
- msgid "pt"
215
- msgstr "pt"
216
-
217
- #: ../yit-common/yith-panel.php:447
218
- msgid "rem"
219
- msgstr "rem"
220
-
221
- #: ../yit-common/yith-panel.php:457
222
- msgid "Select a font family"
223
- msgstr "Kies een font type"
224
-
225
- #: ../yit-common/yith-panel.php:465
226
- msgid "Regular"
227
- msgstr "Normaal"
228
-
229
- #: ../yit-common/yith-panel.php:466
230
- msgid "Bold"
231
- msgstr "Vet"
232
-
233
- #: ../yit-common/yith-panel.php:467
234
- msgid "Extra bold"
235
- msgstr "Extra vet"
236
-
237
- #: ../yit-common/yith-panel.php:468
238
- msgid "Italic"
239
- msgstr "Cursief"
240
-
241
- #: ../yit-common/yith-panel.php:469
242
- msgid "Italic bold"
243
- msgstr "Cursief vet"
244
-
245
- #: ../yit-common/yith-panel.php:481
246
- msgid "Click to preview"
247
- msgstr "Klik voor voorvertoning"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-pt_BR.mo DELETED
Binary file
languages/yit-pt_BR.po DELETED
@@ -1,247 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:31+0100\n"
5
- "PO-Revision-Date: 2014-02-13 09:32+0100\n"
6
- "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:129
18
- msgid "Products Compare"
19
- msgstr "Comparar Produtos"
20
-
21
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
22
- msgid "General Settings"
23
- msgstr "Opções Gerais"
24
-
25
- #: ../class.yith-woocompare-frontend.php:142
26
- msgid "Added"
27
- msgstr "Adicionado"
28
-
29
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
30
- msgid "Product Comparison"
31
- msgstr "Comparação de Produtos"
32
-
33
- #: ../class.yith-woocompare-frontend.php:254
34
- msgid "In stock"
35
- msgstr "No estoque"
36
-
37
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
38
- #: ../widgets/class.yith-woocompare-widget.php:38
39
- msgid "Compare"
40
- msgstr "Comparar"
41
-
42
- #: ../class.yith-woocompare-frontend.php:496
43
- msgid "No products to compare"
44
- msgstr "Não há produtos à comparar"
45
-
46
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
47
- msgid "Remove"
48
- msgstr "Remover"
49
-
50
- #: ../class.yith-woocompare-helper.php:38
51
- msgid "Image"
52
- msgstr "Imagem"
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- #: ../widgets/class.yith-woocompare-widget.php:55
56
- msgid "Title"
57
- msgstr "Título"
58
-
59
- #: ../class.yith-woocompare-helper.php:40
60
- msgid "Price"
61
- msgstr "Preço"
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Add to cart"
65
- msgstr "Adicionar ao carrinho"
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Description"
69
- msgstr "Descrição"
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Availability"
73
- msgstr "Disponibilidade"
74
-
75
- #: ../yith-woocompare-options.php:22
76
- msgid "Link or Button"
77
- msgstr "Link ou Botão"
78
-
79
- #: ../yith-woocompare-options.php:23
80
- msgid "Choose if you want to use a link or a button for the action button."
81
- msgstr "Seleciona se deseja usar link ou botão para a ação do botão"
82
-
83
- #: ../yith-woocompare-options.php:29
84
- msgid "Link"
85
- msgstr "Link"
86
-
87
- #: ../yith-woocompare-options.php:30
88
- msgid "Button"
89
- msgstr "Botão"
90
-
91
- #: ../yith-woocompare-options.php:35
92
- msgid "Link/Button text"
93
- msgstr "Texto Link/Botão"
94
-
95
- #: ../yith-woocompare-options.php:36
96
- msgid "Type the text to use for the button or the link of the compare."
97
- msgstr "Insira o texto usado no botão de comparação."
98
-
99
- #: ../yith-woocompare-options.php:43
100
- msgid "Show button in single product page"
101
- msgstr "Mostrar na página de produto único"
102
-
103
- #: ../yith-woocompare-options.php:44
104
- msgid "Say if you want to show the button in the single product page."
105
- msgstr "Marque para mostrar na página de produto único"
106
-
107
- #: ../yith-woocompare-options.php:52
108
- msgid "Show button in products list"
109
- msgstr "Mostrar na lista de produtos"
110
-
111
- #: ../yith-woocompare-options.php:53
112
- msgid "Say if you want to show the button in the products list."
113
- msgstr "Marque para mostrar na lista de produtos"
114
-
115
- #: ../yith-woocompare-options.php:61
116
- msgid "Open automatically lightbox"
117
- msgstr "Abrir lightbox automaticamente"
118
-
119
- #: ../yith-woocompare-options.php:62
120
- msgid "Open link after click into \"Compare\" button\"."
121
- msgstr "Abre link após clicar no botão de comparação."
122
-
123
- #: ../yith-woocompare-options.php:74
124
- msgid "Table Settings"
125
- msgstr "Opções de tabela"
126
-
127
- #: ../yith-woocompare-options.php:81
128
- msgid "Table title"
129
- msgstr ""
130
-
131
- #: ../yith-woocompare-options.php:82
132
- msgid "Type the text to use for the table title."
133
- msgstr ""
134
-
135
- #: ../yith-woocompare-options.php:84
136
- msgid "Compare products"
137
- msgstr "Comparar produtos"
138
-
139
- #: ../yith-woocompare-options.php:89
140
- msgid "Fields to show"
141
- msgstr "Campos a mostrar"
142
-
143
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
144
- #: ../yith-woocompare-options.php:108
145
- msgid ""
146
- "Select the fields to show in the comparison table and order them by "
147
- "drag&drop (are included also the woocommerce attributes)"
148
- msgstr ""
149
- "Selecione os campos a mostrar na tabela de comparação e organize-os "
150
- "arrastando e soltando (atributos do Woocommerce também são incluídos)"
151
-
152
- #: ../yith-woocompare-options.php:98
153
- msgid "Repeat \"Price\" field at the end of the table"
154
- msgstr "Repetir campo \"Preço\" no final da tabela"
155
-
156
- #: ../yith-woocompare-options.php:107
157
- msgid "Repeat \"Add to cart\" field at the end of the table"
158
- msgstr "Repetir campo \"Adicionar ao carrinho\" no final da tabela"
159
-
160
- #: ../yith-woocompare-options.php:116
161
- msgid "Image size"
162
- msgstr "Tamanho da imagem"
163
-
164
- #: ../yith-woocompare-options.php:117
165
- msgid "Set the size for the images"
166
- msgstr "Especifique um tamanho para as imagens"
167
-
168
- #: ../templates/compare.php:72
169
- msgid "Close window [X]"
170
- msgstr "Fechar janela [X]"
171
-
172
- #: ../templates/compare.php:97
173
- msgid "No products added in the compare table."
174
- msgstr "Não foram adicionados produtos na tabela de comparação"
175
-
176
- #: ../widgets/class.yith-woocompare-widget.php:21
177
- msgid "The widget show the list of products added in the compare table."
178
- msgstr ""
179
- "O widget mostra a lista de produtos adicionados na tabela de comparação."
180
-
181
- #: ../widgets/class.yith-woocompare-widget.php:22
182
- msgid "YITH Woocommerce Compare Widget"
183
- msgstr "Widget de Comparação"
184
-
185
- #: ../widgets/class.yith-woocompare-widget.php:37
186
- msgid "Clear all"
187
- msgstr "Limpar tudo"
188
-
189
- #: ../yit-common/yith-panel.php:406
190
- msgid "Select a date"
191
- msgstr "Selecione uma data"
192
-
193
- #: ../yit-common/yith-panel.php:407
194
- msgid "Hours"
195
- msgstr "Horas"
196
-
197
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
198
- msgid "Minutes"
199
- msgstr "Minutos"
200
-
201
- #: ../yit-common/yith-panel.php:417
202
- msgid "Upload"
203
- msgstr "Enviar"
204
-
205
- #: ../yit-common/yith-panel.php:444
206
- msgid "px"
207
- msgstr "px"
208
-
209
- #: ../yit-common/yith-panel.php:445
210
- msgid "em"
211
- msgstr "em"
212
-
213
- #: ../yit-common/yith-panel.php:446
214
- msgid "pt"
215
- msgstr "pt"
216
-
217
- #: ../yit-common/yith-panel.php:447
218
- msgid "rem"
219
- msgstr "rem"
220
-
221
- #: ../yit-common/yith-panel.php:457
222
- msgid "Select a font family"
223
- msgstr "Seleciona uma família de fontes"
224
-
225
- #: ../yit-common/yith-panel.php:465
226
- msgid "Regular"
227
- msgstr "Normal"
228
-
229
- #: ../yit-common/yith-panel.php:466
230
- msgid "Bold"
231
- msgstr "Negrito"
232
-
233
- #: ../yit-common/yith-panel.php:467
234
- msgid "Extra bold"
235
- msgstr "Extra-negrito"
236
-
237
- #: ../yit-common/yith-panel.php:468
238
- msgid "Italic"
239
- msgstr "Itálico"
240
-
241
- #: ../yit-common/yith-panel.php:469
242
- msgid "Italic bold"
243
- msgstr "Negrito itálico"
244
-
245
- #: ../yit-common/yith-panel.php:481
246
- msgid "Click to preview"
247
- msgstr "Clique para pré-visualizar"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit-tr_TR.mo DELETED
Binary file
languages/yit-tr_TR.po DELETED
@@ -1,248 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:30+0100\n"
5
- "PO-Revision-Date: 2014-07-22 00:03+0200\n"
6
- "Last-Translator: Caner Öncel <caneroncel@gmail.com>\n"
7
- "Language-Team: Caner Öncel <caneroncel@gmail.com>\n"
8
- "Language: tr\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.6.6\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "Plural-Forms: nplurals=1; plural=0;\n"
16
- "X-Poedit-SearchPath-0: ..\n"
17
-
18
- #: ../class.yith-woocompare-admin.php:129
19
- msgid "Products Compare"
20
- msgstr "Ürün Karşılaştırma"
21
-
22
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
23
- msgid "General Settings"
24
- msgstr "Genel Ayarlar"
25
-
26
- #: ../class.yith-woocompare-frontend.php:142
27
- msgid "Added"
28
- msgstr "Eklendi"
29
-
30
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
31
- msgid "Product Comparison"
32
- msgstr "Ürün Karşılaştırma"
33
-
34
- #: ../class.yith-woocompare-frontend.php:254
35
- msgid "In stock"
36
- msgstr "Stokta"
37
-
38
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
39
- #: ../widgets/class.yith-woocompare-widget.php:38
40
- msgid "Compare"
41
- msgstr "Karşılaştır"
42
-
43
- #: ../class.yith-woocompare-frontend.php:496
44
- msgid "No products to compare"
45
- msgstr "Karşılaştırma listeniz boş"
46
-
47
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
48
- msgid "Remove"
49
- msgstr "Kaldır"
50
-
51
- #: ../class.yith-woocompare-helper.php:38
52
- msgid "Image"
53
- msgstr "Resim"
54
-
55
- #: ../class.yith-woocompare-helper.php:39
56
- #: ../widgets/class.yith-woocompare-widget.php:55
57
- msgid "Title"
58
- msgstr "Başlık"
59
-
60
- #: ../class.yith-woocompare-helper.php:40
61
- msgid "Price"
62
- msgstr "Fiyat"
63
-
64
- #: ../class.yith-woocompare-helper.php:41
65
- msgid "Add to cart"
66
- msgstr "Sepete Ekle"
67
-
68
- #: ../class.yith-woocompare-helper.php:42
69
- msgid "Description"
70
- msgstr "Açıklama"
71
-
72
- #: ../class.yith-woocompare-helper.php:43
73
- msgid "Availability"
74
- msgstr "Durum"
75
-
76
- #: ../yith-woocompare-options.php:22
77
- msgid "Link or Button"
78
- msgstr "Link veya Buton"
79
-
80
- #: ../yith-woocompare-options.php:23
81
- msgid "Choose if you want to use a link or a button for the action button."
82
- msgstr ""
83
- "Eylem için kullanmak üzere link veya buton seçeneklerinden birini belirleyin."
84
-
85
- #: ../yith-woocompare-options.php:29
86
- msgid "Link"
87
- msgstr "Link"
88
-
89
- #: ../yith-woocompare-options.php:30
90
- msgid "Button"
91
- msgstr "Buton"
92
-
93
- #: ../yith-woocompare-options.php:35
94
- msgid "Link/Button text"
95
- msgstr "Link/Buton Metni"
96
-
97
- #: ../yith-woocompare-options.php:36
98
- msgid "Type the text to use for the button or the link of the compare."
99
- msgstr "Karşılaştırma butonu veya bağlantısı için kullanılacak metni yazın."
100
-
101
- #: ../yith-woocompare-options.php:43
102
- msgid "Show button in single product page"
103
- msgstr "Tekli ürün sayfasında buton göster"
104
-
105
- #: ../yith-woocompare-options.php:44
106
- msgid "Say if you want to show the button in the single product page."
107
- msgstr "Tekli ürün sayfasında buton göstermek isteyip istemediğinizi belirtin."
108
-
109
- #: ../yith-woocompare-options.php:52
110
- msgid "Show button in products list"
111
- msgstr "Ürün listesinde buton göster"
112
-
113
- #: ../yith-woocompare-options.php:53
114
- msgid "Say if you want to show the button in the products list."
115
- msgstr "Ürün listesinde buton göstermek isteyip istemediğinizi belirtin."
116
-
117
- #: ../yith-woocompare-options.php:61
118
- msgid "Open automatically lightbox"
119
- msgstr "Otomatik lightbox aç"
120
-
121
- #: ../yith-woocompare-options.php:62
122
- msgid "Open link after click into \"Compare\" button\"."
123
- msgstr "\"Karşılaştır\" butonuna tıklandıktan sonra bağlantıyı aç."
124
-
125
- #: ../yith-woocompare-options.php:74
126
- msgid "Table Settings"
127
- msgstr "Tablo Ayarları"
128
-
129
- #: ../yith-woocompare-options.php:81
130
- msgid "Table title"
131
- msgstr "Tablo Başlığı"
132
-
133
- #: ../yith-woocompare-options.php:82
134
- msgid "Type the text to use for the table title."
135
- msgstr "Tablo başlığı metnini buraya yazın."
136
-
137
- #: ../yith-woocompare-options.php:84
138
- msgid "Compare products"
139
- msgstr "Ürünleri Karşılaştır"
140
-
141
- #: ../yith-woocompare-options.php:89
142
- msgid "Fields to show"
143
- msgstr "Gösterilecek alanlar"
144
-
145
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
146
- #: ../yith-woocompare-options.php:108
147
- msgid ""
148
- "Select the fields to show in the comparison table and order them by "
149
- "drag&drop (are included also the woocommerce attributes)"
150
- msgstr ""
151
- "Karşılaştırma tablosunda gösterilecek alanları seçin ve sürükle-bırak "
152
- "yöntemi ile sıralayın (ayrıca Woocommerce özellikleri dahildir)"
153
-
154
- #: ../yith-woocompare-options.php:98
155
- msgid "Repeat \"Price\" field at the end of the table"
156
- msgstr "\"Ücret\" alanını tablonun sonuna kadar tekrarla"
157
-
158
- #: ../yith-woocompare-options.php:107
159
- msgid "Repeat \"Add to cart\" field at the end of the table"
160
- msgstr "\"Sepete ekle\" alanını tablonun sonuna kadar tekrarla"
161
-
162
- #: ../yith-woocompare-options.php:116
163
- msgid "Image size"
164
- msgstr "Resim Boyutu"
165
-
166
- #: ../yith-woocompare-options.php:117
167
- msgid "Set the size for the images"
168
- msgstr "Resimlerin boyutlarını belirtin"
169
-
170
- #: ../templates/compare.php:72
171
- msgid "Close window [X]"
172
- msgstr "Pencereyi Kapat [X]"
173
-
174
- #: ../templates/compare.php:97
175
- msgid "No products added in the compare table."
176
- msgstr "Karşılaştırma tablosuna herhangi bir ürün eklenmedi."
177
-
178
- #: ../widgets/class.yith-woocompare-widget.php:21
179
- msgid "The widget show the list of products added in the compare table."
180
- msgstr "Widget karşılaştırma tablosuna eklenen ürünlerin listesini gösterir."
181
-
182
- #: ../widgets/class.yith-woocompare-widget.php:22
183
- msgid "YITH Woocommerce Compare Widget"
184
- msgstr "YITH Woocommerce Karşılaştırma Widgetı"
185
-
186
- #: ../widgets/class.yith-woocompare-widget.php:37
187
- msgid "Clear all"
188
- msgstr "Hepsini Kaldır"
189
-
190
- #: ../yit-common/yith-panel.php:406
191
- msgid "Select a date"
192
- msgstr "Bir tarih seçin"
193
-
194
- #: ../yit-common/yith-panel.php:407
195
- msgid "Hours"
196
- msgstr "Saat"
197
-
198
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
199
- msgid "Minutes"
200
- msgstr "Dakika"
201
-
202
- #: ../yit-common/yith-panel.php:417
203
- msgid "Upload"
204
- msgstr "Yükle"
205
-
206
- #: ../yit-common/yith-panel.php:444
207
- msgid "px"
208
- msgstr "px"
209
-
210
- #: ../yit-common/yith-panel.php:445
211
- msgid "em"
212
- msgstr "em"
213
-
214
- #: ../yit-common/yith-panel.php:446
215
- msgid "pt"
216
- msgstr "pt"
217
-
218
- #: ../yit-common/yith-panel.php:447
219
- msgid "rem"
220
- msgstr "rem"
221
-
222
- #: ../yit-common/yith-panel.php:457
223
- msgid "Select a font family"
224
- msgstr "Bir font ailesi seçin"
225
-
226
- #: ../yit-common/yith-panel.php:465
227
- msgid "Regular"
228
- msgstr "Normal"
229
-
230
- #: ../yit-common/yith-panel.php:466
231
- msgid "Bold"
232
- msgstr "Kalın"
233
-
234
- #: ../yit-common/yith-panel.php:467
235
- msgid "Extra bold"
236
- msgstr "Ekstra kalın"
237
-
238
- #: ../yit-common/yith-panel.php:468
239
- msgid "Italic"
240
- msgstr "İtalik"
241
-
242
- #: ../yit-common/yith-panel.php:469
243
- msgid "Italic bold"
244
- msgstr "İtalik kalın"
245
-
246
- #: ../yit-common/yith-panel.php:481
247
- msgid "Click to preview"
248
- msgstr "Önizleme için tıklayın"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yit.pot DELETED
@@ -1,248 +0,0 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-12-03 12:49+0100\n"
5
- "PO-Revision-Date: 2014-12-03 12:49+0100\n"
6
- "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
- "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
- "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
16
-
17
- #: ../class.yith-woocompare-admin.php:130
18
- msgid "Products Compare"
19
- msgstr ""
20
-
21
- #: ../class.yith-woocompare-admin.php:144 ../yith-woocompare-options.php:24
22
- msgid "General Settings"
23
- msgstr ""
24
-
25
- #: ../class.yith-woocompare-admin.php:375
26
- msgid "Hard Crop?"
27
- msgstr ""
28
-
29
- #: ../class.yith-woocompare-frontend.php:142
30
- msgid "Added"
31
- msgstr ""
32
-
33
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:51
34
- msgid "Product Comparison"
35
- msgstr ""
36
-
37
- #: ../class.yith-woocompare-frontend.php:254
38
- msgid "In stock"
39
- msgstr ""
40
-
41
- #: ../class.yith-woocompare-frontend.php:338 ../yith-woocompare-options.php:47
42
- #: ../widgets/class.yith-woocompare-widget.php:45
43
- msgid "Compare"
44
- msgstr ""
45
-
46
- #: ../class.yith-woocompare-frontend.php:512
47
- msgid "No products to compare"
48
- msgstr ""
49
-
50
- #: ../class.yith-woocompare-frontend.php:522 ../templates/compare.php:109
51
- msgid "Remove"
52
- msgstr ""
53
-
54
- #: ../class.yith-woocompare-helper.php:39
55
- msgid "Image"
56
- msgstr ""
57
-
58
- #: ../class.yith-woocompare-helper.php:40
59
- #: ../widgets/class.yith-woocompare-widget.php:62
60
- msgid "Title"
61
- msgstr ""
62
-
63
- #: ../class.yith-woocompare-helper.php:41
64
- msgid "Price"
65
- msgstr ""
66
-
67
- #: ../class.yith-woocompare-helper.php:42
68
- msgid "Add to cart"
69
- msgstr ""
70
-
71
- #: ../class.yith-woocompare-helper.php:43
72
- msgid "Description"
73
- msgstr ""
74
-
75
- #: ../class.yith-woocompare-helper.php:44
76
- msgid "Availability"
77
- msgstr ""
78
-
79
- #: ../yith-woocompare-options.php:31
80
- msgid "Link or Button"
81
- msgstr ""
82
-
83
- #: ../yith-woocompare-options.php:32
84
- msgid "Choose if you want to use a link or a button for the action button."
85
- msgstr ""
86
-
87
- #: ../yith-woocompare-options.php:38
88
- msgid "Link"
89
- msgstr ""
90
-
91
- #: ../yith-woocompare-options.php:39
92
- msgid "Button"
93
- msgstr ""
94
-
95
- #: ../yith-woocompare-options.php:44
96
- msgid "Link/Button text"
97
- msgstr ""
98
-
99
- #: ../yith-woocompare-options.php:45
100
- msgid "Type the text to use for the button or the link of the compare."
101
- msgstr ""
102
-
103
- #: ../yith-woocompare-options.php:52
104
- msgid "Show button in single product page"
105
- msgstr ""
106
-
107
- #: ../yith-woocompare-options.php:53
108
- msgid "Say if you want to show the button in the single product page."
109
- msgstr ""
110
-
111
- #: ../yith-woocompare-options.php:61
112
- msgid "Show button in products list"
113
- msgstr ""
114
-
115
- #: ../yith-woocompare-options.php:62
116
- msgid "Say if you want to show the button in the products list."
117
- msgstr ""
118
-
119
- #: ../yith-woocompare-options.php:70
120
- msgid "Open automatically lightbox"
121
- msgstr ""
122
-
123
- #: ../yith-woocompare-options.php:71
124
- msgid "Open link after click into \"Compare\" button\"."
125
- msgstr ""
126
-
127
- #: ../yith-woocompare-options.php:83
128
- msgid "Table Settings"
129
- msgstr ""
130
-
131
- #: ../yith-woocompare-options.php:90
132
- msgid "Table title"
133
- msgstr ""
134
-
135
- #: ../yith-woocompare-options.php:91
136
- msgid "Type the text to use for the table title."
137
- msgstr ""
138
-
139
- #: ../yith-woocompare-options.php:93
140
- msgid "Compare products"
141
- msgstr ""
142
-
143
- #: ../yith-woocompare-options.php:98
144
- msgid "Fields to show"
145
- msgstr ""
146
-
147
- #: ../yith-woocompare-options.php:99 ../yith-woocompare-options.php:108
148
- #: ../yith-woocompare-options.php:117
149
- msgid ""
150
- "Select the fields to show in the comparison table and order them by "
151
- "drag&drop (are included also the woocommerce attributes)"
152
- msgstr ""
153
-
154
- #: ../yith-woocompare-options.php:107
155
- msgid "Repeat \"Price\" field at the end of the table"
156
- msgstr ""
157
-
158
- #: ../yith-woocompare-options.php:116
159
- msgid "Repeat \"Add to cart\" field at the end of the table"
160
- msgstr ""
161
-
162
- #: ../yith-woocompare-options.php:125
163
- msgid "Image size"
164
- msgstr ""
165
-
166
- #: ../yith-woocompare-options.php:126
167
- msgid "Set the size for the images"
168
- msgstr ""
169
-
170
- #: ../templates/compare.php:76
171
- msgid "Close window [X]"
172
- msgstr ""
173
-
174
- #: ../templates/compare.php:101
175
- msgid "No products added in the compare table."
176
- msgstr ""
177
-
178
- #: ../widgets/class.yith-woocompare-widget.php:21
179
- msgid "The widget show the list of products added in the compare table."
180
- msgstr ""
181
-
182
- #: ../widgets/class.yith-woocompare-widget.php:22
183
- msgid "YITH Woocommerce Compare Widget"
184
- msgstr ""
185
-
186
- #: ../widgets/class.yith-woocompare-widget.php:44
187
- msgid "Clear all"
188
- msgstr ""
189
-
190
- #: ../yit-common/yith-panel.php:406
191
- msgid "Select a date"
192
- msgstr ""
193
-
194
- #: ../yit-common/yith-panel.php:407
195
- msgid "Hours"
196
- msgstr ""
197
-
198
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
199
- msgid "Minutes"
200
- msgstr ""
201
-
202
- #: ../yit-common/yith-panel.php:417
203
- msgid "Upload"
204
- msgstr ""
205
-
206
- #: ../yit-common/yith-panel.php:444
207
- msgid "px"
208
- msgstr ""
209
-
210
- #: ../yit-common/yith-panel.php:445
211
- msgid "em"
212
- msgstr ""
213
-
214
- #: ../yit-common/yith-panel.php:446
215
- msgid "pt"
216
- msgstr ""
217
-
218
- #: ../yit-common/yith-panel.php:447
219
- msgid "rem"
220
- msgstr ""
221
-
222
- #: ../yit-common/yith-panel.php:457
223
- msgid "Select a font family"
224
- msgstr ""
225
-
226
- #: ../yit-common/yith-panel.php:465
227
- msgid "Regular"
228
- msgstr ""
229
-
230
- #: ../yit-common/yith-panel.php:466
231
- msgid "Bold"
232
- msgstr ""
233
-
234
- #: ../yit-common/yith-panel.php:467
235
- msgid "Extra bold"
236
- msgstr ""
237
-
238
- #: ../yit-common/yith-panel.php:468
239
- msgid "Italic"
240
- msgstr ""
241
-
242
- #: ../yit-common/yith-panel.php:469
243
- msgid "Italic bold"
244
- msgstr ""
245
-
246
- #: ../yit-common/yith-panel.php:481
247
- msgid "Click to preview"
248
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/yith-wcmp-bg_BG.mo ADDED
Binary file
languages/yith-wcmp-bg_BG.po ADDED
@@ -0,0 +1,397 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:30+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:31+0200\n"
6
+ "Last-Translator: \n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "Сравни"
36
+
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr "Добавено"
75
+
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
+ msgid "Product Comparison"
78
+ msgstr "Сравнение на продуктите"
79
+
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
+ msgid "In stock"
82
+ msgstr "В наличност"
83
+
84
+ #: includes/class.yith-woocompare-frontend.php:548
85
+ msgid "No products to compare"
86
+ msgstr "В момента нямате продукти за сравнение"
87
+
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
+ msgid "Remove"
90
+ msgstr "Премахни"
91
+
92
+ #: includes/class.yith-woocompare-helper.php:45
93
+ msgid "Image"
94
+ msgstr "Снимка"
95
+
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
+ msgid "Title"
99
+ msgstr "Заглавие"
100
+
101
+ #: includes/class.yith-woocompare-helper.php:47
102
+ msgid "Price"
103
+ msgstr "Цена"
104
+
105
+ #: includes/class.yith-woocompare-helper.php:48
106
+ msgid "Add to cart"
107
+ msgstr "КУПИ"
108
+
109
+ #: includes/class.yith-woocompare-helper.php:49
110
+ msgid "Description"
111
+ msgstr "Описание"
112
+
113
+ #: includes/class.yith-woocompare-helper.php:50
114
+ msgid "Availability"
115
+ msgstr "Достъпност"
116
+
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "Общи настройки"
132
+
133
+ #: plugin-options/general-options.php:24
134
+ msgid "Link or Button"
135
+ msgstr "Свържи към бутона"
136
+
137
+ #: plugin-options/general-options.php:25
138
+ msgid "Choose if you want to use a link or a button for the action button."
139
+ msgstr "Изберете дали искате да използвате линк или бутон"
140
+
141
+ #: plugin-options/general-options.php:31
142
+ msgid "Link"
143
+ msgstr "Линк"
144
+
145
+ #: plugin-options/general-options.php:32
146
+ msgid "Button"
147
+ msgstr "Бутон"
148
+
149
+ #: plugin-options/general-options.php:37
150
+ msgid "Link/Button text"
151
+ msgstr "Текст на Линка/Бутона"
152
+
153
+ #: plugin-options/general-options.php:38
154
+ msgid "Type the text to use for the button or the link of the compare."
155
+ msgstr "Напишете текста, който искате да използвате за линка или бутона"
156
+
157
+ #: plugin-options/general-options.php:45
158
+ msgid "Show button in single product page"
159
+ msgstr "Покажете бутона на страницата на продукта"
160
+
161
+ #: plugin-options/general-options.php:46
162
+ msgid "Say if you want to show the button in the single product page."
163
+ msgstr ""
164
+
165
+ #: plugin-options/general-options.php:54
166
+ msgid "Show button in products list"
167
+ msgstr "Покажете бутона в каталога "
168
+
169
+ #: plugin-options/general-options.php:55
170
+ msgid "Say if you want to show the button in the products list."
171
+ msgstr ""
172
+
173
+ #: plugin-options/general-options.php:63
174
+ msgid "Open automatically lightbox"
175
+ msgstr ""
176
+
177
+ #: plugin-options/general-options.php:64
178
+ msgid "Open link after click into \"Compare\" button\"."
179
+ msgstr ""
180
+
181
+ #: plugin-options/general-options.php:77
182
+ msgid "Table Settings"
183
+ msgstr "Настройки на таблицата"
184
+
185
+ #: plugin-options/general-options.php:84
186
+ msgid "Table title"
187
+ msgstr "Заглавие на таблицата"
188
+
189
+ #: plugin-options/general-options.php:85
190
+ msgid "Type the text to use for the table title."
191
+ msgstr ""
192
+
193
+ #: plugin-options/general-options.php:87
194
+ msgid "Compare products"
195
+ msgstr "Сравнете продуктите си"
196
+
197
+ #: plugin-options/general-options.php:92
198
+ msgid "Fields to show"
199
+ msgstr ""
200
+
201
+ #: plugin-options/general-options.php:93
202
+ msgid ""
203
+ "Select the fields to show in the comparison table and order them by "
204
+ "drag&drop (are included also the woocommerce attributes)"
205
+ msgstr ""
206
+
207
+ #: plugin-options/general-options.php:101
208
+ msgid "Repeat \"Price\" field"
209
+ msgstr ""
210
+
211
+ #: plugin-options/general-options.php:102
212
+ msgid "Repeat the \"Price\" field at the end of the table"
213
+ msgstr ""
214
+
215
+ #: plugin-options/general-options.php:110
216
+ msgid "Repeat \"Add to cart\" field"
217
+ msgstr ""
218
+
219
+ #: plugin-options/general-options.php:111
220
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
221
+ msgstr ""
222
+
223
+ #: plugin-options/general-options.php:119
224
+ msgid "Image size"
225
+ msgstr "Размер на изображението"
226
+
227
+ #: plugin-options/general-options.php:120
228
+ msgid "Set the size for the images"
229
+ msgstr ""
230
+
231
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
232
+ #, php-format
233
+ msgid ""
234
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
235
+ "benefit from all features!"
236
+ msgstr ""
237
+
238
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
239
+ msgid "UPGRADE"
240
+ msgstr ""
241
+
242
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
243
+ msgid "to the premium version"
244
+ msgstr ""
245
+
246
+ #: templates/admin/premium.php:238
247
+ msgid "Premium Features"
248
+ msgstr ""
249
+
250
+ #: templates/admin/premium.php:246
251
+ msgid "A DEDICATED PAGE"
252
+ msgstr ""
253
+
254
+ #: templates/admin/premium.php:249
255
+ #, php-format
256
+ msgid ""
257
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
258
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
259
+ "created automatically in your site and, adding it among the menu entries, "
260
+ "you will be able to give to your users the chance to access it easily "
261
+ "whenever they want."
262
+ msgstr ""
263
+
264
+ #: templates/admin/premium.php:259
265
+ msgid "CATEGORY COMPARATION"
266
+ msgstr ""
267
+
268
+ #: templates/admin/premium.php:262
269
+ #, php-format
270
+ msgid ""
271
+ "People are often confused by finding products of different categories in the "
272
+ "comparison table, creating difficulties in comparing the products they are "
273
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
274
+ "need: you will be able to separate the products in the table by category "
275
+ "affinity."
276
+ msgstr ""
277
+
278
+ #: templates/admin/premium.php:278
279
+ msgid "CATEGORY EXCLUSION "
280
+ msgstr ""
281
+
282
+ #: templates/admin/premium.php:281
283
+ #, php-format
284
+ msgid ""
285
+ "In your shop there may be product categories you don't want to be affected "
286
+ "by the plugin features, deleting the comparison button for them. The premium "
287
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
288
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
289
+ "of the feature, allowing the comparison only to those products of the "
290
+ "selected categories."
291
+ msgstr ""
292
+
293
+ #: templates/admin/premium.php:291
294
+ msgid "TABLE IMAGE"
295
+ msgstr ""
296
+
297
+ #: templates/admin/premium.php:294
298
+ #, php-format
299
+ msgid ""
300
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
301
+ "Select an image, upload it from the option panel and show it ahead of the "
302
+ "table to your users. "
303
+ msgstr ""
304
+
305
+ #: templates/admin/premium.php:310
306
+ msgid "DYNAMIC FIELDS"
307
+ msgstr ""
308
+
309
+ #: templates/admin/premium.php:313
310
+ #, php-format
311
+ msgid ""
312
+ "With this precious feature, you will be able to show in the table only the "
313
+ "fields that have information in at least one of the selected products."
314
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
315
+ "be no more empty lines in your comparison table."
316
+ msgstr ""
317
+
318
+ #: templates/admin/premium.php:323
319
+ msgid "SOCIAL NETWORK SHARING"
320
+ msgstr ""
321
+
322
+ #: templates/admin/premium.php:326
323
+ #, php-format
324
+ msgid ""
325
+ "One of the most appealing features of the premium version of the plugin.Four "
326
+ "social network sites for your users (Facebook, Twitter, Google + and "
327
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
328
+ "products they have selected."
329
+ msgstr ""
330
+
331
+ #: templates/admin/premium.php:342
332
+ msgid "RELATED PRODUCTS"
333
+ msgstr ""
334
+
335
+ #: templates/admin/premium.php:345
336
+ #, php-format
337
+ msgid ""
338
+ "All the products that have common categories and/or tags with those in the "
339
+ "comparison table will be showed in a slider, right under the comparison "
340
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
341
+ "users to discover the shop products of the shop related to those they are "
342
+ "interested into."
343
+ msgstr ""
344
+
345
+ #: templates/admin/premium.php:355
346
+ msgid "CUSTOMIZABLE STYLE"
347
+ msgstr ""
348
+
349
+ #: templates/admin/premium.php:358
350
+ #, php-format
351
+ msgid ""
352
+ "An advanced option panel that let you change all the colors of the plugin, "
353
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
354
+ "of your shop.We know it, looks also count... and we give you the right tools "
355
+ "to get to the best result."
356
+ msgstr ""
357
+
358
+ #: templates/compare.php:76
359
+ msgid "Close window [X]"
360
+ msgstr "Затвори"
361
+
362
+ #: templates/compare.php:103
363
+ msgid "No products added in the compare table."
364
+ msgstr "Няма добавени продукти за сравнение."
365
+
366
+ #: widgets/class.yith-woocompare-widget.php:23
367
+ msgid "The widget show the list of products added in the compare table."
368
+ msgstr ""
369
+
370
+ #: widgets/class.yith-woocompare-widget.php:27
371
+ msgid "YITH Woocommerce Compare Widget"
372
+ msgstr ""
373
+
374
+ #: widgets/class.yith-woocompare-widget.php:49
375
+ msgid "Clear all"
376
+ msgstr "Изтрий всички"
377
+
378
+ #~ msgid "Products Compare"
379
+ #~ msgstr "Сравнение на продуктите"
380
+
381
+ #~ msgid "Select a date"
382
+ #~ msgstr "Избери дата"
383
+
384
+ #~ msgid "Hours"
385
+ #~ msgstr "Часове"
386
+
387
+ #~ msgid "Minutes"
388
+ #~ msgstr "Минути"
389
+
390
+ #~ msgid "Upload"
391
+ #~ msgstr "Качи съдържание"
392
+
393
+ #~ msgid "Select a font family"
394
+ #~ msgstr "Изберете шрифт"
395
+
396
+ #~ msgid "Click to preview"
397
+ #~ msgstr "Предварителен преглед"
languages/yith-wcmp-es_ES.mo ADDED
Binary file
languages/yith-wcmp-es_ES.po ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:32+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:32+0200\n"
6
+ "Last-Translator: Radi Angelov <fullmetalradi@hotmail.com>\n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: es_ES\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
19
+
20
+ #: includes/class.yith-woocompare-admin.php:117
21
+ #: includes/class.yith-woocompare-admin.php:139
22
+ msgid "Settings"
23
+ msgstr ""
24
+
25
+ #: includes/class.yith-woocompare-admin.php:118
26
+ #: includes/class.yith-woocompare-admin.php:143
27
+ msgid "Premium Version"
28
+ msgstr ""
29
+
30
+ #: includes/class.yith-woocompare-admin.php:149
31
+ #: includes/class.yith-woocompare-admin.php:150
32
+ #: includes/class.yith-woocompare-frontend.php:353
33
+ #: plugin-options/general-options.php:40
34
+ #: widgets/class.yith-woocompare-widget.php:50
35
+ msgid "Compare"
36
+ msgstr "Comparar"
37
+
38
+ #: includes/class.yith-woocompare-admin.php:213
39
+ msgid "Plugin Documentation"
40
+ msgstr ""
41
+
42
+ #: includes/class.yith-woocompare-admin.php:232
43
+ msgid "YITH WooCommerce Compare Activated"
44
+ msgstr ""
45
+
46
+ #: includes/class.yith-woocompare-admin.php:233
47
+ #, php-format
48
+ msgid ""
49
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
50
+ "With this menu, you can access to all the settings of our plugins that you "
51
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
52
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
53
+ msgstr ""
54
+
55
+ #: includes/class.yith-woocompare-admin.php:244
56
+ msgid "YITH WooCommerce Compare Updated"
57
+ msgstr ""
58
+
59
+ #: includes/class.yith-woocompare-admin.php:245
60
+ #, php-format
61
+ msgid ""
62
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
63
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
64
+ "the previous version. When one of our plugins is updated, a new voice will "
65
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
66
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
67
+ msgstr ""
68
+
69
+ #: includes/class.yith-woocompare-admin.php:390
70
+ msgid "Do you want to hard crop the image?"
71
+ msgstr ""
72
+
73
+ #: includes/class.yith-woocompare-frontend.php:142
74
+ msgid "Added"
75
+ msgstr "Añadido"
76
+
77
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
78
+ msgid "Product Comparison"
79
+ msgstr "Comparacion de producto"
80
+
81
+ #: includes/class.yith-woocompare-frontend.php:265
82
+ msgid "In stock"
83
+ msgstr "En stock"
84
+
85
+ #: includes/class.yith-woocompare-frontend.php:548
86
+ msgid "No products to compare"
87
+ msgstr "Comparador de productos vacio"
88
+
89
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
90
+ msgid "Remove"
91
+ msgstr "Eliminar"
92
+
93
+ #: includes/class.yith-woocompare-helper.php:45
94
+ msgid "Image"
95
+ msgstr "Imagen"
96
+
97
+ #: includes/class.yith-woocompare-helper.php:46
98
+ #: widgets/class.yith-woocompare-widget.php:67
99
+ msgid "Title"
100
+ msgstr "Titulo"
101
+
102
+ #: includes/class.yith-woocompare-helper.php:47
103
+ msgid "Price"
104
+ msgstr "Precio"
105
+
106
+ #: includes/class.yith-woocompare-helper.php:48
107
+ msgid "Add to cart"
108
+ msgstr "Añadir al carrito"
109
+
110
+ #: includes/class.yith-woocompare-helper.php:49
111
+ msgid "Description"
112
+ msgstr "Descripcion"
113
+
114
+ #: includes/class.yith-woocompare-helper.php:50
115
+ msgid "Availability"
116
+ msgstr "Disponibilidad"
117
+
118
+ #: init.php:40
119
+ msgid ""
120
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
121
+ "WooCommerce in order to work."
122
+ msgstr ""
123
+
124
+ #: init.php:48
125
+ msgid ""
126
+ "You can't activate the free version of YITH WooCommerce Compare while you "
127
+ "are using the premium one."
128
+ msgstr ""
129
+
130
+ #: plugin-options/general-options.php:17
131
+ msgid "General Settings"
132
+ msgstr "Obciones generales"
133
+
134
+ #: plugin-options/general-options.php:24
135
+ msgid "Link or Button"
136
+ msgstr "Link o Boton"
137
+
138
+ #: plugin-options/general-options.php:25
139
+ msgid "Choose if you want to use a link or a button for the action button."
140
+ msgstr "Elige si deseas usar boton o link"
141
+
142
+ #: plugin-options/general-options.php:31
143
+ msgid "Link"
144
+ msgstr "Enlace"
145
+
146
+ #: plugin-options/general-options.php:32
147
+ msgid "Button"
148
+ msgstr "Boton"
149
+
150
+ #: plugin-options/general-options.php:37
151
+ msgid "Link/Button text"
152
+ msgstr "Texto del boton/link"
153
+
154
+ #: plugin-options/general-options.php:38
155
+ msgid "Type the text to use for the button or the link of the compare."
156
+ msgstr "Escribe el texto del boton/link comparar."
157
+
158
+ #: plugin-options/general-options.php:45
159
+ msgid "Show button in single product page"
160
+ msgstr "Mostrar boton en pagina de producto individual"
161
+
162
+ #: plugin-options/general-options.php:46
163
+ msgid "Say if you want to show the button in the single product page."
164
+ msgstr ""
165
+ "¿Quieres mostrar el boton de comparar en la pagina individual de cada "
166
+ "producto?"
167
+
168
+ #: plugin-options/general-options.php:54
169
+ msgid "Show button in products list"
170
+ msgstr "Mostrar boton en la lista de productos"
171
+
172
+ #: plugin-options/general-options.php:55
173
+ msgid "Say if you want to show the button in the products list."
174
+ msgstr "¿Quieres mostrar el boton de comparar en la lista de productos?"
175
+
176
+ #: plugin-options/general-options.php:63
177
+ msgid "Open automatically lightbox"
178
+ msgstr "Abrir lightbox (mensaje emergente) automaticamente"
179
+
180
+ #: plugin-options/general-options.php:64
181
+ msgid "Open link after click into \"Compare\" button\"."
182
+ msgstr "Abrir link despues de hacer click en \"Comparar\""
183
+
184
+ #: plugin-options/general-options.php:77
185
+ msgid "Table Settings"
186
+ msgstr "Opciones de tabla"
187
+
188
+ #: plugin-options/general-options.php:84
189
+ msgid "Table title"
190
+ msgstr "Titulo de tabla"
191
+
192
+ #: plugin-options/general-options.php:85
193
+ msgid "Type the text to use for the table title."
194
+ msgstr "Escribe el texto del boton/link comparar."
195
+
196
+ #: plugin-options/general-options.php:87
197
+ msgid "Compare products"
198
+ msgstr "Comparador de productos"
199
+
200
+ #: plugin-options/general-options.php:92
201
+ msgid "Fields to show"
202
+ msgstr "Mostrar boton en la lista de productos"
203
+
204
+ #: plugin-options/general-options.php:93
205
+ msgid ""
206
+ "Select the fields to show in the comparison table and order them by "
207
+ "drag&drop (are included also the woocommerce attributes)"
208
+ msgstr ""
209
+ "Elige que campos quieres mostrar en la tabla del comparador y ordenalos "
210
+ "simplemente arrastrandolos (estan incluidos los atributos de productos de "
211
+ "woocommerce)"
212
+
213
+ #: plugin-options/general-options.php:101
214
+ msgid "Repeat \"Price\" field"
215
+ msgstr ""
216
+
217
+ #: plugin-options/general-options.php:102
218
+ msgid "Repeat the \"Price\" field at the end of the table"
219
+ msgstr ""
220
+
221
+ #: plugin-options/general-options.php:110
222
+ msgid "Repeat \"Add to cart\" field"
223
+ msgstr ""
224
+
225
+ #: plugin-options/general-options.php:111
226
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
227
+ msgstr ""
228
+
229
+ #: plugin-options/general-options.php:119
230
+ msgid "Image size"
231
+ msgstr "Imagen"
232
+
233
+ #: plugin-options/general-options.php:120
234
+ msgid "Set the size for the images"
235
+ msgstr "Fijar el tamaño de la imagen"
236
+
237
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
238
+ #, php-format
239
+ msgid ""
240
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
241
+ "benefit from all features!"
242
+ msgstr ""
243
+
244
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
245
+ msgid "UPGRADE"
246
+ msgstr ""
247
+
248
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
249
+ msgid "to the premium version"
250
+ msgstr ""
251
+
252
+ #: templates/admin/premium.php:238
253
+ msgid "Premium Features"
254
+ msgstr ""
255
+
256
+ #: templates/admin/premium.php:246
257
+ msgid "A DEDICATED PAGE"
258
+ msgstr ""
259
+
260
+ #: templates/admin/premium.php:249
261
+ #, php-format
262
+ msgid ""
263
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
264
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
265
+ "created automatically in your site and, adding it among the menu entries, "
266
+ "you will be able to give to your users the chance to access it easily "
267
+ "whenever they want."
268
+ msgstr ""
269
+
270
+ #: templates/admin/premium.php:259
271
+ msgid "CATEGORY COMPARATION"
272
+ msgstr ""
273
+
274
+ #: templates/admin/premium.php:262
275
+ #, php-format
276
+ msgid ""
277
+ "People are often confused by finding products of different categories in the "
278
+ "comparison table, creating difficulties in comparing the products they are "
279
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
280
+ "need: you will be able to separate the products in the table by category "
281
+ "affinity."
282
+ msgstr ""
283
+
284
+ #: templates/admin/premium.php:278
285
+ msgid "CATEGORY EXCLUSION "
286
+ msgstr ""
287
+
288
+ #: templates/admin/premium.php:281
289
+ #, php-format
290
+ msgid ""
291
+ "In your shop there may be product categories you don't want to be affected "
292
+ "by the plugin features, deleting the comparison button for them. The premium "
293
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
294
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
295
+ "of the feature, allowing the comparison only to those products of the "
296
+ "selected categories."
297
+ msgstr ""
298
+
299
+ #: templates/admin/premium.php:291
300
+ msgid "TABLE IMAGE"
301
+ msgstr ""
302
+
303
+ #: templates/admin/premium.php:294
304
+ #, php-format
305
+ msgid ""
306
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
307
+ "Select an image, upload it from the option panel and show it ahead of the "
308
+ "table to your users. "
309
+ msgstr ""
310
+
311
+ #: templates/admin/premium.php:310
312
+ msgid "DYNAMIC FIELDS"
313
+ msgstr ""
314
+
315
+ #: templates/admin/premium.php:313
316
+ #, php-format
317
+ msgid ""
318
+ "With this precious feature, you will be able to show in the table only the "
319
+ "fields that have information in at least one of the selected products."
320
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
321
+ "be no more empty lines in your comparison table."
322
+ msgstr ""
323
+
324
+ #: templates/admin/premium.php:323
325
+ msgid "SOCIAL NETWORK SHARING"
326
+ msgstr ""
327
+
328
+ #: templates/admin/premium.php:326
329
+ #, php-format
330
+ msgid ""
331
+ "One of the most appealing features of the premium version of the plugin.Four "
332
+ "social network sites for your users (Facebook, Twitter, Google + and "
333
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
334
+ "products they have selected."
335
+ msgstr ""
336
+
337
+ #: templates/admin/premium.php:342
338
+ msgid "RELATED PRODUCTS"
339
+ msgstr ""
340
+
341
+ #: templates/admin/premium.php:345
342
+ #, php-format
343
+ msgid ""
344
+ "All the products that have common categories and/or tags with those in the "
345
+ "comparison table will be showed in a slider, right under the comparison "
346
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
347
+ "users to discover the shop products of the shop related to those they are "
348
+ "interested into."
349
+ msgstr ""
350
+
351
+ #: templates/admin/premium.php:355
352
+ msgid "CUSTOMIZABLE STYLE"
353
+ msgstr ""
354
+
355
+ #: templates/admin/premium.php:358
356
+ #, php-format
357
+ msgid ""
358
+ "An advanced option panel that let you change all the colors of the plugin, "
359
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
360
+ "of your shop.We know it, looks also count... and we give you the right tools "
361
+ "to get to the best result."
362
+ msgstr ""
363
+
364
+ #: templates/compare.php:76
365
+ msgid "Close window [X]"
366
+ msgstr "Cerrar ventana [X]"
367
+
368
+ #: templates/compare.php:103
369
+ msgid "No products added in the compare table."
370
+ msgstr "Comparador de productos"
371
+
372
+ #: widgets/class.yith-woocompare-widget.php:23
373
+ msgid "The widget show the list of products added in the compare table."
374
+ msgstr ""
375
+ "El widget muestra la lista de productos añadidos en la tabla de comparacion"
376
+
377
+ #: widgets/class.yith-woocompare-widget.php:27
378
+ msgid "YITH Woocommerce Compare Widget"
379
+ msgstr "YITH Woocommerce widget de comparador"
380
+
381
+ #: widgets/class.yith-woocompare-widget.php:49
382
+ msgid "Clear all"
383
+ msgstr "Eliminar todos"
384
+
385
+ #~ msgid "Products Compare"
386
+ #~ msgstr "Comparador de productos"
387
+
388
+ #~ msgid "Hard Crop?"
389
+ #~ msgstr "Hard Crop?"
390
+
391
+ #~ msgid "Repeat \"Price\" field at the end of the table"
392
+ #~ msgstr "Repetir campo \"Precio\" al final de la tabla"
393
+
394
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
395
+ #~ msgstr "Repetir campo \"Añadir al carrito\" al final de la tabla"
396
+
397
+ #~ msgid "Select a date"
398
+ #~ msgstr "Seleccionar fecha"
399
+
400
+ #~ msgid "Hours"
401
+ #~ msgstr "Horas"
402
+
403
+ #~ msgid "Minutes"
404
+ #~ msgstr "Minutos"
405
+
406
+ #~ msgid "Upload"
407
+ #~ msgstr "Cargar"
408
+
409
+ #~ msgid "px"
410
+ #~ msgstr "px"
411
+
412
+ #~ msgid "em"
413
+ #~ msgstr "em"
414
+
415
+ #~ msgid "pt"
416
+ #~ msgstr "pt"
417
+
418
+ #~ msgid "rem"
419
+ #~ msgstr "rem"
420
+
421
+ #~ msgid "Select a font family"
422
+ #~ msgstr "Seleccionar fuente"
423
+
424
+ #~ msgid "Regular"
425
+ #~ msgstr "Normal"
426
+
427
+ #~ msgid "Bold"
428
+ #~ msgstr "Negrita"
429
+
430
+ #~ msgid "Extra bold"
431
+ #~ msgstr "Extra negrita"
432
+
433
+ #~ msgid "Italic"
434
+ #~ msgstr "Cursiva"
435
+
436
+ #~ msgid "Italic bold"
437
+ #~ msgstr "Cursiva negrita"
438
+
439
+ #~ msgid "Click to preview"
440
+ #~ msgstr "Click para previsualizar"
languages/yith-wcmp-fa_IR.mo ADDED
Binary file
languages/yith-wcmp-fa_IR.po ADDED
@@ -0,0 +1,420 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:33+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:33+0200\n"
6
+ "Last-Translator: Khalil Delavaran <khalil.delavaran@gmail.com>\n"
7
+ "Language-Team: Qooqnos <khalil.delavaran@gmail.com>\n"
8
+ "Language: fa\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "سنجش"
36
+
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr "اضافه شد"
75
+
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
+ msgid "Product Comparison"
78
+ msgstr "سنجش محصولات"
79
+
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
+ msgid "In stock"
82
+ msgstr "داشتن در انبار"
83
+
84
+ #: includes/class.yith-woocompare-frontend.php:548
85
+ msgid "No products to compare"
86
+ msgstr "محصولاتی برای سنجش نیست"
87
+
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
+ msgid "Remove"
90
+ msgstr "پاک"
91
+
92
+ #: includes/class.yith-woocompare-helper.php:45
93
+ msgid "Image"
94
+ msgstr "نگاره"
95
+
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
+ msgid "Title"
99
+ msgstr "جستار"
100
+
101
+ #: includes/class.yith-woocompare-helper.php:47
102
+ msgid "Price"
103
+ msgstr "قیمت"
104
+
105
+ #: includes/class.yith-woocompare-helper.php:48
106
+ msgid "Add to cart"
107
+ msgstr "افزودن به سبد خرید"
108
+
109
+ #: includes/class.yith-woocompare-helper.php:49
110
+ msgid "Description"
111
+ msgstr "روشنگری"
112
+
113
+ #: includes/class.yith-woocompare-helper.php:50
114
+ msgid "Availability"
115
+ msgstr "دسترس پذیری"
116
+
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "پیکربندی همگانی"
132
+
133
+ #: plugin-options/general-options.php:24
134
+ msgid "Link or Button"
135
+ msgstr "لینک یا دکمه"
136
+
137
+ #: plugin-options/general-options.php:25
138
+ msgid "Choose if you want to use a link or a button for the action button."
139
+ msgstr "گزینش بکار بردن لینک و یا دکمه برای واکنش دکمه"
140
+
141
+ #: plugin-options/general-options.php:31
142
+ msgid "Link"
143
+ msgstr "لینک"
144
+
145
+ #: plugin-options/general-options.php:32
146
+ msgid "Button"
147
+ msgstr "دکمه"
148
+
149
+ #: plugin-options/general-options.php:37
150
+ msgid "Link/Button text"
151
+ msgstr "لینک یا دکمه"
152
+
153
+ #: plugin-options/general-options.php:38
154
+ msgid "Type the text to use for the button or the link of the compare."
155
+ msgstr "نوشته ای برای بکار بردن دکمه یا لینک مقایسه بنویسید"
156
+
157
+ #: plugin-options/general-options.php:45
158
+ msgid "Show button in single product page"
159
+ msgstr "نمایش دکمه در برگه محصول"
160
+
161
+ #: plugin-options/general-options.php:46
162
+ msgid "Say if you want to show the button in the single product page."
163
+ msgstr "اگر می خواهید دکمه در برگه محصول نمایش داده شود"
164
+
165
+ #: plugin-options/general-options.php:54
166
+ msgid "Show button in products list"
167
+ msgstr "نمایش دکمه در لیست محصولات"
168
+
169
+ #: plugin-options/general-options.php:55
170
+ msgid "Say if you want to show the button in the products list."
171
+ msgstr "اگر می خواهید دکمه در لیست محصول نمایش داده شود"
172
+
173
+ #: plugin-options/general-options.php:63
174
+ msgid "Open automatically lightbox"
175
+ msgstr "باز کردن اتوماتیک جعبه نور"
176
+
177
+ #: plugin-options/general-options.php:64
178
+ msgid "Open link after click into \"Compare\" button\"."
179
+ msgstr " باز کردن پیوند پس از \"سنجش\" دکمه\"کلیک کنید"
180
+
181
+ #: plugin-options/general-options.php:77
182
+ msgid "Table Settings"
183
+ msgstr "پیکربندی جدول"
184
+
185
+ #: plugin-options/general-options.php:84
186
+ msgid "Table title"
187
+ msgstr ""
188
+
189
+ #: plugin-options/general-options.php:85
190
+ msgid "Type the text to use for the table title."
191
+ msgstr ""
192
+
193
+ #: plugin-options/general-options.php:87
194
+ msgid "Compare products"
195
+ msgstr "سنجش محصولات"
196
+
197
+ #: plugin-options/general-options.php:92
198
+ msgid "Fields to show"
199
+ msgstr "فیلدهای نمایش"
200
+
201
+ #: plugin-options/general-options.php:93
202
+ msgid ""
203
+ "Select the fields to show in the comparison table and order them by "
204
+ "drag&drop (are included also the woocommerce attributes)"
205
+ msgstr ""
206
+ "انتخاب این گزینه برای نشان دادن در جدول سنجش و سفارش سازی آنها با کشیدن و "
207
+ "رها کردن دکمه ماوس (ویژگی های ووکامرس را شامل می شود)"
208
+
209
+ #: plugin-options/general-options.php:101
210
+ msgid "Repeat \"Price\" field"
211
+ msgstr ""
212
+
213
+ #: plugin-options/general-options.php:102
214
+ msgid "Repeat the \"Price\" field at the end of the table"
215
+ msgstr ""
216
+
217
+ #: plugin-options/general-options.php:110
218
+ msgid "Repeat \"Add to cart\" field"
219
+ msgstr ""
220
+
221
+ #: plugin-options/general-options.php:111
222
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
223
+ msgstr ""
224
+
225
+ #: plugin-options/general-options.php:119
226
+ msgid "Image size"
227
+ msgstr "اندازه نگاره"
228
+
229
+ #: plugin-options/general-options.php:120
230
+ msgid "Set the size for the images"
231
+ msgstr "تعیین اندازه برای نگاره"
232
+
233
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
234
+ #, php-format
235
+ msgid ""
236
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
237
+ "benefit from all features!"
238
+ msgstr ""
239
+
240
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
241
+ msgid "UPGRADE"
242
+ msgstr ""
243
+
244
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
245
+ msgid "to the premium version"
246
+ msgstr ""
247
+
248
+ #: templates/admin/premium.php:238
249
+ msgid "Premium Features"
250
+ msgstr ""
251
+
252
+ #: templates/admin/premium.php:246
253
+ msgid "A DEDICATED PAGE"
254
+ msgstr ""
255
+
256
+ #: templates/admin/premium.php:249
257
+ #, php-format
258
+ msgid ""
259
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
260
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
261
+ "created automatically in your site and, adding it among the menu entries, "
262
+ "you will be able to give to your users the chance to access it easily "
263
+ "whenever they want."
264
+ msgstr ""
265
+
266
+ #: templates/admin/premium.php:259
267
+ msgid "CATEGORY COMPARATION"
268
+ msgstr ""
269
+
270
+ #: templates/admin/premium.php:262
271
+ #, php-format
272
+ msgid ""
273
+ "People are often confused by finding products of different categories in the "
274
+ "comparison table, creating difficulties in comparing the products they are "
275
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
276
+ "need: you will be able to separate the products in the table by category "
277
+ "affinity."
278
+ msgstr ""
279
+
280
+ #: templates/admin/premium.php:278
281
+ msgid "CATEGORY EXCLUSION "
282
+ msgstr ""
283
+
284
+ #: templates/admin/premium.php:281
285
+ #, php-format
286
+ msgid ""
287
+ "In your shop there may be product categories you don't want to be affected "
288
+ "by the plugin features, deleting the comparison button for them. The premium "
289
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
290
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
291
+ "of the feature, allowing the comparison only to those products of the "
292
+ "selected categories."
293
+ msgstr ""
294
+
295
+ #: templates/admin/premium.php:291
296
+ msgid "TABLE IMAGE"
297
+ msgstr ""
298
+
299
+ #: templates/admin/premium.php:294
300
+ #, php-format
301
+ msgid ""
302
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
303
+ "Select an image, upload it from the option panel and show it ahead of the "
304
+ "table to your users. "
305
+ msgstr ""
306
+
307
+ #: templates/admin/premium.php:310
308
+ msgid "DYNAMIC FIELDS"
309
+ msgstr ""
310
+
311
+ #: templates/admin/premium.php:313
312
+ #, php-format
313
+ msgid ""
314
+ "With this precious feature, you will be able to show in the table only the "
315
+ "fields that have information in at least one of the selected products."
316
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
317
+ "be no more empty lines in your comparison table."
318
+ msgstr ""
319
+
320
+ #: templates/admin/premium.php:323
321
+ msgid "SOCIAL NETWORK SHARING"
322
+ msgstr ""
323
+
324
+ #: templates/admin/premium.php:326
325
+ #, php-format
326
+ msgid ""
327
+ "One of the most appealing features of the premium version of the plugin.Four "
328
+ "social network sites for your users (Facebook, Twitter, Google + and "
329
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
330
+ "products they have selected."
331
+ msgstr ""
332
+
333
+ #: templates/admin/premium.php:342
334
+ msgid "RELATED PRODUCTS"
335
+ msgstr ""
336
+
337
+ #: templates/admin/premium.php:345
338
+ #, php-format
339
+ msgid ""
340
+ "All the products that have common categories and/or tags with those in the "
341
+ "comparison table will be showed in a slider, right under the comparison "
342
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
343
+ "users to discover the shop products of the shop related to those they are "
344
+ "interested into."
345
+ msgstr ""
346
+
347
+ #: templates/admin/premium.php:355
348
+ msgid "CUSTOMIZABLE STYLE"
349
+ msgstr ""
350
+
351
+ #: templates/admin/premium.php:358
352
+ #, php-format
353
+ msgid ""
354
+ "An advanced option panel that let you change all the colors of the plugin, "
355
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
356
+ "of your shop.We know it, looks also count... and we give you the right tools "
357
+ "to get to the best result."
358
+ msgstr ""
359
+
360
+ #: templates/compare.php:76
361
+ msgid "Close window [X]"
362
+ msgstr "بستن پنجره [X]"
363
+
364
+ #: templates/compare.php:103
365
+ msgid "No products added in the compare table."
366
+ msgstr "هیچ محصولی افزوده نشده است برای جدول سنجش"
367
+
368
+ #: widgets/class.yith-woocompare-widget.php:23
369
+ msgid "The widget show the list of products added in the compare table."
370
+ msgstr "ویجت نشان می دهد لیستی از محصولات افزوده شده در جدول سنجش"
371
+
372
+ #: widgets/class.yith-woocompare-widget.php:27
373
+ msgid "YITH Woocommerce Compare Widget"
374
+ msgstr "ویجت سنجش ووکاکرس YITH"
375
+
376
+ #: widgets/class.yith-woocompare-widget.php:49
377
+ msgid "Clear all"
378
+ msgstr "پاک کردن همه"
379
+
380
+ #~ msgid "Products Compare"
381
+ #~ msgstr "سنجش محصولات"
382
+
383
+ #~ msgid "Repeat \"Price\" field at the end of the table"
384
+ #~ msgstr "تکرار گزینه \"قیمت\" در پایان جدول"
385
+
386
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
387
+ #~ msgstr "تکرار گزینه \"افزودن به سبد خرید\" در پایان جدول"
388
+
389
+ #~ msgid "Select a date"
390
+ #~ msgstr "انتخاب روز"
391
+
392
+ #~ msgid "Hours"
393
+ #~ msgstr "ساعتها"
394
+
395
+ #~ msgid "Minutes"
396
+ #~ msgstr "دقیقه ها"
397
+
398
+ #~ msgid "Upload"
399
+ #~ msgstr "بارگذاری"
400
+
401
+ #~ msgid "Select a font family"
402
+ #~ msgstr "گزینش قلم"
403
+
404
+ #~ msgid "Regular"
405
+ #~ msgstr "معمولی"
406
+
407
+ #~ msgid "Bold"
408
+ #~ msgstr "کلفت"
409
+
410
+ #~ msgid "Extra bold"
411
+ #~ msgstr "خیلی کلفت"
412
+
413
+ #~ msgid "Italic"
414
+ #~ msgstr "کج"
415
+
416
+ #~ msgid "Italic bold"
417
+ #~ msgstr "کلفت کج"
418
+
419
+ #~ msgid "Click to preview"
420
+ #~ msgstr "کلیک برای پیش نمایش"
languages/yith-wcmp-fr_FR.mo ADDED
Binary file
languages/yith-wcmp-fr_FR.po ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:46+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:46+0200\n"
6
+ "Last-Translator: YIThemes <support@yithemes.com>\n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "Comparer"
36
+
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr "Ajouté"
75
+
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
+ msgid "Product Comparison"
78
+ msgstr "Comparaison de produits"
79
+
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
+ msgid "In stock"
82
+ msgstr "En stock"
83
+
84
+ #: includes/class.yith-woocompare-frontend.php:548
85
+ msgid "No products to compare"
86
+ msgstr "Aucun produits à comparer"
87
+
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
+ msgid "Remove"
90
+ msgstr "Retirer"
91
+
92
+ #: includes/class.yith-woocompare-helper.php:45
93
+ msgid "Image"
94
+ msgstr ""
95
+
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
+ msgid "Title"
99
+ msgstr "Titre"
100
+
101
+ #: includes/class.yith-woocompare-helper.php:47
102
+ msgid "Price"
103
+ msgstr "Prix"
104
+
105
+ #: includes/class.yith-woocompare-helper.php:48
106
+ msgid "Add to cart"
107
+ msgstr "Ajouter au panier"
108
+
109
+ #: includes/class.yith-woocompare-helper.php:49
110
+ msgid "Description"
111
+ msgstr ""
112
+
113
+ #: includes/class.yith-woocompare-helper.php:50
114
+ msgid "Availability"
115
+ msgstr "Disponibilité"
116
+
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "Réglages"
132
+
133
+ #: plugin-options/general-options.php:24
134
+ msgid "Link or Button"
135
+ msgstr "Lien ou bouton"
136
+
137
+ #: plugin-options/general-options.php:25
138
+ msgid "Choose if you want to use a link or a button for the action button."
139
+ msgstr "utiliser un lien ou un bouton"
140
+
141
+ #: plugin-options/general-options.php:31
142
+ msgid "Link"
143
+ msgstr "lien"
144
+
145
+ #: plugin-options/general-options.php:32
146
+ msgid "Button"
147
+ msgstr "bouton"
148
+
149
+ #: plugin-options/general-options.php:37
150
+ msgid "Link/Button text"
151
+ msgstr "texte du lien ou bouton"
152
+
153
+ #: plugin-options/general-options.php:38
154
+ msgid "Type the text to use for the button or the link of the compare."
155
+ msgstr "inscriver le texte pour le bouton ou le lien pour comparer"
156
+
157
+ #: plugin-options/general-options.php:45
158
+ msgid "Show button in single product page"
159
+ msgstr "montrer le bouton sur page produit"
160
+
161
+ #: plugin-options/general-options.php:46
162
+ msgid "Say if you want to show the button in the single product page."
163
+ msgstr "dites si vous souhaitez montrer le bouton sur page produit"
164
+
165
+ #: plugin-options/general-options.php:54
166
+ msgid "Show button in products list"
167
+ msgstr "montrer le bouton sur liste de produit"
168
+
169
+ #: plugin-options/general-options.php:55
170
+ msgid "Say if you want to show the button in the products list."
171
+ msgstr "dites si vous souhaitez montrer le bouton sur liste de produit"
172
+
173
+ #: plugin-options/general-options.php:63
174
+ msgid "Open automatically lightbox"
175
+ msgstr "ouverture lightbox auto"
176
+
177
+ #: plugin-options/general-options.php:64
178
+ msgid "Open link after click into \"Compare\" button\"."
179
+ msgstr "ouvrir lien apres le click sur bouton"
180
+
181
+ #: plugin-options/general-options.php:77
182
+ msgid "Table Settings"
183
+ msgstr "reglages panneau"
184
+
185
+ #: plugin-options/general-options.php:84
186
+ msgid "Table title"
187
+ msgstr ""
188
+
189
+ #: plugin-options/general-options.php:85
190
+ msgid "Type the text to use for the table title."
191
+ msgstr ""
192
+
193
+ #: plugin-options/general-options.php:87
194
+ msgid "Compare products"
195
+ msgstr "Comparer les produits"
196
+
197
+ #: plugin-options/general-options.php:92
198
+ msgid "Fields to show"
199
+ msgstr "champs a montrer"
200
+
201
+ #: plugin-options/general-options.php:93
202
+ msgid ""
203
+ "Select the fields to show in the comparison table and order them by "
204
+ "drag&drop (are included also the woocommerce attributes)"
205
+ msgstr ""
206
+ "selectionnez les champs a montrer dans le tabelau de comparaison (en faisant "
207
+ "glisser deposer)"
208
+
209
+ #: plugin-options/general-options.php:101
210
+ msgid "Repeat \"Price\" field"
211
+ msgstr ""
212
+
213
+ #: plugin-options/general-options.php:102
214
+ msgid "Repeat the \"Price\" field at the end of the table"
215
+ msgstr ""
216
+
217
+ #: plugin-options/general-options.php:110
218
+ msgid "Repeat \"Add to cart\" field"
219
+ msgstr ""
220
+
221
+ #: plugin-options/general-options.php:111
222
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
223
+ msgstr ""
224
+
225
+ #: plugin-options/general-options.php:119
226
+ msgid "Image size"
227
+ msgstr "taille image"
228
+
229
+ #: plugin-options/general-options.php:120
230
+ msgid "Set the size for the images"
231
+ msgstr "ajuster tialle image"
232
+
233
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
234
+ #, php-format
235
+ msgid ""
236
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
237
+ "benefit from all features!"
238
+ msgstr ""
239
+
240
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
241
+ msgid "UPGRADE"
242
+ msgstr ""
243
+
244
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
245
+ msgid "to the premium version"
246
+ msgstr ""
247
+
248
+ #: templates/admin/premium.php:238
249
+ msgid "Premium Features"
250
+ msgstr ""
251
+
252
+ #: templates/admin/premium.php:246
253
+ msgid "A DEDICATED PAGE"
254
+ msgstr ""
255
+
256
+ #: templates/admin/premium.php:249
257
+ #, php-format
258
+ msgid ""
259
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
260
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
261
+ "created automatically in your site and, adding it among the menu entries, "
262
+ "you will be able to give to your users the chance to access it easily "
263
+ "whenever they want."
264
+ msgstr ""
265
+
266
+ #: templates/admin/premium.php:259
267
+ msgid "CATEGORY COMPARATION"
268
+ msgstr ""
269
+
270
+ #: templates/admin/premium.php:262
271
+ #, php-format
272
+ msgid ""
273
+ "People are often confused by finding products of different categories in the "
274
+ "comparison table, creating difficulties in comparing the products they are "
275
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
276
+ "need: you will be able to separate the products in the table by category "
277
+ "affinity."
278
+ msgstr ""
279
+
280
+ #: templates/admin/premium.php:278
281
+ msgid "CATEGORY EXCLUSION "
282
+ msgstr ""
283
+
284
+ #: templates/admin/premium.php:281
285
+ #, php-format
286
+ msgid ""
287
+ "In your shop there may be product categories you don't want to be affected "
288
+ "by the plugin features, deleting the comparison button for them. The premium "
289
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
290
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
291
+ "of the feature, allowing the comparison only to those products of the "
292
+ "selected categories."
293
+ msgstr ""
294
+
295
+ #: templates/admin/premium.php:291
296
+ msgid "TABLE IMAGE"
297
+ msgstr ""
298
+
299
+ #: templates/admin/premium.php:294
300
+ #, php-format
301
+ msgid ""
302
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
303
+ "Select an image, upload it from the option panel and show it ahead of the "
304
+ "table to your users. "
305
+ msgstr ""
306
+
307
+ #: templates/admin/premium.php:310
308
+ msgid "DYNAMIC FIELDS"
309
+ msgstr ""
310
+
311
+ #: templates/admin/premium.php:313
312
+ #, php-format
313
+ msgid ""
314
+ "With this precious feature, you will be able to show in the table only the "
315
+ "fields that have information in at least one of the selected products."
316
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
317
+ "be no more empty lines in your comparison table."
318
+ msgstr ""
319
+
320
+ #: templates/admin/premium.php:323
321
+ msgid "SOCIAL NETWORK SHARING"
322
+ msgstr ""
323
+
324
+ #: templates/admin/premium.php:326
325
+ #, php-format
326
+ msgid ""
327
+ "One of the most appealing features of the premium version of the plugin.Four "
328
+ "social network sites for your users (Facebook, Twitter, Google + and "
329
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
330
+ "products they have selected."
331
+ msgstr ""
332
+
333
+ #: templates/admin/premium.php:342
334
+ msgid "RELATED PRODUCTS"
335
+ msgstr ""
336
+
337
+ #: templates/admin/premium.php:345
338
+ #, php-format
339
+ msgid ""
340
+ "All the products that have common categories and/or tags with those in the "
341
+ "comparison table will be showed in a slider, right under the comparison "
342
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
343
+ "users to discover the shop products of the shop related to those they are "
344
+ "interested into."
345
+ msgstr ""
346
+
347
+ #: templates/admin/premium.php:355
348
+ msgid "CUSTOMIZABLE STYLE"
349
+ msgstr ""
350
+
351
+ #: templates/admin/premium.php:358
352
+ #, php-format
353
+ msgid ""
354
+ "An advanced option panel that let you change all the colors of the plugin, "
355
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
356
+ "of your shop.We know it, looks also count... and we give you the right tools "
357
+ "to get to the best result."
358
+ msgstr ""
359
+
360
+ #: templates/compare.php:76
361
+ msgid "Close window [X]"
362
+ msgstr "Fermer ce tableau"
363
+
364
+ #: templates/compare.php:103
365
+ msgid "No products added in the compare table."
366
+ msgstr "Aucun produit à comparer"
367
+
368
+ #: widgets/class.yith-woocompare-widget.php:23
369
+ msgid "The widget show the list of products added in the compare table."
370
+ msgstr "le widget montre les produits à comparer"
371
+
372
+ #: widgets/class.yith-woocompare-widget.php:27
373
+ msgid "YITH Woocommerce Compare Widget"
374
+ msgstr ""
375
+
376
+ #: widgets/class.yith-woocompare-widget.php:49
377
+ msgid "Clear all"
378
+ msgstr "Retirer tout"
379
+
380
+ #~ msgid "Products Compare"
381
+ #~ msgstr "Comparaison de produits"
382
+
383
+ #~ msgid "Repeat \"Price\" field at the end of the table"
384
+ #~ msgstr "Repeter le prix à la fin du tabelau"
385
+
386
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
387
+ #~ msgstr "repeter ajout au panier a la fin du tableau"
388
+
389
+ #~ msgid "Select a date"
390
+ #~ msgstr "Choisir une date"
391
+
392
+ #~ msgid "Hours"
393
+ #~ msgstr "Heures"
394
+
395
+ #~ msgid "Minutes"
396
+ #~ msgstr "Minutes"
397
+
398
+ #~ msgid "Upload"
399
+ #~ msgstr "Mettre en ligne"
400
+
401
+ #~ msgid "Click to preview"
402
+ #~ msgstr "Cliquer pour previsualiser"
languages/yith-wcmp-it_IT.mo ADDED
Binary file
languages/{yit-it_IT.po → yith-wcmp-it_IT.po} RENAMED
@@ -1,150 +1,207 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: YITH Woocommerce Compare\n"
4
- "POT-Creation-Date: 2014-02-13 09:30+0100\n"
5
- "PO-Revision-Date: 2014-02-13 09:31+0100\n"
6
  "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
  "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
- "Language: English\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "X-Generator: Poedit 1.5.5\n"
13
  "X-Poedit-KeywordsList: __;_e;_x\n"
14
- "X-Poedit-Basepath: ./\n"
15
- "X-Poedit-SearchPath-0: ..\n"
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- #: ../class.yith-woocompare-admin.php:129
18
- msgid "Products Compare"
19
- msgstr "Compara Prodotti"
 
 
 
 
20
 
21
- #: ../class.yith-woocompare-admin.php:143 ../yith-woocompare-options.php:15
22
- msgid "General Settings"
23
- msgstr "Impostazioni Generali"
24
 
25
- #: ../class.yith-woocompare-frontend.php:142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  msgid "Added"
27
  msgstr "Aggiungo"
28
 
29
- #: ../class.yith-woocompare-frontend.php:143 ../templates/compare.php:50
30
  msgid "Product Comparison"
31
  msgstr "Comparazione Prodotto"
32
 
33
- #: ../class.yith-woocompare-frontend.php:254
34
  msgid "In stock"
35
  msgstr "In stock"
36
 
37
- #: ../class.yith-woocompare-frontend.php:337 ../yith-woocompare-options.php:38
38
- #: ../widgets/class.yith-woocompare-widget.php:38
39
- msgid "Compare"
40
- msgstr "Compara"
41
-
42
- #: ../class.yith-woocompare-frontend.php:496
43
  msgid "No products to compare"
44
  msgstr "Nessun prodotto da comparare"
45
 
46
- #: ../class.yith-woocompare-frontend.php:506 ../templates/compare.php:105
47
  msgid "Remove"
48
  msgstr "Rimuovi"
49
 
50
- #: ../class.yith-woocompare-helper.php:38
51
  msgid "Image"
52
  msgstr "Immagine"
53
 
54
- #: ../class.yith-woocompare-helper.php:39
55
- #: ../widgets/class.yith-woocompare-widget.php:55
56
  msgid "Title"
57
  msgstr "Titolo"
58
 
59
- #: ../class.yith-woocompare-helper.php:40
60
  msgid "Price"
61
  msgstr "Prezzo"
62
 
63
- #: ../class.yith-woocompare-helper.php:41
64
  msgid "Add to cart"
65
  msgstr "Aggiungi al carrello"
66
 
67
- #: ../class.yith-woocompare-helper.php:42
68
  msgid "Description"
69
  msgstr "Descrizione"
70
 
71
- #: ../class.yith-woocompare-helper.php:43
72
  msgid "Availability"
73
  msgstr "Disponibilità"
74
 
75
- #: ../yith-woocompare-options.php:22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  msgid "Link or Button"
77
  msgstr "Collegamento o Pulsante"
78
 
79
- #: ../yith-woocompare-options.php:23
80
  msgid "Choose if you want to use a link or a button for the action button."
81
  msgstr ""
82
  "Scegli se vuoi usare un collegamento o un pulsante per l'azione di "
83
  "\"Comparazione\""
84
 
85
- #: ../yith-woocompare-options.php:29
86
  msgid "Link"
87
  msgstr "Collegamento"
88
 
89
- #: ../yith-woocompare-options.php:30
90
  msgid "Button"
91
  msgstr "Pulsante"
92
 
93
- #: ../yith-woocompare-options.php:35
94
  msgid "Link/Button text"
95
  msgstr "Testo Link/Pulsante"
96
 
97
- #: ../yith-woocompare-options.php:36
98
  msgid "Type the text to use for the button or the link of the compare."
99
  msgstr ""
100
 
101
- #: ../yith-woocompare-options.php:43
102
  msgid "Show button in single product page"
103
  msgstr "Mostra pulsante nella pagina del dettaglio prodotto"
104
 
105
- #: ../yith-woocompare-options.php:44
106
  msgid "Say if you want to show the button in the single product page."
107
  msgstr ""
108
  "Scegli se vuoi mostrare il pulsante nella pagina dettaglio del prodotto."
109
 
110
- #: ../yith-woocompare-options.php:52
111
  msgid "Show button in products list"
112
  msgstr "Mostra pulsante nella lista prodotti"
113
 
114
- #: ../yith-woocompare-options.php:53
115
  msgid "Say if you want to show the button in the products list."
116
  msgstr "Imposta se vuoi mostrare il pulsante nella lista prodotti."
117
 
118
- #: ../yith-woocompare-options.php:61
119
  msgid "Open automatically lightbox"
120
  msgstr "Apri la lightbox automaticamente"
121
 
122
- #: ../yith-woocompare-options.php:62
123
  msgid "Open link after click into \"Compare\" button\"."
124
  msgstr "Apri pagina dopo aver cliccato sul pulsante \"Compare\"."
125
 
126
- #: ../yith-woocompare-options.php:74
127
  msgid "Table Settings"
128
  msgstr "Impostazioni tabella."
129
 
130
- #: ../yith-woocompare-options.php:81
131
  msgid "Table title"
132
  msgstr "Titolo Tabella"
133
 
134
- #: ../yith-woocompare-options.php:82
135
  msgid "Type the text to use for the table title."
136
  msgstr ""
137
 
138
- #: ../yith-woocompare-options.php:84
139
  msgid "Compare products"
140
  msgstr "Compara prodotti"
141
 
142
- #: ../yith-woocompare-options.php:89
143
  msgid "Fields to show"
144
  msgstr "Campi da mostrare"
145
 
146
- #: ../yith-woocompare-options.php:90 ../yith-woocompare-options.php:99
147
- #: ../yith-woocompare-options.php:108
148
  msgid ""
149
  "Select the fields to show in the comparison table and order them by "
150
  "drag&drop (are included also the woocommerce attributes)"
@@ -152,110 +209,237 @@ msgstr ""
152
  "Seleziona i campi da mostrare nella tabella di comparazione e ordinali "
153
  "attraverso il drag&drop (sono inclusi anche gli attributi di woocommerce)"
154
 
155
- #: ../yith-woocompare-options.php:98
156
- msgid "Repeat \"Price\" field at the end of the table"
157
- msgstr "Ripeti il campo \"Prezzo\" alla fine della tabella"
 
 
 
 
 
 
 
 
158
 
159
- #: ../yith-woocompare-options.php:107
160
- msgid "Repeat \"Add to cart\" field at the end of the table"
161
- msgstr "Ripeti il campo con \"Aggiungi al carrello\" alla fine della tabella"
162
 
163
- #: ../yith-woocompare-options.php:116
164
  msgid "Image size"
165
  msgstr "Dimensione immagine"
166
 
167
- #: ../yith-woocompare-options.php:117
168
  msgid "Set the size for the images"
169
  msgstr "Imposta la dimensione per le immagini"
170
 
171
- #: ../templates/compare.php:72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  msgid "Close window [X]"
173
  msgstr "Chiudi finestra [X]"
174
 
175
- #: ../templates/compare.php:97
176
  msgid "No products added in the compare table."
177
  msgstr "Nessun prodotto aggiunto nella tabella di comparazione."
178
 
179
- #: ../widgets/class.yith-woocompare-widget.php:21
180
  msgid "The widget show the list of products added in the compare table."
181
  msgstr ""
182
  "Widget che mostra la lista dei prodotti aggiunti nella tabella di "
183
  "comparazione."
184
 
185
- #: ../widgets/class.yith-woocompare-widget.php:22
186
  msgid "YITH Woocommerce Compare Widget"
187
  msgstr "YITH Woocommerce Compare Widget"
188
 
189
- #: ../widgets/class.yith-woocompare-widget.php:37
190
  msgid "Clear all"
191
  msgstr "Cancella tutti"
192
 
193
- #: ../yit-common/yith-panel.php:406
194
- msgid "Select a date"
195
- msgstr "Seleziona data"
196
 
197
- #: ../yit-common/yith-panel.php:407
198
- msgid "Hours"
199
- msgstr "Ore"
200
 
201
- #: ../yit-common/yith-panel.php:408 ../yit-common/yith-panel.php:409
202
- msgid "Minutes"
203
- msgstr "Minuti"
 
 
 
 
 
 
204
 
205
- #: ../yit-common/yith-panel.php:417
206
- msgid "Upload"
207
- msgstr "Carica"
208
 
209
- #: ../yit-common/yith-panel.php:444
210
- msgid "px"
211
- msgstr "px"
212
 
213
- #: ../yit-common/yith-panel.php:445
214
- msgid "em"
215
- msgstr "em"
216
 
217
- #: ../yit-common/yith-panel.php:446
218
- msgid "pt"
219
- msgstr "pt"
220
 
221
- #: ../yit-common/yith-panel.php:447
222
- msgid "rem"
223
- msgstr "rem"
224
 
225
- #: ../yit-common/yith-panel.php:457
226
- msgid "Select a font family"
227
- msgstr "Seleziona la famiglia font"
228
 
229
- #: ../yit-common/yith-panel.php:465
230
- msgid "Regular"
231
- msgstr "Normale"
232
 
233
- #: ../yit-common/yith-panel.php:466
234
- msgid "Bold"
235
- msgstr "Grassetto"
236
 
237
- #: ../yit-common/yith-panel.php:467
238
- msgid "Extra bold"
239
- msgstr "Extra bold"
240
 
241
- #: ../yit-common/yith-panel.php:468
242
- msgid "Italic"
243
- msgstr "Corsivo"
244
 
245
- #: ../yit-common/yith-panel.php:469
246
- msgid "Italic bold"
247
- msgstr "Grassetto corsivo"
248
 
249
- #: ../yit-common/yith-panel.php:481
250
- msgid "Click to preview"
251
- msgstr "Clicca per anteprima"
 
 
252
 
253
  #~ msgid "Woocommerce Compare"
254
  #~ msgstr "Modalità Manutenzione"
255
 
256
- #~ msgid "Settings"
257
- #~ msgstr "Impostazioni"
258
-
259
  #~ msgid "Docs"
260
  #~ msgstr "Documentazione"
261
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:47+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:47+0200\n"
6
  "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
  "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
  "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr "Impostazioni"
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
 
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "Compara"
36
 
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
 
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
  msgid "Added"
74
  msgstr "Aggiungo"
75
 
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
  msgid "Product Comparison"
78
  msgstr "Comparazione Prodotto"
79
 
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
  msgid "In stock"
82
  msgstr "In stock"
83
 
84
+ #: includes/class.yith-woocompare-frontend.php:548
 
 
 
 
 
85
  msgid "No products to compare"
86
  msgstr "Nessun prodotto da comparare"
87
 
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
  msgid "Remove"
90
  msgstr "Rimuovi"
91
 
92
+ #: includes/class.yith-woocompare-helper.php:45
93
  msgid "Image"
94
  msgstr "Immagine"
95
 
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
  msgid "Title"
99
  msgstr "Titolo"
100
 
101
+ #: includes/class.yith-woocompare-helper.php:47
102
  msgid "Price"
103
  msgstr "Prezzo"
104
 
105
+ #: includes/class.yith-woocompare-helper.php:48
106
  msgid "Add to cart"
107
  msgstr "Aggiungi al carrello"
108
 
109
+ #: includes/class.yith-woocompare-helper.php:49
110
  msgid "Description"
111
  msgstr "Descrizione"
112
 
113
+ #: includes/class.yith-woocompare-helper.php:50
114
  msgid "Availability"
115
  msgstr "Disponibilità"
116
 
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "Impostazioni Generali"
132
+
133
+ #: plugin-options/general-options.php:24
134
  msgid "Link or Button"
135
  msgstr "Collegamento o Pulsante"
136
 
137
+ #: plugin-options/general-options.php:25
138
  msgid "Choose if you want to use a link or a button for the action button."
139
  msgstr ""
140
  "Scegli se vuoi usare un collegamento o un pulsante per l'azione di "
141
  "\"Comparazione\""
142
 
143
+ #: plugin-options/general-options.php:31
144
  msgid "Link"
145
  msgstr "Collegamento"
146
 
147
+ #: plugin-options/general-options.php:32
148
  msgid "Button"
149
  msgstr "Pulsante"
150
 
151
+ #: plugin-options/general-options.php:37
152
  msgid "Link/Button text"
153
  msgstr "Testo Link/Pulsante"
154
 
155
+ #: plugin-options/general-options.php:38
156
  msgid "Type the text to use for the button or the link of the compare."
157
  msgstr ""
158
 
159
+ #: plugin-options/general-options.php:45
160
  msgid "Show button in single product page"
161
  msgstr "Mostra pulsante nella pagina del dettaglio prodotto"
162
 
163
+ #: plugin-options/general-options.php:46
164
  msgid "Say if you want to show the button in the single product page."
165
  msgstr ""
166
  "Scegli se vuoi mostrare il pulsante nella pagina dettaglio del prodotto."
167
 
168
+ #: plugin-options/general-options.php:54
169
  msgid "Show button in products list"
170
  msgstr "Mostra pulsante nella lista prodotti"
171
 
172
+ #: plugin-options/general-options.php:55
173
  msgid "Say if you want to show the button in the products list."
174
  msgstr "Imposta se vuoi mostrare il pulsante nella lista prodotti."
175
 
176
+ #: plugin-options/general-options.php:63
177
  msgid "Open automatically lightbox"
178
  msgstr "Apri la lightbox automaticamente"
179
 
180
+ #: plugin-options/general-options.php:64
181
  msgid "Open link after click into \"Compare\" button\"."
182
  msgstr "Apri pagina dopo aver cliccato sul pulsante \"Compare\"."
183
 
184
+ #: plugin-options/general-options.php:77
185
  msgid "Table Settings"
186
  msgstr "Impostazioni tabella."
187
 
188
+ #: plugin-options/general-options.php:84
189
  msgid "Table title"
190
  msgstr "Titolo Tabella"
191
 
192
+ #: plugin-options/general-options.php:85
193
  msgid "Type the text to use for the table title."
194
  msgstr ""
195
 
196
+ #: plugin-options/general-options.php:87
197
  msgid "Compare products"
198
  msgstr "Compara prodotti"
199
 
200
+ #: plugin-options/general-options.php:92
201
  msgid "Fields to show"
202
  msgstr "Campi da mostrare"
203
 
204
+ #: plugin-options/general-options.php:93
 
205
  msgid ""
206
  "Select the fields to show in the comparison table and order them by "
207
  "drag&drop (are included also the woocommerce attributes)"
209
  "Seleziona i campi da mostrare nella tabella di comparazione e ordinali "
210
  "attraverso il drag&drop (sono inclusi anche gli attributi di woocommerce)"
211
 
212
+ #: plugin-options/general-options.php:101
213
+ msgid "Repeat \"Price\" field"
214
+ msgstr ""
215
+
216
+ #: plugin-options/general-options.php:102
217
+ msgid "Repeat the \"Price\" field at the end of the table"
218
+ msgstr ""
219
+
220
+ #: plugin-options/general-options.php:110
221
+ msgid "Repeat \"Add to cart\" field"
222
+ msgstr ""
223
 
224
+ #: plugin-options/general-options.php:111
225
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
226
+ msgstr ""
227
 
228
+ #: plugin-options/general-options.php:119
229
  msgid "Image size"
230
  msgstr "Dimensione immagine"
231
 
232
+ #: plugin-options/general-options.php:120
233
  msgid "Set the size for the images"
234
  msgstr "Imposta la dimensione per le immagini"
235
 
236
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
237
+ #, php-format
238
+ msgid ""
239
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
240
+ "benefit from all features!"
241
+ msgstr ""
242
+
243
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
244
+ msgid "UPGRADE"
245
+ msgstr ""
246
+
247
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
248
+ msgid "to the premium version"
249
+ msgstr ""
250
+
251
+ #: templates/admin/premium.php:238
252
+ msgid "Premium Features"
253
+ msgstr ""
254
+
255
+ #: templates/admin/premium.php:246
256
+ msgid "A DEDICATED PAGE"
257
+ msgstr ""
258
+
259
+ #: templates/admin/premium.php:249
260
+ #, php-format
261
+ msgid ""
262
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
263
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
264
+ "created automatically in your site and, adding it among the menu entries, "
265
+ "you will be able to give to your users the chance to access it easily "
266
+ "whenever they want."
267
+ msgstr ""
268
+
269
+ #: templates/admin/premium.php:259
270
+ msgid "CATEGORY COMPARATION"
271
+ msgstr ""
272
+
273
+ #: templates/admin/premium.php:262
274
+ #, php-format
275
+ msgid ""
276
+ "People are often confused by finding products of different categories in the "
277
+ "comparison table, creating difficulties in comparing the products they are "
278
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
279
+ "need: you will be able to separate the products in the table by category "
280
+ "affinity."
281
+ msgstr ""
282
+
283
+ #: templates/admin/premium.php:278
284
+ msgid "CATEGORY EXCLUSION "
285
+ msgstr ""
286
+
287
+ #: templates/admin/premium.php:281
288
+ #, php-format
289
+ msgid ""
290
+ "In your shop there may be product categories you don't want to be affected "
291
+ "by the plugin features, deleting the comparison button for them. The premium "
292
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
293
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
294
+ "of the feature, allowing the comparison only to those products of the "
295
+ "selected categories."
296
+ msgstr ""
297
+
298
+ #: templates/admin/premium.php:291
299
+ msgid "TABLE IMAGE"
300
+ msgstr ""
301
+
302
+ #: templates/admin/premium.php:294
303
+ #, php-format
304
+ msgid ""
305
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
306
+ "Select an image, upload it from the option panel and show it ahead of the "
307
+ "table to your users. "
308
+ msgstr ""
309
+
310
+ #: templates/admin/premium.php:310
311
+ msgid "DYNAMIC FIELDS"
312
+ msgstr ""
313
+
314
+ #: templates/admin/premium.php:313
315
+ #, php-format
316
+ msgid ""
317
+ "With this precious feature, you will be able to show in the table only the "
318
+ "fields that have information in at least one of the selected products."
319
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
320
+ "be no more empty lines in your comparison table."
321
+ msgstr ""
322
+
323
+ #: templates/admin/premium.php:323
324
+ msgid "SOCIAL NETWORK SHARING"
325
+ msgstr ""
326
+
327
+ #: templates/admin/premium.php:326
328
+ #, php-format
329
+ msgid ""
330
+ "One of the most appealing features of the premium version of the plugin.Four "
331
+ "social network sites for your users (Facebook, Twitter, Google + and "
332
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
333
+ "products they have selected."
334
+ msgstr ""
335
+
336
+ #: templates/admin/premium.php:342
337
+ msgid "RELATED PRODUCTS"
338
+ msgstr ""
339
+
340
+ #: templates/admin/premium.php:345
341
+ #, php-format
342
+ msgid ""
343
+ "All the products that have common categories and/or tags with those in the "
344
+ "comparison table will be showed in a slider, right under the comparison "
345
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
346
+ "users to discover the shop products of the shop related to those they are "
347
+ "interested into."
348
+ msgstr ""
349
+
350
+ #: templates/admin/premium.php:355
351
+ msgid "CUSTOMIZABLE STYLE"
352
+ msgstr ""
353
+
354
+ #: templates/admin/premium.php:358
355
+ #, php-format
356
+ msgid ""
357
+ "An advanced option panel that let you change all the colors of the plugin, "
358
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
359
+ "of your shop.We know it, looks also count... and we give you the right tools "
360
+ "to get to the best result."
361
+ msgstr ""
362
+
363
+ #: templates/compare.php:76
364
  msgid "Close window [X]"
365
  msgstr "Chiudi finestra [X]"
366
 
367
+ #: templates/compare.php:103
368
  msgid "No products added in the compare table."
369
  msgstr "Nessun prodotto aggiunto nella tabella di comparazione."
370
 
371
+ #: widgets/class.yith-woocompare-widget.php:23
372
  msgid "The widget show the list of products added in the compare table."
373
  msgstr ""
374
  "Widget che mostra la lista dei prodotti aggiunti nella tabella di "
375
  "comparazione."
376
 
377
+ #: widgets/class.yith-woocompare-widget.php:27
378
  msgid "YITH Woocommerce Compare Widget"
379
  msgstr "YITH Woocommerce Compare Widget"
380
 
381
+ #: widgets/class.yith-woocompare-widget.php:49
382
  msgid "Clear all"
383
  msgstr "Cancella tutti"
384
 
385
+ #~ msgid "Products Compare"
386
+ #~ msgstr "Compara Prodotti"
 
387
 
388
+ #~ msgid "Repeat \"Price\" field at the end of the table"
389
+ #~ msgstr "Ripeti il campo \"Prezzo\" alla fine della tabella"
 
390
 
391
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
392
+ #~ msgstr ""
393
+ #~ "Ripeti il campo con \"Aggiungi al carrello\" alla fine della tabella"
394
+
395
+ #~ msgid "Select a date"
396
+ #~ msgstr "Seleziona data"
397
+
398
+ #~ msgid "Hours"
399
+ #~ msgstr "Ore"
400
 
401
+ #~ msgid "Minutes"
402
+ #~ msgstr "Minuti"
 
403
 
404
+ #~ msgid "Upload"
405
+ #~ msgstr "Carica"
 
406
 
407
+ #~ msgid "px"
408
+ #~ msgstr "px"
 
409
 
410
+ #~ msgid "em"
411
+ #~ msgstr "em"
 
412
 
413
+ #~ msgid "pt"
414
+ #~ msgstr "pt"
 
415
 
416
+ #~ msgid "rem"
417
+ #~ msgstr "rem"
 
418
 
419
+ #~ msgid "Select a font family"
420
+ #~ msgstr "Seleziona la famiglia font"
 
421
 
422
+ #~ msgid "Regular"
423
+ #~ msgstr "Normale"
 
424
 
425
+ #~ msgid "Bold"
426
+ #~ msgstr "Grassetto"
 
427
 
428
+ #~ msgid "Extra bold"
429
+ #~ msgstr "Extra bold"
 
430
 
431
+ #~ msgid "Italic"
432
+ #~ msgstr "Corsivo"
 
433
 
434
+ #~ msgid "Italic bold"
435
+ #~ msgstr "Grassetto corsivo"
436
+
437
+ #~ msgid "Click to preview"
438
+ #~ msgstr "Clicca per anteprima"
439
 
440
  #~ msgid "Woocommerce Compare"
441
  #~ msgstr "Modalità Manutenzione"
442
 
 
 
 
443
  #~ msgid "Docs"
444
  #~ msgstr "Documentazione"
445
 
languages/yith-wcmp-nl_NL.mo ADDED
Binary file
languages/yith-wcmp-nl_NL.po ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:47+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:47+0200\n"
6
+ "Last-Translator: Frans Pronk <beheer@ifra.nl>\n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "Vergelijk"
36
+
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr "Toegevoegd"
75
+
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
+ msgid "Product Comparison"
78
+ msgstr "Product vergelijk"
79
+
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
+ msgid "In stock"
82
+ msgstr "Op voorraad"
83
+
84
+ #: includes/class.yith-woocompare-frontend.php:548
85
+ msgid "No products to compare"
86
+ msgstr "Geen producten om te vergelijken"
87
+
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
+ msgid "Remove"
90
+ msgstr "Verwijder"
91
+
92
+ #: includes/class.yith-woocompare-helper.php:45
93
+ msgid "Image"
94
+ msgstr "Afbeelding"
95
+
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
+ msgid "Title"
99
+ msgstr "Titel"
100
+
101
+ #: includes/class.yith-woocompare-helper.php:47
102
+ msgid "Price"
103
+ msgstr "Prijs"
104
+
105
+ #: includes/class.yith-woocompare-helper.php:48
106
+ msgid "Add to cart"
107
+ msgstr "Bestellen"
108
+
109
+ #: includes/class.yith-woocompare-helper.php:49
110
+ msgid "Description"
111
+ msgstr "Omschrijving"
112
+
113
+ #: includes/class.yith-woocompare-helper.php:50
114
+ msgid "Availability"
115
+ msgstr "Beschikbaarheid"
116
+
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "Algemene instellingen"
132
+
133
+ #: plugin-options/general-options.php:24
134
+ msgid "Link or Button"
135
+ msgstr "Link of Button"
136
+
137
+ #: plugin-options/general-options.php:25
138
+ msgid "Choose if you want to use a link or a button for the action button."
139
+ msgstr "Kies uit button of link als actie button."
140
+
141
+ #: plugin-options/general-options.php:31
142
+ msgid "Link"
143
+ msgstr "Link"
144
+
145
+ #: plugin-options/general-options.php:32
146
+ msgid "Button"
147
+ msgstr "Button"
148
+
149
+ #: plugin-options/general-options.php:37
150
+ msgid "Link/Button text"
151
+ msgstr ""
152
+
153
+ #: plugin-options/general-options.php:38
154
+ msgid "Type the text to use for the button or the link of the compare."
155
+ msgstr ""
156
+
157
+ #: plugin-options/general-options.php:45
158
+ msgid "Show button in single product page"
159
+ msgstr "Toon button op product pagina"
160
+
161
+ #: plugin-options/general-options.php:46
162
+ msgid "Say if you want to show the button in the single product page."
163
+ msgstr "Selecteer wanneer je een button op de product pagina wilt tonen."
164
+
165
+ #: plugin-options/general-options.php:54
166
+ msgid "Show button in products list"
167
+ msgstr "Toon button op producten overzicht"
168
+
169
+ #: plugin-options/general-options.php:55
170
+ msgid "Say if you want to show the button in the products list."
171
+ msgstr ""
172
+ "Selecteer wanneer een button op de productenoverzichts pagina wilt tonen."
173
+
174
+ #: plugin-options/general-options.php:63
175
+ msgid "Open automatically lightbox"
176
+ msgstr "Open automatisch in lightbox"
177
+
178
+ #: plugin-options/general-options.php:64
179
+ msgid "Open link after click into \"Compare\" button\"."
180
+ msgstr "Open de link direct na aanklikken van \"Vergelijk\" button\"."
181
+
182
+ #: plugin-options/general-options.php:77
183
+ msgid "Table Settings"
184
+ msgstr "Tabel instellingen"
185
+
186
+ #: plugin-options/general-options.php:84
187
+ msgid "Table title"
188
+ msgstr ""
189
+
190
+ #: plugin-options/general-options.php:85
191
+ msgid "Type the text to use for the table title."
192
+ msgstr ""
193
+
194
+ #: plugin-options/general-options.php:87
195
+ msgid "Compare products"
196
+ msgstr "Vergelijk producten"
197
+
198
+ #: plugin-options/general-options.php:92
199
+ msgid "Fields to show"
200
+ msgstr "Velden tonen"
201
+
202
+ #: plugin-options/general-options.php:93
203
+ msgid ""
204
+ "Select the fields to show in the comparison table and order them by "
205
+ "drag&drop (are included also the woocommerce attributes)"
206
+ msgstr ""
207
+ "Selecteer de velden die je in de vergelijkings tabel wilt tonen. Sleep ze "
208
+ "met je muis in de gewenste volgorde."
209
+
210
+ #: plugin-options/general-options.php:101
211
+ msgid "Repeat \"Price\" field"
212
+ msgstr ""
213
+
214
+ #: plugin-options/general-options.php:102
215
+ msgid "Repeat the \"Price\" field at the end of the table"
216
+ msgstr ""
217
+
218
+ #: plugin-options/general-options.php:110
219
+ msgid "Repeat \"Add to cart\" field"
220
+ msgstr ""
221
+
222
+ #: plugin-options/general-options.php:111
223
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
224
+ msgstr ""
225
+
226
+ #: plugin-options/general-options.php:119
227
+ msgid "Image size"
228
+ msgstr "Afbeelding formaat"
229
+
230
+ #: plugin-options/general-options.php:120
231
+ msgid "Set the size for the images"
232
+ msgstr "Stel afbeeldings formaat in "
233
+
234
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
235
+ #, php-format
236
+ msgid ""
237
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
238
+ "benefit from all features!"
239
+ msgstr ""
240
+
241
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
242
+ msgid "UPGRADE"
243
+ msgstr ""
244
+
245
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
246
+ msgid "to the premium version"
247
+ msgstr ""
248
+
249
+ #: templates/admin/premium.php:238
250
+ msgid "Premium Features"
251
+ msgstr ""
252
+
253
+ #: templates/admin/premium.php:246
254
+ msgid "A DEDICATED PAGE"
255
+ msgstr ""
256
+
257
+ #: templates/admin/premium.php:249
258
+ #, php-format
259
+ msgid ""
260
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
261
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
262
+ "created automatically in your site and, adding it among the menu entries, "
263
+ "you will be able to give to your users the chance to access it easily "
264
+ "whenever they want."
265
+ msgstr ""
266
+
267
+ #: templates/admin/premium.php:259
268
+ msgid "CATEGORY COMPARATION"
269
+ msgstr ""
270
+
271
+ #: templates/admin/premium.php:262
272
+ #, php-format
273
+ msgid ""
274
+ "People are often confused by finding products of different categories in the "
275
+ "comparison table, creating difficulties in comparing the products they are "
276
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
277
+ "need: you will be able to separate the products in the table by category "
278
+ "affinity."
279
+ msgstr ""
280
+
281
+ #: templates/admin/premium.php:278
282
+ msgid "CATEGORY EXCLUSION "
283
+ msgstr ""
284
+
285
+ #: templates/admin/premium.php:281
286
+ #, php-format
287
+ msgid ""
288
+ "In your shop there may be product categories you don't want to be affected "
289
+ "by the plugin features, deleting the comparison button for them. The premium "
290
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
291
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
292
+ "of the feature, allowing the comparison only to those products of the "
293
+ "selected categories."
294
+ msgstr ""
295
+
296
+ #: templates/admin/premium.php:291
297
+ msgid "TABLE IMAGE"
298
+ msgstr ""
299
+
300
+ #: templates/admin/premium.php:294
301
+ #, php-format
302
+ msgid ""
303
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
304
+ "Select an image, upload it from the option panel and show it ahead of the "
305
+ "table to your users. "
306
+ msgstr ""
307
+
308
+ #: templates/admin/premium.php:310
309
+ msgid "DYNAMIC FIELDS"
310
+ msgstr ""
311
+
312
+ #: templates/admin/premium.php:313
313
+ #, php-format
314
+ msgid ""
315
+ "With this precious feature, you will be able to show in the table only the "
316
+ "fields that have information in at least one of the selected products."
317
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
318
+ "be no more empty lines in your comparison table."
319
+ msgstr ""
320
+
321
+ #: templates/admin/premium.php:323
322
+ msgid "SOCIAL NETWORK SHARING"
323
+ msgstr ""
324
+
325
+ #: templates/admin/premium.php:326
326
+ #, php-format
327
+ msgid ""
328
+ "One of the most appealing features of the premium version of the plugin.Four "
329
+ "social network sites for your users (Facebook, Twitter, Google + and "
330
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
331
+ "products they have selected."
332
+ msgstr ""
333
+
334
+ #: templates/admin/premium.php:342
335
+ msgid "RELATED PRODUCTS"
336
+ msgstr ""
337
+
338
+ #: templates/admin/premium.php:345
339
+ #, php-format
340
+ msgid ""
341
+ "All the products that have common categories and/or tags with those in the "
342
+ "comparison table will be showed in a slider, right under the comparison "
343
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
344
+ "users to discover the shop products of the shop related to those they are "
345
+ "interested into."
346
+ msgstr ""
347
+
348
+ #: templates/admin/premium.php:355
349
+ msgid "CUSTOMIZABLE STYLE"
350
+ msgstr ""
351
+
352
+ #: templates/admin/premium.php:358
353
+ #, php-format
354
+ msgid ""
355
+ "An advanced option panel that let you change all the colors of the plugin, "
356
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
357
+ "of your shop.We know it, looks also count... and we give you the right tools "
358
+ "to get to the best result."
359
+ msgstr ""
360
+
361
+ #: templates/compare.php:76
362
+ msgid "Close window [X]"
363
+ msgstr "Sluit venster [X]"
364
+
365
+ #: templates/compare.php:103
366
+ msgid "No products added in the compare table."
367
+ msgstr "Geen producten toegevoegd in de vergelijk tabel."
368
+
369
+ #: widgets/class.yith-woocompare-widget.php:23
370
+ msgid "The widget show the list of products added in the compare table."
371
+ msgstr "Deze widget toont een lijst met producten in een vergelijkings tabel."
372
+
373
+ #: widgets/class.yith-woocompare-widget.php:27
374
+ msgid "YITH Woocommerce Compare Widget"
375
+ msgstr "Een YITH Woocommerce Vergelijk Widget"
376
+
377
+ #: widgets/class.yith-woocompare-widget.php:49
378
+ msgid "Clear all"
379
+ msgstr "Wis alles"
380
+
381
+ #~ msgid "Products Compare"
382
+ #~ msgstr "Product vergelijk"
383
+
384
+ #~ msgid "Repeat \"Price\" field at the end of the table"
385
+ #~ msgstr "Toon \"Prijs\" veld aan het einde van de tabel"
386
+
387
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
388
+ #~ msgstr "Toon \"Bestel\" veld aan het einde van de tabel"
389
+
390
+ #~ msgid "Select a date"
391
+ #~ msgstr "Selecteer een datum"
392
+
393
+ #~ msgid "Hours"
394
+ #~ msgstr "Uren"
395
+
396
+ #~ msgid "Minutes"
397
+ #~ msgstr "Minuten"
398
+
399
+ #~ msgid "Upload"
400
+ #~ msgstr "Upload"
401
+
402
+ #~ msgid "px"
403
+ #~ msgstr "px"
404
+
405
+ #~ msgid "em"
406
+ #~ msgstr "em"
407
+
408
+ #~ msgid "pt"
409
+ #~ msgstr "pt"
410
+
411
+ #~ msgid "rem"
412
+ #~ msgstr "rem"
413
+
414
+ #~ msgid "Select a font family"
415
+ #~ msgstr "Kies een font type"
416
+
417
+ #~ msgid "Regular"
418
+ #~ msgstr "Normaal"
419
+
420
+ #~ msgid "Bold"
421
+ #~ msgstr "Vet"
422
+
423
+ #~ msgid "Extra bold"
424
+ #~ msgstr "Extra vet"
425
+
426
+ #~ msgid "Italic"
427
+ #~ msgstr "Cursief"
428
+
429
+ #~ msgid "Italic bold"
430
+ #~ msgstr "Cursief vet"
431
+
432
+ #~ msgid "Click to preview"
433
+ #~ msgstr "Klik voor voorvertoning"
languages/yith-wcmp-pt_BR.mo ADDED
Binary file
languages/yith-wcmp-pt_BR.po ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:48+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:48+0200\n"
6
+ "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: .\n"
17
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
18
+
19
+ #: includes/class.yith-woocompare-admin.php:117
20
+ #: includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: includes/class.yith-woocompare-admin.php:118
25
+ #: includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: includes/class.yith-woocompare-admin.php:149
30
+ #: includes/class.yith-woocompare-admin.php:150
31
+ #: includes/class.yith-woocompare-frontend.php:353
32
+ #: plugin-options/general-options.php:40
33
+ #: widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr "Comparar"
36
+
37
+ #: includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr "Adicionado"
75
+
76
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
77
+ msgid "Product Comparison"
78
+ msgstr "Comparação de Produtos"
79
+
80
+ #: includes/class.yith-woocompare-frontend.php:265
81
+ msgid "In stock"
82
+ msgstr "No estoque"
83
+
84
+ #: includes/class.yith-woocompare-frontend.php:548
85
+ msgid "No products to compare"
86
+ msgstr "Não há produtos à comparar"
87
+
88
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
89
+ msgid "Remove"
90
+ msgstr "Remover"
91
+
92
+ #: includes/class.yith-woocompare-helper.php:45
93
+ msgid "Image"
94
+ msgstr "Imagem"
95
+
96
+ #: includes/class.yith-woocompare-helper.php:46
97
+ #: widgets/class.yith-woocompare-widget.php:67
98
+ msgid "Title"
99
+ msgstr "Título"
100
+
101
+ #: includes/class.yith-woocompare-helper.php:47
102
+ msgid "Price"
103
+ msgstr "Preço"
104
+
105
+ #: includes/class.yith-woocompare-helper.php:48
106
+ msgid "Add to cart"
107
+ msgstr "Adicionar ao carrinho"
108
+
109
+ #: includes/class.yith-woocompare-helper.php:49
110
+ msgid "Description"
111
+ msgstr "Descrição"
112
+
113
+ #: includes/class.yith-woocompare-helper.php:50
114
+ msgid "Availability"
115
+ msgstr "Disponibilidade"
116
+
117
+ #: init.php:40
118
+ msgid ""
119
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
120
+ "WooCommerce in order to work."
121
+ msgstr ""
122
+
123
+ #: init.php:48
124
+ msgid ""
125
+ "You can't activate the free version of YITH WooCommerce Compare while you "
126
+ "are using the premium one."
127
+ msgstr ""
128
+
129
+ #: plugin-options/general-options.php:17
130
+ msgid "General Settings"
131
+ msgstr "Opções Gerais"
132
+
133
+ #: plugin-options/general-options.php:24
134
+ msgid "Link or Button"
135
+ msgstr "Link ou Botão"
136
+
137
+ #: plugin-options/general-options.php:25
138
+ msgid "Choose if you want to use a link or a button for the action button."
139
+ msgstr "Seleciona se deseja usar link ou botão para a ação do botão"
140
+
141
+ #: plugin-options/general-options.php:31
142
+ msgid "Link"
143
+ msgstr "Link"
144
+
145
+ #: plugin-options/general-options.php:32
146
+ msgid "Button"
147
+ msgstr "Botão"
148
+
149
+ #: plugin-options/general-options.php:37
150
+ msgid "Link/Button text"
151
+ msgstr "Texto Link/Botão"
152
+
153
+ #: plugin-options/general-options.php:38
154
+ msgid "Type the text to use for the button or the link of the compare."
155
+ msgstr "Insira o texto usado no botão de comparação."
156
+
157
+ #: plugin-options/general-options.php:45
158
+ msgid "Show button in single product page"
159
+ msgstr "Mostrar na página de produto único"
160
+
161
+ #: plugin-options/general-options.php:46
162
+ msgid "Say if you want to show the button in the single product page."
163
+ msgstr "Marque para mostrar na página de produto único"
164
+
165
+ #: plugin-options/general-options.php:54
166
+ msgid "Show button in products list"
167
+ msgstr "Mostrar na lista de produtos"
168
+
169
+ #: plugin-options/general-options.php:55
170
+ msgid "Say if you want to show the button in the products list."
171
+ msgstr "Marque para mostrar na lista de produtos"
172
+
173
+ #: plugin-options/general-options.php:63
174
+ msgid "Open automatically lightbox"
175
+ msgstr "Abrir lightbox automaticamente"
176
+
177
+ #: plugin-options/general-options.php:64
178
+ msgid "Open link after click into \"Compare\" button\"."
179
+ msgstr "Abre link após clicar no botão de comparação."
180
+
181
+ #: plugin-options/general-options.php:77
182
+ msgid "Table Settings"
183
+ msgstr "Opções de tabela"
184
+
185
+ #: plugin-options/general-options.php:84
186
+ msgid "Table title"
187
+ msgstr ""
188
+
189
+ #: plugin-options/general-options.php:85
190
+ msgid "Type the text to use for the table title."
191
+ msgstr ""
192
+
193
+ #: plugin-options/general-options.php:87
194
+ msgid "Compare products"
195
+ msgstr "Comparar produtos"
196
+
197
+ #: plugin-options/general-options.php:92
198
+ msgid "Fields to show"
199
+ msgstr "Campos a mostrar"
200
+
201
+ #: plugin-options/general-options.php:93
202
+ msgid ""
203
+ "Select the fields to show in the comparison table and order them by "
204
+ "drag&drop (are included also the woocommerce attributes)"
205
+ msgstr ""
206
+ "Selecione os campos a mostrar na tabela de comparação e organize-os "
207
+ "arrastando e soltando (atributos do Woocommerce também são incluídos)"
208
+
209
+ #: plugin-options/general-options.php:101
210
+ msgid "Repeat \"Price\" field"
211
+ msgstr ""
212
+
213
+ #: plugin-options/general-options.php:102
214
+ msgid "Repeat the \"Price\" field at the end of the table"
215
+ msgstr ""
216
+
217
+ #: plugin-options/general-options.php:110
218
+ msgid "Repeat \"Add to cart\" field"
219
+ msgstr ""
220
+
221
+ #: plugin-options/general-options.php:111
222
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
223
+ msgstr ""
224
+
225
+ #: plugin-options/general-options.php:119
226
+ msgid "Image size"
227
+ msgstr "Tamanho da imagem"
228
+
229
+ #: plugin-options/general-options.php:120
230
+ msgid "Set the size for the images"
231
+ msgstr "Especifique um tamanho para as imagens"
232
+
233
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
234
+ #, php-format
235
+ msgid ""
236
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
237
+ "benefit from all features!"
238
+ msgstr ""
239
+
240
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
241
+ msgid "UPGRADE"
242
+ msgstr ""
243
+
244
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
245
+ msgid "to the premium version"
246
+ msgstr ""
247
+
248
+ #: templates/admin/premium.php:238
249
+ msgid "Premium Features"
250
+ msgstr ""
251
+
252
+ #: templates/admin/premium.php:246
253
+ msgid "A DEDICATED PAGE"
254
+ msgstr ""
255
+
256
+ #: templates/admin/premium.php:249
257
+ #, php-format
258
+ msgid ""
259
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
260
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
261
+ "created automatically in your site and, adding it among the menu entries, "
262
+ "you will be able to give to your users the chance to access it easily "
263
+ "whenever they want."
264
+ msgstr ""
265
+
266
+ #: templates/admin/premium.php:259
267
+ msgid "CATEGORY COMPARATION"
268
+ msgstr ""
269
+
270
+ #: templates/admin/premium.php:262
271
+ #, php-format
272
+ msgid ""
273
+ "People are often confused by finding products of different categories in the "
274
+ "comparison table, creating difficulties in comparing the products they are "
275
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
276
+ "need: you will be able to separate the products in the table by category "
277
+ "affinity."
278
+ msgstr ""
279
+
280
+ #: templates/admin/premium.php:278
281
+ msgid "CATEGORY EXCLUSION "
282
+ msgstr ""
283
+
284
+ #: templates/admin/premium.php:281
285
+ #, php-format
286
+ msgid ""
287
+ "In your shop there may be product categories you don't want to be affected "
288
+ "by the plugin features, deleting the comparison button for them. The premium "
289
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
290
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
291
+ "of the feature, allowing the comparison only to those products of the "
292
+ "selected categories."
293
+ msgstr ""
294
+
295
+ #: templates/admin/premium.php:291
296
+ msgid "TABLE IMAGE"
297
+ msgstr ""
298
+
299
+ #: templates/admin/premium.php:294
300
+ #, php-format
301
+ msgid ""
302
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
303
+ "Select an image, upload it from the option panel and show it ahead of the "
304
+ "table to your users. "
305
+ msgstr ""
306
+
307
+ #: templates/admin/premium.php:310
308
+ msgid "DYNAMIC FIELDS"
309
+ msgstr ""
310
+
311
+ #: templates/admin/premium.php:313
312
+ #, php-format
313
+ msgid ""
314
+ "With this precious feature, you will be able to show in the table only the "
315
+ "fields that have information in at least one of the selected products."
316
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
317
+ "be no more empty lines in your comparison table."
318
+ msgstr ""
319
+
320
+ #: templates/admin/premium.php:323
321
+ msgid "SOCIAL NETWORK SHARING"
322
+ msgstr ""
323
+
324
+ #: templates/admin/premium.php:326
325
+ #, php-format
326
+ msgid ""
327
+ "One of the most appealing features of the premium version of the plugin.Four "
328
+ "social network sites for your users (Facebook, Twitter, Google + and "
329
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
330
+ "products they have selected."
331
+ msgstr ""
332
+
333
+ #: templates/admin/premium.php:342
334
+ msgid "RELATED PRODUCTS"
335
+ msgstr ""
336
+
337
+ #: templates/admin/premium.php:345
338
+ #, php-format
339
+ msgid ""
340
+ "All the products that have common categories and/or tags with those in the "
341
+ "comparison table will be showed in a slider, right under the comparison "
342
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
343
+ "users to discover the shop products of the shop related to those they are "
344
+ "interested into."
345
+ msgstr ""
346
+
347
+ #: templates/admin/premium.php:355
348
+ msgid "CUSTOMIZABLE STYLE"
349
+ msgstr ""
350
+
351
+ #: templates/admin/premium.php:358
352
+ #, php-format
353
+ msgid ""
354
+ "An advanced option panel that let you change all the colors of the plugin, "
355
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
356
+ "of your shop.We know it, looks also count... and we give you the right tools "
357
+ "to get to the best result."
358
+ msgstr ""
359
+
360
+ #: templates/compare.php:76
361
+ msgid "Close window [X]"
362
+ msgstr "Fechar janela [X]"
363
+
364
+ #: templates/compare.php:103
365
+ msgid "No products added in the compare table."
366
+ msgstr "Não foram adicionados produtos na tabela de comparação"
367
+
368
+ #: widgets/class.yith-woocompare-widget.php:23
369
+ msgid "The widget show the list of products added in the compare table."
370
+ msgstr ""
371
+ "O widget mostra a lista de produtos adicionados na tabela de comparação."
372
+
373
+ #: widgets/class.yith-woocompare-widget.php:27
374
+ msgid "YITH Woocommerce Compare Widget"
375
+ msgstr "Widget de Comparação"
376
+
377
+ #: widgets/class.yith-woocompare-widget.php:49
378
+ msgid "Clear all"
379
+ msgstr "Limpar tudo"
380
+
381
+ #~ msgid "Products Compare"
382
+ #~ msgstr "Comparar Produtos"
383
+
384
+ #~ msgid "Repeat \"Price\" field at the end of the table"
385
+ #~ msgstr "Repetir campo \"Preço\" no final da tabela"
386
+
387
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
388
+ #~ msgstr "Repetir campo \"Adicionar ao carrinho\" no final da tabela"
389
+
390
+ #~ msgid "Select a date"
391
+ #~ msgstr "Selecione uma data"
392
+
393
+ #~ msgid "Hours"
394
+ #~ msgstr "Horas"
395
+
396
+ #~ msgid "Minutes"
397
+ #~ msgstr "Minutos"
398
+
399
+ #~ msgid "Upload"
400
+ #~ msgstr "Enviar"
401
+
402
+ #~ msgid "px"
403
+ #~ msgstr "px"
404
+
405
+ #~ msgid "em"
406
+ #~ msgstr "em"
407
+
408
+ #~ msgid "pt"
409
+ #~ msgstr "pt"
410
+
411
+ #~ msgid "rem"
412
+ #~ msgstr "rem"
413
+
414
+ #~ msgid "Select a font family"
415
+ #~ msgstr "Seleciona uma família de fontes"
416
+
417
+ #~ msgid "Regular"
418
+ #~ msgstr "Normal"
419
+
420
+ #~ msgid "Bold"
421
+ #~ msgstr "Negrito"
422
+
423
+ #~ msgid "Extra bold"
424
+ #~ msgstr "Extra-negrito"
425
+
426
+ #~ msgid "Italic"
427
+ #~ msgstr "Itálico"
428
+
429
+ #~ msgid "Italic bold"
430
+ #~ msgstr "Negrito itálico"
431
+
432
+ #~ msgid "Click to preview"
433
+ #~ msgstr "Clique para pré-visualizar"
languages/yith-wcmp-tr_TR.mo ADDED
Binary file
languages/yith-wcmp-tr_TR.po ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:48+0200\n"
5
+ "PO-Revision-Date: 2015-07-14 15:48+0200\n"
6
+ "Last-Translator: Caner Öncel <caneroncel@gmail.com>\n"
7
+ "Language-Team: Caner Öncel <caneroncel@gmail.com>\n"
8
+ "Language: tr\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.2\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ..\n"
15
+ "Plural-Forms: nplurals=1; plural=0;\n"
16
+ "X-Poedit-SourceCharset: UTF-8\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+ "X-Poedit-SearchPathExcluded-0: plugin-fw\n"
19
+
20
+ #: includes/class.yith-woocompare-admin.php:117
21
+ #: includes/class.yith-woocompare-admin.php:139
22
+ msgid "Settings"
23
+ msgstr ""
24
+
25
+ #: includes/class.yith-woocompare-admin.php:118
26
+ #: includes/class.yith-woocompare-admin.php:143
27
+ msgid "Premium Version"
28
+ msgstr ""
29
+
30
+ #: includes/class.yith-woocompare-admin.php:149
31
+ #: includes/class.yith-woocompare-admin.php:150
32
+ #: includes/class.yith-woocompare-frontend.php:353
33
+ #: plugin-options/general-options.php:40
34
+ #: widgets/class.yith-woocompare-widget.php:50
35
+ msgid "Compare"
36
+ msgstr "Karşılaştır"
37
+
38
+ #: includes/class.yith-woocompare-admin.php:213
39
+ msgid "Plugin Documentation"
40
+ msgstr ""
41
+
42
+ #: includes/class.yith-woocompare-admin.php:232
43
+ msgid "YITH WooCommerce Compare Activated"
44
+ msgstr ""
45
+
46
+ #: includes/class.yith-woocompare-admin.php:233
47
+ #, php-format
48
+ msgid ""
49
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
50
+ "With this menu, you can access to all the settings of our plugins that you "
51
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
52
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
53
+ msgstr ""
54
+
55
+ #: includes/class.yith-woocompare-admin.php:244
56
+ msgid "YITH WooCommerce Compare Updated"
57
+ msgstr ""
58
+
59
+ #: includes/class.yith-woocompare-admin.php:245
60
+ #, php-format
61
+ msgid ""
62
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
63
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
64
+ "the previous version. When one of our plugins is updated, a new voice will "
65
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
66
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
67
+ msgstr ""
68
+
69
+ #: includes/class.yith-woocompare-admin.php:390
70
+ msgid "Do you want to hard crop the image?"
71
+ msgstr ""
72
+
73
+ #: includes/class.yith-woocompare-frontend.php:142
74
+ msgid "Added"
75
+ msgstr "Eklendi"
76
+
77
+ #: includes/class.yith-woocompare-frontend.php:143 templates/compare.php:51
78
+ msgid "Product Comparison"
79
+ msgstr "Ürün Karşılaştırma"
80
+
81
+ #: includes/class.yith-woocompare-frontend.php:265
82
+ msgid "In stock"
83
+ msgstr "Stokta"
84
+
85
+ #: includes/class.yith-woocompare-frontend.php:548
86
+ msgid "No products to compare"
87
+ msgstr "Karşılaştırma listeniz boş"
88
+
89
+ #: includes/class.yith-woocompare-frontend.php:559 templates/compare.php:111
90
+ msgid "Remove"
91
+ msgstr "Kaldır"
92
+
93
+ #: includes/class.yith-woocompare-helper.php:45
94
+ msgid "Image"
95
+ msgstr "Resim"
96
+
97
+ #: includes/class.yith-woocompare-helper.php:46
98
+ #: widgets/class.yith-woocompare-widget.php:67
99
+ msgid "Title"
100
+ msgstr "Başlık"
101
+
102
+ #: includes/class.yith-woocompare-helper.php:47
103
+ msgid "Price"
104
+ msgstr "Fiyat"
105
+
106
+ #: includes/class.yith-woocompare-helper.php:48
107
+ msgid "Add to cart"
108
+ msgstr "Sepete Ekle"
109
+
110
+ #: includes/class.yith-woocompare-helper.php:49
111
+ msgid "Description"
112
+ msgstr "Açıklama"
113
+
114
+ #: includes/class.yith-woocompare-helper.php:50
115
+ msgid "Availability"
116
+ msgstr "Durum"
117
+
118
+ #: init.php:40
119
+ msgid ""
120
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
121
+ "WooCommerce in order to work."
122
+ msgstr ""
123
+
124
+ #: init.php:48
125
+ msgid ""
126
+ "You can't activate the free version of YITH WooCommerce Compare while you "
127
+ "are using the premium one."
128
+ msgstr ""
129
+
130
+ #: plugin-options/general-options.php:17
131
+ msgid "General Settings"
132
+ msgstr "Genel Ayarlar"
133
+
134
+ #: plugin-options/general-options.php:24
135
+ msgid "Link or Button"
136
+ msgstr "Link veya Buton"
137
+
138
+ #: plugin-options/general-options.php:25
139
+ msgid "Choose if you want to use a link or a button for the action button."
140
+ msgstr ""
141
+ "Eylem için kullanmak üzere link veya buton seçeneklerinden birini belirleyin."
142
+
143
+ #: plugin-options/general-options.php:31
144
+ msgid "Link"
145
+ msgstr "Link"
146
+
147
+ #: plugin-options/general-options.php:32
148
+ msgid "Button"
149
+ msgstr "Buton"
150
+
151
+ #: plugin-options/general-options.php:37
152
+ msgid "Link/Button text"
153
+ msgstr "Link/Buton Metni"
154
+
155
+ #: plugin-options/general-options.php:38
156
+ msgid "Type the text to use for the button or the link of the compare."
157
+ msgstr "Karşılaştırma butonu veya bağlantısı için kullanılacak metni yazın."
158
+
159
+ #: plugin-options/general-options.php:45
160
+ msgid "Show button in single product page"
161
+ msgstr "Tekli ürün sayfasında buton göster"
162
+
163
+ #: plugin-options/general-options.php:46
164
+ msgid "Say if you want to show the button in the single product page."
165
+ msgstr "Tekli ürün sayfasında buton göstermek isteyip istemediğinizi belirtin."
166
+
167
+ #: plugin-options/general-options.php:54
168
+ msgid "Show button in products list"
169
+ msgstr "Ürün listesinde buton göster"
170
+
171
+ #: plugin-options/general-options.php:55
172
+ msgid "Say if you want to show the button in the products list."
173
+ msgstr "Ürün listesinde buton göstermek isteyip istemediğinizi belirtin."
174
+
175
+ #: plugin-options/general-options.php:63
176
+ msgid "Open automatically lightbox"
177
+ msgstr "Otomatik lightbox aç"
178
+
179
+ #: plugin-options/general-options.php:64
180
+ msgid "Open link after click into \"Compare\" button\"."
181
+ msgstr "\"Karşılaştır\" butonuna tıklandıktan sonra bağlantıyı aç."
182
+
183
+ #: plugin-options/general-options.php:77
184
+ msgid "Table Settings"
185
+ msgstr "Tablo Ayarları"
186
+
187
+ #: plugin-options/general-options.php:84
188
+ msgid "Table title"
189
+ msgstr "Tablo Başlığı"
190
+
191
+ #: plugin-options/general-options.php:85
192
+ msgid "Type the text to use for the table title."
193
+ msgstr "Tablo başlığı metnini buraya yazın."
194
+
195
+ #: plugin-options/general-options.php:87
196
+ msgid "Compare products"
197
+ msgstr "Ürünleri Karşılaştır"
198
+
199
+ #: plugin-options/general-options.php:92
200
+ msgid "Fields to show"
201
+ msgstr "Gösterilecek alanlar"
202
+
203
+ #: plugin-options/general-options.php:93
204
+ msgid ""
205
+ "Select the fields to show in the comparison table and order them by "
206
+ "drag&drop (are included also the woocommerce attributes)"
207
+ msgstr ""
208
+ "Karşılaştırma tablosunda gösterilecek alanları seçin ve sürükle-bırak "
209
+ "yöntemi ile sıralayın (ayrıca Woocommerce özellikleri dahildir)"
210
+
211
+ #: plugin-options/general-options.php:101
212
+ msgid "Repeat \"Price\" field"
213
+ msgstr ""
214
+
215
+ #: plugin-options/general-options.php:102
216
+ msgid "Repeat the \"Price\" field at the end of the table"
217
+ msgstr ""
218
+
219
+ #: plugin-options/general-options.php:110
220
+ msgid "Repeat \"Add to cart\" field"
221
+ msgstr ""
222
+
223
+ #: plugin-options/general-options.php:111
224
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
225
+ msgstr ""
226
+
227
+ #: plugin-options/general-options.php:119
228
+ msgid "Image size"
229
+ msgstr "Resim Boyutu"
230
+
231
+ #: plugin-options/general-options.php:120
232
+ msgid "Set the size for the images"
233
+ msgstr "Resimlerin boyutlarını belirtin"
234
+
235
+ #: templates/admin/premium.php:228 templates/admin/premium.php:370
236
+ #, php-format
237
+ msgid ""
238
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
239
+ "benefit from all features!"
240
+ msgstr ""
241
+
242
+ #: templates/admin/premium.php:231 templates/admin/premium.php:373
243
+ msgid "UPGRADE"
244
+ msgstr ""
245
+
246
+ #: templates/admin/premium.php:232 templates/admin/premium.php:374
247
+ msgid "to the premium version"
248
+ msgstr ""
249
+
250
+ #: templates/admin/premium.php:238
251
+ msgid "Premium Features"
252
+ msgstr ""
253
+
254
+ #: templates/admin/premium.php:246
255
+ msgid "A DEDICATED PAGE"
256
+ msgstr ""
257
+
258
+ #: templates/admin/premium.php:249
259
+ #, php-format
260
+ msgid ""
261
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
262
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
263
+ "created automatically in your site and, adding it among the menu entries, "
264
+ "you will be able to give to your users the chance to access it easily "
265
+ "whenever they want."
266
+ msgstr ""
267
+
268
+ #: templates/admin/premium.php:259
269
+ msgid "CATEGORY COMPARATION"
270
+ msgstr ""
271
+
272
+ #: templates/admin/premium.php:262
273
+ #, php-format
274
+ msgid ""
275
+ "People are often confused by finding products of different categories in the "
276
+ "comparison table, creating difficulties in comparing the products they are "
277
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
278
+ "need: you will be able to separate the products in the table by category "
279
+ "affinity."
280
+ msgstr ""
281
+
282
+ #: templates/admin/premium.php:278
283
+ msgid "CATEGORY EXCLUSION "
284
+ msgstr ""
285
+
286
+ #: templates/admin/premium.php:281
287
+ #, php-format
288
+ msgid ""
289
+ "In your shop there may be product categories you don't want to be affected "
290
+ "by the plugin features, deleting the comparison button for them. The premium "
291
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
292
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
293
+ "of the feature, allowing the comparison only to those products of the "
294
+ "selected categories."
295
+ msgstr ""
296
+
297
+ #: templates/admin/premium.php:291
298
+ msgid "TABLE IMAGE"
299
+ msgstr ""
300
+
301
+ #: templates/admin/premium.php:294
302
+ #, php-format
303
+ msgid ""
304
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
305
+ "Select an image, upload it from the option panel and show it ahead of the "
306
+ "table to your users. "
307
+ msgstr ""
308
+
309
+ #: templates/admin/premium.php:310
310
+ msgid "DYNAMIC FIELDS"
311
+ msgstr ""
312
+
313
+ #: templates/admin/premium.php:313
314
+ #, php-format
315
+ msgid ""
316
+ "With this precious feature, you will be able to show in the table only the "
317
+ "fields that have information in at least one of the selected products."
318
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
319
+ "be no more empty lines in your comparison table."
320
+ msgstr ""
321
+
322
+ #: templates/admin/premium.php:323
323
+ msgid "SOCIAL NETWORK SHARING"
324
+ msgstr ""
325
+
326
+ #: templates/admin/premium.php:326
327
+ #, php-format
328
+ msgid ""
329
+ "One of the most appealing features of the premium version of the plugin.Four "
330
+ "social network sites for your users (Facebook, Twitter, Google + and "
331
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
332
+ "products they have selected."
333
+ msgstr ""
334
+
335
+ #: templates/admin/premium.php:342
336
+ msgid "RELATED PRODUCTS"
337
+ msgstr ""
338
+
339
+ #: templates/admin/premium.php:345
340
+ #, php-format
341
+ msgid ""
342
+ "All the products that have common categories and/or tags with those in the "
343
+ "comparison table will be showed in a slider, right under the comparison "
344
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
345
+ "users to discover the shop products of the shop related to those they are "
346
+ "interested into."
347
+ msgstr ""
348
+
349
+ #: templates/admin/premium.php:355
350
+ msgid "CUSTOMIZABLE STYLE"
351
+ msgstr ""
352
+
353
+ #: templates/admin/premium.php:358
354
+ #, php-format
355
+ msgid ""
356
+ "An advanced option panel that let you change all the colors of the plugin, "
357
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
358
+ "of your shop.We know it, looks also count... and we give you the right tools "
359
+ "to get to the best result."
360
+ msgstr ""
361
+
362
+ #: templates/compare.php:76
363
+ msgid "Close window [X]"
364
+ msgstr "Pencereyi Kapat [X]"
365
+
366
+ #: templates/compare.php:103
367
+ msgid "No products added in the compare table."
368
+ msgstr "Karşılaştırma tablosuna herhangi bir ürün eklenmedi."
369
+
370
+ #: widgets/class.yith-woocompare-widget.php:23
371
+ msgid "The widget show the list of products added in the compare table."
372
+ msgstr "Widget karşılaştırma tablosuna eklenen ürünlerin listesini gösterir."
373
+
374
+ #: widgets/class.yith-woocompare-widget.php:27
375
+ msgid "YITH Woocommerce Compare Widget"
376
+ msgstr "YITH Woocommerce Karşılaştırma Widgetı"
377
+
378
+ #: widgets/class.yith-woocompare-widget.php:49
379
+ msgid "Clear all"
380
+ msgstr "Hepsini Kaldır"
381
+
382
+ #~ msgid "Products Compare"
383
+ #~ msgstr "Ürün Karşılaştırma"
384
+
385
+ #~ msgid "Repeat \"Price\" field at the end of the table"
386
+ #~ msgstr "\"Ücret\" alanını tablonun sonuna kadar tekrarla"
387
+
388
+ #~ msgid "Repeat \"Add to cart\" field at the end of the table"
389
+ #~ msgstr "\"Sepete ekle\" alanını tablonun sonuna kadar tekrarla"
390
+
391
+ #~ msgid "Select a date"
392
+ #~ msgstr "Bir tarih seçin"
393
+
394
+ #~ msgid "Hours"
395
+ #~ msgstr "Saat"
396
+
397
+ #~ msgid "Minutes"
398
+ #~ msgstr "Dakika"
399
+
400
+ #~ msgid "Upload"
401
+ #~ msgstr "Yükle"
402
+
403
+ #~ msgid "px"
404
+ #~ msgstr "px"
405
+
406
+ #~ msgid "em"
407
+ #~ msgstr "em"
408
+
409
+ #~ msgid "pt"
410
+ #~ msgstr "pt"
411
+
412
+ #~ msgid "rem"
413
+ #~ msgstr "rem"
414
+
415
+ #~ msgid "Select a font family"
416
+ #~ msgstr "Bir font ailesi seçin"
417
+
418
+ #~ msgid "Regular"
419
+ #~ msgstr "Normal"
420
+
421
+ #~ msgid "Bold"
422
+ #~ msgstr "Kalın"
423
+
424
+ #~ msgid "Extra bold"
425
+ #~ msgstr "Ekstra kalın"
426
+
427
+ #~ msgid "Italic"
428
+ #~ msgstr "İtalik"
429
+
430
+ #~ msgid "Italic bold"
431
+ #~ msgstr "İtalik kalın"
432
+
433
+ #~ msgid "Click to preview"
434
+ #~ msgstr "Önizleme için tıklayın"
languages/yith-wcmp.pot ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: YITH Woocommerce Compare\n"
4
+ "POT-Creation-Date: 2015-07-14 15:10+0100\n"
5
+ "PO-Revision-Date: 2015-07-14 15:10+0100\n"
6
+ "Last-Translator: Nicola Mustone <mail@nicolamustone.it>\n"
7
+ "Language-Team: Your Inspiration Themes <support@yithemes.com>\n"
8
+ "Language: en\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.7.6\n"
13
+ "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ./\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-SearchPath-0: ..\n"
17
+ "X-Poedit-SearchPathExcluded-0: ../plugin-fw\n"
18
+
19
+ #: ../includes/class.yith-woocompare-admin.php:117
20
+ #: ../includes/class.yith-woocompare-admin.php:139
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: ../includes/class.yith-woocompare-admin.php:118
25
+ #: ../includes/class.yith-woocompare-admin.php:143
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: ../includes/class.yith-woocompare-admin.php:149
30
+ #: ../includes/class.yith-woocompare-admin.php:150
31
+ #: ../includes/class.yith-woocompare-frontend.php:353
32
+ #: ../plugin-options/general-options.php:40
33
+ #: ../widgets/class.yith-woocompare-widget.php:50
34
+ msgid "Compare"
35
+ msgstr ""
36
+
37
+ #: ../includes/class.yith-woocompare-admin.php:213
38
+ msgid "Plugin Documentation"
39
+ msgstr ""
40
+
41
+ #: ../includes/class.yith-woocompare-admin.php:232
42
+ msgid "YITH WooCommerce Compare Activated"
43
+ msgstr ""
44
+
45
+ #: ../includes/class.yith-woocompare-admin.php:233
46
+ #, php-format
47
+ msgid ""
48
+ "In the YIT Plugin tab you can find the YITH WooCommerce Compare options. "
49
+ "With this menu, you can access to all the settings of our plugins that you "
50
+ "have activated. YITH WooCommerce Compare is available in an outstanding "
51
+ "PREMIUM version with many new options, <a href=\"%s\">discover it now</a>."
52
+ msgstr ""
53
+
54
+ #: ../includes/class.yith-woocompare-admin.php:244
55
+ msgid "YITH WooCommerce Compare Updated"
56
+ msgstr ""
57
+
58
+ #: ../includes/class.yith-woocompare-admin.php:245
59
+ #, php-format
60
+ msgid ""
61
+ "From now on, you can find all the options of YITH WooCommerce Compare under "
62
+ "YIT Plugin -> Compare instead of WooCommerce -> Settings -> Compare, as in "
63
+ "the previous version. When one of our plugins is updated, a new voice will "
64
+ "be added to this menu. YITH WooCommerce Compare has been updated with new "
65
+ "available options, <a href=\"%s\">discover the PREMIUM version.</a>"
66
+ msgstr ""
67
+
68
+ #: ../includes/class.yith-woocompare-admin.php:390
69
+ msgid "Do you want to hard crop the image?"
70
+ msgstr ""
71
+
72
+ #: ../includes/class.yith-woocompare-frontend.php:142
73
+ msgid "Added"
74
+ msgstr ""
75
+
76
+ #: ../includes/class.yith-woocompare-frontend.php:143
77
+ #: ../templates/compare.php:51
78
+ msgid "Product Comparison"
79
+ msgstr ""
80
+
81
+ #: ../includes/class.yith-woocompare-frontend.php:265
82
+ msgid "In stock"
83
+ msgstr ""
84
+
85
+ #: ../includes/class.yith-woocompare-frontend.php:548
86
+ msgid "No products to compare"
87
+ msgstr ""
88
+
89
+ #: ../includes/class.yith-woocompare-frontend.php:559
90
+ #: ../templates/compare.php:111
91
+ msgid "Remove"
92
+ msgstr ""
93
+
94
+ #: ../includes/class.yith-woocompare-helper.php:45
95
+ msgid "Image"
96
+ msgstr ""
97
+
98
+ #: ../includes/class.yith-woocompare-helper.php:46
99
+ #: ../widgets/class.yith-woocompare-widget.php:67
100
+ msgid "Title"
101
+ msgstr ""
102
+
103
+ #: ../includes/class.yith-woocompare-helper.php:47
104
+ msgid "Price"
105
+ msgstr ""
106
+
107
+ #: ../includes/class.yith-woocompare-helper.php:48
108
+ msgid "Add to cart"
109
+ msgstr ""
110
+
111
+ #: ../includes/class.yith-woocompare-helper.php:49
112
+ msgid "Description"
113
+ msgstr ""
114
+
115
+ #: ../includes/class.yith-woocompare-helper.php:50
116
+ msgid "Availability"
117
+ msgstr ""
118
+
119
+ #: ../init.php:40
120
+ msgid ""
121
+ "YITH WooCommerce Compare is enabled but not effective. It requires "
122
+ "WooCommerce in order to work."
123
+ msgstr ""
124
+
125
+ #: ../init.php:48
126
+ msgid ""
127
+ "You can't activate the free version of YITH WooCommerce Compare while you "
128
+ "are using the premium one."
129
+ msgstr ""
130
+
131
+ #: ../plugin-options/general-options.php:17
132
+ msgid "General Settings"
133
+ msgstr ""
134
+
135
+ #: ../plugin-options/general-options.php:24
136
+ msgid "Link or Button"
137
+ msgstr ""
138
+
139
+ #: ../plugin-options/general-options.php:25
140
+ msgid "Choose if you want to use a link or a button for the action button."
141
+ msgstr ""
142
+
143
+ #: ../plugin-options/general-options.php:31
144
+ msgid "Link"
145
+ msgstr ""
146
+
147
+ #: ../plugin-options/general-options.php:32
148
+ msgid "Button"
149
+ msgstr ""
150
+
151
+ #: ../plugin-options/general-options.php:37
152
+ msgid "Link/Button text"
153
+ msgstr ""
154
+
155
+ #: ../plugin-options/general-options.php:38
156
+ msgid "Type the text to use for the button or the link of the compare."
157
+ msgstr ""
158
+
159
+ #: ../plugin-options/general-options.php:45
160
+ msgid "Show button in single product page"
161
+ msgstr ""
162
+
163
+ #: ../plugin-options/general-options.php:46
164
+ msgid "Say if you want to show the button in the single product page."
165
+ msgstr ""
166
+
167
+ #: ../plugin-options/general-options.php:54
168
+ msgid "Show button in products list"
169
+ msgstr ""
170
+
171
+ #: ../plugin-options/general-options.php:55
172
+ msgid "Say if you want to show the button in the products list."
173
+ msgstr ""
174
+
175
+ #: ../plugin-options/general-options.php:63
176
+ msgid "Open automatically lightbox"
177
+ msgstr ""
178
+
179
+ #: ../plugin-options/general-options.php:64
180
+ msgid "Open link after click into \"Compare\" button\"."
181
+ msgstr ""
182
+
183
+ #: ../plugin-options/general-options.php:77
184
+ msgid "Table Settings"
185
+ msgstr ""
186
+
187
+ #: ../plugin-options/general-options.php:84
188
+ msgid "Table title"
189
+ msgstr ""
190
+
191
+ #: ../plugin-options/general-options.php:85
192
+ msgid "Type the text to use for the table title."
193
+ msgstr ""
194
+
195
+ #: ../plugin-options/general-options.php:87
196
+ msgid "Compare products"
197
+ msgstr ""
198
+
199
+ #: ../plugin-options/general-options.php:92
200
+ msgid "Fields to show"
201
+ msgstr ""
202
+
203
+ #: ../plugin-options/general-options.php:93
204
+ msgid ""
205
+ "Select the fields to show in the comparison table and order them by "
206
+ "drag&drop (are included also the woocommerce attributes)"
207
+ msgstr ""
208
+
209
+ #: ../plugin-options/general-options.php:101
210
+ msgid "Repeat \"Price\" field"
211
+ msgstr ""
212
+
213
+ #: ../plugin-options/general-options.php:102
214
+ msgid "Repeat the \"Price\" field at the end of the table"
215
+ msgstr ""
216
+
217
+ #: ../plugin-options/general-options.php:110
218
+ msgid "Repeat \"Add to cart\" field"
219
+ msgstr ""
220
+
221
+ #: ../plugin-options/general-options.php:111
222
+ msgid "Repeat the \"Add to cart\" field at the end of the table"
223
+ msgstr ""
224
+
225
+ #: ../plugin-options/general-options.php:119
226
+ msgid "Image size"
227
+ msgstr ""
228
+
229
+ #: ../plugin-options/general-options.php:120
230
+ msgid "Set the size for the images"
231
+ msgstr ""
232
+
233
+ #: ../templates/admin/premium.php:228 ../templates/admin/premium.php:370
234
+ #, php-format
235
+ msgid ""
236
+ "Upgrade to %1$spremium version%2$s of %1$sYITH WooCommerce Compare%2$s to "
237
+ "benefit from all features!"
238
+ msgstr ""
239
+
240
+ #: ../templates/admin/premium.php:231 ../templates/admin/premium.php:373
241
+ msgid "UPGRADE"
242
+ msgstr ""
243
+
244
+ #: ../templates/admin/premium.php:232 ../templates/admin/premium.php:374
245
+ msgid "to the premium version"
246
+ msgstr ""
247
+
248
+ #: ../templates/admin/premium.php:238
249
+ msgid "Premium Features"
250
+ msgstr ""
251
+
252
+ #: ../templates/admin/premium.php:246
253
+ msgid "A DEDICATED PAGE"
254
+ msgstr ""
255
+
256
+ #: ../templates/admin/premium.php:249
257
+ #, php-format
258
+ msgid ""
259
+ "Don't you want to compare your products in a modal window anymore?%3$sWith "
260
+ "the premium version of %1$sYITH WooCommerce Compare%2$s, a new page will be "
261
+ "created automatically in your site and, adding it among the menu entries, "
262
+ "you will be able to give to your users the chance to access it easily "
263
+ "whenever they want."
264
+ msgstr ""
265
+
266
+ #: ../templates/admin/premium.php:259
267
+ msgid "CATEGORY COMPARATION"
268
+ msgstr ""
269
+
270
+ #: ../templates/admin/premium.php:262
271
+ #, php-format
272
+ msgid ""
273
+ "People are often confused by finding products of different categories in the "
274
+ "comparison table, creating difficulties in comparing the products they are "
275
+ "interested into.The %1$s\"Compare by category\"%2$s option exists for this "
276
+ "need: you will be able to separate the products in the table by category "
277
+ "affinity."
278
+ msgstr ""
279
+
280
+ #: ../templates/admin/premium.php:278
281
+ msgid "CATEGORY EXCLUSION "
282
+ msgstr ""
283
+
284
+ #: ../templates/admin/premium.php:281
285
+ #, php-format
286
+ msgid ""
287
+ "In your shop there may be product categories you don't want to be affected "
288
+ "by the plugin features, deleting the comparison button for them. The premium "
289
+ "version of the plugin offers this too.%3$sAnd there's more! Activating the "
290
+ "%1$s\"Reverse exclusion list\"%2$s option, you can also invert the behavior "
291
+ "of the feature, allowing the comparison only to those products of the "
292
+ "selected categories."
293
+ msgstr ""
294
+
295
+ #: ../templates/admin/premium.php:291
296
+ msgid "TABLE IMAGE"
297
+ msgstr ""
298
+
299
+ #: ../templates/admin/premium.php:294
300
+ #, php-format
301
+ msgid ""
302
+ "Give a personal touch to the %1$scomparison table%2$s your users will see. "
303
+ "Select an image, upload it from the option panel and show it ahead of the "
304
+ "table to your users. "
305
+ msgstr ""
306
+
307
+ #: ../templates/admin/premium.php:310
308
+ msgid "DYNAMIC FIELDS"
309
+ msgstr ""
310
+
311
+ #: ../templates/admin/premium.php:313
312
+ #, php-format
313
+ msgid ""
314
+ "With this precious feature, you will be able to show in the table only the "
315
+ "fields that have information in at least one of the selected products."
316
+ "%3$sActivate the %1$s\"Dynamic Attribute fields\"%2$s option and there will "
317
+ "be no more empty lines in your comparison table."
318
+ msgstr ""
319
+
320
+ #: ../templates/admin/premium.php:323
321
+ msgid "SOCIAL NETWORK SHARING"
322
+ msgstr ""
323
+
324
+ #: ../templates/admin/premium.php:326
325
+ #, php-format
326
+ msgid ""
327
+ "One of the most appealing features of the premium version of the plugin.Four "
328
+ "social network sites for your users (Facebook, Twitter, Google + and "
329
+ "Pinterest) and the email system %1$sto share%2$s the comparison table of the "
330
+ "products they have selected."
331
+ msgstr ""
332
+
333
+ #: ../templates/admin/premium.php:342
334
+ msgid "RELATED PRODUCTS"
335
+ msgstr ""
336
+
337
+ #: ../templates/admin/premium.php:345
338
+ #, php-format
339
+ msgid ""
340
+ "All the products that have common categories and/or tags with those in the "
341
+ "comparison table will be showed in a slider, right under the comparison "
342
+ "table.%3$sA completely %1$s\"touch friendly\"%2$s slider to encourage your "
343
+ "users to discover the shop products of the shop related to those they are "
344
+ "interested into."
345
+ msgstr ""
346
+
347
+ #: ../templates/admin/premium.php:355
348
+ msgid "CUSTOMIZABLE STYLE"
349
+ msgstr ""
350
+
351
+ #: ../templates/admin/premium.php:358
352
+ #, php-format
353
+ msgid ""
354
+ "An advanced option panel that let you change all the colors of the plugin, "
355
+ "so that you can adapt stylistically all its elements to the %1$slayout%2$s "
356
+ "of your shop.We know it, looks also count... and we give you the right tools "
357
+ "to get to the best result."
358
+ msgstr ""
359
+
360
+ #: ../templates/compare.php:76
361
+ msgid "Close window [X]"
362
+ msgstr ""
363
+
364
+ #: ../templates/compare.php:103
365
+ msgid "No products added in the compare table."
366
+ msgstr ""
367
+
368
+ #: ../widgets/class.yith-woocompare-widget.php:23
369
+ msgid "The widget show the list of products added in the compare table."
370
+ msgstr ""
371
+
372
+ #: ../widgets/class.yith-woocompare-widget.php:27
373
+ msgid "YITH Woocommerce Compare Widget"
374
+ msgstr ""
375
+
376
+ #: ../widgets/class.yith-woocompare-widget.php:49
377
+ msgid "Clear all"
378
+ msgstr ""
plugin-fw/assets/css/chosen/chosen.css ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ /* @group Base */
14
+ .chosen-container {
15
+ position: relative;
16
+ display: inline-block;
17
+ vertical-align: middle;
18
+ font-size: 13px;
19
+ zoom: 1;
20
+ *display: inline;
21
+ -webkit-user-select: none;
22
+ -moz-user-select: none;
23
+ user-select: none;
24
+ }
25
+ .chosen-container .chosen-drop {
26
+ position: absolute;
27
+ top: 100%;
28
+ left: -9999px;
29
+ z-index: 1010;
30
+ -webkit-box-sizing: border-box;
31
+ -moz-box-sizing: border-box;
32
+ box-sizing: border-box;
33
+ width: 100%;
34
+ border: 1px solid #aaa;
35
+ border-top: 0;
36
+ background: #fff;
37
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
38
+ }
39
+ .chosen-container.chosen-with-drop .chosen-drop {
40
+ left: 0;
41
+ }
42
+ .chosen-container a {
43
+ cursor: pointer;
44
+ }
45
+
46
+ /* @end */
47
+ /* @group Single Chosen */
48
+ .chosen-container-single .chosen-single {
49
+ position: relative;
50
+ display: block;
51
+ overflow: hidden;
52
+ padding: 0 0 0 8px;
53
+ height: 23px;
54
+ border: 1px solid #aaa;
55
+ border-radius: 5px;
56
+ background-color: #fff;
57
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
58
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
59
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
60
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
61
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
62
+ background-clip: padding-box;
63
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
64
+ color: #444;
65
+ text-decoration: none;
66
+ white-space: nowrap;
67
+ line-height: 24px;
68
+ }
69
+ .chosen-container-single .chosen-default {
70
+ color: #999;
71
+ }
72
+ .chosen-container-single .chosen-single span {
73
+ display: block;
74
+ overflow: hidden;
75
+ margin-right: 26px;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ }
79
+ .chosen-container-single .chosen-single-with-deselect span {
80
+ margin-right: 38px;
81
+ }
82
+ .chosen-container-single .chosen-single abbr {
83
+ position: absolute;
84
+ top: 6px;
85
+ right: 26px;
86
+ display: block;
87
+ width: 12px;
88
+ height: 12px;
89
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
90
+ font-size: 1px;
91
+ }
92
+ .chosen-container-single .chosen-single abbr:hover {
93
+ background-position: -42px -10px;
94
+ }
95
+ .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
96
+ background-position: -42px -10px;
97
+ }
98
+ .chosen-container-single .chosen-single div {
99
+ position: absolute;
100
+ top: 0;
101
+ right: 0;
102
+ display: block;
103
+ width: 18px;
104
+ height: 100%;
105
+ }
106
+ .chosen-container-single .chosen-single div b {
107
+ display: block;
108
+ width: 100%;
109
+ height: 100%;
110
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 0px 2px;
111
+ }
112
+ .chosen-container-single .chosen-search {
113
+ position: relative;
114
+ z-index: 1010;
115
+ margin: 0;
116
+ padding: 3px 4px;
117
+ white-space: nowrap;
118
+ }
119
+ .chosen-container-single .chosen-search input[type="text"] {
120
+ -webkit-box-sizing: border-box;
121
+ -moz-box-sizing: border-box;
122
+ box-sizing: border-box;
123
+ margin: 1px 0;
124
+ padding: 4px 20px 4px 5px;
125
+ width: 100%;
126
+ height: auto;
127
+ outline: 0;
128
+ border: 1px solid #aaa;
129
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
130
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
131
+ font-size: 1em;
132
+ font-family: sans-serif;
133
+ line-height: normal;
134
+ border-radius: 0;
135
+ }
136
+ .chosen-container-single .chosen-drop {
137
+ margin-top: -1px;
138
+ border-radius: 0 0 4px 4px;
139
+ background-clip: padding-box;
140
+ }
141
+ .chosen-container-single.chosen-container-single-nosearch .chosen-search {
142
+ position: absolute;
143
+ left: -9999px;
144
+ }
145
+
146
+ /* @end */
147
+ /* @group Results */
148
+ .chosen-container .chosen-results {
149
+ position: relative;
150
+ overflow-x: hidden;
151
+ overflow-y: auto;
152
+ margin: 0 4px 4px 0;
153
+ padding: 0 0 0 4px;
154
+ max-height: 240px;
155
+ -webkit-overflow-scrolling: touch;
156
+ }
157
+ .chosen-container .chosen-results li {
158
+ display: none;
159
+ margin: 0;
160
+ padding: 5px 6px;
161
+ list-style: none;
162
+ line-height: 15px;
163
+ -webkit-touch-callout: none;
164
+ }
165
+ .chosen-container .chosen-results li.active-result {
166
+ display: list-item;
167
+ cursor: pointer;
168
+ }
169
+ .chosen-container .chosen-results li.disabled-result {
170
+ display: list-item;
171
+ color: #ccc;
172
+ cursor: default;
173
+ }
174
+ .chosen-container .chosen-results li.highlighted {
175
+ background-color: #3875d7;
176
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
177
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
178
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
179
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
180
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
181
+ color: #fff;
182
+ }
183
+ .chosen-container .chosen-results li.no-results {
184
+ display: list-item;
185
+ background: #f4f4f4;
186
+ }
187
+ .chosen-container .chosen-results li.group-result {
188
+ display: list-item;
189
+ font-weight: bold;
190
+ cursor: default;
191
+ }
192
+ .chosen-container .chosen-results li.group-option {
193
+ padding-left: 15px;
194
+ }
195
+ .chosen-container .chosen-results li em {
196
+ font-style: normal;
197
+ text-decoration: underline;
198
+ }
199
+
200
+ /* @end */
201
+ /* @group Multi Chosen */
202
+ .chosen-container-multi .chosen-choices {
203
+ position: relative;
204
+ overflow: hidden;
205
+ -webkit-box-sizing: border-box;
206
+ -moz-box-sizing: border-box;
207
+ box-sizing: border-box;
208
+ margin: 0;
209
+ padding: 0;
210
+ width: 100%;
211
+ height: auto !important;
212
+ height: 1%;
213
+ border: 1px solid #aaa;
214
+ background-color: #fff;
215
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
216
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
217
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
218
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
219
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
220
+ cursor: text;
221
+ }
222
+ .chosen-container-multi .chosen-choices li {
223
+ float: left;
224
+ list-style: none;
225
+ }
226
+ .chosen-container-multi .chosen-choices li.search-field {
227
+ margin: 0;
228
+ padding: 0;
229
+ white-space: nowrap;
230
+ }
231
+ .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
232
+ margin: 1px 0;
233
+ padding: 5px;
234
+ height: 15px;
235
+ outline: 0;
236
+ border: 0 !important;
237
+ background: transparent !important;
238
+ box-shadow: none;
239
+ color: #666;
240
+ font-size: 100%;
241
+ font-family: sans-serif;
242
+ line-height: normal;
243
+ border-radius: 0;
244
+ }
245
+ .chosen-container-multi .chosen-choices li.search-field .default {
246
+ color: #999;
247
+ }
248
+ .chosen-container-multi .chosen-choices li.search-choice {
249
+ position: relative;
250
+ margin: 3px 0 3px 5px;
251
+ padding: 3px 20px 3px 5px;
252
+ border: 1px solid #aaa;
253
+ border-radius: 3px;
254
+ background-color: #e4e4e4;
255
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
256
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
257
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
258
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
259
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
260
+ background-clip: padding-box;
261
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
262
+ color: #333;
263
+ line-height: 13px;
264
+ cursor: default;
265
+ }
266
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
267
+ position: absolute;
268
+ top: 4px;
269
+ right: 3px;
270
+ display: block;
271
+ width: 12px;
272
+ height: 12px;
273
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
274
+ font-size: 1px;
275
+ }
276
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
277
+ background-position: -42px -10px;
278
+ }
279
+ .chosen-container-multi .chosen-choices li.search-choice-disabled {
280
+ padding-right: 5px;
281
+ border: 1px solid #ccc;
282
+ background-color: #e4e4e4;
283
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
284
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
285
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
286
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
287
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
288
+ color: #666;
289
+ }
290
+ .chosen-container-multi .chosen-choices li.search-choice-focus {
291
+ background: #d4d4d4;
292
+ }
293
+ .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
294
+ background-position: -42px -10px;
295
+ }
296
+ .chosen-container-multi .chosen-results {
297
+ margin: 0;
298
+ padding: 0;
299
+ }
300
+ .chosen-container-multi .chosen-drop .result-selected {
301
+ display: list-item;
302
+ color: #ccc;
303
+ cursor: default;
304
+ }
305
+
306
+ /* @end */
307
+ /* @group Active */
308
+ .chosen-container-active .chosen-single {
309
+ border: 1px solid #5897fb;
310
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
311
+ }
312
+ .chosen-container-active.chosen-with-drop .chosen-single {
313
+ border: 1px solid #aaa;
314
+ -moz-border-radius-bottomright: 0;
315
+ border-bottom-right-radius: 0;
316
+ -moz-border-radius-bottomleft: 0;
317
+ border-bottom-left-radius: 0;
318
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
319
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
320
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
321
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
322
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
323
+ box-shadow: 0 1px 0 #fff inset;
324
+ }
325
+ .chosen-container-active.chosen-with-drop .chosen-single div {
326
+ border-left: none;
327
+ background: transparent;
328
+ }
329
+ .chosen-container-active.chosen-with-drop .chosen-single div b {
330
+ background-position: -18px 2px;
331
+ }
332
+ .chosen-container-active .chosen-choices {
333
+ border: 1px solid #5897fb;
334
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
335
+ }
336
+ .chosen-container-active .chosen-choices li.search-field input[type="text"] {
337
+ color: #111 !important;
338
+ }
339
+
340
+ /* @end */
341
+ /* @group Disabled Support */
342
+ .chosen-disabled {
343
+ opacity: 0.5 !important;
344
+ cursor: default;
345
+ }
346
+ .chosen-disabled .chosen-single {
347
+ cursor: default;
348
+ }
349
+ .chosen-disabled .chosen-choices .search-choice .search-choice-close {
350
+ cursor: default;
351
+ }
352
+
353
+ /* @end */
354
+ /* @group Right to Left */
355
+ .chosen-rtl {
356
+ text-align: right;
357
+ }
358
+ .chosen-rtl .chosen-single {
359
+ overflow: visible;
360
+ padding: 0 8px 0 0;
361
+ }
362
+ .chosen-rtl .chosen-single span {
363
+ margin-right: 0;
364
+ margin-left: 26px;
365
+ direction: rtl;
366
+ }
367
+ .chosen-rtl .chosen-single-with-deselect span {
368
+ margin-left: 38px;
369
+ }
370
+ .chosen-rtl .chosen-single div {
371
+ right: auto;
372
+ left: 3px;
373
+ }
374
+ .chosen-rtl .chosen-single abbr {
375
+ right: auto;
376
+ left: 26px;
377
+ }
378
+ .chosen-rtl .chosen-choices li {
379
+ float: right;
380
+ }
381
+ .chosen-rtl .chosen-choices li.search-field input[type="text"] {
382
+ direction: rtl;
383
+ }
384
+ .chosen-rtl .chosen-choices li.search-choice {
385
+ margin: 3px 5px 3px 0;
386
+ padding: 3px 5px 3px 19px;
387
+ }
388
+ .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
389
+ right: auto;
390
+ left: 4px;
391
+ }
392
+ .chosen-rtl.chosen-container-single-nosearch .chosen-search,
393
+ .chosen-rtl .chosen-drop {
394
+ left: 9999px;
395
+ }
396
+ .chosen-rtl.chosen-container-single .chosen-results {
397
+ margin: 0 0 4px 4px;
398
+ padding: 0 4px 0 0;
399
+ }
400
+ .chosen-rtl .chosen-results li.group-option {
401
+ padding-right: 15px;
402
+ padding-left: 0;
403
+ }
404
+ .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
405
+ border-right: none;
406
+ }
407
+ .chosen-rtl .chosen-search input[type="text"] {
408
+ padding: 4px 5px 4px 20px;
409
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
410
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
411
+ direction: rtl;
412
+ }
413
+ .chosen-rtl.chosen-container-single .chosen-single div b {
414
+ background-position: 6px 2px;
415
+ }
416
+ .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
417
+ background-position: -12px 2px;
418
+ }
419
+
420
+ /* @end */
421
+ /* @group Retina compatibility */
422
+ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
423
+ .chosen-rtl .chosen-search input[type="text"],
424
+ .chosen-container-single .chosen-single abbr,
425
+ .chosen-container-single .chosen-single div b,
426
+ .chosen-container-single .chosen-search input[type="text"],
427
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
428
+ .chosen-container .chosen-results-scroll-down span,
429
+ .chosen-container .chosen-results-scroll-up span {
430
+ background-image: url('../../images/chosen/chosen-sprite@2x.png') !important;
431
+ background-size: 52px 37px !important;
432
+ background-repeat: no-repeat !important;
433
+ }
434
+ }
435
+ /* @end */
plugin-fw/assets/css/codemirror/codemirror.css ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* BASICS */
2
+
3
+ .CodeMirror {
4
+ /* Set height, width, borders, and global font properties here */
5
+ font-family: monospace;
6
+ height: 400px;
7
+ clear: both;
8
+ padding: 0;
9
+ }
10
+ .CodeMirror-scroll {
11
+ /* Set scrolling behaviour here */
12
+ overflow: auto;
13
+ }
14
+
15
+ /* PADDING */
16
+
17
+ .CodeMirror-lines {
18
+ padding: 4px 0; /* Vertical padding around content */
19
+ }
20
+ .CodeMirror pre {
21
+ padding: 0 4px; /* Horizontal padding of content */
22
+ }
23
+
24
+ .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
25
+ background-color: white; /* The little square between H and V scrollbars */
26
+ }
27
+
28
+ /* GUTTER */
29
+
30
+ .CodeMirror-gutters {
31
+ border-right: 1px solid #ddd;
32
+ background-color: #f7f7f7;
33
+ white-space: nowrap;
34
+ }
35
+ .CodeMirror-linenumbers {}
36
+ .CodeMirror-linenumber {
37
+ padding: 0 3px 0 5px;
38
+ min-width: 20px;
39
+ text-align: right;
40
+ color: #999;
41
+ }
42
+
43
+ /* CURSOR */
44
+
45
+ .CodeMirror div.CodeMirror-cursor {
46
+ border-left: 1px solid black;
47
+ z-index: 3;
48
+ }
49
+ /* Shown when moving in bi-directional text */
50
+ .CodeMirror div.CodeMirror-secondarycursor {
51
+ border-left: 1px solid silver;
52
+ }
53
+ .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
54
+ width: auto;
55
+ border: 0;
56
+ background: #7e7;
57
+ z-index: 1;
58
+ }
59
+ /* Can style cursor different in overwrite (non-insert) mode */
60
+ .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
61
+
62
+ .cm-tab { display: inline-block; }
63
+
64
+ /* DEFAULT THEME */
65
+
66
+ .cm-s-default .cm-keyword {color: #708;}
67
+ .cm-s-default .cm-atom {color: #219;}
68
+ .cm-s-default .cm-number {color: #164;}
69
+ .cm-s-default .cm-def {color: #00f;}
70
+ .cm-s-default .cm-variable {color: black;}
71
+ .cm-s-default .cm-variable-2 {color: #05a;}
72
+ .cm-s-default .cm-variable-3 {color: #085;}
73
+ .cm-s-default .cm-property {color: black;}
74
+ .cm-s-default .cm-operator {color: black;}
75
+ .cm-s-default .cm-comment {color: #a50;}
76
+ .cm-s-default .cm-string {color: #a11;}
77
+ .cm-s-default .cm-string-2 {color: #f50;}
78
+ .cm-s-default .cm-meta {color: #555;}
79
+ .cm-s-default .cm-error {color: #f00;}
80
+ .cm-s-default .cm-qualifier {color: #555;}
81
+ .cm-s-default .cm-builtin {color: #30a;}
82
+ .cm-s-default .cm-bracket {color: #997;}
83
+ .cm-s-default .cm-tag {color: #170;}
84
+ .cm-s-default .cm-attribute {color: #00c;}
85
+ .cm-s-default .cm-header {color: blue;}
86
+ .cm-s-default .cm-quote {color: #090;}
87
+ .cm-s-default .cm-hr {color: #999;}
88
+ .cm-s-default .cm-link {color: #00c;}
89
+
90
+ .cm-negative {color: #d44;}
91
+ .cm-positive {color: #292;}
92
+ .cm-header, .cm-strong {font-weight: bold;}
93
+ .cm-em {font-style: italic;}
94
+ .cm-link {text-decoration: underline;}
95
+
96
+ .cm-invalidchar {color: #f00;}
97
+
98
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
99
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
100
+
101
+ /* STOP */
102
+
103
+ /* The rest of this file contains styles related to the mechanics of
104
+ the editor. You probably shouldn't touch them. */
105
+
106
+ .CodeMirror {
107
+ line-height: 1;
108
+ position: relative;
109
+ overflow: hidden;
110
+ background: #fafafa;
111
+ color: black;
112
+ }
113
+
114
+ .CodeMirror-scroll {
115
+ /* 30px is the magic margin used to hide the element's real scrollbars */
116
+ /* See overflow: hidden in .CodeMirror */
117
+ margin-bottom: -30px; margin-right: -30px;
118
+ padding-bottom: 30px; padding-right: 30px;
119
+ height: 100%;
120
+ outline: none; /* Prevent dragging from highlighting the element */
121
+ position: relative;
122
+ }
123
+ .CodeMirror-sizer {
124
+ position: relative;
125
+ }
126
+
127
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
128
+ before actuall scrolling happens, thus preventing shaking and
129
+ flickering artifacts. */
130
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
131
+ position: absolute;
132
+ z-index: 6;
133
+ display: none;
134
+ }
135
+ .CodeMirror-vscrollbar {
136
+ right: 0; top: 0;
137
+ overflow-x: hidden;
138
+ overflow-y: scroll;
139
+ }
140
+ .CodeMirror-hscrollbar {
141
+ bottom: 0; left: 0;
142
+ overflow-y: hidden;
143
+ overflow-x: scroll;
144
+ }
145
+ .CodeMirror-scrollbar-filler {
146
+ right: 0; bottom: 0;
147
+ }
148
+ .CodeMirror-gutter-filler {
149
+ left: 0; bottom: 0;
150
+ }
151
+
152
+ .CodeMirror-gutters {
153
+ position: absolute; left: 0; top: 0;
154
+ padding-bottom: 30px;
155
+ z-index: 3;
156
+ }
157
+ .CodeMirror-gutter {
158
+ white-space: normal;
159
+ height: 100%;
160
+ padding-bottom: 30px;
161
+ margin-bottom: -32px;
162
+ display: inline-block;
163
+ /* Hack to make IE7 behave */
164
+ *zoom:1;
165
+ *display:inline;
166
+ }
167
+ .CodeMirror-gutter-elt {
168
+ position: absolute;
169
+ cursor: default;
170
+ z-index: 4;
171
+ }
172
+
173
+ .CodeMirror-lines {
174
+ cursor: text;
175
+ }
176
+ .CodeMirror pre {
177
+ /* Reset some styles that the rest of the page might have set */
178
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
179
+ border-width: 0;
180
+ background: transparent;
181
+ font-family: inherit;
182
+ font-size: inherit;
183
+ margin: 0;
184
+ white-space: pre;
185
+ word-wrap: normal;
186
+ line-height: inherit;
187
+ color: inherit;
188
+ z-index: 2;
189
+ position: relative;
190
+ overflow: visible;
191
+ }
192
+ .CodeMirror-wrap pre {
193
+ word-wrap: break-word;
194
+ white-space: pre-wrap;
195
+ word-break: normal;
196
+ }
197
+ .CodeMirror-code pre {
198
+ border-right: 30px solid transparent;
199
+ width: -webkit-fit-content;
200
+ width: -moz-fit-content;
201
+ width: fit-content;
202
+ }
203
+ .CodeMirror-wrap .CodeMirror-code pre {
204
+ border-right: none;
205
+ width: auto;
206
+ }
207
+ .CodeMirror-linebackground {
208
+ position: absolute;
209
+ left: 0; right: 0; top: 0; bottom: 0;
210
+ z-index: 0;
211
+ }
212
+
213
+ .CodeMirror-linewidget {
214
+ position: relative;
215
+ z-index: 2;
216
+ overflow: auto;
217
+ }
218
+
219
+ .CodeMirror-widget {
220
+ }
221
+
222
+ .CodeMirror-wrap .CodeMirror-scroll {
223
+ overflow-x: hidden;
224
+ }
225
+
226
+ .CodeMirror-measure {
227
+ position: absolute;
228
+ width: 100%; height: 0px;
229
+ overflow: hidden;
230
+ visibility: hidden;
231
+ }
232
+ .CodeMirror-measure pre { position: static; }
233
+
234
+ .CodeMirror div.CodeMirror-cursor {
235
+ position: absolute;
236
+ visibility: hidden;
237
+ border-right: none;
238
+ width: 0;
239
+ }
240
+ .CodeMirror-focused div.CodeMirror-cursor {
241
+ visibility: visible;
242
+ }
243
+
244
+ .CodeMirror-selected { background: #d9d9d9; }
245
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
246
+
247
+ .cm-searching {
248
+ background: #ffa;
249
+ background: rgba(255, 255, 0, .4);
250
+ }
251
+
252
+ /* IE7 hack to prevent it from returning funny offsetTops on the spans */
253
+ .CodeMirror span { *vertical-align: text-bottom; }
254
+
255
+ @media print {
256
+ /* Hide the cursor when printing */
257
+ .CodeMirror div.CodeMirror-cursor {
258
+ visibility: hidden;
259
+ }
260
+ }
plugin-fw/assets/css/metaboxes.css ADDED
@@ -0,0 +1,609 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* self-clear floats */
2
+ .clearfix:after { content:"."; display:block; height:0; clear:both; visibility:hidden; overflow:hidden; }
3
+ /* ie.css */
4
+ * html .clearfix { /* IE6 */
5
+ height:1%;
6
+ }
7
+ *:first-child+html .clearfix { /* IE7 */
8
+ min-height:1%;
9
+ }
10
+
11
+ .clearboth { clear: both }
12
+
13
+ /* === TAB STYLE */
14
+ .metaboxes-tab { margin:-6px -12px -8px; }
15
+ .metaboxes-tab div.tabs-panel { height:auto; overflow:visible; margin-top:0px; padding:0 10px; background:none; border:0; border-top:1px solid #D4D4D4; }
16
+ .metaboxes-tab ul.metaboxes-tabs { background:#F5F5F5; margin:0; padding:10px 0 0 5px; }
17
+ .metaboxes-tab ul.metaboxes-tabs li { padding:8px 15px; border:1px solid #D4D4D4; float:left; background:#EDEDED; border-bottom-color:#EDEDED; margin:0 0 -1px 5px; box-shadow:1px 1px 1px 0 #FFFFFF inset; }
18
+ .metaboxes-tab ul.metaboxes-tabs li a { color:#555; text-decoration:none; }
19
+ .metaboxes-tab ul.metaboxes-tabs li.tabs { background:#F6F6F6; border-bottom:1px solid #F6F6F6; }
20
+ .metaboxes-tab p.field-row { margin:20px 0; }
21
+ .metaboxes-tab div.sep { height:1px; background:#DFDFDF; clear:both; margin-left:-10px; margin-right:-10px; }
22
+ .metaboxes-tab label { font-weight:bold; width:160px; float:left; line-height:23px; margin-left:-184px; }
23
+ .metaboxes-tab label small { font-weight:normal; line-height:15px; font-style:italic; color:#999; display:block; }
24
+ .metaboxes-tab input[type="text"], .metaboxes-tab select, .metaboxes-tab textarea { width:30%; }
25
+ .metaboxes-tab input[type="checkbox"] { vertical-align: middle }
26
+ .metaboxes-tab select {padding:0;}
27
+ .metaboxes-tab input.button-secondary, .metaboxes-tab input.checkbox { width:auto; }
28
+ .metaboxes-tab .description { color:#AFAFAF; font-size:90%; font-style:italic; line-height:23px; padding-left:5px; }
29
+ .metaboxes-tab p.field-row.textarea .description { vertical-align:top; }
30
+ .metaboxes-tab p.field-row.checkbox {background:none;}
31
+
32
+ .metaboxes-tab .the-metabox { margin:20px 0; margin-left:184px;}
33
+ .metaboxes-tab .the-metabox.no-label { margin:20px 0; margin-left:0;}
34
+ .metaboxes-tab hr { height: 0px; border-top: 1px solid #dadada; width: auto; margin-left: -10px; margin-right: -10px; }
35
+ .metaboxes-tab .the-metabox p { margin:0;}
36
+ .metaboxes-tab .the-metabox:last-child { border-bottom: 0px; }
37
+ .metaboxes-tab .the-metabox.checkbox { background:none; }
38
+ .metaboxes-tab .the-metabox.slider .ui-slider { margin-right:15px; }
39
+
40
+ .metaboxes-tab span.desc { font-size: 11px; color: #AFAFAF; }
41
+ .metaboxes-tab span.desc.inline { display: inline-block; vertical-align: top; line-height: 23px; }
42
+ .metaboxes-tab .onoff span.desc, .metaboxes-tab .onoff label { padding:6px 0; }
43
+ .metaboxes-tab .select span.desc, .metaboxes-tab .select label { padding:2px 0; }
44
+ .metaboxes-tab .slider span.desc, .metaboxes-tab .slider label { padding:15px 0; }
45
+ .metaboxes-tab .slider span.desc { display:block; padding:20px 0; }
46
+
47
+ .metaboxes-tab ul.metaboxes-tabs li {
48
+ -webkit-border-top-left-radius: 3px;
49
+ -webkit-border-top-right-radius: 3px;
50
+ -moz-border-radius-topleft: 3px;
51
+ -moz-border-radius-topright: 3px;
52
+ border-top-left-radius: 3px;
53
+ border-top-right-radius: 3px;
54
+ }
55
+
56
+ /* image gallery */
57
+ .metaboxes-tab .image-gallery ul li{
58
+ display: inline-block;
59
+ width: 80px;
60
+ margin-left: 10px;
61
+ position: relative;
62
+ }
63
+ .metaboxes-tab .image-gallery ul li img{
64
+ width: 80px;
65
+ border: 1px solid #ccc;
66
+ }
67
+ .metaboxes-tab .image-gallery ul li ul{
68
+ position: absolute;
69
+ top: -6px;
70
+ right: -1px;
71
+ width: 20px;
72
+ height: 20px;
73
+ }
74
+ .metaboxes-tab .image-gallery ul a.delete{
75
+ background: url(../images/x.png) no-repeat;
76
+ width: 20px;
77
+ height: 20px;
78
+ display: block;
79
+ text-indent: -99999px;
80
+ }
81
+ /* sidebar layout */
82
+ .yit-sidebar-layout input[type="radio"] {
83
+ display: none;
84
+ width: 0px;
85
+ }
86
+ .yit-sidebar-layout input[type="radio"]:first-child {
87
+ margin-right: -2px;
88
+ }
89
+
90
+ .yit-sidebar-layout input[type="radio"] + img {
91
+ border: 2px solid #fff;
92
+ padding: 1px;
93
+ }
94
+
95
+ .yit-sidebar-layout input[type="radio"] + img:hover {
96
+ cursor: pointer;
97
+ }
98
+
99
+ .yit-sidebar-layout input[checked] + img {
100
+ border: 2px solid #f2ad35;
101
+ padding: 1px;
102
+ }
103
+
104
+ .yit-sidebar-layout select {
105
+ vertical-align: 12px;
106
+ width: inherit !important;
107
+ }
108
+
109
+ /* wp editor */
110
+ .the-metabox.textarea-editor .mceIframeContainer {
111
+ background:#fff;
112
+ }
113
+ .the-metabox.textarea-editor label {
114
+ margin-top:24px;
115
+ }
116
+
117
+ /* categories */
118
+ .categories-panel { width:30%; float:left; margin-right:4px; }
119
+ .categories-panel .box { height:200px; border:1px solid #DFDFDF; background:#fff; padding:6px 10px; overflow: auto; }
120
+ .categories-panel ul { list-style:none; margin:0; }
121
+ .categories-panel ul li { line-height: 19px; margin: 0; padding: 0; word-wrap: break-word; }
122
+ .categories-panel ul li label { font-weight:normal !important; margin-left:0 !important; }
123
+ .categories-panel input.newcategory { width:100%; margin-bottom:3px; }
124
+
125
+ /* contact form */
126
+ .contactform_item {
127
+ border-style: solid;
128
+ border-width: 1px;
129
+ line-height: 1;
130
+ margin-bottom: 20px;
131
+ padding: 0;
132
+ background-color: #F5F5F5;
133
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
134
+ border-color: #DFDFDF;
135
+ border-radius: 3px 3px 3px 3px;
136
+ box-shadow: 0 1px 0 #FFFFFF inset;
137
+ min-width: 255px;
138
+ position: relative;
139
+ }
140
+ .contactform_item .handlediv { position:relative; top: -4px; }
141
+ .contactform_item h3 { min-height: 21px }
142
+ .contactform_item .inside { padding: 10px !important; }
143
+ .contactform_item .deps { display: none; }
144
+ .contactform_item .addoptions p.option { margin: 5px 0 5px 200px }
145
+ .contactform_item .addoptions p label { width: 80px !important; }
146
+ .contactform_item .add-field-option { margin-bottom: 10px !important; }
147
+ .remove_item { float: right; }
148
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
149
+
150
+ /* features tab */
151
+ .featurestab_item{
152
+ border-style: solid;
153
+ border-width: 1px;
154
+ line-height: 1;
155
+ margin-bottom: 20px;
156
+ padding: 0;
157
+ background-color: #F5F5F5;
158
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
159
+ border-color: #DFDFDF;
160
+ border-radius: 3px 3px 3px 3px;
161
+ box-shadow: 0 1px 0 #FFFFFF inset;
162
+ min-width: 255px;
163
+ position: relative;
164
+ }
165
+ .featurestab_item .handlediv { position:relative; top: -4px; }
166
+ .featurestab_item h3 { min-height: 21px }
167
+ .featurestab_item .inside { padding: 10px !important; }
168
+ .featurestab_item .deps { display: none; }
169
+ .featurestab_item .addoptions p.option { margin: 5px 0 5px 200px }
170
+ .featurestab_item .addoptions p label { width: 80px !important; }
171
+ .featurestab_item .add-field-option { margin-bottom: 10px !important; }
172
+
173
+ /* slider */
174
+ .the-metabox.slider { padding-top:20px; }
175
+
176
+ /* on off */
177
+ .the-metabox .rm_onoff span.onoff { float:left; margin-right:5px; margin-left:-4px; /* image fix */ }
178
+
179
+ /* select */
180
+ .the-metabox .select_wrapper { width:341px; background-color:#fff; }
181
+ .the-metabox .select_wrapper select { width:100%; }
182
+ .the-metabox .icon_type{ width:30%; float: left; margin-right: 40px }
183
+ .the-metabox .icon_type select, .the-metabox div.option .select_wrapper select{ width: 100% }
184
+
185
+ #post-type-settings .category-list label { width: 187px; }
186
+ .remove_cat { float: right; text-align:center; display: block; width: 20px; height: 20px; border-radius: 20px; font-weight: bold; font-size: 10px; background: #efefef; text-decoration: none; }
187
+
188
+ .the-metabox .select_wrapper {
189
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
190
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
191
+ border-radius: 4px 4px 4px 4px;
192
+ border-style: solid;
193
+ border-width: 1px;
194
+ color: #555555;
195
+ display: block;
196
+ float: left;
197
+ font-family: sans-serif;
198
+ font-size: 12px;
199
+ min-height: 26px;
200
+ margin-bottom: 9px !important;
201
+ margin-left: 0;
202
+ margin-right: 5px;
203
+ margin-top: 0;
204
+ width: 400px;
205
+ position: relative;
206
+ }
207
+
208
+ /*chosen*/
209
+
210
+ .chosen .select_wrapper {
211
+ background: none;
212
+ border: none;
213
+ }
214
+ .chosen .select_wrapper .chosen-container{
215
+ width: 338px!important;
216
+ }
217
+ .chosen .select_wrapper .chosen-container .search-field input{
218
+ height: 27px!important;
219
+ color: #333;
220
+ }
221
+ .chosen .select_wrapper .chosen-container .chosen-choices{
222
+ border: 1px solid #ddd;
223
+ box-shadow: none;
224
+ }
225
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
226
+ height: 15px!important;
227
+ min-width: 105px;
228
+ }
229
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
230
+ line-height: 15px;
231
+ height: 15px;
232
+ padding-top: 2px;
233
+ }
234
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
235
+ top: 5px;
236
+ }
237
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
238
+ width: 100%!important;
239
+ }
240
+
241
+ /* typography */
242
+ .the-metabox.typography .select_wrapper.font-family { width:200px; }
243
+ .the-metabox.typography .spinner_container { float:left; margin-right:10px; }
244
+ .the-metabox.typography .spinner_container input.number {
245
+ width:50px !important;
246
+ -webkit-border-top-right-radius: 0px;
247
+ -webkit-border-bottom-right-radius: 0px;
248
+ -moz-border-radius-topright: 0px;
249
+ -moz-border-radius-bottomright: 0px;
250
+ border-top-right-radius: 0px;
251
+ border-bottom-right-radius: 0px;
252
+ }
253
+
254
+ /* number */
255
+ .the-metabox.number input.number { width:50px !important; }
256
+ /* number */
257
+ .rm_number .number {
258
+ width: 70px;
259
+ text-align: right;
260
+ -webkit-border-top-right-radius: 0px;
261
+ -webkit-border-bottom-right-radius: 0px;
262
+ -moz-border-radius-topright: 0px;
263
+ -moz-border-radius-bottomright: 0px;
264
+ border-top-right-radius: 0px;
265
+ border-bottom-right-radius: 0px;
266
+ }
267
+
268
+ .spinner-wrapper { position: relative; height: 23px; overflow: hidden; }
269
+ .spinner-wrapper input.number { float: left; }
270
+ .spinner-wrapper .spinner-button { cursor:pointer; float: left; position: absolute; left: 69px; width: 15px; height: 12px; border: 1px solid #DFDFDF; background: #fff; margin: 0; padding: 0; line-height: 9999px; overflow: hidden; background: url('../images/spinner.png') no-repeat center -11px }
271
+ .spinner-wrapper .spinner-button.button-plus { top: 0; -webkit-border-top-right-radius: 3px !important; -moz-border-radius-topright: 3px !important; border-top-right-radius: 3px !important; }
272
+ .spinner-wrapper .spinner-button.button-minus { bottom: 0; background-position: center -30px; -webkit-border-bottom-right-radius: 3px !important; -moz-border-radius-bottomright: 3px !important; border-bottom-right-radius: 3px !important; }
273
+
274
+
275
+ .spinner-wrapper .spinner-button.button-plus:active { background-position: center 0px; }
276
+ .spinner-wrapper .spinner-button.button-minus:active { background-position: center -20px; }
277
+
278
+
279
+ .rm_typography .spinner_container { float: left; margin-right: 10px; }
280
+ .rm_typography .spinner-wrapper { height: 28px; }
281
+ .rm_typography .spinner-wrapper input.number { height: 28px; }
282
+ .rm_typography .spinner-wrapper .spinner-button.button-plus { height: 15px; background-position: center -10px; }
283
+ .rm_typography .spinner-wrapper .spinner-button.button-minus { height: 14px; }
284
+
285
+ .the-metabox .spinner-wrapper .spinner-button { left: 49px; }
286
+ .the-metabox.typography .spinner-wrapper .spinner-button { left: 35px; }
287
+
288
+ /* colorpicker */
289
+ .the-metabox.colorpicker { display:block; width: auto; height: auto; overflow: visible; background-image: none; position: static; font-family: inherit;}
290
+ .the-metabox.colorpicker input { background-color: transparent; border: 1px solid #DFDFDF; position: static; font-size: inherit; font-family: inherit; color: inherit; text-align: center; margin: 0 5px 0px; padding: 0; outline: none; width: auto; }
291
+
292
+ /* images */
293
+ .the-metabox.images, .the-metabox.images label { margin-left:0; display:block; }
294
+ .the-metabox.images .slides-wrapper { clear:both; }
295
+ .the-metabox.images .slides-wrapper li { position:relative; }
296
+ .the-metabox.images a.delete { display:block; margin-left:4px; text-decoration:none; font-weight:bold; color:red; position:absolute; top:0; right:0; width:10px; height:18px; z-index:10; cursor:pointer !important; }
297
+
298
+ /* wp editor */
299
+ .wp_themeSkin iframe { background: #fff !important; }
300
+
301
+ /* custom tabs */
302
+ .customtab_item {
303
+ border-style: solid;
304
+ border-width: 1px;
305
+ line-height: 1;
306
+ margin-bottom: 20px;
307
+ padding: 0;
308
+ background-color: #F5F5F5;
309
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
310
+ border-color: #DFDFDF;
311
+ border-radius: 3px 3px 3px 3px;
312
+ box-shadow: 0 1px 0 #FFFFFF inset;
313
+ min-width: 255px;
314
+ position: relative;
315
+ }
316
+ .customtab_item .handlediv { position:relative; top: -4px; }
317
+ .customtab_item h3 { min-height: 21px }
318
+ .customtab_item .inside { padding: 10px !important; }
319
+ .customtab_item .deps { display: none; }
320
+ .customtab_item .addoptions p.option { margin: 5px 0 5px 200px }
321
+ .customtab_item .addoptions p label { width: 80px !important; }
322
+ .customtab_item .add-field-option { margin-bottom: 10px !important; }
323
+ .customtab_item .remove_item { float: right; }
324
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
325
+
326
+ .the-metabox.customtabs {
327
+ margin-left: 0;
328
+ }
329
+
330
+ #customtab_item_sample {
331
+ display: none;
332
+ }
333
+
334
+ .the-metabox.customtabs .field-row {
335
+ margin-bottom: 10px;
336
+ }
337
+
338
+ #yit_custom_tabs label {
339
+ font-weight: normal;
340
+ width: auto;
341
+ float: none;
342
+ line-height: auto;
343
+ margin-left: 0;
344
+ }
345
+
346
+
347
+ .wp-admin p label input[type=radio]{
348
+ width: 16px;
349
+ margin-right: 10px;
350
+ margin-top: 3px;
351
+ }
352
+ .wp-admin .form-field._preset_onsale_icon_field label input[type=radio]{
353
+ margin-top: 0;
354
+ }
355
+
356
+ .the-metabox .spinner {
357
+ margin-top: 5px;
358
+ float: none;
359
+ }
360
+
361
+ /* slider */
362
+ /*numbers*/
363
+ .ui-slider .maxCaption, .ui-slider .minCaption {
364
+ margin-bottom: 5px;
365
+ }
366
+ .ui-slider .feedback {
367
+ background: url(../images/slider/tooltip.png) no-repeat center top;
368
+ position: absolute;
369
+ top: -25px;
370
+ width: 35px;
371
+ height: 43px;
372
+ text-align: center;
373
+ width: 100%;
374
+ display: block;
375
+ }
376
+ .ui-slider .feedback strong {
377
+ display: inline-block;
378
+ padding-top: 4px;
379
+ top: -30px;
380
+ }
381
+ /*handle*/
382
+ .ui-slider-horizontal .ui-slider-handle{
383
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
384
+ border: 0px !important;
385
+ top: -.35em !important;
386
+ width: 18px !important;
387
+ height: 19px !important;
388
+ }
389
+
390
+ /*bg on the left:grey*/
391
+ .ui-slider.ui-widget-content {
392
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
393
+ border-color: #c1c1c0 !important;
394
+ height: 10px !important;
395
+ }
396
+
397
+ .iris-slider-offset.ui-slider.ui-widget-content {
398
+ background: transparent!important;
399
+ height: auto!important;
400
+ }
401
+
402
+ /*bg on the right:orange*/
403
+ .ui-slider.ui-widget-content .ui-widget-header {
404
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
405
+ left: 2px !important;
406
+ -webkit-border-radius: 15px;
407
+ -moz-border-radius: 15px;
408
+ -khtml-border-radius: 15px;
409
+ border-radius: 15px;
410
+ }
411
+
412
+
413
+ /*sidebars*/
414
+
415
+ #choose-sidebars.choose{
416
+ margin-left: 0px;
417
+ }
418
+
419
+
420
+ #_active_page_options-container label, #_active_page_options-container p{
421
+ display: inline-block;
422
+ margin: 0px;
423
+ }
424
+ #_active_page_options-container label{
425
+ margin-right: 10px;
426
+ margin-top: 3px;
427
+ }
428
+ #_active_page_options-container {
429
+ float: right;
430
+ margin-right: 20px;
431
+ margin-top: 5px;
432
+ }
433
+
434
+ /* sortable table posts */
435
+
436
+ #the-list.ui-sortable tr:hover {
437
+ cursor: move;
438
+ }
439
+
440
+
441
+ /*datepicker*/
442
+ /*! jQuery UI - v1.11.2 - 2015-01-21
443
+ * http://jqueryui.com
444
+ * Includes: core.css, datepicker.css, theme.css
445
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=%23dddddd&bgTextureHeader=flat&bgImgOpacityHeader=60&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23e9e9e9&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%23d3d3d3&fcDefault=%23555555&iconColorDefault=%23888888&bgColorHover=%23dadada&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%23999999&fcHover=%23212121&iconColorHover=%23454545&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23aaaaaa&fcActive=%23212121&iconColorActive=%23454545&bgColorHighlight=%23fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%2389b17e&fcHighlight=%23363636&iconColorHighlight=%232e83ff&bgColorError=%23fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=%23cd0a0a&fcError=%23cd0a0a&iconColorError=%23cd0a0a&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
446
+ * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
447
+
448
+ /* Layout helpers
449
+ ----------------------------------*/
450
+ .ui-helper-hidden {
451
+ display: none;
452
+ }
453
+ .ui-helper-hidden-accessible {
454
+ border: 0;
455
+ clip: rect(0 0 0 0);
456
+ height: 1px;
457
+ margin: -1px;
458
+ overflow: hidden;
459
+ padding: 0;
460
+ position: absolute;
461
+ width: 1px;
462
+ }
463
+ .ui-helper-reset {
464
+ margin: 0;
465
+ padding: 0;
466
+ border: 0;
467
+ outline: 0;
468
+ line-height: 1.3;
469
+ text-decoration: none;
470
+ font-size: 100%;
471
+ list-style: none;
472
+ }
473
+ .ui-helper-clearfix:before,
474
+ .ui-helper-clearfix:after {
475
+ content: "";
476
+ display: table;
477
+ border-collapse: collapse;
478
+ }
479
+ .ui-helper-clearfix:after {
480
+ clear: both;
481
+ }
482
+ .ui-helper-clearfix {
483
+ min-height: 0; /* support: IE7 */
484
+ }
485
+ .ui-helper-zfix {
486
+ width: 100%;
487
+ height: 100%;
488
+ top: 0;
489
+ left: 0;
490
+ position: absolute;
491
+ opacity: 0;
492
+ filter:Alpha(Opacity=0); /* support: IE8 */
493
+ }
494
+
495
+ .ui-front {
496
+ z-index: 100;
497
+ }
498
+
499
+
500
+ /* Interaction Cues
501
+ ----------------------------------*/
502
+ .ui-state-disabled {
503
+ cursor: default !important;
504
+ }
505
+
506
+
507
+ /* Icons
508
+ ----------------------------------*/
509
+
510
+ /* states and images */
511
+ .ui-icon {
512
+ display: block;
513
+ text-indent: -99999px;
514
+ overflow: hidden;
515
+ background-repeat: no-repeat;
516
+ }
517
+
518
+
519
+ /* DATE PICKER
520
+ ----------------------------------*/
521
+
522
+ .ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}
523
+ .ui-datepicker{width:17em;padding:.2em .2em 0;display:none;z-index:100!important;}
524
+ .ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}
525
+ .ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}
526
+ .ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}
527
+ .ui-datepicker .ui-datepicker-prev{left:2px}
528
+ .ui-datepicker .ui-datepicker-next{right:2px}
529
+ .ui-datepicker .ui-datepicker-prev-hover{left:1px}
530
+ .ui-datepicker .ui-datepicker-next-hover{right:1px}
531
+ .ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}
532
+ .ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}
533
+ .ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}
534
+ .ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}
535
+ .ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}
536
+ .ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}
537
+ .ui-datepicker td{border:0;padding:1px}
538
+ .ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}
539
+ .ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}
540
+ .ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em;width:auto;overflow:visible}
541
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}
542
+ .ui-datepicker.ui-datepicker-multi{width:auto}
543
+ .ui-datepicker-multi .ui-datepicker-group{float:left}
544
+ .ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}
545
+ .ui-datepicker-multi-2 .ui-datepicker-group{width:50%}
546
+ .ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}
547
+ .ui-datepicker-multi-4 .ui-datepicker-group{width:25%}
548
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}
549
+ .ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}
550
+ .ui-datepicker-row-break{clear:both;width:100%;font-size:0}
551
+ .ui-datepicker-rtl{direction:rtl}
552
+ .ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}
553
+ .ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}
554
+ .ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}
555
+ .ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}
556
+ .ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}
557
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}
558
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}
559
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}
560
+ .ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}
561
+ .ui-widget .ui-widget{font-size:1em}
562
+ .ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}
563
+ .ui-widget-content{border:1px solid #aaa;background:#fff 50% 50% repeat-x;color:#222}
564
+ .ui-widget-content a{color:#222}
565
+ .ui-widget-header{border:1px solid #aaa;background:#ddd 50% 50% repeat-x;color:#222;font-weight:700}
566
+ .ui-widget-header a{color:#222}
567
+ .ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:0 solid #d3d3d3;background:#e9e9e9 50% 50% repeat-x;font-weight:400;color:#555}
568
+ .ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}
569
+ .ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:0 solid #999;background:#dadada 50% 50% repeat-x;font-weight:400;color:#212121}
570
+ .ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}
571
+ .ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:0 solid #aaa;background:#fff 50% 50% repeat-x;font-weight:400;color:#212121}
572
+ .ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}
573
+ .ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:0 solid #89b17e;background:#fbf9ee 50% 50% repeat-x;color:#363636}
574
+ .ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}
575
+ .ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:0 solid #cd0a0a;background:#fef1ec 50% 50% repeat-x;color:#cd0a0a}
576
+ .ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}
577
+ .ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}
578
+ .ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:700}
579
+ .ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:400}
580
+ .ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}
581
+ .ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}
582
+ .ui-icon{width:16px;height:16px}
583
+ .ui-icon,.ui-widget-content .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
584
+ .ui-widget-header .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
585
+ .ui-state-default .ui-icon{background-image:url(../images/ui-icons_888888_256x240.png)}
586
+ .ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
587
+ .ui-state-active .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
588
+ .ui-state-highlight .ui-icon{background-image:url(../images/ui-icons_2e83ff_256x240.png)}
589
+ .ui-icon-circle-triangle-e{background-position:-48px -192px}
590
+ .ui-icon-circle-triangle-s{background-position:-64px -192px}
591
+ .ui-icon-circle-triangle-w{background-position:-80px -192px}
592
+ .ui-icon-circle-triangle-n{background-position:-96px -192px}
593
+ .ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:0}
594
+ .ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:0}
595
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:0}
596
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:0}
597
+ .ui-widget-overlay{background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}
598
+ .ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
599
+
600
+
601
+ .the-metabox.preview{
602
+ float: none;
603
+ }
604
+ .metaboxes-tab .the-metabox.no-label.preview{
605
+ margin-left: 184px;
606
+ }
607
+ .metaboxes-tab .the-metabox.no-label.preview img{
608
+ box-shadow: 0 1px 8px rgba(0,0,0,0.2);
609
+ }
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI CSS Framework 1.8.8
3
+ *
4
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Theming/API
9
+ */
10
+
11
+ /* Layout helpers
12
+ ----------------------------------*/
13
+ .ui-helper-hidden { display: none; }
14
+ .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
15
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
16
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
17
+ .ui-helper-clearfix { display: inline-block; }
18
+ /* required comment for clearfix to work in Opera \*/
19
+ * html .ui-helper-clearfix { height:1%; }
20
+ .ui-helper-clearfix { display:block; }
21
+ /* end clearfix */
22
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
23
+
24
+
25
+ /* Interaction Cues
26
+ ----------------------------------*/
27
+ .ui-state-disabled { cursor: default !important; }
28
+
29
+
30
+ /* Icons
31
+ ----------------------------------*/
32
+
33
+ /* states and images */
34
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
35
+
36
+
37
+ /* Misc visuals
38
+ ----------------------------------*/
39
+
40
+ /* Overlays */
41
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
42
+
43
+
44
+ /*
45
+ * jQuery UI CSS Framework 1.8.8
46
+ *
47
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
48
+ * Dual licensed under the MIT or GPL Version 2 licenses.
49
+ * http://jquery.org/license
50
+ *
51
+ * http://docs.jquery.com/UI/Theming/API
52
+ *
53
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Helvetica,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=dddddd&bgTextureHeader=02_glass.png&bgImgOpacityHeader=35&borderColorHeader=bbbbbb&fcHeader=444444&iconColorHeader=999999&bgColorContent=c9c9c9&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=50&borderColorContent=aaaaaa&fcContent=333333&iconColorContent=999999&bgColorDefault=eeeeee&bgTextureDefault=02_glass.png&bgImgOpacityDefault=60&borderColorDefault=cccccc&fcDefault=3383bb&iconColorDefault=70b2e1&bgColorHover=f8f8f8&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=bbbbbb&fcHover=599fcf&iconColorHover=3383bb&bgColorActive=999999&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=75&borderColorActive=999999&fcActive=ffffff&iconColorActive=454545&bgColorHighlight=eeeeee&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=ffffff&fcHighlight=444444&iconColorHighlight=3383bb&bgColorError=c0402a&bgTextureError=01_flat.png&bgImgOpacityError=55&borderColorError=c0402a&fcError=ffffff&iconColorError=fbc856&bgColorOverlay=eeeeee&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0pxdow=0px
54
+ */
55
+
56
+
57
+ /* Component containers
58
+ ----------------------------------*/
59
+ .ui-widget { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1.1em; }
60
+ .ui-widget .ui-widget { font-size: 1em; }
61
+ .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1em; }
62
+ .ui-widget-content { border: 1px solid #aaaaaa; background: #f1f1f1; color: #333333; }
63
+ .ui-widget-content a { color: #333333; }
64
+ .ui-widget-header { border: 1px solid #bbbbbb; background: #ccc; color: #444444; font-weight: bold; }
65
+ .ui-widget-header a { color: #444444; }
66
+
67
+ /* Interaction states
68
+ ----------------------------------*/
69
+ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_glass_60_eeeeee_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #3383bb; }
70
+ .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #3383bb; text-decoration: none; }
71
+ .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #bbbbbb; background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #599fcf; }
72
+ .ui-state-hover a, .ui-state-hover a:hover { color: #599fcf; text-decoration: none; }
73
+ .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #999999; background: #999999 url(images/ui-bg_inset-hard_75_999999_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; }
74
+ .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
75
+ .ui-widget :active { outline: none; }
76
+
77
+ /* Interaction Cues
78
+ ----------------------------------*/
79
+ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #ffffff; background: #eeeeee url(images/ui-bg_flat_55_eeeeee_40x100.png) 50% 50% repeat-x; color: #444444; }
80
+ .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; }
81
+ .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #c0402a; background: #c0402a url(images/ui-bg_flat_55_c0402a_40x100.png) 50% 50% repeat-x; color: #ffffff; }
82
+ .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
83
+ .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
84
+ .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
85
+ .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
86
+ .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
87
+ .ui-sortable-placeholder { border: 1px dotted black; visibility: visible !important; }
88
+ .ui-sortable-placeholder * { visibility: hidden; }
89
+
90
+ /* Icons
91
+ ----------------------------------*/
92
+
93
+ /* states and images */
94
+ /*.ui-widget-content .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); }
95
+ .ui-widget-header .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); } */
96
+ .ui-state-default .ui-icon { background-image: url(images/ui-icons_70b2e1_256x240.png); }
97
+ /*.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
98
+ .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
99
+ .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
100
+ .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fbc856_256x240.png); } */
101
+
102
+ /* positioning */
103
+ /*.ui-icon-carat-1-n { background-position: 0 0; }
104
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
105
+ .ui-icon-carat-1-e { background-position: -32px 0; }
106
+ .ui-icon-carat-1-se { background-position: -48px 0; }
107
+ .ui-icon-carat-1-s { background-position: -64px 0; }
108
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
109
+ .ui-icon-carat-1-w { background-position: -96px 0; }
110
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
111
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
112
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
113
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
114
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
115
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
116
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
117
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
118
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
119
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
120
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
121
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
122
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
123
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
124
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
125
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
126
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
127
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
128
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
129
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
130
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
131
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
132
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
133
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
134
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
135
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
136
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
137
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
138
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
139
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
140
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
141
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
142
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
143
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
144
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
145
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
146
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
147
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
148
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
149
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
150
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
151
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
152
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
153
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
154
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
155
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
156
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
157
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
158
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
159
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
160
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
161
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
162
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
163
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
164
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
165
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
166
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
167
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
168
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
169
+ .ui-icon-extlink { background-position: -32px -80px; }
170
+ .ui-icon-newwin { background-position: -48px -80px; }
171
+ .ui-icon-refresh { background-position: -64px -80px; }
172
+ .ui-icon-shuffle { background-position: -80px -80px; }
173
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
174
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
175
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
176
+ .ui-icon-folder-open { background-position: -16px -96px; }
177
+ .ui-icon-document { background-position: -32px -96px; }
178
+ .ui-icon-document-b { background-position: -48px -96px; }
179
+ .ui-icon-note { background-position: -64px -96px; }
180
+ .ui-icon-mail-closed { background-position: -80px -96px; }
181
+ .ui-icon-mail-open { background-position: -96px -96px; }
182
+ .ui-icon-suitcase { background-position: -112px -96px; }
183
+ .ui-icon-comment { background-position: -128px -96px; }
184
+ .ui-icon-person { background-position: -144px -96px; }
185
+ .ui-icon-print { background-position: -160px -96px; }
186
+ .ui-icon-trash { background-position: -176px -96px; }
187
+ .ui-icon-locked { background-position: -192px -96px; }
188
+ .ui-icon-unlocked { background-position: -208px -96px; }
189
+ .ui-icon-bookmark { background-position: -224px -96px; }
190
+ .ui-icon-tag { background-position: -240px -96px; }
191
+ .ui-icon-home { background-position: 0 -112px; }
192
+ .ui-icon-flag { background-position: -16px -112px; }
193
+ .ui-icon-calendar { background-position: -32px -112px; }
194
+ .ui-icon-cart { background-position: -48px -112px; }
195
+ .ui-icon-pencil { background-position: -64px -112px; }
196
+ .ui-icon-clock { background-position: -80px -112px; }
197
+ .ui-icon-disk { background-position: -96px -112px; }
198
+ .ui-icon-calculator { background-position: -112px -112px; }
199
+ .ui-icon-zoomin { background-position: -128px -112px; }
200
+ .ui-icon-zoomout { background-position: -144px -112px; }
201
+ .ui-icon-search { background-position: -160px -112px; }
202
+ .ui-icon-wrench { background-position: -176px -112px; }
203
+ .ui-icon-gear { background-position: -192px -112px; }
204
+ .ui-icon-heart { background-position: -208px -112px; }
205
+ .ui-icon-star { background-position: -224px -112px; }
206
+ .ui-icon-link { background-position: -240px -112px; }
207
+ .ui-icon-cancel { background-position: 0 -128px; } */
208
+ .ui-icon-plus { background-position: -16px -128px; }
209
+ .ui-icon-minus { background-position: -48px -128px; }
210
+ .ui-icon-minusthick { background-position: -64px -128px; }
211
+ /*.ui-icon-plusthick { background-position: -32px -128px; }
212
+ .ui-icon-close { background-position: -80px -128px; }
213
+ .ui-icon-closethick { background-position: -96px -128px; }
214
+ .ui-icon-key { background-position: -112px -128px; }
215
+ .ui-icon-lightbulb { background-position: -128px -128px; }
216
+ .ui-icon-scissors { background-position: -144px -128px; }
217
+ .ui-icon-clipboard { background-position: -160px -128px; }
218
+ .ui-icon-copy { background-position: -176px -128px; }
219
+ .ui-icon-contact { background-position: -192px -128px; }
220
+ .ui-icon-image { background-position: -208px -128px; }
221
+ .ui-icon-video { background-position: -224px -128px; }
222
+ .ui-icon-script { background-position: -240px -128px; }
223
+ .ui-icon-alert { background-position: 0 -144px; }
224
+ .ui-icon-info { background-position: -16px -144px; }
225
+ .ui-icon-notice { background-position: -32px -144px; }
226
+ .ui-icon-help { background-position: -48px -144px; }
227
+ .ui-icon-check { background-position: -64px -144px; }
228
+ .ui-icon-bullet { background-position: -80px -144px; }
229
+ .ui-icon-radio-off { background-position: -96px -144px; }
230
+ .ui-icon-radio-on { background-position: -112px -144px; }
231
+ .ui-icon-pin-w { background-position: -128px -144px; }
232
+ .ui-icon-pin-s { background-position: -144px -144px; }
233
+ .ui-icon-play { background-position: 0 -160px; }
234
+ .ui-icon-pause { background-position: -16px -160px; }
235
+ .ui-icon-seek-next { background-position: -32px -160px; }
236
+ .ui-icon-seek-prev { background-position: -48px -160px; }
237
+ .ui-icon-seek-end { background-position: -64px -160px; }
238
+ .ui-icon-seek-start { background-position: -80px -160px; } */
239
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
240
+ /*.ui-icon-seek-first { background-position: -80px -160px; }
241
+ .ui-icon-stop { background-position: -96px -160px; }
242
+ .ui-icon-eject { background-position: -112px -160px; }
243
+ .ui-icon-volume-off { background-position: -128px -160px; }
244
+ .ui-icon-volume-on { background-position: -144px -160px; }
245
+ .ui-icon-power { background-position: 0 -176px; }
246
+ .ui-icon-signal-diag { background-position: -16px -176px; }
247
+ .ui-icon-signal { background-position: -32px -176px; }
248
+ .ui-icon-battery-0 { background-position: -48px -176px; }
249
+ .ui-icon-battery-1 { background-position: -64px -176px; }
250
+ .ui-icon-battery-2 { background-position: -80px -176px; }
251
+ .ui-icon-battery-3 { background-position: -96px -176px; }
252
+ .ui-icon-circle-plus { background-position: 0 -192px; }
253
+ .ui-icon-circle-minus { background-position: -16px -192px; }
254
+ .ui-icon-circle-close { background-position: -32px -192px; }
255
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
256
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
257
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
258
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
259
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
260
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
261
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
262
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
263
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
264
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
265
+ .ui-icon-circle-check { background-position: -208px -192px; }
266
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
267
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
268
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
269
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
270
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
271
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
272
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
273
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
274
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
275
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
276
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
277
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; } */
278
+
279
+
280
+ /* Misc visuals
281
+ ----------------------------------*/
282
+
283
+ /* Corner radius */
284
+ .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
285
+ .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
286
+ .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
287
+ .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
288
+ .ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
289
+ .ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
290
+ .ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
291
+ .ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
292
+ .ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
293
+
294
+ /* Overlays */
295
+ .ui-widget-overlay { background: #eeeeee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
296
+ .ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0pxdow=0px; -webkit-border-radius: 0pxdow=0px; border-radius: 0pxdow=0px; }/*
297
+ * jQuery UI Slider 1.8.8
298
+ *
299
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
300
+ * Dual licensed under the MIT or GPL Version 2 licenses.
301
+ * http://jquery.org/license
302
+ *
303
+ * http://docs.jquery.com/UI/Slider#theming
304
+ */
305
+ .ui-slider { position: relative; text-align: left; width:340px; float:left }
306
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
307
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
308
+ .ui-slider .minCaption { float: left }
309
+ .ui-slider .maxCaption { float: right }
310
+ .ui-slider .feedback { text-align:center; width:100%; display:block }
311
+
312
+ .ui-slider-horizontal { height: .8em; }
313
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
314
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
315
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
316
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
317
+
318
+ .ui-slider-vertical { width: .8em; height: 100px; }
319
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
320
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
321
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
322
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }
plugin-fw/assets/css/yit-plugin-panel.css ADDED
@@ -0,0 +1,648 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ /* onoff */
11
+ .rm_onoff input {
12
+ display: none;
13
+ }
14
+
15
+ .rm_onoff input + span {
16
+ cursor: pointer;
17
+ text-indent: -9999px;
18
+ display: block;
19
+ width: 85px;
20
+ height: 37px;
21
+ background: transparent url(../images/off.png);
22
+ }
23
+
24
+ .rm_onoff input:checked + span {
25
+ background: transparent url(../images/on.png);
26
+ }
27
+
28
+ .rm_onoff input.onoffchecked + span {
29
+ background: transparent url(../images/on.png);
30
+ }
31
+
32
+ /* slider */
33
+ /*numbers*/
34
+ .ui-slider .maxCaption, .ui-slider .minCaption {
35
+ margin-bottom: 5px;
36
+ }
37
+ .ui-slider .feedback {
38
+ background: url(../images/slider/tooltip.png) no-repeat center top;
39
+ position: absolute;
40
+ top: -25px;
41
+ width: 35px;
42
+ height: 43px;
43
+ text-align: center;
44
+ width: 100%;
45
+ display: block;
46
+ }
47
+ .ui-slider .feedback strong {
48
+ display: inline-block;
49
+ padding-top: 4px;
50
+ top: -30px;
51
+ }
52
+ /*handle*/
53
+ .yit-options .ui-slider-horizontal .ui-slider-handle,
54
+ .yit_options .ui-slider-horizontal .ui-slider-handle {
55
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
56
+ border: 0px !important;
57
+ top: -.35em !important;
58
+ width: 18px !important;
59
+ height: 19px !important;
60
+ }
61
+
62
+ /*bg on the left:grey*/
63
+ .yit-options .ui-slider.ui-widget-content,
64
+ .yit_options .ui-slider.ui-widget-content {
65
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
66
+ border-color: #c1c1c0 !important;
67
+ height: 10px !important;
68
+ }
69
+
70
+ .iris-slider-offset.ui-slider.ui-widget-content {
71
+ background: transparent!important;
72
+ height: auto!important;
73
+ }
74
+
75
+ /*bg on the right:orange*/
76
+ .ui-slider.ui-widget-content .ui-widget-header {
77
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
78
+ left: 2px !important;
79
+ -webkit-border-radius: 15px;
80
+ -moz-border-radius: 15px;
81
+ -khtml-border-radius: 15px;
82
+ border-radius: 15px;
83
+ }
84
+
85
+ .plugin-option tr{
86
+ border-bottom: 1px solid #ccc;
87
+ }
88
+ .plugin-option .yit_options,
89
+ .plugin-option .yit-options{
90
+ border-bottom: 0px;
91
+ }
92
+ .plugin-option .yit-options .option,
93
+ .plugin-option .yit_options .option {
94
+ width: 600px;
95
+ float: left;
96
+ }
97
+
98
+ .plugin-option .form-table td{
99
+ padding: 25px 10px;
100
+ }
101
+
102
+ .yit_options .select_wrapper,
103
+ .yit-options .select_wrapper {
104
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
105
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
106
+ border-radius: 4px 4px 4px 4px;
107
+ border-style: solid;
108
+ border-width: 1px;
109
+ color: #555555;
110
+ display: block;
111
+ float: left;
112
+ font-family: sans-serif;
113
+ font-size: 12px;
114
+ height: 26px;
115
+ margin-bottom: 9px !important;
116
+ margin-left: 0;
117
+ margin-right: 5px;
118
+ margin-top: 0;
119
+ width: 400px;
120
+ }
121
+ .chosen .select_wrapper {
122
+ background: none;
123
+ border: none;
124
+ }
125
+ .chosen .select_wrapper .chosen-container{
126
+ width: 338px!important;
127
+ }
128
+ .chosen .select_wrapper .chosen-container .search-field input{
129
+ height: 27px!important;
130
+ color: #333;
131
+ }
132
+ .chosen .select_wrapper .chosen-container .chosen-choices{
133
+ border: 1px solid #ddd;
134
+ box-shadow: none;
135
+ }
136
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
137
+ height: 15px!important;
138
+ min-width: 105px;
139
+ }
140
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
141
+ line-height: 15px;
142
+ height: 15px;
143
+ padding-top: 2px;
144
+ }
145
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
146
+ top: 5px;
147
+ }
148
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
149
+ width: 100%!important;
150
+ }
151
+
152
+ /* === Multiple Chosen Customizzation === */
153
+
154
+ .yith-choosen .chosen-choices {
155
+ line-height: 27px;
156
+ min-height: 27px;
157
+ border: 1px solid #ddd;
158
+ }
159
+
160
+ .yith-choosen .chosen-container-active .chosen-choices{
161
+ border: 1px solid #5b9dd9;
162
+ -webkit-box-shadow: 0 0 2px rgba(30,140,190,.8);
163
+ box-shadow: 0 0 2px rgba(30,140,190,.8);
164
+ }
165
+
166
+ .select_wrapper span {
167
+ height: 26px;
168
+ line-height: 26px;
169
+ padding-left: 6px;
170
+ position: absolute;
171
+ z-index: 2;
172
+ overflow: hidden;
173
+ }
174
+ .ie8 .yit_options select,
175
+ .ie8 .yit-options select {
176
+ height: 26px;
177
+ }
178
+ .yit_options select, .yit-options select, .the-metabox .select_wrapper select {
179
+ cursor: pointer;
180
+ height: 28px;
181
+ margin: 0;
182
+ opacity: 0;
183
+ padding: 0;
184
+ position: relative;
185
+ width: inherit;
186
+ z-index: 4;
187
+ background-color: #FAFAFA;
188
+ }
189
+
190
+ /* === Single Chosen Customizzation === */
191
+
192
+ .yith-choosen .chosen-container-single .chosen-default {
193
+ background: transparent;
194
+ border-color: #ddd;
195
+ }
196
+
197
+ .yith-choosen .chosen-search > input[type=text]{
198
+ width: 100% !important;
199
+ }
200
+
201
+ .yith-choosen .chosen-container-single .chosen-single {
202
+ background: transparent;
203
+ border-color: #ddd;
204
+ }
205
+
206
+
207
+ /* Style to woocommerce panel*/
208
+
209
+ #plugin-fw-wc{
210
+ padding-top: 20px;
211
+ }
212
+ #plugin-fw-wc table.form-table{
213
+ background-color: #fff;
214
+ margin-bottom: 20px;
215
+ }
216
+ #plugin-fw-wc table.form-table th {
217
+ padding: 20px;
218
+ }
219
+ #plugin-fw-wc h3{
220
+ padding:0px 10px 10px ;
221
+ border-bottom: 1px solid #eee;
222
+ }
223
+
224
+ /* === VIDEO BOX === */
225
+
226
+ .yith-videobox-wrapper {
227
+ padding-top: 20px;
228
+ }
229
+ .yith-videobox-wrapper h3{
230
+ padding:0px 10px 10px ;
231
+ border-bottom: 1px solid #eee;
232
+ }
233
+
234
+ .yith-videobox-wrapper .postbox {
235
+ display: inline-block;
236
+ }
237
+ .yith-videobox-wrapper .yith_videobox .column {
238
+ width: 45%;
239
+ float: left;
240
+ padding-right: 2.5%;
241
+ border-right: 1px solid #ebebeb;
242
+ padding-bottom: 2em;
243
+ }
244
+ .yith-videobox-wrapper .yith_videobox .column.two {
245
+ margin-right: 0;
246
+ padding-right: 0;
247
+ padding-left: 2.5%;
248
+ border: 0;
249
+ max-width: 49%;
250
+ }
251
+ .yith-videobox-wrapper .yith_videobox h2{
252
+ font-size: 16px;
253
+ margin-bottom: 20px;
254
+ }
255
+ .yith-videobox-wrapper .yith-video-link {
256
+ width: 100%;
257
+ max-width: 200px;
258
+ float: left;
259
+ margin: 0 1.5em 1.5em 0;
260
+ }
261
+ .yith-videobox-wrapper .yith-video-link {
262
+ width: 100%;
263
+ max-width: 200px;
264
+ float: left;
265
+ margin: 0 1.5em 1.5em 0;
266
+ }
267
+ .yith-videobox-wrapper .yith-image-frame img {
268
+ max-width: 100%;
269
+ height: auto;
270
+ }
271
+ .yith-videobox-wrapper .yith-video-link img {
272
+ max-width: 100%;
273
+ height: auto;
274
+ }
275
+ .yith-videobox-wrapper .yith-video-iframe {
276
+ display: none;
277
+
278
+ }
279
+
280
+ /* === Plugins Upgrader === */
281
+
282
+ .yit-plugin-changelog-wrapper {
283
+ display: none;
284
+ }
285
+
286
+ .yit-plugin-changelog-title {
287
+ text-transform: uppercase;
288
+ }
289
+
290
+ .yit-plugin-changelog {
291
+ background: #fcfcfc;
292
+ height: 97%;
293
+ z-index: 999;
294
+ overflow: auto;
295
+ }
296
+
297
+ /* === Plugins Licence Activation === */
298
+
299
+ .yit-container.plugin-licence-activation {
300
+ font-family: 'Raleway', sans-serif;
301
+ }
302
+
303
+ .yit-container.plugin-licence-activation .to-active-wrapper {
304
+ margin-bottom: 60px;
305
+ }
306
+
307
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form {
308
+ position: relative;
309
+ border-color: #e1e1e1;
310
+ border-style: solid;
311
+ border-width: 0;
312
+ }
313
+
314
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:first-child {
315
+ border-top-width: 1px;
316
+ }
317
+
318
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:last-child {
319
+ border-bottom-width: 1px;
320
+ }
321
+
322
+ .yit-container.plugin-licence-activation .to-active-wrapper table.to-active-table {
323
+ border-width: 0;
324
+ border-spacing: 0;
325
+ width: 100%;
326
+ }
327
+
328
+ .yit-container.plugin-licence-activation .message {
329
+ display: none;
330
+ line-height: normal;
331
+ background: #ffffff url(../images/licence-error.png) 15px center no-repeat;
332
+ padding-left: 65px;
333
+ padding-right: 15px;
334
+ width: 150px;
335
+ }
336
+
337
+ .yit-container.plugin-licence-activation .message-wrapper {
338
+ height: 75px;
339
+ display: none;
340
+ position: absolute;
341
+ top: 0;
342
+ right: -250px;
343
+ border: 1px solid #ff3838;
344
+ }
345
+
346
+ .yit-container.plugin-licence-activation .message-wrapper.visible {
347
+ display: table;
348
+ }
349
+
350
+ .yit-container.plugin-licence-activation .message {
351
+ display: table-cell;
352
+ vertical-align: middle;
353
+ }
354
+
355
+ .yit-container.plugin-licence-activation .arrow-left:after,
356
+ .yit-container.plugin-licence-activation .arrow-left:before {
357
+ content: "";
358
+ display: block;
359
+ width: 0;
360
+ height: 0;
361
+ position: absolute;
362
+ }
363
+
364
+ .yit-container.plugin-licence-activation .arrow-left:before {
365
+ border-top: 9px solid transparent;
366
+ border-bottom: 9px solid transparent;
367
+ border-right: 9px solid #ff3838;
368
+ top: 26px;
369
+ left: -9px;
370
+ }
371
+
372
+ .yit-container.plugin-licence-activation .arrow-left:after {
373
+ border-top: 8px solid transparent;
374
+ border-bottom: 8px solid transparent;
375
+ border-right: 8px solid #fff;
376
+ left: -8px;
377
+ top: 27px;
378
+ }
379
+
380
+ .yit-container.plugin-licence-activation h2,
381
+ .yit-container.plugin-licence-activation h3 {
382
+ text-transform: uppercase;
383
+ font-weight: 800;
384
+ margin-bottom: 30px;
385
+ }
386
+
387
+ .yit-container.plugin-licence-activation h2 {
388
+ color: #808a97;
389
+ font-size: 25px;
390
+ }
391
+ .yit-container.plugin-licence-activation h3 {
392
+ color: #313131;
393
+ font-size: 15px;
394
+ height: 20px;
395
+ }
396
+
397
+ .yit-container.plugin-licence-activation h3.to-active {
398
+ height: 20px;
399
+ position: relative;
400
+ vertical-align: top;
401
+ }
402
+
403
+ .yit-container.plugin-licence-activation .spinner.show{
404
+ display: inline-block;
405
+ vertical-align: middle;
406
+ float: none;
407
+ }
408
+
409
+ .yit-container.plugin-licence-activation h3.to-active > .spinner.show {
410
+ display: inline-block;
411
+ float: none;
412
+ top: -3px;
413
+ position: relative;
414
+ }
415
+
416
+ .yit-container.plugin-licence-activation .licence-check-section{
417
+ margin-bottom: 60px;
418
+ }
419
+
420
+ .yit-container.plugin-licence-activation span.licence-label {
421
+ font-weight: 500;
422
+ color: #606060;
423
+ margin-bottom: 30px;
424
+ }
425
+
426
+ .yit-container.plugin-licence-activation .button-licence {
427
+ border: 0;
428
+ font-size: 13px;
429
+ text-transform: uppercase;
430
+ background-color: #808a97;
431
+ color: #fff;
432
+ font-weight: 700;
433
+ border-radius: 3px;
434
+ cursor: pointer;
435
+ text-decoration: none;
436
+ padding: 5px 7px;
437
+ -webkit-transition: background-color 0.3s ease;
438
+ -moz-transition: background-color 0.3s ease;
439
+ -ms-transition: background-color 0.3s ease;
440
+ -o-transition: background-color 0.3s ease;
441
+ transition: background-color 0.3s ease;
442
+ }
443
+
444
+ .yit-container.plugin-licence-activation .button-licence:hover {
445
+ background-color: #4d5c6f;
446
+ }
447
+
448
+ .yit-container.plugin-licence-activation .button-licence.clicked {
449
+ cursor: not-allowed;
450
+ background-color: #e2e2e2 !important;
451
+ }
452
+
453
+ .yit-container.plugin-licence-activation .button-licence.licence-check {
454
+ font-weight: 400;
455
+ padding: 12px 19px;
456
+ }
457
+
458
+ .yit-container.plugin-licence-activation .button-licence.licence-renew {
459
+ text-decoration: none;
460
+ padding: 7px 12px;
461
+ font-size: 9px;
462
+ }
463
+
464
+ .yit-container.plugin-licence-activation .button-licence.licence-renew:focus {
465
+ box-shadow: none;
466
+ }
467
+
468
+ .yit-container.plugin-licence-activation table:not(.to-active-table) {
469
+ width: 100%;
470
+ border: 1px solid #dcdcdc;
471
+ border-spacing: 0;
472
+ border-radius: 5px;
473
+ border-collapse: separate;
474
+ overflow: hidden;
475
+ }
476
+
477
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
478
+ border-bottom: 1px solid #dcdcdc;
479
+ }
480
+
481
+ .yit-container.plugin-licence-activation table:not(.to-active-table) td,
482
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
483
+ border-right: 1px solid #dcdcdc;
484
+ }
485
+ .yit-container.plugin-licence-activation table td:last-child,
486
+ .yit-container.plugin-licence-activation table th:last-child {
487
+ border-right: 0;
488
+ }
489
+
490
+ .yit-container.plugin-licence-activation table thead tr {
491
+ background-color: #f6f4f4;
492
+ }
493
+
494
+ .yit-container.plugin-licence-activation table tbody tr {
495
+ background-color: #ffffff;
496
+ }
497
+
498
+ .yit-container.plugin-licence-activation table thead tr th {
499
+ font-size: 13px;
500
+ color: #313131;
501
+ text-transform: uppercase;
502
+ font-weight: bold;
503
+ }
504
+
505
+ .yit-container.plugin-licence-activation table thead tr,
506
+ .yit-container.plugin-licence-activation table tbody tr {
507
+ line-height: 60px;
508
+ }
509
+
510
+ .yit-container.plugin-licence-activation table tbody tr td{
511
+ text-align: center;
512
+ line-height: 20px;
513
+ padding: 10px 5px;
514
+ }
515
+
516
+ .yit-container.plugin-licence-activation .button-licence.licence-activation {
517
+ padding: 12px 18px;
518
+ }
519
+
520
+ .yit-container.plugin-licence-activation .to-active-table tr {
521
+ line-height: 75px;
522
+ }
523
+
524
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row {
525
+ background-color: transparent;
526
+ -webkit-transition: all 0.3s ease;
527
+ -moz-transition: all 0.3s ease;
528
+ -ms-transition: all 0.3s ease;
529
+ -o-transition: all 0.3s ease;
530
+ transition: all 0.3s ease;
531
+ }
532
+
533
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row.error {
534
+ background-color: #ffdcdc;
535
+ }
536
+
537
+ .yit-container.plugin-licence-activation .to-active-table td {
538
+ padding-right: 12px;
539
+ width: 33%;
540
+ }
541
+
542
+
543
+ .yit-container.plugin-licence-activation .to-active-table td.plugin-name {
544
+ color: #808a97;
545
+ font-size: 12px;
546
+ text-transform: uppercase;
547
+ font-weight: bold;
548
+ line-height: 20px;
549
+ width: 20%;
550
+ padding-left: 20px;
551
+ }
552
+
553
+ .yit-container.plugin-licence-activation .to-active-table td.activate-button {
554
+ width: 15%;
555
+ position: relative;
556
+ }
557
+
558
+ .yit-container.plugin-licence-activation input[type=text],
559
+ .yit-container.plugin-licence-activation input[type=email]{
560
+ -webkit-transition: all 0.3s ease;
561
+ -moz-transition: all 0.3s ease;
562
+ -ms-transition: all 0.3s ease;
563
+ -o-transition: all 0.3s ease;
564
+ transition: all 0.3s ease;
565
+
566
+ border: 1px solid #dcdcdc;
567
+ padding: 0 15px;
568
+ border-radius: 3px;
569
+ height: 41px;
570
+ width: 100%;
571
+ }
572
+
573
+ .yit-container.plugin-licence-activation input[type=text].require,
574
+ .yit-container.plugin-licence-activation input[type=email].require {
575
+ border: 1px solid #ff3838;
576
+ }
577
+
578
+ .yit-container.plugin-licence-activation input[type=text]:focus,
579
+ .yit-container.plugin-licence-activation input[type=email]:focus{
580
+ webkit-box-shadow: 0 0 1px rgba(30,140,190,.8);
581
+ box-shadow: 0 0 1px rgba(30,140,190,.8);
582
+ }
583
+
584
+ .yit-container.plugin-licence-activation input[type=text]{
585
+ text-transform: uppercase;
586
+ text-align: center;
587
+ }
588
+
589
+ .yit-container.plugin-licence-activation input[type=email] {
590
+ text-align: left;
591
+ }
592
+
593
+ .yit-container.plugin-licence-activation input[type=submit]:focus{
594
+ outline: 0;
595
+ }
596
+
597
+ /* === Woocommerce panel === */
598
+ #plugin-fw-wc .yit_options{
599
+ padding: 0;
600
+ border: 0;
601
+ }
602
+ #plugin-fw-wc .yit_options input.upload_button, .yit_options input.button{
603
+ background: none;
604
+ border: 1px solid #ccc;
605
+ }
606
+
607
+ /* === WP Pointers === */
608
+
609
+ #adminmenu li.menu-top.yit-pointer-selected-row,
610
+ #adminmenu li.menu-top.yit-pointer-selected-row:hover,
611
+ #adminmenu li.yit-pointer-selected-row a.menu-top {
612
+ background-color: #acc327;
613
+ color: #000;
614
+ }
615
+
616
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer{
617
+ color: #000;
618
+ }
619
+
620
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer:hover,
621
+ #adminmenu .wp-submenu a.yit-pointer-selected-row {
622
+ color: #fff;
623
+ }
624
+
625
+ #adminmenu .wp-submenu a.yit-pointer-selected-row:hover {
626
+ color: #45bbe6;
627
+ }
628
+
629
+ /* === Responsive === */
630
+
631
+ @media (max-width: 767px) {}
632
+
633
+ @media (max-width: 480px) {}
634
+
635
+ @media (min-width: 768px) and (max-width: 992px) {}
636
+
637
+ @media (min-width: 980px) and (max-width: 1199px) {}
638
+
639
+ @media (min-width: 1200px) {
640
+ .yit-container.plugin-licence-activation{
641
+ width: 900px;
642
+ }
643
+ }
644
+
645
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
646
+ only screen and (-o-min-device-pixel-ratio: 3/2),
647
+ only screen and (min--moz-device-pixel-ratio: 1.5),
648
+ only screen and (min-device-pixel-ratio: 1.5) {}
plugin-fw/assets/css/yit-upgrader.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* === Plugins Upgrader === */
2
+
3
+ .yit-plugin-changelog-wrapper {
4
+ display: none;
5
+ }
6
+
7
+ .yit-plugin-changelog-title {
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .yit-plugin-changelog {
12
+ background: #fcfcfc;
13
+ height: 97%;
14
+ }
plugin-fw/assets/images/chosen/chosen-sprite.png ADDED
Binary file
plugin-fw/assets/images/chosen/chosen-sprite@2x.png ADDED
Binary file
plugin-fw/assets/images/double-sidebar.png ADDED
Binary file
plugin-fw/assets/images/licence-error.png ADDED
Binary file
plugin-fw/assets/images/no-sidebar.png ADDED
Binary file
plugin-fw/assets/images/off.png ADDED
Binary file
plugin-fw/assets/images/on.png ADDED
Binary file
plugin-fw/assets/images/select.png ADDED
Binary file
plugin-fw/assets/images/sidebar-left.png ADDED
Binary file
plugin-fw/assets/images/sidebar-right.png ADDED
Binary file
plugin-fw/assets/images/sleep.png ADDED
Binary file
plugin-fw/assets/images/slider/grey.gif ADDED
Binary file
plugin-fw/assets/images/slider/handle.png ADDED
Binary file
plugin-fw/assets/images/slider/orange.gif ADDED
Binary file
plugin-fw/assets/images/slider/tooltip.png ADDED
Binary file
plugin-fw/assets/images/spinner.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_222222_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_888888_256x240.png ADDED
Binary file
plugin-fw/assets/images/x.png ADDED
Binary file
plugin-fw/assets/images/yithemes-icon.png ADDED
Binary file
plugin-fw/assets/js/chosen/ajax-chosen.jquery.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Generated by CoffeeScript 1.3.1
2
+
3
+ (function($) {
4
+ return $.fn.ajaxChosen = function(settings, callback) {
5
+ var chosenXhr, defaultOptions, options, select;
6
+ if (settings == null) {
7
+ settings = {};
8
+ }
9
+ if (callback == null) {
10
+ callback = function() {};
11
+ }
12
+ defaultOptions = {
13
+ minTermLength: 3,
14
+ afterTypeDelay: 500,
15
+ jsonTermKey: "term"
16
+ };
17
+ select = this;
18
+ chosenXhr = null;
19
+ options = $.extend({}, defaultOptions, settings);
20
+ this.chosen();
21
+ return this.each(function() {
22
+ return $(this).next('.chosen-container').find(".search-field > input, .chosen-search > input").bind('keyup', function() {
23
+ var field, msg, success, val;
24
+ val = $.trim($(this).attr('value'));
25
+ msg = val.length < options.minTermLength ? "Keep typing..." : "Looking for '" + val + "'";
26
+ select.next('.chosen-container').find('.no-results').text(msg);
27
+ if (val === $(this).data('prevVal')) {
28
+ return false;
29
+ }
30
+ $(this).data('prevVal', val);
31
+ if (this.timer) {
32
+ clearTimeout(this.timer);
33
+ }
34
+ if (val.length < options.minTermLength) {
35
+ return false;
36
+ }
37
+ field = $(this);
38
+ if (!(options.data != null)) {
39
+ options.data = {};
40
+ }
41
+ options.data[options.jsonTermKey] = val;
42
+ if (options.dataCallback != null) {
43
+ options.data = options.dataCallback(options.data);
44
+ }
45
+ success = options.success;
46
+ options.success = function(data) {
47
+ var items, selected_values;
48
+ if (!(data != null)) {
49
+ return;
50
+ }
51
+ selected_values = [];
52
+ select.find('option').each(function() {
53
+ if (!$(this).is(":selected")) {
54
+ return $(this).remove();
55
+ } else {
56
+ return selected_values.push($(this).val() + "-" + $(this).text());
57
+ }
58
+ });
59
+ items = callback(data);
60
+ $.each(items, function(value, text) {
61
+ if ($.inArray(value + "-" + text, selected_values) === -1) {
62
+ return $("<option />").attr('value', value).html(text).appendTo(select);
63
+ }
64
+ });
65
+ select.trigger("chosen:updated");
66
+ if (success != null) {
67
+ success(data);
68
+ }
69
+ field.attr('value', val);
70
+ return field.css('width', 'auto');
71
+ };
72
+ return this.timer = setTimeout(function() {
73
+ if (chosenXhr) {
74
+ chosenXhr.abort();
75
+ }
76
+ return chosenXhr = $.ajax(options);
77
+ }, options.afterTypeDelay);
78
+ });
79
+ });
80
+ };
81
+ })(jQuery);
plugin-fw/assets/js/chosen/ajax-chosen.jquery.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ // Generated by CoffeeScript 1.3.1
2
+ (function(e){return e.fn.ajaxChosen=function(t,n){var r,i,s,o;t==null&&(t={});n==null&&(n=function(){});i={minTermLength:3,afterTypeDelay:500,jsonTermKey:"term"};o=this;r=null;s=e.extend({},i,t);this.chosen();return this.each(function(){return e(this).next(".chosen-container").find(".search-field > input, .chosen-search > input").bind("keyup",function(){var t,i,u,a;a=e.trim(e(this).attr("value"));i=a.length<s.minTermLength?"Keep typing...":"Looking for '"+a+"'";o.next(".chosen-container").find(".no-results").text(i);if(a===e(this).data("prevVal"))return!1;e(this).data("prevVal",a);this.timer&&clearTimeout(this.timer);if(a.length<s.minTermLength)return!1;t=e(this);s.data==null&&(s.data={});s.data[s.jsonTermKey]=a;s.dataCallback!=null&&(s.data=s.dataCallback(s.data));u=s.success;s.success=function(r){var i,s;if(r==null)return;s=[];o.find("option").each(function(){return e(this).is(":selected")?s.push(e(this).val()+"-"+e(this).text()):e(this).remove()});i=n(r);e.each(i,function(t,n){if(e.inArray(t+"-"+n,s)===-1)return e("<option />").attr("value",t).html(n).appendTo(o)});o.trigger("chosen:updated");u!=null&&u(r);t.attr("value",a);return t.css("width","auto")};return this.timer=setTimeout(function(){r&&r.abort();return r=e.ajax(s)},s.afterTypeDelay)})})}})(jQuery);
plugin-fw/assets/js/chosen/chosen.jquery.js ADDED
@@ -0,0 +1,1211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ (function() {
14
+ var $, AbstractChosen, Chosen, SelectParser, _ref,
15
+ __hasProp = {}.hasOwnProperty,
16
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17
+
18
+ SelectParser = (function() {
19
+ function SelectParser() {
20
+ this.options_index = 0;
21
+ this.parsed = [];
22
+ }
23
+
24
+ SelectParser.prototype.add_node = function(child) {
25
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
+ return this.add_group(child);
27
+ } else {
28
+ return this.add_option(child);
29
+ }
30
+ };
31
+
32
+ SelectParser.prototype.add_group = function(group) {
33
+ var group_position, option, _i, _len, _ref, _results;
34
+ group_position = this.parsed.length;
35
+ this.parsed.push({
36
+ array_index: group_position,
37
+ group: true,
38
+ label: this.escapeExpression(group.label),
39
+ children: 0,
40
+ disabled: group.disabled
41
+ });
42
+ _ref = group.childNodes;
43
+ _results = [];
44
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
45
+ option = _ref[_i];
46
+ _results.push(this.add_option(option, group_position, group.disabled));
47
+ }
48
+ return _results;
49
+ };
50
+
51
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
52
+ if (option.nodeName.toUpperCase() === "OPTION") {
53
+ if (option.text !== "") {
54
+ if (group_position != null) {
55
+ this.parsed[group_position].children += 1;
56
+ }
57
+ this.parsed.push({
58
+ array_index: this.parsed.length,
59
+ options_index: this.options_index,
60
+ value: option.value,
61
+ text: option.text,
62
+ html: option.innerHTML,
63
+ selected: option.selected,
64
+ disabled: group_disabled === true ? group_disabled : option.disabled,
65
+ group_array_index: group_position,
66
+ classes: option.className,
67
+ style: option.style.cssText
68
+ });
69
+ } else {
70
+ this.parsed.push({
71
+ array_index: this.parsed.length,
72
+ options_index: this.options_index,
73
+ empty: true
74
+ });
75
+ }
76
+ return this.options_index += 1;
77
+ }
78
+ };
79
+
80
+ SelectParser.prototype.escapeExpression = function(text) {
81
+ var map, unsafe_chars;
82
+ if ((text == null) || text === false) {
83
+ return "";
84
+ }
85
+ if (!/[\&\<\>\"\'\`]/.test(text)) {
86
+ return text;
87
+ }
88
+ map = {
89
+ "<": "&lt;",
90
+ ">": "&gt;",
91
+ '"': "&quot;",
92
+ "'": "&#x27;",
93
+ "`": "&#x60;"
94
+ };
95
+ unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
96
+ return text.replace(unsafe_chars, function(chr) {
97
+ return map[chr] || "&amp;";
98
+ });
99
+ };
100
+
101
+ return SelectParser;
102
+
103
+ })();
104
+
105
+ SelectParser.select_to_array = function(select) {
106
+ var child, parser, _i, _len, _ref;
107
+ parser = new SelectParser();
108
+ _ref = select.childNodes;
109
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
110
+ child = _ref[_i];
111
+ parser.add_node(child);
112
+ }
113
+ return parser.parsed;
114
+ };
115
+
116
+ AbstractChosen = (function() {
117
+ function AbstractChosen(form_field, options) {
118
+ this.form_field = form_field;
119
+ this.options = options != null ? options : {};
120
+ if (!AbstractChosen.browser_is_supported()) {
121
+ return;
122
+ }
123
+ this.is_multiple = this.form_field.multiple;
124
+ this.set_default_text();
125
+ this.set_default_values();
126
+ this.setup();
127
+ this.set_up_html();
128
+ this.register_observers();
129
+ }
130
+
131
+ AbstractChosen.prototype.set_default_values = function() {
132
+ var _this = this;
133
+ this.click_test_action = function(evt) {
134
+ return _this.test_active_click(evt);
135
+ };
136
+ this.activate_action = function(evt) {
137
+ return _this.activate_field(evt);
138
+ };
139
+ this.active_field = false;
140
+ this.mouse_on_container = false;
141
+ this.results_showing = false;
142
+ this.result_highlighted = null;
143
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
144
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
145
+ this.disable_search = this.options.disable_search || false;
146
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
147
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
148
+ this.search_contains = this.options.search_contains || false;
149
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
150
+ this.max_selected_options = this.options.max_selected_options || Infinity;
151
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
152
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
153
+ return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
154
+ };
155
+
156
+ AbstractChosen.prototype.set_default_text = function() {
157
+ if (this.form_field.getAttribute("data-placeholder")) {
158
+ this.default_text = this.form_field.getAttribute("data-placeholder");
159
+ } else if (this.is_multiple) {
160
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
161
+ } else {
162
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
163
+ }
164
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
165
+ };
166
+
167
+ AbstractChosen.prototype.mouse_enter = function() {
168
+ return this.mouse_on_container = true;
169
+ };
170
+
171
+ AbstractChosen.prototype.mouse_leave = function() {
172
+ return this.mouse_on_container = false;
173
+ };
174
+
175
+ AbstractChosen.prototype.input_focus = function(evt) {
176
+ var _this = this;
177
+ if (this.is_multiple) {
178
+ if (!this.active_field) {
179
+ return setTimeout((function() {
180
+ return _this.container_mousedown();
181
+ }), 50);
182
+ }
183
+ } else {
184
+ if (!this.active_field) {
185
+ return this.activate_field();
186
+ }
187
+ }
188
+ };
189
+
190
+ AbstractChosen.prototype.input_blur = function(evt) {
191
+ var _this = this;
192
+ if (!this.mouse_on_container) {
193
+ this.active_field = false;
194
+ return setTimeout((function() {
195
+ return _this.blur_test();
196
+ }), 100);
197
+ }
198
+ };
199
+
200
+ AbstractChosen.prototype.results_option_build = function(options) {
201
+ var content, data, _i, _len, _ref;
202
+ content = '';
203
+ _ref = this.results_data;
204
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
205
+ data = _ref[_i];
206
+ if (data.group) {
207
+ content += this.result_add_group(data);
208
+ } else {
209
+ content += this.result_add_option(data);
210
+ }
211
+ if (options != null ? options.first : void 0) {
212
+ if (data.selected && this.is_multiple) {
213
+ this.choice_build(data);
214
+ } else if (data.selected && !this.is_multiple) {
215
+ this.single_set_selected_text(data.text);
216
+ }
217
+ }
218
+ }
219
+ return content;
220
+ };
221
+
222
+ AbstractChosen.prototype.result_add_option = function(option) {
223
+ var classes, option_el;
224
+ if (!option.search_match) {
225
+ return '';
226
+ }
227
+ if (!this.include_option_in_results(option)) {
228
+ return '';
229
+ }
230
+ classes = [];
231
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
232
+ classes.push("active-result");
233
+ }
234
+ if (option.disabled && !(option.selected && this.is_multiple)) {
235
+ classes.push("disabled-result");
236
+ }
237
+ if (option.selected) {
238
+ classes.push("result-selected");
239
+ }
240
+ if (option.group_array_index != null) {
241
+ classes.push("group-option");
242
+ }
243
+ if (option.classes !== "") {
244
+ classes.push(option.classes);
245
+ }
246
+ option_el = document.createElement("li");
247
+ option_el.className = classes.join(" ");
248
+ option_el.style.cssText = option.style;
249
+ option_el.setAttribute("data-option-array-index", option.array_index);
250
+ option_el.innerHTML = option.search_text;
251
+ return this.outerHTML(option_el);
252
+ };
253
+
254
+ AbstractChosen.prototype.result_add_group = function(group) {
255
+ var group_el;
256
+ if (!(group.search_match || group.group_match)) {
257
+ return '';
258
+ }
259
+ if (!(group.active_options > 0)) {
260
+ return '';
261
+ }
262
+ group_el = document.createElement("li");
263
+ group_el.className = "group-result";
264
+ group_el.innerHTML = group.search_text;
265
+ return this.outerHTML(group_el);
266
+ };
267
+
268
+ AbstractChosen.prototype.results_update_field = function() {
269
+ this.set_default_text();
270
+ if (!this.is_multiple) {
271
+ this.results_reset_cleanup();
272
+ }
273
+ this.result_clear_highlight();
274
+ this.results_build();
275
+ if (this.results_showing) {
276
+ return this.winnow_results();
277
+ }
278
+ };
279
+
280
+ AbstractChosen.prototype.reset_single_select_options = function() {
281
+ var result, _i, _len, _ref, _results;
282
+ _ref = this.results_data;
283
+ _results = [];
284
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285
+ result = _ref[_i];
286
+ if (result.selected) {
287
+ _results.push(result.selected = false);
288
+ } else {
289
+ _results.push(void 0);
290
+ }
291
+ }
292
+ return _results;
293
+ };
294
+
295
+ AbstractChosen.prototype.results_toggle = function() {
296
+ if (this.results_showing) {
297
+ return this.results_hide();
298
+ } else {
299
+ return this.results_show();
300
+ }
301
+ };
302
+
303
+ AbstractChosen.prototype.results_search = function(evt) {
304
+ if (this.results_showing) {
305
+ return this.winnow_results();
306
+ } else {
307
+ return this.results_show();
308
+ }
309
+ };
310
+
311
+ AbstractChosen.prototype.winnow_results = function() {
312
+ var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
313
+ this.no_results_clear();
314
+ results = 0;
315
+ searchText = this.get_search_text();
316
+ escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
317
+ regexAnchor = this.search_contains ? "" : "^";
318
+ regex = new RegExp(regexAnchor + escapedSearchText, 'i');
319
+ zregex = new RegExp(escapedSearchText, 'i');
320
+ _ref = this.results_data;
321
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
322
+ option = _ref[_i];
323
+ option.search_match = false;
324
+ results_group = null;
325
+ if (this.include_option_in_results(option)) {
326
+ if (option.group) {
327
+ option.group_match = false;
328
+ option.active_options = 0;
329
+ }
330
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
331
+ results_group = this.results_data[option.group_array_index];
332
+ if (results_group.active_options === 0 && results_group.search_match) {
333
+ results += 1;
334
+ }
335
+ results_group.active_options += 1;
336
+ }
337
+ if (!(option.group && !this.group_search)) {
338
+ option.search_text = option.group ? option.label : option.html;
339
+ option.search_match = this.search_string_match(option.search_text, regex);
340
+ if (option.search_match && !option.group) {
341
+ results += 1;
342
+ }
343
+ if (option.search_match) {
344
+ if (searchText.length) {
345
+ startpos = option.search_text.search(zregex);
346
+ text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
347
+ option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
348
+ }
349
+ if (results_group != null) {
350
+ results_group.group_match = true;
351
+ }
352
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
353
+ option.search_match = true;
354
+ }
355
+ }
356
+ }
357
+ }
358
+ this.result_clear_highlight();
359
+ if (results < 1 && searchText.length) {
360
+ this.update_results_content("");
361
+ return this.no_results(searchText);
362
+ } else {
363
+ this.update_results_content(this.results_option_build());
364
+ return this.winnow_results_set_highlight();
365
+ }
366
+ };
367
+
368
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
369
+ var part, parts, _i, _len;
370
+ if (regex.test(search_string)) {
371
+ return true;
372
+ } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
373
+ parts = search_string.replace(/\[|\]/g, "").split(" ");
374
+ if (parts.length) {
375
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
376
+ part = parts[_i];
377
+ if (regex.test(part)) {
378
+ return true;
379
+ }
380
+ }
381
+ }
382
+ }
383
+ };
384
+
385
+ AbstractChosen.prototype.choices_count = function() {
386
+ var option, _i, _len, _ref;
387
+ if (this.selected_option_count != null) {
388
+ return this.selected_option_count;
389
+ }
390
+ this.selected_option_count = 0;
391
+ _ref = this.form_field.options;
392
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
+ option = _ref[_i];
394
+ if (option.selected) {
395
+ this.selected_option_count += 1;
396
+ }
397
+ }
398
+ return this.selected_option_count;
399
+ };
400
+
401
+ AbstractChosen.prototype.choices_click = function(evt) {
402
+ evt.preventDefault();
403
+ if (!(this.results_showing || this.is_disabled)) {
404
+ return this.results_show();
405
+ }
406
+ };
407
+
408
+ AbstractChosen.prototype.keyup_checker = function(evt) {
409
+ var stroke, _ref;
410
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
411
+ this.search_field_scale();
412
+ switch (stroke) {
413
+ case 8:
414
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
415
+ return this.keydown_backstroke();
416
+ } else if (!this.pending_backstroke) {
417
+ this.result_clear_highlight();
418
+ return this.results_search();
419
+ }
420
+ break;
421
+ case 13:
422
+ evt.preventDefault();
423
+ if (this.results_showing) {
424
+ return this.result_select(evt);
425
+ }
426
+ break;
427
+ case 27:
428
+ if (this.results_showing) {
429
+ this.results_hide();
430
+ }
431
+ return true;
432
+ case 9:
433
+ case 38:
434
+ case 40:
435
+ case 16:
436
+ case 91:
437
+ case 17:
438
+ break;
439
+ default:
440
+ return this.results_search();
441
+ }
442
+ };
443
+
444
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
445
+ var _this = this;
446
+ return setTimeout((function() {
447
+ return _this.results_search();
448
+ }), 50);
449
+ };
450
+
451
+ AbstractChosen.prototype.container_width = function() {
452
+ if (this.options.width != null) {
453
+ return this.options.width;
454
+ } else {
455
+ return "" + this.form_field.offsetWidth + "px";
456
+ }
457
+ };
458
+
459
+ AbstractChosen.prototype.include_option_in_results = function(option) {
460
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
461
+ return false;
462
+ }
463
+ if (!this.display_disabled_options && option.disabled) {
464
+ return false;
465
+ }
466
+ if (option.empty) {
467
+ return false;
468
+ }
469
+ return true;
470
+ };
471
+
472
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
473
+ this.touch_started = true;
474
+ return this.search_results_mouseover(evt);
475
+ };
476
+
477
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
478
+ this.touch_started = false;
479
+ return this.search_results_mouseout(evt);
480
+ };
481
+
482
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
483
+ if (this.touch_started) {
484
+ return this.search_results_mouseup(evt);
485
+ }
486
+ };
487
+
488
+ AbstractChosen.prototype.outerHTML = function(element) {
489
+ var tmp;
490
+ if (element.outerHTML) {
491
+ return element.outerHTML;
492
+ }
493
+ tmp = document.createElement("div");
494
+ tmp.appendChild(element);
495
+ return tmp.innerHTML;
496
+ };
497
+
498
+ AbstractChosen.browser_is_supported = function() {
499
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
500
+ return document.documentMode >= 8;
501
+ }
502
+ if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
503
+ return false;
504
+ }
505
+ if (/Android/i.test(window.navigator.userAgent)) {
506
+ if (/Mobile/i.test(window.navigator.userAgent)) {
507
+ return false;
508
+ }
509
+ }
510
+ return true;
511
+ };
512
+
513
+ AbstractChosen.default_multiple_text = "Select Some Options";
514
+
515
+ AbstractChosen.default_single_text = "Select an Option";
516
+
517
+ AbstractChosen.default_no_result_text = "No results match";
518
+
519
+ return AbstractChosen;
520
+
521
+ })();
522
+
523
+ $ = jQuery;
524
+
525
+ $.fn.extend({
526
+ chosen: function(options) {
527
+ if (!AbstractChosen.browser_is_supported()) {
528
+ return this;
529
+ }
530
+ return this.each(function(input_field) {
531
+ var $this, chosen;
532
+ $this = $(this);
533
+ chosen = $this.data('chosen');
534
+ if (options === 'destroy' && chosen) {
535
+ chosen.destroy();
536
+ } else if (!chosen) {
537
+ $this.data('chosen', new Chosen(this, options));
538
+ }
539
+ });
540
+ }
541
+ });
542
+
543
+ Chosen = (function(_super) {
544
+ __extends(Chosen, _super);
545
+
546
+ function Chosen() {
547
+ _ref = Chosen.__super__.constructor.apply(this, arguments);
548
+ return _ref;
549
+ }
550
+
551
+ Chosen.prototype.setup = function() {
552
+ this.form_field_jq = $(this.form_field);
553
+ this.current_selectedIndex = this.form_field.selectedIndex;
554
+ return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
555
+ };
556
+
557
+ Chosen.prototype.set_up_html = function() {
558
+ var container_classes, container_props;
559
+ container_classes = ["chosen-container"];
560
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
561
+ if (this.inherit_select_classes && this.form_field.className) {
562
+ container_classes.push(this.form_field.className);
563
+ }
564
+ if (this.is_rtl) {
565
+ container_classes.push("chosen-rtl");
566
+ }
567
+ container_props = {
568
+ 'class': container_classes.join(' '),
569
+ 'style': "width: " + (this.container_width()) + ";",
570
+ 'title': this.form_field.title
571
+ };
572
+ if (this.form_field.id.length) {
573
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
574
+ }
575
+ this.container = $("<div />", container_props);
576
+ if (this.is_multiple) {
577
+ this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
578
+ } else {
579
+ this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
580
+ }
581
+ this.form_field_jq.hide().after(this.container);
582
+ this.dropdown = this.container.find('div.chosen-drop').first();
583
+ this.search_field = this.container.find('input').first();
584
+ this.search_results = this.container.find('ul.chosen-results').first();
585
+ this.search_field_scale();
586
+ this.search_no_results = this.container.find('li.no-results').first();
587
+ if (this.is_multiple) {
588
+ this.search_choices = this.container.find('ul.chosen-choices').first();
589
+ this.search_container = this.container.find('li.search-field').first();
590
+ } else {
591
+ this.search_container = this.container.find('div.chosen-search').first();
592
+ this.selected_item = this.container.find('.chosen-single').first();
593
+ }
594
+ this.results_build();
595
+ this.set_tab_index();
596
+ this.set_label_behavior();
597
+ return this.form_field_jq.trigger("chosen:ready", {
598
+ chosen: this
599
+ });
600
+ };
601
+
602
+ Chosen.prototype.register_observers = function() {
603
+ var _this = this;
604
+ this.container.bind('mousedown.chosen', function(evt) {
605
+ _this.container_mousedown(evt);
606
+ });
607
+ this.container.bind('mouseup.chosen', function(evt) {
608
+ _this.container_mouseup(evt);
609
+ });
610
+ this.container.bind('mouseenter.chosen', function(evt) {
611
+ _this.mouse_enter(evt);
612
+ });
613
+ this.container.bind('mouseleave.chosen', function(evt) {
614
+ _this.mouse_leave(evt);
615
+ });
616
+ this.search_results.bind('mouseup.chosen', function(evt) {
617
+ _this.search_results_mouseup(evt);
618
+ });
619
+ this.search_results.bind('mouseover.chosen', function(evt) {
620
+ _this.search_results_mouseover(evt);
621
+ });
622
+ this.search_results.bind('mouseout.chosen', function(evt) {
623
+ _this.search_results_mouseout(evt);
624
+ });
625
+ this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
626
+ _this.search_results_mousewheel(evt);
627
+ });
628
+ this.search_results.bind('touchstart.chosen', function(evt) {
629
+ _this.search_results_touchstart(evt);
630
+ });
631
+ this.search_results.bind('touchmove.chosen', function(evt) {
632
+ _this.search_results_touchmove(evt);
633
+ });
634
+ this.search_results.bind('touchend.chosen', function(evt) {
635
+ _this.search_results_touchend(evt);
636
+ });
637
+ this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
638
+ _this.results_update_field(evt);
639
+ });
640
+ this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
641
+ _this.activate_field(evt);
642
+ });
643
+ this.form_field_jq.bind("chosen:open.chosen", function(evt) {
644
+ _this.container_mousedown(evt);
645
+ });
646
+ this.form_field_jq.bind("chosen:close.chosen", function(evt) {
647
+ _this.input_blur(evt);
648
+ });
649
+ this.search_field.bind('blur.chosen', function(evt) {
650
+ _this.input_blur(evt);
651
+ });
652
+ this.search_field.bind('keyup.chosen', function(evt) {
653
+ _this.keyup_checker(evt);
654
+ });
655
+ this.search_field.bind('keydown.chosen', function(evt) {
656
+ _this.keydown_checker(evt);
657
+ });
658
+ this.search_field.bind('focus.chosen', function(evt) {
659
+ _this.input_focus(evt);
660
+ });
661
+ this.search_field.bind('cut.chosen', function(evt) {
662
+ _this.clipboard_event_checker(evt);
663
+ });
664
+ this.search_field.bind('paste.chosen', function(evt) {
665
+ _this.clipboard_event_checker(evt);
666
+ });
667
+ if (this.is_multiple) {
668
+ return this.search_choices.bind('click.chosen', function(evt) {
669
+ _this.choices_click(evt);
670
+ });
671
+ } else {
672
+ return this.container.bind('click.chosen', function(evt) {
673
+ evt.preventDefault();
674
+ });
675
+ }
676
+ };
677
+
678
+ Chosen.prototype.destroy = function() {
679
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
680
+ if (this.search_field[0].tabIndex) {
681
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
682
+ }
683
+ this.container.remove();
684
+ this.form_field_jq.removeData('chosen');
685
+ return this.form_field_jq.show();
686
+ };
687
+
688
+ Chosen.prototype.search_field_disabled = function() {
689
+ this.is_disabled = this.form_field_jq[0].disabled;
690
+ if (this.is_disabled) {
691
+ this.container.addClass('chosen-disabled');
692
+ this.search_field[0].disabled = true;
693
+ if (!this.is_multiple) {
694
+ this.selected_item.unbind("focus.chosen", this.activate_action);
695
+ }
696
+ return this.close_field();
697
+ } else {
698
+ this.container.removeClass('chosen-disabled');
699
+ this.search_field[0].disabled = false;
700
+ if (!this.is_multiple) {
701
+ return this.selected_item.bind("focus.chosen", this.activate_action);
702
+ }
703
+ }
704
+ };
705
+
706
+ Chosen.prototype.container_mousedown = function(evt) {
707
+ if (!this.is_disabled) {
708
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
709
+ evt.preventDefault();
710
+ }
711
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
712
+ if (!this.active_field) {
713
+ if (this.is_multiple) {
714
+ this.search_field.val("");
715
+ }
716
+ $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
717
+ this.results_show();
718
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
719
+ evt.preventDefault();
720
+ this.results_toggle();
721
+ }
722
+ return this.activate_field();
723
+ }
724
+ }
725
+ };
726
+
727
+ Chosen.prototype.container_mouseup = function(evt) {
728
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
729
+ return this.results_reset(evt);
730
+ }
731
+ };
732
+
733
+ Chosen.prototype.search_results_mousewheel = function(evt) {
734
+ var delta;
735
+ if (evt.originalEvent) {
736
+ delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
737
+ }
738
+ if (delta != null) {
739
+ evt.preventDefault();
740
+ if (evt.type === 'DOMMouseScroll') {
741
+ delta = delta * 40;
742
+ }
743
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
744
+ }
745
+ };
746
+
747
+ Chosen.prototype.blur_test = function(evt) {
748
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
749
+ return this.close_field();
750
+ }
751
+ };
752
+
753
+ Chosen.prototype.close_field = function() {
754
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
755
+ this.active_field = false;
756
+ this.results_hide();
757
+ this.container.removeClass("chosen-container-active");
758
+ this.clear_backstroke();
759
+ this.show_search_field_default();
760
+ return this.search_field_scale();
761
+ };
762
+
763
+ Chosen.prototype.activate_field = function() {
764
+ this.container.addClass("chosen-container-active");
765
+ this.active_field = true;
766
+ this.search_field.val(this.search_field.val());
767
+ return this.search_field.focus();
768
+ };
769
+
770
+ Chosen.prototype.test_active_click = function(evt) {
771
+ var active_container;
772
+ active_container = $(evt.target).closest('.chosen-container');
773
+ if (active_container.length && this.container[0] === active_container[0]) {
774
+ return this.active_field = true;
775
+ } else {
776
+ return this.close_field();
777
+ }
778
+ };
779
+
780
+ Chosen.prototype.results_build = function() {
781
+ this.parsing = true;
782
+ this.selected_option_count = null;
783
+ this.results_data = SelectParser.select_to_array(this.form_field);
784
+ if (this.is_multiple) {
785
+ this.search_choices.find("li.search-choice").remove();
786
+ } else if (!this.is_multiple) {
787
+ this.single_set_selected_text();
788
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
789
+ this.search_field[0].readOnly = true;
790
+ this.container.addClass("chosen-container-single-nosearch");
791
+ } else {
792
+ this.search_field[0].readOnly = false;
793
+ this.container.removeClass("chosen-container-single-nosearch");
794
+ }
795
+ }
796
+ this.update_results_content(this.results_option_build({
797
+ first: true
798
+ }));
799
+ this.search_field_disabled();
800
+ this.show_search_field_default();
801
+ this.search_field_scale();
802
+ return this.parsing = false;
803
+ };
804
+
805
+ Chosen.prototype.result_do_highlight = function(el) {
806
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
807
+ if (el.length) {
808
+ this.result_clear_highlight();
809
+ this.result_highlight = el;
810
+ this.result_highlight.addClass("highlighted");
811
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
812
+ visible_top = this.search_results.scrollTop();
813
+ visible_bottom = maxHeight + visible_top;
814
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
815
+ high_bottom = high_top + this.result_highlight.outerHeight();
816
+ if (high_bottom >= visible_bottom) {
817
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
818
+ } else if (high_top < visible_top) {
819
+ return this.search_results.scrollTop(high_top);
820
+ }
821
+ }
822
+ };
823
+
824
+ Chosen.prototype.result_clear_highlight = function() {
825
+ if (this.result_highlight) {
826
+ this.result_highlight.removeClass("highlighted");
827
+ }
828
+ return this.result_highlight = null;
829
+ };
830
+
831
+ Chosen.prototype.results_show = function() {
832
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
833
+ this.form_field_jq.trigger("chosen:maxselected", {
834
+ chosen: this
835
+ });
836
+ return false;
837
+ }
838
+ this.container.addClass("chosen-with-drop");
839
+ this.results_showing = true;
840
+ this.search_field.focus();
841
+ this.search_field.val(this.search_field.val());
842
+ this.winnow_results();
843
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
844
+ chosen: this
845
+ });
846
+ };
847
+
848
+ Chosen.prototype.update_results_content = function(content) {
849
+ return this.search_results.html(content);
850
+ };
851
+
852
+ Chosen.prototype.results_hide = function() {
853
+ if (this.results_showing) {
854
+ this.result_clear_highlight();
855
+ this.container.removeClass("chosen-with-drop");
856
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
857
+ chosen: this
858
+ });
859
+ }
860
+ return this.results_showing = false;
861
+ };
862
+
863
+ Chosen.prototype.set_tab_index = function(el) {
864
+ var ti;
865
+ if (this.form_field.tabIndex) {
866
+ ti = this.form_field.tabIndex;
867
+ this.form_field.tabIndex = -1;
868
+ return this.search_field[0].tabIndex = ti;
869
+ }
870
+ };
871
+
872
+ Chosen.prototype.set_label_behavior = function() {
873
+ var _this = this;
874
+ this.form_field_label = this.form_field_jq.parents("label");
875
+ if (!this.form_field_label.length && this.form_field.id.length) {
876
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
877
+ }
878
+ if (this.form_field_label.length > 0) {
879
+ return this.form_field_label.bind('click.chosen', function(evt) {
880
+ if (_this.is_multiple) {
881
+ return _this.container_mousedown(evt);
882
+ } else {
883
+ return _this.activate_field();
884
+ }
885
+ });
886
+ }
887
+ };
888
+
889
+ Chosen.prototype.show_search_field_default = function() {
890
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
891
+ this.search_field.val(this.default_text);
892
+ return this.search_field.addClass("default");
893
+ } else {
894
+ this.search_field.val("");
895
+ return this.search_field.removeClass("default");
896
+ }
897
+ };
898
+
899
+ Chosen.prototype.search_results_mouseup = function(evt) {
900
+ var target;
901
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
902
+ if (target.length) {
903
+ this.result_highlight = target;
904
+ this.result_select(evt);
905
+ return this.search_field.focus();
906
+ }
907
+ };
908
+
909
+ Chosen.prototype.search_results_mouseover = function(evt) {
910
+ var target;
911
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
912
+ if (target) {
913
+ return this.result_do_highlight(target);
914
+ }
915
+ };
916
+
917
+ Chosen.prototype.search_results_mouseout = function(evt) {
918
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
919
+ return this.result_clear_highlight();
920
+ }
921
+ };
922
+
923
+ Chosen.prototype.choice_build = function(item) {
924
+ var choice, close_link,
925
+ _this = this;
926
+ choice = $('<li />', {
927
+ "class": "search-choice"
928
+ }).html("<span>" + item.html + "</span>");
929
+ if (item.disabled) {
930
+ choice.addClass('search-choice-disabled');
931
+ } else {
932
+ close_link = $('<a />', {
933
+ "class": 'search-choice-close',
934
+ 'data-option-array-index': item.array_index
935
+ });
936
+ close_link.bind('click.chosen', function(evt) {
937
+ return _this.choice_destroy_link_click(evt);
938
+ });
939
+ choice.append(close_link);
940
+ }
941
+ return this.search_container.before(choice);
942
+ };
943
+
944
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
945
+ evt.preventDefault();
946
+ evt.stopPropagation();
947
+ if (!this.is_disabled) {
948
+ return this.choice_destroy($(evt.target));
949
+ }
950
+ };
951
+
952
+ Chosen.prototype.choice_destroy = function(link) {
953
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
954
+ this.show_search_field_default();
955
+ if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
956
+ this.results_hide();
957
+ }
958
+ link.parents('li').first().remove();
959
+ return this.search_field_scale();
960
+ }
961
+ };
962
+
963
+ Chosen.prototype.results_reset = function() {
964
+ this.reset_single_select_options();
965
+ this.form_field.options[0].selected = true;
966
+ this.single_set_selected_text();
967
+ this.show_search_field_default();
968
+ this.results_reset_cleanup();
969
+ this.form_field_jq.trigger("change");
970
+ if (this.active_field) {
971
+ return this.results_hide();
972
+ }
973
+ };
974
+
975
+ Chosen.prototype.results_reset_cleanup = function() {
976
+ this.current_selectedIndex = this.form_field.selectedIndex;
977
+ return this.selected_item.find("abbr").remove();
978
+ };
979
+
980
+ Chosen.prototype.result_select = function(evt) {
981
+ var high, item;
982
+ if (this.result_highlight) {
983
+ high = this.result_highlight;
984
+ this.result_clear_highlight();
985
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
986
+ this.form_field_jq.trigger("chosen:maxselected", {
987
+ chosen: this
988
+ });
989
+ return false;
990
+ }
991
+ if (this.is_multiple) {
992
+ high.removeClass("active-result");
993
+ } else {
994
+ this.reset_single_select_options();
995
+ }
996
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
997
+ item.selected = true;
998
+ this.form_field.options[item.options_index].selected = true;
999
+ this.selected_option_count = null;
1000
+ if (this.is_multiple) {
1001
+ this.choice_build(item);
1002
+ } else {
1003
+ this.single_set_selected_text(item.text);
1004
+ }
1005
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1006
+ this.results_hide();
1007
+ }
1008
+ this.search_field.val("");
1009
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1010
+ this.form_field_jq.trigger("change", {
1011
+ 'selected': this.form_field.options[item.options_index].value
1012
+ });
1013
+ }
1014
+ this.current_selectedIndex = this.form_field.selectedIndex;
1015
+ return this.search_field_scale();
1016
+ }
1017
+ };
1018
+
1019
+ Chosen.prototype.single_set_selected_text = function(text) {
1020
+ if (text == null) {
1021
+ text = this.default_text;
1022
+ }
1023
+ if (text === this.default_text) {
1024
+ this.selected_item.addClass("chosen-default");
1025
+ } else {
1026
+ this.single_deselect_control_build();
1027
+ this.selected_item.removeClass("chosen-default");
1028
+ }
1029
+ return this.selected_item.find("span").text(text);
1030
+ };
1031
+
1032
+ Chosen.prototype.result_deselect = function(pos) {
1033
+ var result_data;
1034
+ result_data = this.results_data[pos];
1035
+ if (!this.form_field.options[result_data.options_index].disabled) {
1036
+ result_data.selected = false;
1037
+ this.form_field.options[result_data.options_index].selected = false;
1038
+ this.selected_option_count = null;
1039
+ this.result_clear_highlight();
1040
+ if (this.results_showing) {
1041
+ this.winnow_results();
1042
+ }
1043
+ this.form_field_jq.trigger("change", {
1044
+ deselected: this.form_field.options[result_data.options_index].value
1045
+ });
1046
+ this.search_field_scale();
1047
+ return true;
1048
+ } else {
1049
+ return false;
1050
+ }
1051
+ };
1052
+
1053
+ Chosen.prototype.single_deselect_control_build = function() {
1054
+ if (!this.allow_single_deselect) {
1055
+ return;
1056
+ }
1057
+ if (!this.selected_item.find("abbr").length) {
1058
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1059
+ }
1060
+ return this.selected_item.addClass("chosen-single-with-deselect");
1061
+ };
1062
+
1063
+ Chosen.prototype.get_search_text = function() {
1064
+ if (this.search_field.val() === this.default_text) {
1065
+ return "";
1066
+ } else {
1067
+ return $('<div/>').text($.trim(this.search_field.val())).html();
1068
+ }
1069
+ };
1070
+
1071
+ Chosen.prototype.winnow_results_set_highlight = function() {
1072
+ var do_high, selected_results;
1073
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1074
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1075
+ if (do_high != null) {
1076
+ return this.result_do_highlight(do_high);
1077
+ }
1078
+ };
1079
+
1080
+ Chosen.prototype.no_results = function(terms) {
1081
+ var no_results_html;
1082
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1083
+ no_results_html.find("span").first().html(terms);
1084
+ this.search_results.append(no_results_html);
1085
+ return this.form_field_jq.trigger("chosen:no_results", {
1086
+ chosen: this
1087
+ });
1088
+ };
1089
+
1090
+ Chosen.prototype.no_results_clear = function() {
1091
+ return this.search_results.find(".no-results").remove();
1092
+ };
1093
+
1094
+ Chosen.prototype.keydown_arrow = function() {
1095
+ var next_sib;
1096
+ if (this.results_showing && this.result_highlight) {
1097
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
1098
+ if (next_sib) {
1099
+ return this.result_do_highlight(next_sib);
1100
+ }
1101
+ } else {
1102
+ return this.results_show();
1103
+ }
1104
+ };
1105
+
1106
+ Chosen.prototype.keyup_arrow = function() {
1107
+ var prev_sibs;
1108
+ if (!this.results_showing && !this.is_multiple) {
1109
+ return this.results_show();
1110
+ } else if (this.result_highlight) {
1111
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
1112
+ if (prev_sibs.length) {
1113
+ return this.result_do_highlight(prev_sibs.first());
1114
+ } else {
1115
+ if (this.choices_count() > 0) {
1116
+ this.results_hide();
1117
+ }
1118
+ return this.result_clear_highlight();
1119
+ }
1120
+ }
1121
+ };
1122
+
1123
+ Chosen.prototype.keydown_backstroke = function() {
1124
+ var next_available_destroy;
1125
+ if (this.pending_backstroke) {
1126
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1127
+ return this.clear_backstroke();
1128
+ } else {
1129
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1130
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1131
+ this.pending_backstroke = next_available_destroy;
1132
+ if (this.single_backstroke_delete) {
1133
+ return this.keydown_backstroke();
1134
+ } else {
1135
+ return this.pending_backstroke.addClass("search-choice-focus");
1136
+ }
1137
+ }
1138
+ }
1139
+ };
1140
+
1141
+ Chosen.prototype.clear_backstroke = function() {
1142
+ if (this.pending_backstroke) {
1143
+ this.pending_backstroke.removeClass("search-choice-focus");
1144
+ }
1145
+ return this.pending_backstroke = null;
1146
+ };
1147
+
1148
+ Chosen.prototype.keydown_checker = function(evt) {
1149
+ var stroke, _ref1;
1150
+ stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
+ this.search_field_scale();
1152
+ if (stroke !== 8 && this.pending_backstroke) {
1153
+ this.clear_backstroke();
1154
+ }
1155
+ switch (stroke) {
1156
+ case 8:
1157
+ this.backstroke_length = this.search_field.val().length;
1158
+ break;
1159
+ case 9:
1160
+ if (this.results_showing && !this.is_multiple) {
1161
+ this.result_select(evt);
1162
+ }
1163
+ this.mouse_on_container = false;
1164
+ break;
1165
+ case 13:
1166
+ evt.preventDefault();
1167
+ break;
1168
+ case 38:
1169
+ evt.preventDefault();
1170
+ this.keyup_arrow();
1171
+ break;
1172
+ case 40:
1173
+ evt.preventDefault();
1174
+ this.keydown_arrow();
1175
+ break;
1176
+ }
1177
+ };
1178
+
1179
+ Chosen.prototype.search_field_scale = function() {
1180
+ var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
+ if (this.is_multiple) {
1182
+ h = 0;
1183
+ w = 0;
1184
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1185
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1186
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
1187
+ style = styles[_i];
1188
+ style_block += style + ":" + this.search_field.css(style) + ";";
1189
+ }
1190
+ div = $('<div />', {
1191
+ 'style': style_block
1192
+ });
1193
+ div.text(this.search_field.val());
1194
+ $('body').append(div);
1195
+ w = div.width() + 25;
1196
+ div.remove();
1197
+ f_width = this.container.outerWidth();
1198
+ if (w > f_width - 10) {
1199
+ w = f_width - 10;
1200
+ }
1201
+ return this.search_field.css({
1202
+ 'width': w + 'px'
1203
+ });
1204
+ }
1205
+ };
1206
+
1207
+ return Chosen;
1208
+
1209
+ })(AbstractChosen);
1210
+
1211
+ }).call(this);
plugin-fw/assets/js/codemirror/codemirror.js ADDED
@@ -0,0 +1,5799 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror version 3.15
2
+ //
3
+ // CodeMirror is the only global var we claim
4
+ window.CodeMirror = (function() {
5
+ "use strict";
6
+
7
+ // BROWSER SNIFFING
8
+
9
+ // Crude, but necessary to handle a number of hard-to-feature-detect
10
+ // bugs and behavior differences.
11
+ var gecko = /gecko\/\d/i.test(navigator.userAgent);
12
+ var ie = /MSIE \d/.test(navigator.userAgent);
13
+ var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
14
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
15
+ var webkit = /WebKit\//.test(navigator.userAgent);
16
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
17
+ var chrome = /Chrome\//.test(navigator.userAgent);
18
+ var opera = /Opera\//.test(navigator.userAgent);
19
+ var safari = /Apple Computer/.test(navigator.vendor);
20
+ var khtml = /KHTML\//.test(navigator.userAgent);
21
+ var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
22
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
23
+ var phantom = /PhantomJS/.test(navigator.userAgent);
24
+
25
+ var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
26
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
27
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
28
+ var mac = ios || /Mac/.test(navigator.platform);
29
+ var windows = /windows/i.test(navigator.platform);
30
+
31
+ var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32
+ if (opera_version) opera_version = Number(opera_version[1]);
33
+ if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
34
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
35
+ var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
36
+ var captureMiddleClick = gecko || (ie && !ie_lt9);
37
+
38
+ // Optimize some code when these features are not used
39
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
40
+
41
+ // CONSTRUCTOR
42
+
43
+ function CodeMirror(place, options) {
44
+ if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
45
+
46
+ this.options = options = options || {};
47
+ // Determine effective options based on given values and defaults.
48
+ for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
49
+ options[opt] = defaults[opt];
50
+ setGuttersForLineNumbers(options);
51
+
52
+ var docStart = typeof options.value == "string" ? 0 : options.value.first;
53
+ var display = this.display = makeDisplay(place, docStart);
54
+ display.wrapper.CodeMirror = this;
55
+ updateGutters(this);
56
+ if (options.autofocus && !mobile) focusInput(this);
57
+
58
+ this.state = {keyMaps: [],
59
+ overlays: [],
60
+ modeGen: 0,
61
+ overwrite: false, focused: false,
62
+ suppressEdits: false, pasteIncoming: false,
63
+ draggingText: false,
64
+ highlight: new Delayed()};
65
+
66
+ themeChanged(this);
67
+ if (options.lineWrapping)
68
+ this.display.wrapper.className += " CodeMirror-wrap";
69
+
70
+ var doc = options.value;
71
+ if (typeof doc == "string") doc = new Doc(options.value, options.mode);
72
+ operation(this, attachDoc)(this, doc);
73
+
74
+ // Override magic textarea content restore that IE sometimes does
75
+ // on our hidden textarea on reload
76
+ if (ie) setTimeout(bind(resetInput, this, true), 20);
77
+
78
+ registerEventHandlers(this);
79
+ // IE throws unspecified error in certain cases, when
80
+ // trying to access activeElement before onload
81
+ var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
82
+ if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
83
+ else onBlur(this);
84
+
85
+ operation(this, function() {
86
+ for (var opt in optionHandlers)
87
+ if (optionHandlers.propertyIsEnumerable(opt))
88
+ optionHandlers[opt](this, options[opt], Init);
89
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
90
+ })();
91
+ }
92
+
93
+ // DISPLAY CONSTRUCTOR
94
+
95
+ function makeDisplay(place, docStart) {
96
+ var d = {};
97
+
98
+ var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
99
+ if (webkit) input.style.width = "1000px";
100
+ else input.setAttribute("wrap", "off");
101
+ // if border: 0; -- iOS fails to open keyboard (issue #1287)
102
+ if (ios) input.style.border = "1px solid black";
103
+ input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
104
+
105
+ // Wraps and hides input textarea
106
+ d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
107
+ // The actual fake scrollbars.
108
+ d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
109
+ d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
110
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
111
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
112
+ // DIVs containing the selection and the actual code
113
+ d.lineDiv = elt("div", null, "CodeMirror-code");
114
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
115
+ // Blinky cursor, and element used to ensure cursor fits at the end of a line
116
+ d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
117
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
118
+ d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
119
+ // Used to measure text size
120
+ d.measure = elt("div", null, "CodeMirror-measure");
121
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
122
+ d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
123
+ null, "position: relative; outline: none");
124
+ // Moved around its parent to cover visible view
125
+ d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
126
+ // Set to the height of the text, causes scrolling
127
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
128
+ // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
129
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
130
+ // Will contain the gutters, if any
131
+ d.gutters = elt("div", null, "CodeMirror-gutters");
132
+ d.lineGutter = null;
133
+ // Provides scrolling
134
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
135
+ d.scroller.setAttribute("tabIndex", "-1");
136
+ // The element in which the editor lives.
137
+ d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
138
+ d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
139
+ // Work around IE7 z-index bug
140
+ if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
141
+ if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
142
+
143
+ // Needed to hide big blue blinking cursor on Mobile Safari
144
+ if (ios) input.style.width = "0px";
145
+ if (!webkit) d.scroller.draggable = true;
146
+ // Needed to handle Tab key in KHTML
147
+ if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
148
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
149
+ else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
150
+
151
+ // Current visible range (may be bigger than the view window).
152
+ d.viewOffset = d.lastSizeC = 0;
153
+ d.showingFrom = d.showingTo = docStart;
154
+
155
+ // Used to only resize the line number gutter when necessary (when
156
+ // the amount of lines crosses a boundary that makes its width change)
157
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
158
+ // See readInput and resetInput
159
+ d.prevInput = "";
160
+ // Set to true when a non-horizontal-scrolling widget is added. As
161
+ // an optimization, widget aligning is skipped when d is false.
162
+ d.alignWidgets = false;
163
+ // Flag that indicates whether we currently expect input to appear
164
+ // (after some event like 'keypress' or 'input') and are polling
165
+ // intensively.
166
+ d.pollingFast = false;
167
+ // Self-resetting timeout for the poller
168
+ d.poll = new Delayed();
169
+
170
+ d.cachedCharWidth = d.cachedTextHeight = null;
171
+ d.measureLineCache = [];
172
+ d.measureLineCachePos = 0;
173
+
174
+ // Tracks when resetInput has punted to just putting a short
175
+ // string instead of the (large) selection.
176
+ d.inaccurateSelection = false;
177
+
178
+ // Tracks the maximum line length so that the horizontal scrollbar
179
+ // can be kept static when scrolling.
180
+ d.maxLine = null;
181
+ d.maxLineLength = 0;
182
+ d.maxLineChanged = false;
183
+
184
+ // Used for measuring wheel scrolling granularity
185
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
186
+
187
+ return d;
188
+ }
189
+
190
+ // STATE UPDATES
191
+
192
+ // Used to get the editor into a consistent state again when options change.
193
+
194
+ function loadMode(cm) {
195
+ cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
196
+ cm.doc.iter(function(line) {
197
+ if (line.stateAfter) line.stateAfter = null;
198
+ if (line.styles) line.styles = null;
199
+ });
200
+ cm.doc.frontier = cm.doc.first;
201
+ startWorker(cm, 100);
202
+ cm.state.modeGen++;
203
+ if (cm.curOp) regChange(cm);
204
+ }
205
+
206
+ function wrappingChanged(cm) {
207
+ if (cm.options.lineWrapping) {
208
+ cm.display.wrapper.className += " CodeMirror-wrap";
209
+ cm.display.sizer.style.minWidth = "";
210
+ } else {
211
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
212
+ computeMaxLength(cm);
213
+ }
214
+ estimateLineHeights(cm);
215
+ regChange(cm);
216
+ clearCaches(cm);
217
+ setTimeout(function(){updateScrollbars(cm);}, 100);
218
+ }
219
+
220
+ function estimateHeight(cm) {
221
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
222
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
223
+ return function(line) {
224
+ if (lineIsHidden(cm.doc, line))
225
+ return 0;
226
+ else if (wrapping)
227
+ return (Math.ceil(line.text.length / perLine) || 1) * th;
228
+ else
229
+ return th;
230
+ };
231
+ }
232
+
233
+ function estimateLineHeights(cm) {
234
+ var doc = cm.doc, est = estimateHeight(cm);
235
+ doc.iter(function(line) {
236
+ var estHeight = est(line);
237
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
238
+ });
239
+ }
240
+
241
+ function keyMapChanged(cm) {
242
+ var map = keyMap[cm.options.keyMap], style = map.style;
243
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
244
+ (style ? " cm-keymap-" + style : "");
245
+ cm.state.disableInput = map.disableInput;
246
+ }
247
+
248
+ function themeChanged(cm) {
249
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
250
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
251
+ clearCaches(cm);
252
+ }
253
+
254
+ function guttersChanged(cm) {
255
+ updateGutters(cm);
256
+ regChange(cm);
257
+ setTimeout(function(){alignHorizontally(cm);}, 20);
258
+ }
259
+
260
+ function updateGutters(cm) {
261
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
262
+ removeChildren(gutters);
263
+ for (var i = 0; i < specs.length; ++i) {
264
+ var gutterClass = specs[i];
265
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
266
+ if (gutterClass == "CodeMirror-linenumbers") {
267
+ cm.display.lineGutter = gElt;
268
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
269
+ }
270
+ }
271
+ gutters.style.display = i ? "" : "none";
272
+ }
273
+
274
+ function lineLength(doc, line) {
275
+ if (line.height == 0) return 0;
276
+ var len = line.text.length, merged, cur = line;
277
+ while (merged = collapsedSpanAtStart(cur)) {
278
+ var found = merged.find();
279
+ cur = getLine(doc, found.from.line);
280
+ len += found.from.ch - found.to.ch;
281
+ }
282
+ cur = line;
283
+ while (merged = collapsedSpanAtEnd(cur)) {
284
+ var found = merged.find();
285
+ len -= cur.text.length - found.from.ch;
286
+ cur = getLine(doc, found.to.line);
287
+ len += cur.text.length - found.to.ch;
288
+ }
289
+ return len;
290
+ }
291
+
292
+ function computeMaxLength(cm) {
293
+ var d = cm.display, doc = cm.doc;
294
+ d.maxLine = getLine(doc, doc.first);
295
+ d.maxLineLength = lineLength(doc, d.maxLine);
296
+ d.maxLineChanged = true;
297
+ doc.iter(function(line) {
298
+ var len = lineLength(doc, line);
299
+ if (len > d.maxLineLength) {
300
+ d.maxLineLength = len;
301
+ d.maxLine = line;
302
+ }
303
+ });
304
+ }
305
+
306
+ // Make sure the gutters options contains the element
307
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
308
+ function setGuttersForLineNumbers(options) {
309
+ var found = false;
310
+ for (var i = 0; i < options.gutters.length; ++i) {
311
+ if (options.gutters[i] == "CodeMirror-linenumbers") {
312
+ if (options.lineNumbers) found = true;
313
+ else options.gutters.splice(i--, 1);
314
+ }
315
+ }
316
+ if (!found && options.lineNumbers)
317
+ options.gutters.push("CodeMirror-linenumbers");
318
+ }
319
+
320
+ // SCROLLBARS
321
+
322
+ // Re-synchronize the fake scrollbars with the actual size of the
323
+ // content. Optionally force a scrollTop.
324
+ function updateScrollbars(cm) {
325
+ var d = cm.display, docHeight = cm.doc.height;
326
+ var totalHeight = docHeight + paddingVert(d);
327
+ d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
328
+ d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
329
+ var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
330
+ var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
331
+ var needsV = scrollHeight > (d.scroller.clientHeight + 1);
332
+ if (needsV) {
333
+ d.scrollbarV.style.display = "block";
334
+ d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
335
+ d.scrollbarV.firstChild.style.height =
336
+ (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
337
+ } else d.scrollbarV.style.display = "";
338
+ if (needsH) {
339
+ d.scrollbarH.style.display = "block";
340
+ d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
341
+ d.scrollbarH.firstChild.style.width =
342
+ (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
343
+ } else d.scrollbarH.style.display = "";
344
+ if (needsH && needsV) {
345
+ d.scrollbarFiller.style.display = "block";
346
+ d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
347
+ } else d.scrollbarFiller.style.display = "";
348
+ if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
349
+ d.gutterFiller.style.display = "block";
350
+ d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
351
+ d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
352
+ } else d.gutterFiller.style.display = "";
353
+
354
+ if (mac_geLion && scrollbarWidth(d.measure) === 0)
355
+ d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
356
+ }
357
+
358
+ function visibleLines(display, doc, viewPort) {
359
+ var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
360
+ if (typeof viewPort == "number") top = viewPort;
361
+ else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
362
+ top = Math.floor(top - paddingTop(display));
363
+ var bottom = Math.ceil(top + height);
364
+ return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
365
+ }
366
+
367
+ // LINE NUMBERS
368
+
369
+ function alignHorizontally(cm) {
370
+ var display = cm.display;
371
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
372
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
373
+ var gutterW = display.gutters.offsetWidth, l = comp + "px";
374
+ for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
375
+ for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
376
+ }
377
+ if (cm.options.fixedGutter)
378
+ display.gutters.style.left = (comp + gutterW) + "px";
379
+ }
380
+
381
+ function maybeUpdateLineNumberWidth(cm) {
382
+ if (!cm.options.lineNumbers) return false;
383
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
384
+ if (last.length != display.lineNumChars) {
385
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
386
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
387
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
388
+ display.lineGutter.style.width = "";
389
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
390
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
391
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
392
+ display.lineGutter.style.width = display.lineNumWidth + "px";
393
+ return true;
394
+ }
395
+ return false;
396
+ }
397
+
398
+ function lineNumberFor(options, i) {
399
+ return String(options.lineNumberFormatter(i + options.firstLineNumber));
400
+ }
401
+ function compensateForHScroll(display) {
402
+ return getRect(display.scroller).left - getRect(display.sizer).left;
403
+ }
404
+
405
+ // DISPLAY DRAWING
406
+
407
+ function updateDisplay(cm, changes, viewPort, forced) {
408
+ var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
409
+ var visible = visibleLines(cm.display, cm.doc, viewPort);
410
+ for (;;) {
411
+ if (!updateDisplayInner(cm, changes, visible, forced)) break;
412
+ forced = false;
413
+ updated = true;
414
+ updateSelection(cm);
415
+ updateScrollbars(cm);
416
+
417
+ // Clip forced viewport to actual scrollable area
418
+ if (viewPort)
419
+ viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
420
+ typeof viewPort == "number" ? viewPort : viewPort.top);
421
+ visible = visibleLines(cm.display, cm.doc, viewPort);
422
+ if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
423
+ break;
424
+ changes = [];
425
+ }
426
+
427
+ if (updated) {
428
+ signalLater(cm, "update", cm);
429
+ if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
430
+ signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
431
+ }
432
+ return updated;
433
+ }
434
+
435
+ // Uses a set of changes plus the current scroll position to
436
+ // determine which DOM updates have to be made, and makes the
437
+ // updates.
438
+ function updateDisplayInner(cm, changes, visible, forced) {
439
+ var display = cm.display, doc = cm.doc;
440
+ if (!display.wrapper.clientWidth) {
441
+ display.showingFrom = display.showingTo = doc.first;
442
+ display.viewOffset = 0;
443
+ return;
444
+ }
445
+
446
+ // Bail out if the visible area is already rendered and nothing changed.
447
+ if (!forced && changes.length == 0 &&
448
+ visible.from > display.showingFrom && visible.to < display.showingTo)
449
+ return;
450
+
451
+ if (maybeUpdateLineNumberWidth(cm))
452
+ changes = [{from: doc.first, to: doc.first + doc.size}];
453
+ var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
454
+ display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
455
+
456
+ // Used to determine which lines need their line numbers updated
457
+ var positionsChangedFrom = Infinity;
458
+ if (cm.options.lineNumbers)
459
+ for (var i = 0; i < changes.length; ++i)
460
+ if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
461
+
462
+ var end = doc.first + doc.size;
463
+ var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
464
+ var to = Math.min(end, visible.to + cm.options.viewportMargin);
465
+ if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
466
+ if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
467
+ if (sawCollapsedSpans) {
468
+ from = lineNo(visualLine(doc, getLine(doc, from)));
469
+ while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
470
+ }
471
+
472
+ // Create a range of theoretically intact lines, and punch holes
473
+ // in that using the change info.
474
+ var intact = [{from: Math.max(display.showingFrom, doc.first),
475
+ to: Math.min(display.showingTo, end)}];
476
+ if (intact[0].from >= intact[0].to) intact = [];
477
+ else intact = computeIntact(intact, changes);
478
+ // When merged lines are present, we might have to reduce the
479
+ // intact ranges because changes in continued fragments of the
480
+ // intact lines do require the lines to be redrawn.
481
+ if (sawCollapsedSpans)
482
+ for (var i = 0; i < intact.length; ++i) {
483
+ var range = intact[i], merged;
484
+ while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
485
+ var newTo = merged.find().from.line;
486
+ if (newTo > range.from) range.to = newTo;
487
+ else { intact.splice(i--, 1); break; }
488
+ }
489
+ }
490
+
491
+ // Clip off the parts that won't be visible
492
+ var intactLines = 0;
493
+ for (var i = 0; i < intact.length; ++i) {
494
+ var range = intact[i];
495
+ if (range.from < from) range.from = from;
496
+ if (range.to > to) range.to = to;
497
+ if (range.from >= range.to) intact.splice(i--, 1);
498
+ else intactLines += range.to - range.from;
499
+ }
500
+ if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
501
+ updateViewOffset(cm);
502
+ return;
503
+ }
504
+ intact.sort(function(a, b) {return a.from - b.from;});
505
+
506
+ // Avoid crashing on IE's "unspecified error" when in iframes
507
+ try {
508
+ var focused = document.activeElement;
509
+ } catch(e) {}
510
+ if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
511
+ patchDisplay(cm, from, to, intact, positionsChangedFrom);
512
+ display.lineDiv.style.display = "";
513
+ if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
514
+
515
+ var different = from != display.showingFrom || to != display.showingTo ||
516
+ display.lastSizeC != display.wrapper.clientHeight;
517
+ // This is just a bogus formula that detects when the editor is
518
+ // resized or the font size changes.
519
+ if (different) {
520
+ display.lastSizeC = display.wrapper.clientHeight;
521
+ startWorker(cm, 400);
522
+ }
523
+ display.showingFrom = from; display.showingTo = to;
524
+
525
+ updateHeightsInViewport(cm);
526
+ updateViewOffset(cm);
527
+
528
+ return true;
529
+ }
530
+
531
+ function updateHeightsInViewport(cm) {
532
+ var display = cm.display;
533
+ var prevBottom = display.lineDiv.offsetTop;
534
+ for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
535
+ if (ie_lt8) {
536
+ var bot = node.offsetTop + node.offsetHeight;
537
+ height = bot - prevBottom;
538
+ prevBottom = bot;
539
+ } else {
540
+ var box = getRect(node);
541
+ height = box.bottom - box.top;
542
+ }
543
+ var diff = node.lineObj.height - height;
544
+ if (height < 2) height = textHeight(display);
545
+ if (diff > .001 || diff < -.001) {
546
+ updateLineHeight(node.lineObj, height);
547
+ var widgets = node.lineObj.widgets;
548
+ if (widgets) for (var i = 0; i < widgets.length; ++i)
549
+ widgets[i].height = widgets[i].node.offsetHeight;
550
+ }
551
+ }
552
+ }
553
+
554
+ function updateViewOffset(cm) {
555
+ var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
556
+ // Position the mover div to align with the current virtual scroll position
557
+ cm.display.mover.style.top = off + "px";
558
+ }
559
+
560
+ function computeIntact(intact, changes) {
561
+ for (var i = 0, l = changes.length || 0; i < l; ++i) {
562
+ var change = changes[i], intact2 = [], diff = change.diff || 0;
563
+ for (var j = 0, l2 = intact.length; j < l2; ++j) {
564
+ var range = intact[j];
565
+ if (change.to <= range.from && change.diff) {
566
+ intact2.push({from: range.from + diff, to: range.to + diff});
567
+ } else if (change.to <= range.from || change.from >= range.to) {
568
+ intact2.push(range);
569
+ } else {
570
+ if (change.from > range.from)
571
+ intact2.push({from: range.from, to: change.from});
572
+ if (change.to < range.to)
573
+ intact2.push({from: change.to + diff, to: range.to + diff});
574
+ }
575
+ }
576
+ intact = intact2;
577
+ }
578
+ return intact;
579
+ }
580
+
581
+ function getDimensions(cm) {
582
+ var d = cm.display, left = {}, width = {};
583
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
584
+ left[cm.options.gutters[i]] = n.offsetLeft;
585
+ width[cm.options.gutters[i]] = n.offsetWidth;
586
+ }
587
+ return {fixedPos: compensateForHScroll(d),
588
+ gutterTotalWidth: d.gutters.offsetWidth,
589
+ gutterLeft: left,
590
+ gutterWidth: width,
591
+ wrapperWidth: d.wrapper.clientWidth};
592
+ }
593
+
594
+ function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
595
+ var dims = getDimensions(cm);
596
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
597
+ if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
598
+ removeChildren(display.lineDiv);
599
+ var container = display.lineDiv, cur = container.firstChild;
600
+
601
+ function rm(node) {
602
+ var next = node.nextSibling;
603
+ if (webkit && mac && cm.display.currentWheelTarget == node) {
604
+ node.style.display = "none";
605
+ node.lineObj = null;
606
+ } else {
607
+ node.parentNode.removeChild(node);
608
+ }
609
+ return next;
610
+ }
611
+
612
+ var nextIntact = intact.shift(), lineN = from;
613
+ cm.doc.iter(from, to, function(line) {
614
+ if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
615
+ if (lineIsHidden(cm.doc, line)) {
616
+ if (line.height != 0) updateLineHeight(line, 0);
617
+ if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
618
+ var w = line.widgets[i];
619
+ if (w.showIfHidden) {
620
+ var prev = cur.previousSibling;
621
+ if (/pre/i.test(prev.nodeName)) {
622
+ var wrap = elt("div", null, null, "position: relative");
623
+ prev.parentNode.replaceChild(wrap, prev);
624
+ wrap.appendChild(prev);
625
+ prev = wrap;
626
+ }
627
+ var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
628
+ if (!w.handleMouseEvents) wnode.ignoreEvents = true;
629
+ positionLineWidget(w, wnode, prev, dims);
630
+ }
631
+ }
632
+ } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
633
+ // This line is intact. Skip to the actual node. Update its
634
+ // line number if needed.
635
+ while (cur.lineObj != line) cur = rm(cur);
636
+ if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
637
+ setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
638
+ cur = cur.nextSibling;
639
+ } else {
640
+ // For lines with widgets, make an attempt to find and reuse
641
+ // the existing element, so that widgets aren't needlessly
642
+ // removed and re-inserted into the dom
643
+ if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
644
+ if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
645
+ // This line needs to be generated.
646
+ var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
647
+ if (lineNode != reuse) {
648
+ container.insertBefore(lineNode, cur);
649
+ } else {
650
+ while (cur != reuse) cur = rm(cur);
651
+ cur = cur.nextSibling;
652
+ }
653
+
654
+ lineNode.lineObj = line;
655
+ }
656
+ ++lineN;
657
+ });
658
+ while (cur) cur = rm(cur);
659
+ }
660
+
661
+ function buildLineElement(cm, line, lineNo, dims, reuse) {
662
+ var lineElement = lineContent(cm, line);
663
+ var markers = line.gutterMarkers, display = cm.display, wrap;
664
+
665
+ if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
666
+ return lineElement;
667
+
668
+ // Lines with gutter elements, widgets or a background class need
669
+ // to be wrapped again, and have the extra elements added to the
670
+ // wrapper div
671
+
672
+ if (reuse) {
673
+ reuse.alignable = null;
674
+ var isOk = true, widgetsSeen = 0, insertBefore = null;
675
+ for (var n = reuse.firstChild, next; n; n = next) {
676
+ next = n.nextSibling;
677
+ if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
678
+ reuse.removeChild(n);
679
+ } else {
680
+ for (var i = 0; i < line.widgets.length; ++i) {
681
+ var widget = line.widgets[i];
682
+ if (widget.node == n.firstChild) {
683
+ if (!widget.above && !insertBefore) insertBefore = n;
684
+ positionLineWidget(widget, n, reuse, dims);
685
+ ++widgetsSeen;
686
+ break;
687
+ }
688
+ }
689
+ if (i == line.widgets.length) { isOk = false; break; }
690
+ }
691
+ }
692
+ reuse.insertBefore(lineElement, insertBefore);
693
+ if (isOk && widgetsSeen == line.widgets.length) {
694
+ wrap = reuse;
695
+ reuse.className = line.wrapClass || "";
696
+ }
697
+ }
698
+ if (!wrap) {
699
+ wrap = elt("div", null, line.wrapClass, "position: relative");
700
+ wrap.appendChild(lineElement);
701
+ }
702
+ // Kludge to make sure the styled element lies behind the selection (by z-index)
703
+ if (line.bgClass)
704
+ wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
705
+ if (cm.options.lineNumbers || markers) {
706
+ var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
707
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
708
+ wrap.firstChild);
709
+ if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
710
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
711
+ wrap.lineNumber = gutterWrap.appendChild(
712
+ elt("div", lineNumberFor(cm.options, lineNo),
713
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
714
+ "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
715
+ + display.lineNumInnerWidth + "px"));
716
+ if (markers)
717
+ for (var k = 0; k < cm.options.gutters.length; ++k) {
718
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
719
+ if (found)
720
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
721
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
722
+ }
723
+ }
724
+ if (ie_lt8) wrap.style.zIndex = 2;
725
+ if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
726
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
727
+ if (!widget.handleMouseEvents) node.ignoreEvents = true;
728
+ positionLineWidget(widget, node, wrap, dims);
729
+ if (widget.above)
730
+ wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
731
+ else
732
+ wrap.appendChild(node);
733
+ signalLater(widget, "redraw");
734
+ }
735
+ return wrap;
736
+ }
737
+
738
+ function positionLineWidget(widget, node, wrap, dims) {
739
+ if (widget.noHScroll) {
740
+ (wrap.alignable || (wrap.alignable = [])).push(node);
741
+ var width = dims.wrapperWidth;
742
+ node.style.left = dims.fixedPos + "px";
743
+ if (!widget.coverGutter) {
744
+ width -= dims.gutterTotalWidth;
745
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
746
+ }
747
+ node.style.width = width + "px";
748
+ }
749
+ if (widget.coverGutter) {
750
+ node.style.zIndex = 5;
751
+ node.style.position = "relative";
752
+ if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
753
+ }
754
+ }
755
+
756
+ // SELECTION / CURSOR
757
+
758
+ function updateSelection(cm) {
759
+ var display = cm.display;
760
+ var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
761
+ if (collapsed || cm.options.showCursorWhenSelecting)
762
+ updateSelectionCursor(cm);
763
+ else
764
+ display.cursor.style.display = display.otherCursor.style.display = "none";
765
+ if (!collapsed)
766
+ updateSelectionRange(cm);
767
+ else
768
+ display.selectionDiv.style.display = "none";
769
+
770
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
771
+ if (cm.options.moveInputWithCursor) {
772
+ var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
773
+ var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
774
+ display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
775
+ headPos.top + lineOff.top - wrapOff.top)) + "px";
776
+ display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
777
+ headPos.left + lineOff.left - wrapOff.left)) + "px";
778
+ }
779
+ }
780
+
781
+ // No selection, plain cursor
782
+ function updateSelectionCursor(cm) {
783
+ var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
784
+ display.cursor.style.left = pos.left + "px";
785
+ display.cursor.style.top = pos.top + "px";
786
+ display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
787
+ display.cursor.style.display = "";
788
+
789
+ if (pos.other) {
790
+ display.otherCursor.style.display = "";
791
+ display.otherCursor.style.left = pos.other.left + "px";
792
+ display.otherCursor.style.top = pos.other.top + "px";
793
+ display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
794
+ } else { display.otherCursor.style.display = "none"; }
795
+ }
796
+
797
+ // Highlight selection
798
+ function updateSelectionRange(cm) {
799
+ var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
800
+ var fragment = document.createDocumentFragment();
801
+ var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
802
+
803
+ function add(left, top, width, bottom) {
804
+ if (top < 0) top = 0;
805
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
806
+ "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
807
+ "px; height: " + (bottom - top) + "px"));
808
+ }
809
+
810
+ function drawForLine(line, fromArg, toArg) {
811
+ var lineObj = getLine(doc, line);
812
+ var lineLen = lineObj.text.length;
813
+ var start, end;
814
+ function coords(ch, bias) {
815
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
816
+ }
817
+
818
+ iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
819
+ var leftPos = coords(from, "left"), rightPos, left, right;
820
+ if (from == to) {
821
+ rightPos = leftPos;
822
+ left = right = leftPos.left;
823
+ } else {
824
+ rightPos = coords(to - 1, "right");
825
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
826
+ left = leftPos.left;
827
+ right = rightPos.right;
828
+ }
829
+ if (fromArg == null && from == 0) left = pl;
830
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
831
+ add(left, leftPos.top, null, leftPos.bottom);
832
+ left = pl;
833
+ if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
834
+ }
835
+ if (toArg == null && to == lineLen) right = clientWidth;
836
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
837
+ start = leftPos;
838
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
839
+ end = rightPos;
840
+ if (left < pl + 1) left = pl;
841
+ add(left, rightPos.top, right - left, rightPos.bottom);
842
+ });
843
+ return {start: start, end: end};
844
+ }
845
+
846
+ if (sel.from.line == sel.to.line) {
847
+ drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
848
+ } else {
849
+ var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
850
+ var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
851
+ var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
852
+ var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
853
+ if (singleVLine) {
854
+ if (leftEnd.top < rightStart.top - 2) {
855
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
856
+ add(pl, rightStart.top, rightStart.left, rightStart.bottom);
857
+ } else {
858
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
859
+ }
860
+ }
861
+ if (leftEnd.bottom < rightStart.top)
862
+ add(pl, leftEnd.bottom, null, rightStart.top);
863
+ }
864
+
865
+ removeChildrenAndAdd(display.selectionDiv, fragment);
866
+ display.selectionDiv.style.display = "";
867
+ }
868
+
869
+ // Cursor-blinking
870
+ function restartBlink(cm) {
871
+ if (!cm.state.focused) return;
872
+ var display = cm.display;
873
+ clearInterval(display.blinker);
874
+ var on = true;
875
+ display.cursor.style.visibility = display.otherCursor.style.visibility = "";
876
+ display.blinker = setInterval(function() {
877
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
878
+ }, cm.options.cursorBlinkRate);
879
+ }
880
+
881
+ // HIGHLIGHT WORKER
882
+
883
+ function startWorker(cm, time) {
884
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
885
+ cm.state.highlight.set(time, bind(highlightWorker, cm));
886
+ }
887
+
888
+ function highlightWorker(cm) {
889
+ var doc = cm.doc;
890
+ if (doc.frontier < doc.first) doc.frontier = doc.first;
891
+ if (doc.frontier >= cm.display.showingTo) return;
892
+ var end = +new Date + cm.options.workTime;
893
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
894
+ var changed = [], prevChange;
895
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
896
+ if (doc.frontier >= cm.display.showingFrom) { // Visible
897
+ var oldStyles = line.styles;
898
+ line.styles = highlightLine(cm, line, state);
899
+ var ischange = !oldStyles || oldStyles.length != line.styles.length;
900
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
901
+ if (ischange) {
902
+ if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
903
+ else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
904
+ }
905
+ line.stateAfter = copyState(doc.mode, state);
906
+ } else {
907
+ processLine(cm, line, state);
908
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
909
+ }
910
+ ++doc.frontier;
911
+ if (+new Date > end) {
912
+ startWorker(cm, cm.options.workDelay);
913
+ return true;
914
+ }
915
+ });
916
+ if (changed.length)
917
+ operation(cm, function() {
918
+ for (var i = 0; i < changed.length; ++i)
919
+ regChange(this, changed[i].start, changed[i].end);
920
+ })();
921
+ }
922
+
923
+ // Finds the line to start with when starting a parse. Tries to
924
+ // find a line with a stateAfter, so that it can start with a
925
+ // valid state. If that fails, it returns the line with the
926
+ // smallest indentation, which tends to need the least context to
927
+ // parse correctly.
928
+ function findStartLine(cm, n, precise) {
929
+ var minindent, minline, doc = cm.doc;
930
+ for (var search = n, lim = n - 100; search > lim; --search) {
931
+ if (search <= doc.first) return doc.first;
932
+ var line = getLine(doc, search - 1);
933
+ if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
934
+ var indented = countColumn(line.text, null, cm.options.tabSize);
935
+ if (minline == null || minindent > indented) {
936
+ minline = search - 1;
937
+ minindent = indented;
938
+ }
939
+ }
940
+ return minline;
941
+ }
942
+
943
+ function getStateBefore(cm, n, precise) {
944
+ var doc = cm.doc, display = cm.display;
945
+ if (!doc.mode.startState) return true;
946
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
947
+ if (!state) state = startState(doc.mode);
948
+ else state = copyState(doc.mode, state);
949
+ doc.iter(pos, n, function(line) {
950
+ processLine(cm, line, state);
951
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
952
+ line.stateAfter = save ? copyState(doc.mode, state) : null;
953
+ ++pos;
954
+ });
955
+ return state;
956
+ }
957
+
958
+ // POSITION MEASUREMENT
959
+
960
+ function paddingTop(display) {return display.lineSpace.offsetTop;}
961
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
962
+ function paddingLeft(display) {
963
+ var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
964
+ return e.offsetLeft;
965
+ }
966
+
967
+ function measureChar(cm, line, ch, data, bias) {
968
+ var dir = -1;
969
+ data = data || measureLine(cm, line);
970
+
971
+ for (var pos = ch;; pos += dir) {
972
+ var r = data[pos];
973
+ if (r) break;
974
+ if (dir < 0 && pos == 0) dir = 1;
975
+ }
976
+ bias = pos > ch ? "left" : pos < ch ? "right" : bias;
977
+ if (bias == "left" && r.leftSide) r = r.leftSide;
978
+ else if (bias == "right" && r.rightSide) r = r.rightSide;
979
+ return {left: pos < ch ? r.right : r.left,
980
+ right: pos > ch ? r.left : r.right,
981
+ top: r.top,
982
+ bottom: r.bottom};
983
+ }
984
+
985
+ function findCachedMeasurement(cm, line) {
986
+ var cache = cm.display.measureLineCache;
987
+ for (var i = 0; i < cache.length; ++i) {
988
+ var memo = cache[i];
989
+ if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
990
+ cm.display.scroller.clientWidth == memo.width &&
991
+ memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
992
+ return memo;
993
+ }
994
+ }
995
+
996
+ function clearCachedMeasurement(cm, line) {
997
+ var exists = findCachedMeasurement(cm, line);
998
+ if (exists) exists.text = exists.measure = exists.markedSpans = null;
999
+ }
1000
+
1001
+ function measureLine(cm, line) {
1002
+ // First look in the cache
1003
+ var cached = findCachedMeasurement(cm, line);
1004
+ if (cached) return cached.measure;
1005
+
1006
+ // Failing that, recompute and store result in cache
1007
+ var measure = measureLineInner(cm, line);
1008
+ var cache = cm.display.measureLineCache;
1009
+ var memo = {text: line.text, width: cm.display.scroller.clientWidth,
1010
+ markedSpans: line.markedSpans, measure: measure,
1011
+ classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
1012
+ if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
1013
+ else cache.push(memo);
1014
+ return measure;
1015
+ }
1016
+
1017
+ function measureLineInner(cm, line) {
1018
+ var display = cm.display, measure = emptyArray(line.text.length);
1019
+ var pre = lineContent(cm, line, measure, true);
1020
+
1021
+ // IE does not cache element positions of inline elements between
1022
+ // calls to getBoundingClientRect. This makes the loop below,
1023
+ // which gathers the positions of all the characters on the line,
1024
+ // do an amount of layout work quadratic to the number of
1025
+ // characters. When line wrapping is off, we try to improve things
1026
+ // by first subdividing the line into a bunch of inline blocks, so
1027
+ // that IE can reuse most of the layout information from caches
1028
+ // for those blocks. This does interfere with line wrapping, so it
1029
+ // doesn't work when wrapping is on, but in that case the
1030
+ // situation is slightly better, since IE does cache line-wrapping
1031
+ // information and only recomputes per-line.
1032
+ if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
1033
+ var fragment = document.createDocumentFragment();
1034
+ var chunk = 10, n = pre.childNodes.length;
1035
+ for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
1036
+ var wrap = elt("div", null, null, "display: inline-block");
1037
+ for (var j = 0; j < chunk && n; ++j) {
1038
+ wrap.appendChild(pre.firstChild);
1039
+ --n;
1040
+ }
1041
+ fragment.appendChild(wrap);
1042
+ }
1043
+ pre.appendChild(fragment);
1044
+ }
1045
+
1046
+ removeChildrenAndAdd(display.measure, pre);
1047
+
1048
+ var outer = getRect(display.lineDiv);
1049
+ var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
1050
+ // Work around an IE7/8 bug where it will sometimes have randomly
1051
+ // replaced our pre with a clone at this point.
1052
+ if (ie_lt9 && display.measure.first != pre)
1053
+ removeChildrenAndAdd(display.measure, pre);
1054
+
1055
+ function measureRect(rect) {
1056
+ var top = rect.top - outer.top, bot = rect.bottom - outer.top;
1057
+ if (bot > maxBot) bot = maxBot;
1058
+ if (top < 0) top = 0;
1059
+ for (var i = vranges.length - 2; i >= 0; i -= 2) {
1060
+ var rtop = vranges[i], rbot = vranges[i+1];
1061
+ if (rtop > bot || rbot < top) continue;
1062
+ if (rtop <= top && rbot >= bot ||
1063
+ top <= rtop && bot >= rbot ||
1064
+ Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1065
+ vranges[i] = Math.min(top, rtop);
1066
+ vranges[i+1] = Math.max(bot, rbot);
1067
+ break;
1068
+ }
1069
+ }
1070
+ if (i < 0) { i = vranges.length; vranges.push(top, bot); }
1071
+ return {left: rect.left - outer.left,
1072
+ right: rect.right - outer.left,
1073
+ top: i, bottom: null};
1074
+ }
1075
+ function finishRect(rect) {
1076
+ rect.bottom = vranges[rect.top+1];
1077
+ rect.top = vranges[rect.top];
1078
+ }
1079
+
1080
+ for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1081
+ var node = cur, rect = null;
1082
+ // A widget might wrap, needs special care
1083
+ if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1084
+ if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1085
+ var rects = node.getClientRects();
1086
+ if (rects.length > 1) {
1087
+ rect = data[i] = measureRect(rects[0]);
1088
+ rect.rightSide = measureRect(rects[rects.length - 1]);
1089
+ }
1090
+ }
1091
+ if (!rect) rect = data[i] = measureRect(getRect(node));
1092
+ if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
1093
+ if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
1094
+ }
1095
+ for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1096
+ finishRect(cur);
1097
+ if (cur.leftSide) finishRect(cur.leftSide);
1098
+ if (cur.rightSide) finishRect(cur.rightSide);
1099
+ }
1100
+ return data;
1101
+ }
1102
+
1103
+ function measureLineWidth(cm, line) {
1104
+ var hasBadSpan = false;
1105
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
1106
+ var sp = line.markedSpans[i];
1107
+ if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
1108
+ }
1109
+ var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1110
+ if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1111
+
1112
+ var pre = lineContent(cm, line, null, true);
1113
+ var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1114
+ removeChildrenAndAdd(cm.display.measure, pre);
1115
+ return getRect(end).right - getRect(cm.display.lineDiv).left;
1116
+ }
1117
+
1118
+ function clearCaches(cm) {
1119
+ cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
1120
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
1121
+ if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
1122
+ cm.display.lineNumChars = null;
1123
+ }
1124
+
1125
+ function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
1126
+ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
1127
+
1128
+ // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
1129
+ function intoCoordSystem(cm, lineObj, rect, context) {
1130
+ if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1131
+ var size = widgetHeight(lineObj.widgets[i]);
1132
+ rect.top += size; rect.bottom += size;
1133
+ }
1134
+ if (context == "line") return rect;
1135
+ if (!context) context = "local";
1136
+ var yOff = heightAtLine(cm, lineObj);
1137
+ if (context == "local") yOff += paddingTop(cm.display);
1138
+ else yOff -= cm.display.viewOffset;
1139
+ if (context == "page" || context == "window") {
1140
+ var lOff = getRect(cm.display.lineSpace);
1141
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
1142
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
1143
+ rect.left += xOff; rect.right += xOff;
1144
+ }
1145
+ rect.top += yOff; rect.bottom += yOff;
1146
+ return rect;
1147
+ }
1148
+
1149
+ // Context may be "window", "page", "div", or "local"/null
1150
+ // Result is in "div" coords
1151
+ function fromCoordSystem(cm, coords, context) {
1152
+ if (context == "div") return coords;
1153
+ var left = coords.left, top = coords.top;
1154
+ // First move into "page" coordinate system
1155
+ if (context == "page") {
1156
+ left -= pageScrollX();
1157
+ top -= pageScrollY();
1158
+ } else if (context == "local" || !context) {
1159
+ var localBox = getRect(cm.display.sizer);
1160
+ left += localBox.left;
1161
+ top += localBox.top;
1162
+ }
1163
+
1164
+ var lineSpaceBox = getRect(cm.display.lineSpace);
1165
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
1166
+ }
1167
+
1168
+ function charCoords(cm, pos, context, lineObj, bias) {
1169
+ if (!lineObj) lineObj = getLine(cm.doc, pos.line);
1170
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
1171
+ }
1172
+
1173
+ function cursorCoords(cm, pos, context, lineObj, measurement) {
1174
+ lineObj = lineObj || getLine(cm.doc, pos.line);
1175
+ if (!measurement) measurement = measureLine(cm, lineObj);
1176
+ function get(ch, right) {
1177
+ var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
1178
+ if (right) m.left = m.right; else m.right = m.left;
1179
+ return intoCoordSystem(cm, lineObj, m, context);
1180
+ }
1181
+ function getBidi(ch, partPos) {
1182
+ var part = order[partPos], right = part.level % 2;
1183
+ if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
1184
+ part = order[--partPos];
1185
+ ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
1186
+ right = true;
1187
+ } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
1188
+ part = order[++partPos];
1189
+ ch = bidiLeft(part) - part.level % 2;
1190
+ right = false;
1191
+ }
1192
+ if (right && ch == part.to && ch > part.from) return get(ch - 1);
1193
+ return get(ch, right);
1194
+ }
1195
+ var order = getOrder(lineObj), ch = pos.ch;
1196
+ if (!order) return get(ch);
1197
+ var partPos = getBidiPartAt(order, ch);
1198
+ var val = getBidi(ch, partPos);
1199
+ if (bidiOther != null) val.other = getBidi(ch, bidiOther);
1200
+ return val;
1201
+ }
1202
+
1203
+ function PosWithInfo(line, ch, outside, xRel) {
1204
+ var pos = new Pos(line, ch);
1205
+ pos.xRel = xRel;
1206
+ if (outside) pos.outside = true;
1207
+ return pos;
1208
+ }
1209
+
1210
+ // Coords must be lineSpace-local
1211
+ function coordsChar(cm, x, y) {
1212
+ var doc = cm.doc;
1213
+ y += cm.display.viewOffset;
1214
+ if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
1215
+ var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
1216
+ if (lineNo > last)
1217
+ return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
1218
+ if (x < 0) x = 0;
1219
+
1220
+ for (;;) {
1221
+ var lineObj = getLine(doc, lineNo);
1222
+ var found = coordsCharInner(cm, lineObj, lineNo, x, y);
1223
+ var merged = collapsedSpanAtEnd(lineObj);
1224
+ var mergedPos = merged && merged.find();
1225
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
1226
+ lineNo = mergedPos.to.line;
1227
+ else
1228
+ return found;
1229
+ }
1230
+ }
1231
+
1232
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
1233
+ var innerOff = y - heightAtLine(cm, lineObj);
1234
+ var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
1235
+ var measurement = measureLine(cm, lineObj);
1236
+
1237
+ function getX(ch) {
1238
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
1239
+ lineObj, measurement);
1240
+ wrongLine = true;
1241
+ if (innerOff > sp.bottom) return sp.left - adjust;
1242
+ else if (innerOff < sp.top) return sp.left + adjust;
1243
+ else wrongLine = false;
1244
+ return sp.left;
1245
+ }
1246
+
1247
+ var bidi = getOrder(lineObj), dist = lineObj.text.length;
1248
+ var from = lineLeft(lineObj), to = lineRight(lineObj);
1249
+ var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
1250
+
1251
+ if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
1252
+ // Do a binary search between these bounds.
1253
+ for (;;) {
1254
+ if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1255
+ var ch = x < fromX || x - fromX <= toX - x ? from : to;
1256
+ var xDiff = x - (ch == from ? fromX : toX);
1257
+ while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
1258
+ var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
1259
+ xDiff < 0 ? -1 : xDiff ? 1 : 0);
1260
+ return pos;
1261
+ }
1262
+ var step = Math.ceil(dist / 2), middle = from + step;
1263
+ if (bidi) {
1264
+ middle = from;
1265
+ for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1266
+ }
1267
+ var middleX = getX(middle);
1268
+ if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
1269
+ else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
1270
+ }
1271
+ }
1272
+
1273
+ var measureText;
1274
+ function textHeight(display) {
1275
+ if (display.cachedTextHeight != null) return display.cachedTextHeight;
1276
+ if (measureText == null) {
1277
+ measureText = elt("pre");
1278
+ // Measure a bunch of lines, for browsers that compute
1279
+ // fractional heights.
1280
+ for (var i = 0; i < 49; ++i) {
1281
+ measureText.appendChild(document.createTextNode("x"));
1282
+ measureText.appendChild(elt("br"));
1283
+ }
1284
+ measureText.appendChild(document.createTextNode("x"));
1285
+ }
1286
+ removeChildrenAndAdd(display.measure, measureText);
1287
+ var height = measureText.offsetHeight / 50;
1288
+ if (height > 3) display.cachedTextHeight = height;
1289
+ removeChildren(display.measure);
1290
+ return height || 1;
1291
+ }
1292
+
1293
+ function charWidth(display) {
1294
+ if (display.cachedCharWidth != null) return display.cachedCharWidth;
1295
+ var anchor = elt("span", "x");
1296
+ var pre = elt("pre", [anchor]);
1297
+ removeChildrenAndAdd(display.measure, pre);
1298
+ var width = anchor.offsetWidth;
1299
+ if (width > 2) display.cachedCharWidth = width;
1300
+ return width || 10;
1301
+ }
1302
+
1303
+ // OPERATIONS
1304
+
1305
+ // Operations are used to wrap changes in such a way that each
1306
+ // change won't have to update the cursor and display (which would
1307
+ // be awkward, slow, and error-prone), but instead updates are
1308
+ // batched and then all combined and executed at once.
1309
+
1310
+ var nextOpId = 0;
1311
+ function startOperation(cm) {
1312
+ cm.curOp = {
1313
+ // An array of ranges of lines that have to be updated. See
1314
+ // updateDisplay.
1315
+ changes: [],
1316
+ forceUpdate: false,
1317
+ updateInput: null,
1318
+ userSelChange: null,
1319
+ textChanged: null,
1320
+ selectionChanged: false,
1321
+ cursorActivity: false,
1322
+ updateMaxLine: false,
1323
+ updateScrollPos: false,
1324
+ id: ++nextOpId
1325
+ };
1326
+ if (!delayedCallbackDepth++) delayedCallbacks = [];
1327
+ }
1328
+
1329
+ function endOperation(cm) {
1330
+ var op = cm.curOp, doc = cm.doc, display = cm.display;
1331
+ cm.curOp = null;
1332
+
1333
+ if (op.updateMaxLine) computeMaxLength(cm);
1334
+ if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
1335
+ var width = measureLineWidth(cm, display.maxLine);
1336
+ display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
1337
+ display.maxLineChanged = false;
1338
+ var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
1339
+ if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
1340
+ setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
1341
+ }
1342
+ var newScrollPos, updated;
1343
+ if (op.updateScrollPos) {
1344
+ newScrollPos = op.updateScrollPos;
1345
+ } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
1346
+ var coords = cursorCoords(cm, doc.sel.head);
1347
+ newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1348
+ }
1349
+ if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
1350
+ updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
1351
+ if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1352
+ }
1353
+ if (!updated && op.selectionChanged) updateSelection(cm);
1354
+ if (op.updateScrollPos) {
1355
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
1356
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
1357
+ alignHorizontally(cm);
1358
+ if (op.scrollToPos)
1359
+ scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
1360
+ } else if (newScrollPos) {
1361
+ scrollCursorIntoView(cm);
1362
+ }
1363
+ if (op.selectionChanged) restartBlink(cm);
1364
+
1365
+ if (cm.state.focused && op.updateInput)
1366
+ resetInput(cm, op.userSelChange);
1367
+
1368
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
1369
+ if (hidden) for (var i = 0; i < hidden.length; ++i)
1370
+ if (!hidden[i].lines.length) signal(hidden[i], "hide");
1371
+ if (unhidden) for (var i = 0; i < unhidden.length; ++i)
1372
+ if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
1373
+
1374
+ var delayed;
1375
+ if (!--delayedCallbackDepth) {
1376
+ delayed = delayedCallbacks;
1377
+ delayedCallbacks = null;
1378
+ }
1379
+ if (op.textChanged)
1380
+ signal(cm, "change", cm, op.textChanged);
1381
+ if (op.cursorActivity) signal(cm, "cursorActivity", cm);
1382
+ if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
1383
+ }
1384
+
1385
+ // Wraps a function in an operation. Returns the wrapped function.
1386
+ function operation(cm1, f) {
1387
+ return function() {
1388
+ var cm = cm1 || this, withOp = !cm.curOp;
1389
+ if (withOp) startOperation(cm);
1390
+ try { var result = f.apply(cm, arguments); }
1391
+ finally { if (withOp) endOperation(cm); }
1392
+ return result;
1393
+ };
1394
+ }
1395
+ function docOperation(f) {
1396
+ return function() {
1397
+ var withOp = this.cm && !this.cm.curOp, result;
1398
+ if (withOp) startOperation(this.cm);
1399
+ try { result = f.apply(this, arguments); }
1400
+ finally { if (withOp) endOperation(this.cm); }
1401
+ return result;
1402
+ };
1403
+ }
1404
+ function runInOp(cm, f) {
1405
+ var withOp = !cm.curOp, result;
1406
+ if (withOp) startOperation(cm);
1407
+ try { result = f(); }
1408
+ finally { if (withOp) endOperation(cm); }
1409
+ return result;
1410
+ }
1411
+
1412
+ function regChange(cm, from, to, lendiff) {
1413
+ if (from == null) from = cm.doc.first;
1414
+ if (to == null) to = cm.doc.first + cm.doc.size;
1415
+ cm.curOp.changes.push({from: from, to: to, diff: lendiff});
1416
+ }
1417
+
1418
+ // INPUT HANDLING
1419
+
1420
+ function slowPoll(cm) {
1421
+ if (cm.display.pollingFast) return;
1422
+ cm.display.poll.set(cm.options.pollInterval, function() {
1423
+ readInput(cm);
1424
+ if (cm.state.focused) slowPoll(cm);
1425
+ });
1426
+ }
1427
+
1428
+ function fastPoll(cm) {
1429
+ var missed = false;
1430
+ cm.display.pollingFast = true;
1431
+ function p() {
1432
+ var changed = readInput(cm);
1433
+ if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
1434
+ else {cm.display.pollingFast = false; slowPoll(cm);}
1435
+ }
1436
+ cm.display.poll.set(20, p);
1437
+ }
1438
+
1439
+ // prevInput is a hack to work with IME. If we reset the textarea
1440
+ // on every change, that breaks IME. So we look for changes
1441
+ // compared to the previous content instead. (Modern browsers have
1442
+ // events that indicate IME taking place, but these are not widely
1443
+ // supported or compatible enough yet to rely on.)
1444
+ function readInput(cm) {
1445
+ var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
1446
+ if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
1447
+ var text = input.value;
1448
+ if (text == prevInput && posEq(sel.from, sel.to)) return false;
1449
+ if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
1450
+ resetInput(cm, true);
1451
+ return false;
1452
+ }
1453
+
1454
+ var withOp = !cm.curOp;
1455
+ if (withOp) startOperation(cm);
1456
+ sel.shift = false;
1457
+ var same = 0, l = Math.min(prevInput.length, text.length);
1458
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
1459
+ var from = sel.from, to = sel.to;
1460
+ if (same < prevInput.length)
1461
+ from = Pos(from.line, from.ch - (prevInput.length - same));
1462
+ else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
1463
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
1464
+
1465
+ var updateInput = cm.curOp.updateInput;
1466
+ var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
1467
+ origin: cm.state.pasteIncoming ? "paste" : "+input"};
1468
+ makeChange(cm.doc, changeEvent, "end");
1469
+ cm.curOp.updateInput = updateInput;
1470
+ signalLater(cm, "inputRead", cm, changeEvent);
1471
+
1472
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
1473
+ else cm.display.prevInput = text;
1474
+ if (withOp) endOperation(cm);
1475
+ cm.state.pasteIncoming = false;
1476
+ return true;
1477
+ }
1478
+
1479
+ function resetInput(cm, user) {
1480
+ var minimal, selected, doc = cm.doc;
1481
+ if (!posEq(doc.sel.from, doc.sel.to)) {
1482
+ cm.display.prevInput = "";
1483
+ minimal = hasCopyEvent &&
1484
+ (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
1485
+ var content = minimal ? "-" : selected || cm.getSelection();
1486
+ cm.display.input.value = content;
1487
+ if (cm.state.focused) selectInput(cm.display.input);
1488
+ if (ie && !ie_lt9) cm.display.inputHasSelection = content;
1489
+ } else if (user) {
1490
+ cm.display.prevInput = cm.display.input.value = "";
1491
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
1492
+ }
1493
+ cm.display.inaccurateSelection = minimal;
1494
+ }
1495
+
1496
+ function focusInput(cm) {
1497
+ if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
1498
+ cm.display.input.focus();
1499
+ }
1500
+
1501
+ function isReadOnly(cm) {
1502
+ return cm.options.readOnly || cm.doc.cantEdit;
1503
+ }
1504
+
1505
+ // EVENT HANDLERS
1506
+
1507
+ function registerEventHandlers(cm) {
1508
+ var d = cm.display;
1509
+ on(d.scroller, "mousedown", operation(cm, onMouseDown));
1510
+ if (ie)
1511
+ on(d.scroller, "dblclick", operation(cm, function(e) {
1512
+ if (signalDOMEvent(cm, e)) return;
1513
+ var pos = posFromMouse(cm, e);
1514
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
1515
+ e_preventDefault(e);
1516
+ var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
1517
+ extendSelection(cm.doc, word.from, word.to);
1518
+ }));
1519
+ else
1520
+ on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
1521
+ on(d.lineSpace, "selectstart", function(e) {
1522
+ if (!eventInWidget(d, e)) e_preventDefault(e);
1523
+ });
1524
+ // Gecko browsers fire contextmenu *after* opening the menu, at
1525
+ // which point we can't mess with it anymore. Context menu is
1526
+ // handled in onMouseDown for Gecko.
1527
+ if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
1528
+
1529
+ on(d.scroller, "scroll", function() {
1530
+ if (d.scroller.clientHeight) {
1531
+ setScrollTop(cm, d.scroller.scrollTop);
1532
+ setScrollLeft(cm, d.scroller.scrollLeft, true);
1533
+ signal(cm, "scroll", cm);
1534
+ }
1535
+ });
1536
+ on(d.scrollbarV, "scroll", function() {
1537
+ if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
1538
+ });
1539
+ on(d.scrollbarH, "scroll", function() {
1540
+ if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
1541
+ });
1542
+
1543
+ on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
1544
+ on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
1545
+
1546
+ function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
1547
+ on(d.scrollbarH, "mousedown", reFocus);
1548
+ on(d.scrollbarV, "mousedown", reFocus);
1549
+ // Prevent wrapper from ever scrolling
1550
+ on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
1551
+
1552
+ var resizeTimer;
1553
+ function onResize() {
1554
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
1555
+ resizeTimer = null;
1556
+ // Might be a text scaling operation, clear size caches.
1557
+ d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
1558
+ clearCaches(cm);
1559
+ runInOp(cm, bind(regChange, cm));
1560
+ }, 100);
1561
+ }
1562
+ on(window, "resize", onResize);
1563
+ // Above handler holds on to the editor and its data structures.
1564
+ // Here we poll to unregister it when the editor is no longer in
1565
+ // the document, so that it can be garbage-collected.
1566
+ function unregister() {
1567
+ for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
1568
+ if (p) setTimeout(unregister, 5000);
1569
+ else off(window, "resize", onResize);
1570
+ }
1571
+ setTimeout(unregister, 5000);
1572
+
1573
+ on(d.input, "keyup", operation(cm, function(e) {
1574
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1575
+ if (e.keyCode == 16) cm.doc.sel.shift = false;
1576
+ }));
1577
+ on(d.input, "input", bind(fastPoll, cm));
1578
+ on(d.input, "keydown", operation(cm, onKeyDown));
1579
+ on(d.input, "keypress", operation(cm, onKeyPress));
1580
+ on(d.input, "focus", bind(onFocus, cm));
1581
+ on(d.input, "blur", bind(onBlur, cm));
1582
+
1583
+ function drag_(e) {
1584
+ if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
1585
+ e_stop(e);
1586
+ }
1587
+ if (cm.options.dragDrop) {
1588
+ on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
1589
+ on(d.scroller, "dragenter", drag_);
1590
+ on(d.scroller, "dragover", drag_);
1591
+ on(d.scroller, "drop", operation(cm, onDrop));
1592
+ }
1593
+ on(d.scroller, "paste", function(e){
1594
+ if (eventInWidget(d, e)) return;
1595
+ focusInput(cm);
1596
+ fastPoll(cm);
1597
+ });
1598
+ on(d.input, "paste", function() {
1599
+ cm.state.pasteIncoming = true;
1600
+ fastPoll(cm);
1601
+ });
1602
+
1603
+ function prepareCopy() {
1604
+ if (d.inaccurateSelection) {
1605
+ d.prevInput = "";
1606
+ d.inaccurateSelection = false;
1607
+ d.input.value = cm.getSelection();
1608
+ selectInput(d.input);
1609
+ }
1610
+ }
1611
+ on(d.input, "cut", prepareCopy);
1612
+ on(d.input, "copy", prepareCopy);
1613
+
1614
+ // Needed to handle Tab key in KHTML
1615
+ if (khtml) on(d.sizer, "mouseup", function() {
1616
+ if (document.activeElement == d.input) d.input.blur();
1617
+ focusInput(cm);
1618
+ });
1619
+ }
1620
+
1621
+ function eventInWidget(display, e) {
1622
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
1623
+ if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
1624
+ }
1625
+ }
1626
+
1627
+ function posFromMouse(cm, e, liberal) {
1628
+ var display = cm.display;
1629
+ if (!liberal) {
1630
+ var target = e_target(e);
1631
+ if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
1632
+ target == display.scrollbarV || target == display.scrollbarV.firstChild ||
1633
+ target == display.scrollbarFiller || target == display.gutterFiller) return null;
1634
+ }
1635
+ var x, y, space = getRect(display.lineSpace);
1636
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
1637
+ try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1638
+ return coordsChar(cm, x - space.left, y - space.top);
1639
+ }
1640
+
1641
+ var lastClick, lastDoubleClick;
1642
+ function onMouseDown(e) {
1643
+ if (signalDOMEvent(this, e)) return;
1644
+ var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
1645
+ sel.shift = e.shiftKey;
1646
+
1647
+ if (eventInWidget(display, e)) {
1648
+ if (!webkit) {
1649
+ display.scroller.draggable = false;
1650
+ setTimeout(function(){display.scroller.draggable = true;}, 100);
1651
+ }
1652
+ return;
1653
+ }
1654
+ if (clickInGutter(cm, e)) return;
1655
+ var start = posFromMouse(cm, e);
1656
+
1657
+ switch (e_button(e)) {
1658
+ case 3:
1659
+ if (captureMiddleClick) onContextMenu.call(cm, cm, e);
1660
+ return;
1661
+ case 2:
1662
+ if (start) extendSelection(cm.doc, start);
1663
+ setTimeout(bind(focusInput, cm), 20);
1664
+ e_preventDefault(e);
1665
+ return;
1666
+ }
1667
+ // For button 1, if it was clicked inside the editor
1668
+ // (posFromMouse returning non-null), we have to adjust the
1669
+ // selection.
1670
+ if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
1671
+
1672
+ if (!cm.state.focused) onFocus(cm);
1673
+
1674
+ var now = +new Date, type = "single";
1675
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
1676
+ type = "triple";
1677
+ e_preventDefault(e);
1678
+ setTimeout(bind(focusInput, cm), 20);
1679
+ selectLine(cm, start.line);
1680
+ } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
1681
+ type = "double";
1682
+ lastDoubleClick = {time: now, pos: start};
1683
+ e_preventDefault(e);
1684
+ var word = findWordAt(getLine(doc, start.line).text, start);
1685
+ extendSelection(cm.doc, word.from, word.to);
1686
+ } else { lastClick = {time: now, pos: start}; }
1687
+
1688
+ var last = start;
1689
+ if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
1690
+ !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
1691
+ var dragEnd = operation(cm, function(e2) {
1692
+ if (webkit) display.scroller.draggable = false;
1693
+ cm.state.draggingText = false;
1694
+ off(document, "mouseup", dragEnd);
1695
+ off(display.scroller, "drop", dragEnd);
1696
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
1697
+ e_preventDefault(e2);
1698
+ extendSelection(cm.doc, start);
1699
+ focusInput(cm);
1700
+ }
1701
+ });
1702
+ // Let the drag handler handle this.
1703
+ if (webkit) display.scroller.draggable = true;
1704
+ cm.state.draggingText = dragEnd;
1705
+ // IE's approach to draggable
1706
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
1707
+ on(document, "mouseup", dragEnd);
1708
+ on(display.scroller, "drop", dragEnd);
1709
+ return;
1710
+ }
1711
+ e_preventDefault(e);
1712
+ if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
1713
+
1714
+ var startstart = sel.from, startend = sel.to, lastPos = start;
1715
+
1716
+ function doSelect(cur) {
1717
+ if (posEq(lastPos, cur)) return;
1718
+ lastPos = cur;
1719
+
1720
+ if (type == "single") {
1721
+ extendSelection(cm.doc, clipPos(doc, start), cur);
1722
+ return;
1723
+ }
1724
+
1725
+ startstart = clipPos(doc, startstart);
1726
+ startend = clipPos(doc, startend);
1727
+ if (type == "double") {
1728
+ var word = findWordAt(getLine(doc, cur.line).text, cur);
1729
+ if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
1730
+ else extendSelection(cm.doc, startstart, word.to);
1731
+ } else if (type == "triple") {
1732
+ if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
1733
+ else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
1734
+ }
1735
+ }
1736
+
1737
+ var editorSize = getRect(display.wrapper);
1738
+ // Used to ensure timeout re-tries don't fire when another extend
1739
+ // happened in the meantime (clearTimeout isn't reliable -- at
1740
+ // least on Chrome, the timeouts still happen even when cleared,
1741
+ // if the clear happens after their scheduled firing time).
1742
+ var counter = 0;
1743
+
1744
+ function extend(e) {
1745
+ var curCount = ++counter;
1746
+ var cur = posFromMouse(cm, e, true);
1747
+ if (!cur) return;
1748
+ if (!posEq(cur, last)) {
1749
+ if (!cm.state.focused) onFocus(cm);
1750
+ last = cur;
1751
+ doSelect(cur);
1752
+ var visible = visibleLines(display, doc);
1753
+ if (cur.line >= visible.to || cur.line < visible.from)
1754
+ setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
1755
+ } else {
1756
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
1757
+ if (outside) setTimeout(operation(cm, function() {
1758
+ if (counter != curCount) return;
1759
+ display.scroller.scrollTop += outside;
1760
+ extend(e);
1761
+ }), 50);
1762
+ }
1763
+ }
1764
+
1765
+ function done(e) {
1766
+ counter = Infinity;
1767
+ e_preventDefault(e);
1768
+ focusInput(cm);
1769
+ off(document, "mousemove", move);
1770
+ off(document, "mouseup", up);
1771
+ }
1772
+
1773
+ var move = operation(cm, function(e) {
1774
+ if (!ie && !e_button(e)) done(e);
1775
+ else extend(e);
1776
+ });
1777
+ var up = operation(cm, done);
1778
+ on(document, "mousemove", move);
1779
+ on(document, "mouseup", up);
1780
+ }
1781
+
1782
+ function clickInGutter(cm, e) {
1783
+ var display = cm.display;
1784
+ try { var mX = e.clientX, mY = e.clientY; }
1785
+ catch(e) { return false; }
1786
+
1787
+ if (mX >= Math.floor(getRect(display.gutters).right)) return false;
1788
+ e_preventDefault(e);
1789
+ if (!hasHandler(cm, "gutterClick")) return true;
1790
+
1791
+ var lineBox = getRect(display.lineDiv);
1792
+ if (mY > lineBox.bottom) return true;
1793
+ mY -= lineBox.top - display.viewOffset;
1794
+
1795
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
1796
+ var g = display.gutters.childNodes[i];
1797
+ if (g && getRect(g).right >= mX) {
1798
+ var line = lineAtHeight(cm.doc, mY);
1799
+ var gutter = cm.options.gutters[i];
1800
+ signalLater(cm, "gutterClick", cm, line, gutter, e);
1801
+ break;
1802
+ }
1803
+ }
1804
+ return true;
1805
+ }
1806
+
1807
+ // Kludge to work around strange IE behavior where it'll sometimes
1808
+ // re-fire a series of drag-related events right after the drop (#1551)
1809
+ var lastDrop = 0;
1810
+
1811
+ function onDrop(e) {
1812
+ var cm = this;
1813
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
1814
+ return;
1815
+ e_preventDefault(e);
1816
+ if (ie) lastDrop = +new Date;
1817
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
1818
+ if (!pos || isReadOnly(cm)) return;
1819
+ if (files && files.length && window.FileReader && window.File) {
1820
+ var n = files.length, text = Array(n), read = 0;
1821
+ var loadFile = function(file, i) {
1822
+ var reader = new FileReader;
1823
+ reader.onload = function() {
1824
+ text[i] = reader.result;
1825
+ if (++read == n) {
1826
+ pos = clipPos(cm.doc, pos);
1827
+ makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
1828
+ }
1829
+ };
1830
+ reader.readAsText(file);
1831
+ };
1832
+ for (var i = 0; i < n; ++i) loadFile(files[i], i);
1833
+ } else {
1834
+ // Don't do a replace if the drop happened inside of the selected text.
1835
+ if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
1836
+ cm.state.draggingText(e);
1837
+ // Ensure the editor is re-focused
1838
+ setTimeout(bind(focusInput, cm), 20);
1839
+ return;
1840
+ }
1841
+ try {
1842
+ var text = e.dataTransfer.getData("Text");
1843
+ if (text) {
1844
+ var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
1845
+ setSelection(cm.doc, pos, pos);
1846
+ if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
1847
+ cm.replaceSelection(text, null, "paste");
1848
+ focusInput(cm);
1849
+ onFocus(cm);
1850
+ }
1851
+ }
1852
+ catch(e){}
1853
+ }
1854
+ }
1855
+
1856
+ function onDragStart(cm, e) {
1857
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
1858
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
1859
+
1860
+ var txt = cm.getSelection();
1861
+ e.dataTransfer.setData("Text", txt);
1862
+
1863
+ // Use dummy image instead of default browsers image.
1864
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
1865
+ if (e.dataTransfer.setDragImage && !safari) {
1866
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
1867
+ if (opera) {
1868
+ img.width = img.height = 1;
1869
+ cm.display.wrapper.appendChild(img);
1870
+ // Force a relayout, or Opera won't use our image for some obscure reason
1871
+ img._top = img.offsetTop;
1872
+ }
1873
+ e.dataTransfer.setDragImage(img, 0, 0);
1874
+ if (opera) img.parentNode.removeChild(img);
1875
+ }
1876
+ }
1877
+
1878
+ function setScrollTop(cm, val) {
1879
+ if (Math.abs(cm.doc.scrollTop - val) < 2) return;
1880
+ cm.doc.scrollTop = val;
1881
+ if (!gecko) updateDisplay(cm, [], val);
1882
+ if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
1883
+ if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
1884
+ if (gecko) updateDisplay(cm, []);
1885
+ startWorker(cm, 100);
1886
+ }
1887
+ function setScrollLeft(cm, val, isScroller) {
1888
+ if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
1889
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
1890
+ cm.doc.scrollLeft = val;
1891
+ alignHorizontally(cm);
1892
+ if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
1893
+ if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
1894
+ }
1895
+
1896
+ // Since the delta values reported on mouse wheel events are
1897
+ // unstandardized between browsers and even browser versions, and
1898
+ // generally horribly unpredictable, this code starts by measuring
1899
+ // the scroll effect that the first few mouse wheel events have,
1900
+ // and, from that, detects the way it can convert deltas to pixel
1901
+ // offsets afterwards.
1902
+ //
1903
+ // The reason we want to know the amount a wheel event will scroll
1904
+ // is that it gives us a chance to update the display before the
1905
+ // actual scrolling happens, reducing flickering.
1906
+
1907
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
1908
+ // Fill in a browser-detected starting value on browsers where we
1909
+ // know one. These don't have to be accurate -- the result of them
1910
+ // being wrong would just be a slight flicker on the first wheel
1911
+ // scroll (if it is large enough).
1912
+ if (ie) wheelPixelsPerUnit = -.53;
1913
+ else if (gecko) wheelPixelsPerUnit = 15;
1914
+ else if (chrome) wheelPixelsPerUnit = -.7;
1915
+ else if (safari) wheelPixelsPerUnit = -1/3;
1916
+
1917
+ function onScrollWheel(cm, e) {
1918
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
1919
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
1920
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
1921
+ else if (dy == null) dy = e.wheelDelta;
1922
+
1923
+ var display = cm.display, scroll = display.scroller;
1924
+ // Quit if there's nothing to scroll here
1925
+ if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
1926
+ dy && scroll.scrollHeight > scroll.clientHeight)) return;
1927
+
1928
+ // Webkit browsers on OS X abort momentum scrolls when the target
1929
+ // of the scroll event is removed from the scrollable element.
1930
+ // This hack (see related code in patchDisplay) makes sure the
1931
+ // element is kept around.
1932
+ if (dy && mac && webkit) {
1933
+ for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
1934
+ if (cur.lineObj) {
1935
+ cm.display.currentWheelTarget = cur;
1936
+ break;
1937
+ }
1938
+ }
1939
+ }
1940
+
1941
+ // On some browsers, horizontal scrolling will cause redraws to
1942
+ // happen before the gutter has been realigned, causing it to
1943
+ // wriggle around in a most unseemly way. When we have an
1944
+ // estimated pixels/delta value, we just handle horizontal
1945
+ // scrolling entirely here. It'll be slightly off from native, but
1946
+ // better than glitching out.
1947
+ if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
1948
+ if (dy)
1949
+ setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
1950
+ setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
1951
+ e_preventDefault(e);
1952
+ display.wheelStartX = null; // Abort measurement, if in progress
1953
+ return;
1954
+ }
1955
+
1956
+ if (dy && wheelPixelsPerUnit != null) {
1957
+ var pixels = dy * wheelPixelsPerUnit;
1958
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
1959
+ if (pixels < 0) top = Math.max(0, top + pixels - 50);
1960
+ else bot = Math.min(cm.doc.height, bot + pixels + 50);
1961
+ updateDisplay(cm, [], {top: top, bottom: bot});
1962
+ }
1963
+
1964
+ if (wheelSamples < 20) {
1965
+ if (display.wheelStartX == null) {
1966
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
1967
+ display.wheelDX = dx; display.wheelDY = dy;
1968
+ setTimeout(function() {
1969
+ if (display.wheelStartX == null) return;
1970
+ var movedX = scroll.scrollLeft - display.wheelStartX;
1971
+ var movedY = scroll.scrollTop - display.wheelStartY;
1972
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
1973
+ (movedX && display.wheelDX && movedX / display.wheelDX);
1974
+ display.wheelStartX = display.wheelStartY = null;
1975
+ if (!sample) return;
1976
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
1977
+ ++wheelSamples;
1978
+ }, 200);
1979
+ } else {
1980
+ display.wheelDX += dx; display.wheelDY += dy;
1981
+ }
1982
+ }
1983
+ }
1984
+
1985
+ function doHandleBinding(cm, bound, dropShift) {
1986
+ if (typeof bound == "string") {
1987
+ bound = commands[bound];
1988
+ if (!bound) return false;
1989
+ }
1990
+ // Ensure previous input has been read, so that the handler sees a
1991
+ // consistent view of the document
1992
+ if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
1993
+ var doc = cm.doc, prevShift = doc.sel.shift, done = false;
1994
+ try {
1995
+ if (isReadOnly(cm)) cm.state.suppressEdits = true;
1996
+ if (dropShift) doc.sel.shift = false;
1997
+ done = bound(cm) != Pass;
1998
+ } finally {
1999
+ doc.sel.shift = prevShift;
2000
+ cm.state.suppressEdits = false;
2001
+ }
2002
+ return done;
2003
+ }
2004
+
2005
+ function allKeyMaps(cm) {
2006
+ var maps = cm.state.keyMaps.slice(0);
2007
+ if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
2008
+ maps.push(cm.options.keyMap);
2009
+ return maps;
2010
+ }
2011
+
2012
+ var maybeTransition;
2013
+ function handleKeyBinding(cm, e) {
2014
+ // Handle auto keymap transitions
2015
+ var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
2016
+ clearTimeout(maybeTransition);
2017
+ if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
2018
+ if (getKeyMap(cm.options.keyMap) == startMap) {
2019
+ cm.options.keyMap = (next.call ? next.call(null, cm) : next);
2020
+ keyMapChanged(cm);
2021
+ }
2022
+ }, 50);
2023
+
2024
+ var name = keyName(e, true), handled = false;
2025
+ if (!name) return false;
2026
+ var keymaps = allKeyMaps(cm);
2027
+
2028
+ if (e.shiftKey) {
2029
+ // First try to resolve full name (including 'Shift-'). Failing
2030
+ // that, see if there is a cursor-motion command (starting with
2031
+ // 'go') bound to the keyname without 'Shift-'.
2032
+ handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
2033
+ || lookupKey(name, keymaps, function(b) {
2034
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
2035
+ return doHandleBinding(cm, b);
2036
+ });
2037
+ } else {
2038
+ handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
2039
+ }
2040
+
2041
+ if (handled) {
2042
+ e_preventDefault(e);
2043
+ restartBlink(cm);
2044
+ if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
2045
+ signalLater(cm, "keyHandled", cm, name, e);
2046
+ }
2047
+ return handled;
2048
+ }
2049
+
2050
+ function handleCharBinding(cm, e, ch) {
2051
+ var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
2052
+ function(b) { return doHandleBinding(cm, b, true); });
2053
+ if (handled) {
2054
+ e_preventDefault(e);
2055
+ restartBlink(cm);
2056
+ signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
2057
+ }
2058
+ return handled;
2059
+ }
2060
+
2061
+ var lastStoppedKey = null;
2062
+ function onKeyDown(e) {
2063
+ var cm = this;
2064
+ if (!cm.state.focused) onFocus(cm);
2065
+ if (ie && e.keyCode == 27) { e.returnValue = false; }
2066
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2067
+ var code = e.keyCode;
2068
+ // IE does strange things with escape.
2069
+ cm.doc.sel.shift = code == 16 || e.shiftKey;
2070
+ // First give onKeyEvent option a chance to handle this.
2071
+ var handled = handleKeyBinding(cm, e);
2072
+ if (opera) {
2073
+ lastStoppedKey = handled ? code : null;
2074
+ // Opera has no cut event... we try to at least catch the key combo
2075
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
2076
+ cm.replaceSelection("");
2077
+ }
2078
+ }
2079
+
2080
+ function onKeyPress(e) {
2081
+ var cm = this;
2082
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2083
+ var keyCode = e.keyCode, charCode = e.charCode;
2084
+ if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
2085
+ if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
2086
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
2087
+ if (this.options.electricChars && this.doc.mode.electricChars &&
2088
+ this.options.smartIndent && !isReadOnly(this) &&
2089
+ this.doc.mode.electricChars.indexOf(ch) > -1)
2090
+ setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
2091
+ if (handleCharBinding(cm, e, ch)) return;
2092
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
2093
+ fastPoll(cm);
2094
+ }
2095
+
2096
+ function onFocus(cm) {
2097
+ if (cm.options.readOnly == "nocursor") return;
2098
+ if (!cm.state.focused) {
2099
+ signal(cm, "focus", cm);
2100
+ cm.state.focused = true;
2101
+ if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
2102
+ cm.display.wrapper.className += " CodeMirror-focused";
2103
+ resetInput(cm, true);
2104
+ }
2105
+ slowPoll(cm);
2106
+ restartBlink(cm);
2107
+ }
2108
+ function onBlur(cm) {
2109
+ if (cm.state.focused) {
2110
+ signal(cm, "blur", cm);
2111
+ cm.state.focused = false;
2112
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
2113
+ }
2114
+ clearInterval(cm.display.blinker);
2115
+ setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
2116
+ }
2117
+
2118
+ var detectingSelectAll;
2119
+ function onContextMenu(cm, e) {
2120
+ if (signalDOMEvent(cm, e, "contextmenu")) return;
2121
+ var display = cm.display, sel = cm.doc.sel;
2122
+ if (eventInWidget(display, e)) return;
2123
+
2124
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
2125
+ if (!pos || opera) return; // Opera is difficult.
2126
+ if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
2127
+ operation(cm, setSelection)(cm.doc, pos, pos);
2128
+
2129
+ var oldCSS = display.input.style.cssText;
2130
+ display.inputDiv.style.position = "absolute";
2131
+ display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
2132
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
2133
+ "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
2134
+ focusInput(cm);
2135
+ resetInput(cm, true);
2136
+ // Adds "Select all" to context menu in FF
2137
+ if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
2138
+
2139
+ function prepareSelectAllHack() {
2140
+ if (display.input.selectionStart != null) {
2141
+ var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
2142
+ display.prevInput = " ";
2143
+ display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
2144
+ }
2145
+ }
2146
+ function rehide() {
2147
+ display.inputDiv.style.position = "relative";
2148
+ display.input.style.cssText = oldCSS;
2149
+ if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
2150
+ slowPoll(cm);
2151
+
2152
+ // Try to detect the user choosing select-all
2153
+ if (display.input.selectionStart != null) {
2154
+ if (!ie || ie_lt9) prepareSelectAllHack();
2155
+ clearTimeout(detectingSelectAll);
2156
+ var i = 0, poll = function(){
2157
+ if (display.prevInput == " " && display.input.selectionStart == 0)
2158
+ operation(cm, commands.selectAll)(cm);
2159
+ else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
2160
+ else resetInput(cm);
2161
+ };
2162
+ detectingSelectAll = setTimeout(poll, 200);
2163
+ }
2164
+ }
2165
+
2166
+ if (ie && !ie_lt9) prepareSelectAllHack();
2167
+ if (captureMiddleClick) {
2168
+ e_stop(e);
2169
+ var mouseup = function() {
2170
+ off(window, "mouseup", mouseup);
2171
+ setTimeout(rehide, 20);
2172
+ };
2173
+ on(window, "mouseup", mouseup);
2174
+ } else {
2175
+ setTimeout(rehide, 50);
2176
+ }
2177
+ }
2178
+
2179
+ // UPDATING
2180
+
2181
+ var changeEnd = CodeMirror.changeEnd = function(change) {
2182
+ if (!change.text) return change.to;
2183
+ return Pos(change.from.line + change.text.length - 1,
2184
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
2185
+ };
2186
+
2187
+ // Make sure a position will be valid after the given change.
2188
+ function clipPostChange(doc, change, pos) {
2189
+ if (!posLess(change.from, pos)) return clipPos(doc, pos);
2190
+ var diff = (change.text.length - 1) - (change.to.line - change.from.line);
2191
+ if (pos.line > change.to.line + diff) {
2192
+ var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
2193
+ if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
2194
+ return clipToLen(pos, getLine(doc, preLine).text.length);
2195
+ }
2196
+ if (pos.line == change.to.line + diff)
2197
+ return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
2198
+ getLine(doc, change.to.line).text.length - change.to.ch);
2199
+ var inside = pos.line - change.from.line;
2200
+ return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
2201
+ }
2202
+
2203
+ // Hint can be null|"end"|"start"|"around"|{anchor,head}
2204
+ function computeSelAfterChange(doc, change, hint) {
2205
+ if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
2206
+ return {anchor: clipPostChange(doc, change, hint.anchor),
2207
+ head: clipPostChange(doc, change, hint.head)};
2208
+
2209
+ if (hint == "start") return {anchor: change.from, head: change.from};
2210
+
2211
+ var end = changeEnd(change);
2212
+ if (hint == "around") return {anchor: change.from, head: end};
2213
+ if (hint == "end") return {anchor: end, head: end};
2214
+
2215
+ // hint is null, leave the selection alone as much as possible
2216
+ var adjustPos = function(pos) {
2217
+ if (posLess(pos, change.from)) return pos;
2218
+ if (!posLess(change.to, pos)) return end;
2219
+
2220
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
2221
+ if (pos.line == change.to.line) ch += end.ch - change.to.ch;
2222
+ return Pos(line, ch);
2223
+ };
2224
+ return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
2225
+ }
2226
+
2227
+ function filterChange(doc, change, update) {
2228
+ var obj = {
2229
+ canceled: false,
2230
+ from: change.from,
2231
+ to: change.to,
2232
+ text: change.text,
2233
+ origin: change.origin,
2234
+ cancel: function() { this.canceled = true; }
2235
+ };
2236
+ if (update) obj.update = function(from, to, text, origin) {
2237
+ if (from) this.from = clipPos(doc, from);
2238
+ if (to) this.to = clipPos(doc, to);
2239
+ if (text) this.text = text;
2240
+ if (origin !== undefined) this.origin = origin;
2241
+ };
2242
+ signal(doc, "beforeChange", doc, obj);
2243
+ if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
2244
+
2245
+ if (obj.canceled) return null;
2246
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
2247
+ }
2248
+
2249
+ // Replace the range from from to to by the strings in replacement.
2250
+ // change is a {from, to, text [, origin]} object
2251
+ function makeChange(doc, change, selUpdate, ignoreReadOnly) {
2252
+ if (doc.cm) {
2253
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
2254
+ if (doc.cm.state.suppressEdits) return;
2255
+ }
2256
+
2257
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
2258
+ change = filterChange(doc, change, true);
2259
+ if (!change) return;
2260
+ }
2261
+
2262
+ // Possibly split or suppress the update based on the presence
2263
+ // of read-only spans in its range.
2264
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
2265
+ if (split) {
2266
+ for (var i = split.length - 1; i >= 1; --i)
2267
+ makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
2268
+ if (split.length)
2269
+ makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
2270
+ } else {
2271
+ makeChangeNoReadonly(doc, change, selUpdate);
2272
+ }
2273
+ }
2274
+
2275
+ function makeChangeNoReadonly(doc, change, selUpdate) {
2276
+ var selAfter = computeSelAfterChange(doc, change, selUpdate);
2277
+ addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
2278
+
2279
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
2280
+ var rebased = [];
2281
+
2282
+ linkedDocs(doc, function(doc, sharedHist) {
2283
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2284
+ rebaseHist(doc.history, change);
2285
+ rebased.push(doc.history);
2286
+ }
2287
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
2288
+ });
2289
+ }
2290
+
2291
+ function makeChangeFromHistory(doc, type) {
2292
+ if (doc.cm && doc.cm.state.suppressEdits) return;
2293
+
2294
+ var hist = doc.history;
2295
+ var event = (type == "undo" ? hist.done : hist.undone).pop();
2296
+ if (!event) return;
2297
+
2298
+ var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
2299
+ anchorAfter: event.anchorBefore, headAfter: event.headBefore,
2300
+ generation: hist.generation};
2301
+ (type == "undo" ? hist.undone : hist.done).push(anti);
2302
+ hist.generation = event.generation || ++hist.maxGeneration;
2303
+
2304
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
2305
+
2306
+ for (var i = event.changes.length - 1; i >= 0; --i) {
2307
+ var change = event.changes[i];
2308
+ change.origin = type;
2309
+ if (filter && !filterChange(doc, change, false)) {
2310
+ (type == "undo" ? hist.done : hist.undone).length = 0;
2311
+ return;
2312
+ }
2313
+
2314
+ anti.changes.push(historyChangeFromChange(doc, change));
2315
+
2316
+ var after = i ? computeSelAfterChange(doc, change, null)
2317
+ : {anchor: event.anchorBefore, head: event.headBefore};
2318
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
2319
+ var rebased = [];
2320
+
2321
+ linkedDocs(doc, function(doc, sharedHist) {
2322
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2323
+ rebaseHist(doc.history, change);
2324
+ rebased.push(doc.history);
2325
+ }
2326
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
2327
+ });
2328
+ }
2329
+ }
2330
+
2331
+ function shiftDoc(doc, distance) {
2332
+ function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
2333
+ doc.first += distance;
2334
+ if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
2335
+ doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
2336
+ doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
2337
+ }
2338
+
2339
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
2340
+ if (doc.cm && !doc.cm.curOp)
2341
+ return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
2342
+
2343
+ if (change.to.line < doc.first) {
2344
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
2345
+ return;
2346
+ }
2347
+ if (change.from.line > doc.lastLine()) return;
2348
+
2349
+ // Clip the change to the size of this doc
2350
+ if (change.from.line < doc.first) {
2351
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
2352
+ shiftDoc(doc, shift);
2353
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
2354
+ text: [lst(change.text)], origin: change.origin};
2355
+ }
2356
+ var last = doc.lastLine();
2357
+ if (change.to.line > last) {
2358
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
2359
+ text: [change.text[0]], origin: change.origin};
2360
+ }
2361
+
2362
+ change.removed = getBetween(doc, change.from, change.to);
2363
+
2364
+ if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
2365
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
2366
+ else updateDoc(doc, change, spans, selAfter);
2367
+ }
2368
+
2369
+ function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
2370
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
2371
+
2372
+ var recomputeMaxLength = false, checkWidthStart = from.line;
2373
+ if (!cm.options.lineWrapping) {
2374
+ checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
2375
+ doc.iter(checkWidthStart, to.line + 1, function(line) {
2376
+ if (line == display.maxLine) {
2377
+ recomputeMaxLength = true;
2378
+ return true;
2379
+ }
2380
+ });
2381
+ }
2382
+
2383
+ if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
2384
+ cm.curOp.cursorActivity = true;
2385
+
2386
+ updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
2387
+
2388
+ if (!cm.options.lineWrapping) {
2389
+ doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
2390
+ var len = lineLength(doc, line);
2391
+ if (len > display.maxLineLength) {
2392
+ display.maxLine = line;
2393
+ display.maxLineLength = len;
2394
+ display.maxLineChanged = true;
2395
+ recomputeMaxLength = false;
2396
+ }
2397
+ });
2398
+ if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
2399
+ }
2400
+
2401
+ // Adjust frontier, schedule worker
2402
+ doc.frontier = Math.min(doc.frontier, from.line);
2403
+ startWorker(cm, 400);
2404
+
2405
+ var lendiff = change.text.length - (to.line - from.line) - 1;
2406
+ // Remember that these lines changed, for updating the display
2407
+ regChange(cm, from.line, to.line + 1, lendiff);
2408
+
2409
+ if (hasHandler(cm, "change")) {
2410
+ var changeObj = {from: from, to: to,
2411
+ text: change.text,
2412
+ removed: change.removed,
2413
+ origin: change.origin};
2414
+ if (cm.curOp.textChanged) {
2415
+ for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
2416
+ cur.next = changeObj;
2417
+ } else cm.curOp.textChanged = changeObj;
2418
+ }
2419
+ }
2420
+
2421
+ function replaceRange(doc, code, from, to, origin) {
2422
+ if (!to) to = from;
2423
+ if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
2424
+ if (typeof code == "string") code = splitLines(code);
2425
+ makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
2426
+ }
2427
+
2428
+ // POSITION OBJECT
2429
+
2430
+ function Pos(line, ch) {
2431
+ if (!(this instanceof Pos)) return new Pos(line, ch);
2432
+ this.line = line; this.ch = ch;
2433
+ }
2434
+ CodeMirror.Pos = Pos;
2435
+
2436
+ function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
2437
+ function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
2438
+ function copyPos(x) {return Pos(x.line, x.ch);}
2439
+
2440
+ // SELECTION
2441
+
2442
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
2443
+ function clipPos(doc, pos) {
2444
+ if (pos.line < doc.first) return Pos(doc.first, 0);
2445
+ var last = doc.first + doc.size - 1;
2446
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
2447
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
2448
+ }
2449
+ function clipToLen(pos, linelen) {
2450
+ var ch = pos.ch;
2451
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
2452
+ else if (ch < 0) return Pos(pos.line, 0);
2453
+ else return pos;
2454
+ }
2455
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
2456
+
2457
+ // If shift is held, this will move the selection anchor. Otherwise,
2458
+ // it'll set the whole selection.
2459
+ function extendSelection(doc, pos, other, bias) {
2460
+ if (doc.sel.shift || doc.sel.extend) {
2461
+ var anchor = doc.sel.anchor;
2462
+ if (other) {
2463
+ var posBefore = posLess(pos, anchor);
2464
+ if (posBefore != posLess(other, anchor)) {
2465
+ anchor = pos;
2466
+ pos = other;
2467
+ } else if (posBefore != posLess(pos, other)) {
2468
+ pos = other;
2469
+ }
2470
+ }
2471
+ setSelection(doc, anchor, pos, bias);
2472
+ } else {
2473
+ setSelection(doc, pos, other || pos, bias);
2474
+ }
2475
+ if (doc.cm) doc.cm.curOp.userSelChange = true;
2476
+ }
2477
+
2478
+ function filterSelectionChange(doc, anchor, head) {
2479
+ var obj = {anchor: anchor, head: head};
2480
+ signal(doc, "beforeSelectionChange", doc, obj);
2481
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2482
+ obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
2483
+ return obj;
2484
+ }
2485
+
2486
+ // Update the selection. Last two args are only used by
2487
+ // updateDoc, since they have to be expressed in the line
2488
+ // numbers before the update.
2489
+ function setSelection(doc, anchor, head, bias, checkAtomic) {
2490
+ if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
2491
+ var filtered = filterSelectionChange(doc, anchor, head);
2492
+ head = filtered.head;
2493
+ anchor = filtered.anchor;
2494
+ }
2495
+
2496
+ var sel = doc.sel;
2497
+ sel.goalColumn = null;
2498
+ // Skip over atomic spans.
2499
+ if (checkAtomic || !posEq(anchor, sel.anchor))
2500
+ anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
2501
+ if (checkAtomic || !posEq(head, sel.head))
2502
+ head = skipAtomic(doc, head, bias, checkAtomic != "push");
2503
+
2504
+ if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
2505
+
2506
+ sel.anchor = anchor; sel.head = head;
2507
+ var inv = posLess(head, anchor);
2508
+ sel.from = inv ? head : anchor;
2509
+ sel.to = inv ? anchor : head;
2510
+
2511
+ if (doc.cm)
2512
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
2513
+ doc.cm.curOp.cursorActivity = true;
2514
+
2515
+ signalLater(doc, "cursorActivity", doc);
2516
+ }
2517
+
2518
+ function reCheckSelection(cm) {
2519
+ setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
2520
+ }
2521
+
2522
+ function skipAtomic(doc, pos, bias, mayClear) {
2523
+ var flipped = false, curPos = pos;
2524
+ var dir = bias || 1;
2525
+ doc.cantEdit = false;
2526
+ search: for (;;) {
2527
+ var line = getLine(doc, curPos.line);
2528
+ if (line.markedSpans) {
2529
+ for (var i = 0; i < line.markedSpans.length; ++i) {
2530
+ var sp = line.markedSpans[i], m = sp.marker;
2531
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2532
+ (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2533
+ if (mayClear) {
2534
+ signal(m, "beforeCursorEnter");
2535
+ if (m.explicitlyCleared) {
2536
+ if (!line.markedSpans) break;
2537
+ else {--i; continue;}
2538
+ }
2539
+ }
2540
+ if (!m.atomic) continue;
2541
+ var newPos = m.find()[dir < 0 ? "from" : "to"];
2542
+ if (posEq(newPos, curPos)) {
2543
+ newPos.ch += dir;
2544
+ if (newPos.ch < 0) {
2545
+ if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
2546
+ else newPos = null;
2547
+ } else if (newPos.ch > line.text.length) {
2548
+ if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
2549
+ else newPos = null;
2550
+ }
2551
+ if (!newPos) {
2552
+ if (flipped) {
2553
+ // Driven in a corner -- no valid cursor position found at all
2554
+ // -- try again *with* clearing, if we didn't already
2555
+ if (!mayClear) return skipAtomic(doc, pos, bias, true);
2556
+ // Otherwise, turn off editing until further notice, and return the start of the doc
2557
+ doc.cantEdit = true;
2558
+ return Pos(doc.first, 0);
2559
+ }
2560
+ flipped = true; newPos = pos; dir = -dir;
2561
+ }
2562
+ }
2563
+ curPos = newPos;
2564
+ continue search;
2565
+ }
2566
+ }
2567
+ }
2568
+ return curPos;
2569
+ }
2570
+ }
2571
+
2572
+ // SCROLLING
2573
+
2574
+ function scrollCursorIntoView(cm) {
2575
+ var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
2576
+ if (!cm.state.focused) return;
2577
+ var display = cm.display, box = getRect(display.sizer), doScroll = null;
2578
+ if (coords.top + box.top < 0) doScroll = true;
2579
+ else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
2580
+ if (doScroll != null && !phantom) {
2581
+ var hidden = display.cursor.style.display == "none";
2582
+ if (hidden) {
2583
+ display.cursor.style.display = "";
2584
+ display.cursor.style.left = coords.left + "px";
2585
+ display.cursor.style.top = (coords.top - display.viewOffset) + "px";
2586
+ }
2587
+ display.cursor.scrollIntoView(doScroll);
2588
+ if (hidden) display.cursor.style.display = "none";
2589
+ }
2590
+ }
2591
+
2592
+ function scrollPosIntoView(cm, pos, margin) {
2593
+ if (margin == null) margin = 0;
2594
+ for (;;) {
2595
+ var changed = false, coords = cursorCoords(cm, pos);
2596
+ var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
2597
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
2598
+ if (scrollPos.scrollTop != null) {
2599
+ setScrollTop(cm, scrollPos.scrollTop);
2600
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
2601
+ }
2602
+ if (scrollPos.scrollLeft != null) {
2603
+ setScrollLeft(cm, scrollPos.scrollLeft);
2604
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
2605
+ }
2606
+ if (!changed) return coords;
2607
+ }
2608
+ }
2609
+
2610
+ function scrollIntoView(cm, x1, y1, x2, y2) {
2611
+ var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
2612
+ if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
2613
+ if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
2614
+ }
2615
+
2616
+ function calculateScrollPos(cm, x1, y1, x2, y2) {
2617
+ var display = cm.display, snapMargin = textHeight(cm.display);
2618
+ if (y1 < 0) y1 = 0;
2619
+ var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
2620
+ var docBottom = cm.doc.height + paddingVert(display);
2621
+ var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
2622
+ if (y1 < screentop) {
2623
+ result.scrollTop = atTop ? 0 : y1;
2624
+ } else if (y2 > screentop + screen) {
2625
+ var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
2626
+ if (newTop != screentop) result.scrollTop = newTop;
2627
+ }
2628
+
2629
+ var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
2630
+ x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
2631
+ var gutterw = display.gutters.offsetWidth;
2632
+ var atLeft = x1 < gutterw + 10;
2633
+ if (x1 < screenleft + gutterw || atLeft) {
2634
+ if (atLeft) x1 = 0;
2635
+ result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
2636
+ } else if (x2 > screenw + screenleft - 3) {
2637
+ result.scrollLeft = x2 + 10 - screenw;
2638
+ }
2639
+ return result;
2640
+ }
2641
+
2642
+ function updateScrollPos(cm, left, top) {
2643
+ cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
2644
+ scrollTop: top == null ? cm.doc.scrollTop : top};
2645
+ }
2646
+
2647
+ function addToScrollPos(cm, left, top) {
2648
+ var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
2649
+ var scroll = cm.display.scroller;
2650
+ pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
2651
+ pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
2652
+ }
2653
+
2654
+ // API UTILITIES
2655
+
2656
+ function indentLine(cm, n, how, aggressive) {
2657
+ var doc = cm.doc;
2658
+ if (how == null) how = "add";
2659
+ if (how == "smart") {
2660
+ if (!cm.doc.mode.indent) how = "prev";
2661
+ else var state = getStateBefore(cm, n);
2662
+ }
2663
+
2664
+ var tabSize = cm.options.tabSize;
2665
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
2666
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation;
2667
+ if (how == "smart") {
2668
+ indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
2669
+ if (indentation == Pass) {
2670
+ if (!aggressive) return;
2671
+ how = "prev";
2672
+ }
2673
+ }
2674
+ if (how == "prev") {
2675
+ if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
2676
+ else indentation = 0;
2677
+ } else if (how == "add") {
2678
+ indentation = curSpace + cm.options.indentUnit;
2679
+ } else if (how == "subtract") {
2680
+ indentation = curSpace - cm.options.indentUnit;
2681
+ } else if (typeof how == "number") {
2682
+ indentation = curSpace + how;
2683
+ }
2684
+ indentation = Math.max(0, indentation);
2685
+
2686
+ var indentString = "", pos = 0;
2687
+ if (cm.options.indentWithTabs)
2688
+ for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
2689
+ if (pos < indentation) indentString += spaceStr(indentation - pos);
2690
+
2691
+ if (indentString != curSpaceString)
2692
+ replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
2693
+ line.stateAfter = null;
2694
+ }
2695
+
2696
+ function changeLine(cm, handle, op) {
2697
+ var no = handle, line = handle, doc = cm.doc;
2698
+ if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
2699
+ else no = lineNo(handle);
2700
+ if (no == null) return null;
2701
+ if (op(line, no)) regChange(cm, no, no + 1);
2702
+ else return null;
2703
+ return line;
2704
+ }
2705
+
2706
+ function findPosH(doc, pos, dir, unit, visually) {
2707
+ var line = pos.line, ch = pos.ch, origDir = dir;
2708
+ var lineObj = getLine(doc, line);
2709
+ var possible = true;
2710
+ function findNextLine() {
2711
+ var l = line + dir;
2712
+ if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
2713
+ line = l;
2714
+ return lineObj = getLine(doc, l);
2715
+ }
2716
+ function moveOnce(boundToLine) {
2717
+ var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
2718
+ if (next == null) {
2719
+ if (!boundToLine && findNextLine()) {
2720
+ if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
2721
+ else ch = dir < 0 ? lineObj.text.length : 0;
2722
+ } else return (possible = false);
2723
+ } else ch = next;
2724
+ return true;
2725
+ }
2726
+
2727
+ if (unit == "char") moveOnce();
2728
+ else if (unit == "column") moveOnce(true);
2729
+ else if (unit == "word" || unit == "group") {
2730
+ var sawType = null, group = unit == "group";
2731
+ for (var first = true;; first = false) {
2732
+ if (dir < 0 && !moveOnce(!first)) break;
2733
+ var cur = lineObj.text.charAt(ch) || "\n";
2734
+ var type = isWordChar(cur) ? "w"
2735
+ : !group ? null
2736
+ : /\s/.test(cur) ? null
2737
+ : "p";
2738
+ if (sawType && sawType != type) {
2739
+ if (dir < 0) {dir = 1; moveOnce();}
2740
+ break;
2741
+ }
2742
+ if (type) sawType = type;
2743
+ if (dir > 0 && !moveOnce(!first)) break;
2744
+ }
2745
+ }
2746
+ var result = skipAtomic(doc, Pos(line, ch), origDir, true);
2747
+ if (!possible) result.hitSide = true;
2748
+ return result;
2749
+ }
2750
+
2751
+ function findPosV(cm, pos, dir, unit) {
2752
+ var doc = cm.doc, x = pos.left, y;
2753
+ if (unit == "page") {
2754
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
2755
+ y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
2756
+ } else if (unit == "line") {
2757
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
2758
+ }
2759
+ for (;;) {
2760
+ var target = coordsChar(cm, x, y);
2761
+ if (!target.outside) break;
2762
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
2763
+ y += dir * 5;
2764
+ }
2765
+ return target;
2766
+ }
2767
+
2768
+ function findWordAt(line, pos) {
2769
+ var start = pos.ch, end = pos.ch;
2770
+ if (line) {
2771
+ if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
2772
+ var startChar = line.charAt(start);
2773
+ var check = isWordChar(startChar) ? isWordChar
2774
+ : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
2775
+ : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
2776
+ while (start > 0 && check(line.charAt(start - 1))) --start;
2777
+ while (end < line.length && check(line.charAt(end))) ++end;
2778
+ }
2779
+ return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
2780
+ }
2781
+
2782
+ function selectLine(cm, line) {
2783
+ extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
2784
+ }
2785
+
2786
+ // PROTOTYPE
2787
+
2788
+ // The publicly visible API. Note that operation(null, f) means
2789
+ // 'wrap f in an operation, performed on its `this` parameter'
2790
+
2791
+ CodeMirror.prototype = {
2792
+ constructor: CodeMirror,
2793
+ focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2794
+
2795
+ setOption: function(option, value) {
2796
+ var options = this.options, old = options[option];
2797
+ if (options[option] == value && option != "mode") return;
2798
+ options[option] = value;
2799
+ if (optionHandlers.hasOwnProperty(option))
2800
+ operation(this, optionHandlers[option])(this, value, old);
2801
+ },
2802
+
2803
+ getOption: function(option) {return this.options[option];},
2804
+ getDoc: function() {return this.doc;},
2805
+
2806
+ addKeyMap: function(map, bottom) {
2807
+ this.state.keyMaps[bottom ? "push" : "unshift"](map);
2808
+ },
2809
+ removeKeyMap: function(map) {
2810
+ var maps = this.state.keyMaps;
2811
+ for (var i = 0; i < maps.length; ++i)
2812
+ if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
2813
+ maps.splice(i, 1);
2814
+ return true;
2815
+ }
2816
+ },
2817
+
2818
+ addOverlay: operation(null, function(spec, options) {
2819
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
2820
+ if (mode.startState) throw new Error("Overlays may not be stateful.");
2821
+ this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
2822
+ this.state.modeGen++;
2823
+ regChange(this);
2824
+ }),
2825
+ removeOverlay: operation(null, function(spec) {
2826
+ var overlays = this.state.overlays;
2827
+ for (var i = 0; i < overlays.length; ++i) {
2828
+ var cur = overlays[i].modeSpec;
2829
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
2830
+ overlays.splice(i, 1);
2831
+ this.state.modeGen++;
2832
+ regChange(this);
2833
+ return;
2834
+ }
2835
+ }
2836
+ }),
2837
+
2838
+ indentLine: operation(null, function(n, dir, aggressive) {
2839
+ if (typeof dir != "string" && typeof dir != "number") {
2840
+ if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
2841
+ else dir = dir ? "add" : "subtract";
2842
+ }
2843
+ if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
2844
+ }),
2845
+ indentSelection: operation(null, function(how) {
2846
+ var sel = this.doc.sel;
2847
+ if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
2848
+ var e = sel.to.line - (sel.to.ch ? 0 : 1);
2849
+ for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
2850
+ }),
2851
+
2852
+ // Fetch the parser token for a given character. Useful for hacks
2853
+ // that want to inspect the mode state (say, for completion).
2854
+ getTokenAt: function(pos, precise) {
2855
+ var doc = this.doc;
2856
+ pos = clipPos(doc, pos);
2857
+ var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
2858
+ var line = getLine(doc, pos.line);
2859
+ var stream = new StringStream(line.text, this.options.tabSize);
2860
+ while (stream.pos < pos.ch && !stream.eol()) {
2861
+ stream.start = stream.pos;
2862
+ var style = mode.token(stream, state);
2863
+ }
2864
+ return {start: stream.start,
2865
+ end: stream.pos,
2866
+ string: stream.current(),
2867
+ className: style || null, // Deprecated, use 'type' instead
2868
+ type: style || null,
2869
+ state: state};
2870
+ },
2871
+
2872
+ getTokenTypeAt: function(pos) {
2873
+ pos = clipPos(this.doc, pos);
2874
+ var styles = getLineStyles(this, getLine(this.doc, pos.line));
2875
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2876
+ if (ch == 0) return styles[2];
2877
+ for (;;) {
2878
+ var mid = (before + after) >> 1;
2879
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
2880
+ else if (styles[mid * 2 + 1] < ch) before = mid + 1;
2881
+ else return styles[mid * 2 + 2];
2882
+ }
2883
+ },
2884
+
2885
+ getModeAt: function(pos) {
2886
+ var mode = this.doc.mode;
2887
+ if (!mode.innerMode) return mode;
2888
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
2889
+ },
2890
+
2891
+ getHelper: function(pos, type) {
2892
+ if (!helpers.hasOwnProperty(type)) return;
2893
+ var help = helpers[type], mode = this.getModeAt(pos);
2894
+ return mode[type] && help[mode[type]] ||
2895
+ mode.helperType && help[mode.helperType] ||
2896
+ help[mode.name];
2897
+ },
2898
+
2899
+ getStateAfter: function(line, precise) {
2900
+ var doc = this.doc;
2901
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
2902
+ return getStateBefore(this, line + 1, precise);
2903
+ },
2904
+
2905
+ cursorCoords: function(start, mode) {
2906
+ var pos, sel = this.doc.sel;
2907
+ if (start == null) pos = sel.head;
2908
+ else if (typeof start == "object") pos = clipPos(this.doc, start);
2909
+ else pos = start ? sel.from : sel.to;
2910
+ return cursorCoords(this, pos, mode || "page");
2911
+ },
2912
+
2913
+ charCoords: function(pos, mode) {
2914
+ return charCoords(this, clipPos(this.doc, pos), mode || "page");
2915
+ },
2916
+
2917
+ coordsChar: function(coords, mode) {
2918
+ coords = fromCoordSystem(this, coords, mode || "page");
2919
+ return coordsChar(this, coords.left, coords.top);
2920
+ },
2921
+
2922
+ lineAtHeight: function(height, mode) {
2923
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
2924
+ return lineAtHeight(this.doc, height + this.display.viewOffset);
2925
+ },
2926
+ heightAtLine: function(line, mode) {
2927
+ var end = false, last = this.doc.first + this.doc.size - 1;
2928
+ if (line < this.doc.first) line = this.doc.first;
2929
+ else if (line > last) { line = last; end = true; }
2930
+ var lineObj = getLine(this.doc, line);
2931
+ return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
2932
+ (end ? lineObj.height : 0);
2933
+ },
2934
+
2935
+ defaultTextHeight: function() { return textHeight(this.display); },
2936
+ defaultCharWidth: function() { return charWidth(this.display); },
2937
+
2938
+ setGutterMarker: operation(null, function(line, gutterID, value) {
2939
+ return changeLine(this, line, function(line) {
2940
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
2941
+ markers[gutterID] = value;
2942
+ if (!value && isEmpty(markers)) line.gutterMarkers = null;
2943
+ return true;
2944
+ });
2945
+ }),
2946
+
2947
+ clearGutter: operation(null, function(gutterID) {
2948
+ var cm = this, doc = cm.doc, i = doc.first;
2949
+ doc.iter(function(line) {
2950
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
2951
+ line.gutterMarkers[gutterID] = null;
2952
+ regChange(cm, i, i + 1);
2953
+ if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
2954
+ }
2955
+ ++i;
2956
+ });
2957
+ }),
2958
+
2959
+ addLineClass: operation(null, function(handle, where, cls) {
2960
+ return changeLine(this, handle, function(line) {
2961
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2962
+ if (!line[prop]) line[prop] = cls;
2963
+ else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
2964
+ else line[prop] += " " + cls;
2965
+ return true;
2966
+ });
2967
+ }),
2968
+
2969
+ removeLineClass: operation(null, function(handle, where, cls) {
2970
+ return changeLine(this, handle, function(line) {
2971
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2972
+ var cur = line[prop];
2973
+ if (!cur) return false;
2974
+ else if (cls == null) line[prop] = null;
2975
+ else {
2976
+ var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
2977
+ if (!found) return false;
2978
+ var end = found.index + found[0].length;
2979
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
2980
+ }
2981
+ return true;
2982
+ });
2983
+ }),
2984
+
2985
+ addLineWidget: operation(null, function(handle, node, options) {
2986
+ return addLineWidget(this, handle, node, options);
2987
+ }),
2988
+
2989
+ removeLineWidget: function(widget) { widget.clear(); },
2990
+
2991
+ lineInfo: function(line) {
2992
+ if (typeof line == "number") {
2993
+ if (!isLine(this.doc, line)) return null;
2994
+ var n = line;
2995
+ line = getLine(this.doc, line);
2996
+ if (!line) return null;
2997
+ } else {
2998
+ var n = lineNo(line);
2999
+ if (n == null) return null;
3000
+ }
3001
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
3002
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
3003
+ widgets: line.widgets};
3004
+ },
3005
+
3006
+ getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
3007
+
3008
+ addWidget: function(pos, node, scroll, vert, horiz) {
3009
+ var display = this.display;
3010
+ pos = cursorCoords(this, clipPos(this.doc, pos));
3011
+ var top = pos.bottom, left = pos.left;
3012
+ node.style.position = "absolute";
3013
+ display.sizer.appendChild(node);
3014
+ if (vert == "over") {
3015
+ top = pos.top;
3016
+ } else if (vert == "above" || vert == "near") {
3017
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
3018
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
3019
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
3020
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
3021
+ top = pos.top - node.offsetHeight;
3022
+ else if (pos.bottom + node.offsetHeight <= vspace)
3023
+ top = pos.bottom;
3024
+ if (left + node.offsetWidth > hspace)
3025
+ left = hspace - node.offsetWidth;
3026
+ }
3027
+ node.style.top = top + "px";
3028
+ node.style.left = node.style.right = "";
3029
+ if (horiz == "right") {
3030
+ left = display.sizer.clientWidth - node.offsetWidth;
3031
+ node.style.right = "0px";
3032
+ } else {
3033
+ if (horiz == "left") left = 0;
3034
+ else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
3035
+ node.style.left = left + "px";
3036
+ }
3037
+ if (scroll)
3038
+ scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
3039
+ },
3040
+
3041
+ triggerOnKeyDown: operation(null, onKeyDown),
3042
+
3043
+ execCommand: function(cmd) {return commands[cmd](this);},
3044
+
3045
+ findPosH: function(from, amount, unit, visually) {
3046
+ var dir = 1;
3047
+ if (amount < 0) { dir = -1; amount = -amount; }
3048
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3049
+ cur = findPosH(this.doc, cur, dir, unit, visually);
3050
+ if (cur.hitSide) break;
3051
+ }
3052
+ return cur;
3053
+ },
3054
+
3055
+ moveH: operation(null, function(dir, unit) {
3056
+ var sel = this.doc.sel, pos;
3057
+ if (sel.shift || sel.extend || posEq(sel.from, sel.to))
3058
+ pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
3059
+ else
3060
+ pos = dir < 0 ? sel.from : sel.to;
3061
+ extendSelection(this.doc, pos, pos, dir);
3062
+ }),
3063
+
3064
+ deleteH: operation(null, function(dir, unit) {
3065
+ var sel = this.doc.sel;
3066
+ if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
3067
+ else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
3068
+ this.curOp.userSelChange = true;
3069
+ }),
3070
+
3071
+ findPosV: function(from, amount, unit, goalColumn) {
3072
+ var dir = 1, x = goalColumn;
3073
+ if (amount < 0) { dir = -1; amount = -amount; }
3074
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3075
+ var coords = cursorCoords(this, cur, "div");
3076
+ if (x == null) x = coords.left;
3077
+ else coords.left = x;
3078
+ cur = findPosV(this, coords, dir, unit);
3079
+ if (cur.hitSide) break;
3080
+ }
3081
+ return cur;
3082
+ },
3083
+
3084
+ moveV: operation(null, function(dir, unit) {
3085
+ var sel = this.doc.sel;
3086
+ var pos = cursorCoords(this, sel.head, "div");
3087
+ if (sel.goalColumn != null) pos.left = sel.goalColumn;
3088
+ var target = findPosV(this, pos, dir, unit);
3089
+
3090
+ if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
3091
+ extendSelection(this.doc, target, target, dir);
3092
+ sel.goalColumn = pos.left;
3093
+ }),
3094
+
3095
+ toggleOverwrite: function(value) {
3096
+ if (value != null && value == this.state.overwrite) return;
3097
+ if (this.state.overwrite = !this.state.overwrite)
3098
+ this.display.cursor.className += " CodeMirror-overwrite";
3099
+ else
3100
+ this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
3101
+ },
3102
+ hasFocus: function() { return this.state.focused; },
3103
+
3104
+ scrollTo: operation(null, function(x, y) {
3105
+ updateScrollPos(this, x, y);
3106
+ }),
3107
+ getScrollInfo: function() {
3108
+ var scroller = this.display.scroller, co = scrollerCutOff;
3109
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
3110
+ height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
3111
+ clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
3112
+ },
3113
+
3114
+ scrollIntoView: operation(null, function(pos, margin) {
3115
+ if (typeof pos == "number") pos = Pos(pos, 0);
3116
+ if (!margin) margin = 0;
3117
+ var coords = pos;
3118
+
3119
+ if (!pos || pos.line != null) {
3120
+ this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
3121
+ this.curOp.scrollToPosMargin = margin;
3122
+ coords = cursorCoords(this, this.curOp.scrollToPos);
3123
+ }
3124
+ var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
3125
+ updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3126
+ }),
3127
+
3128
+ setSize: operation(null, function(width, height) {
3129
+ function interpret(val) {
3130
+ return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3131
+ }
3132
+ if (width != null) this.display.wrapper.style.width = interpret(width);
3133
+ if (height != null) this.display.wrapper.style.height = interpret(height);
3134
+ if (this.options.lineWrapping)
3135
+ this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
3136
+ this.curOp.forceUpdate = true;
3137
+ }),
3138
+
3139
+ operation: function(f){return runInOp(this, f);},
3140
+
3141
+ refresh: operation(null, function() {
3142
+ clearCaches(this);
3143
+ updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
3144
+ regChange(this);
3145
+ }),
3146
+
3147
+ swapDoc: operation(null, function(doc) {
3148
+ var old = this.doc;
3149
+ old.cm = null;
3150
+ attachDoc(this, doc);
3151
+ clearCaches(this);
3152
+ resetInput(this, true);
3153
+ updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
3154
+ return old;
3155
+ }),
3156
+
3157
+ getInputField: function(){return this.display.input;},
3158
+ getWrapperElement: function(){return this.display.wrapper;},
3159
+ getScrollerElement: function(){return this.display.scroller;},
3160
+ getGutterElement: function(){return this.display.gutters;}
3161
+ };
3162
+ eventMixin(CodeMirror);
3163
+
3164
+ // OPTION DEFAULTS
3165
+
3166
+ var optionHandlers = CodeMirror.optionHandlers = {};
3167
+
3168
+ // The default configuration options.
3169
+ var defaults = CodeMirror.defaults = {};
3170
+
3171
+ function option(name, deflt, handle, notOnInit) {
3172
+ CodeMirror.defaults[name] = deflt;
3173
+ if (handle) optionHandlers[name] =
3174
+ notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
3175
+ }
3176
+
3177
+ var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
3178
+
3179
+ // These two are, on init, called from the constructor because they
3180
+ // have to be initialized before the editor can start at all.
3181
+ option("value", "", function(cm, val) {
3182
+ cm.setValue(val);
3183
+ }, true);
3184
+ option("mode", null, function(cm, val) {
3185
+ cm.doc.modeOption = val;
3186
+ loadMode(cm);
3187
+ }, true);
3188
+
3189
+ option("indentUnit", 2, loadMode, true);
3190
+ option("indentWithTabs", false);
3191
+ option("smartIndent", true);
3192
+ option("tabSize", 4, function(cm) {
3193
+ loadMode(cm);
3194
+ clearCaches(cm);
3195
+ regChange(cm);
3196
+ }, true);
3197
+ option("electricChars", true);
3198
+ option("rtlMoveVisually", !windows);
3199
+
3200
+ option("theme", "default", function(cm) {
3201
+ themeChanged(cm);
3202
+ guttersChanged(cm);
3203
+ }, true);
3204
+ option("keyMap", "default", keyMapChanged);
3205
+ option("extraKeys", null);
3206
+
3207
+ option("onKeyEvent", null);
3208
+ option("onDragEvent", null);
3209
+
3210
+ option("lineWrapping", false, wrappingChanged, true);
3211
+ option("gutters", [], function(cm) {
3212
+ setGuttersForLineNumbers(cm.options);
3213
+ guttersChanged(cm);
3214
+ }, true);
3215
+ option("fixedGutter", true, function(cm, val) {
3216
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
3217
+ cm.refresh();
3218
+ }, true);
3219
+ option("coverGutterNextToScrollbar", false, updateScrollbars, true);
3220
+ option("lineNumbers", false, function(cm) {
3221
+ setGuttersForLineNumbers(cm.options);
3222
+ guttersChanged(cm);
3223
+ }, true);
3224
+ option("firstLineNumber", 1, guttersChanged, true);
3225
+ option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
3226
+ option("showCursorWhenSelecting", false, updateSelection, true);
3227
+
3228
+ option("readOnly", false, function(cm, val) {
3229
+ if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
3230
+ else if (!val) resetInput(cm, true);
3231
+ });
3232
+ option("dragDrop", true);
3233
+
3234
+ option("cursorBlinkRate", 530);
3235
+ option("cursorScrollMargin", 0);
3236
+ option("cursorHeight", 1);
3237
+ option("workTime", 100);
3238
+ option("workDelay", 100);
3239
+ option("flattenSpans", true);
3240
+ option("pollInterval", 100);
3241
+ option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
3242
+ option("historyEventDelay", 500);
3243
+ option("viewportMargin", 10, function(cm){cm.refresh();}, true);
3244
+ option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
3245
+ option("moveInputWithCursor", true, function(cm, val) {
3246
+ if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
3247
+ });
3248
+
3249
+ option("tabindex", null, function(cm, val) {
3250
+ cm.display.input.tabIndex = val || "";
3251
+ });
3252
+ option("autofocus", null);
3253
+
3254
+ // MODE DEFINITION AND QUERYING
3255
+
3256
+ // Known modes, by name and by MIME
3257
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
3258
+
3259
+ CodeMirror.defineMode = function(name, mode) {
3260
+ if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
3261
+ if (arguments.length > 2) {
3262
+ mode.dependencies = [];
3263
+ for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
3264
+ }
3265
+ modes[name] = mode;
3266
+ };
3267
+
3268
+ CodeMirror.defineMIME = function(mime, spec) {
3269
+ mimeModes[mime] = spec;
3270
+ };
3271
+
3272
+ CodeMirror.resolveMode = function(spec) {
3273
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3274
+ spec = mimeModes[spec];
3275
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3276
+ var found = mimeModes[spec.name];
3277
+ spec = createObj(found, spec);
3278
+ spec.name = found.name;
3279
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3280
+ return CodeMirror.resolveMode("application/xml");
3281
+ }
3282
+ if (typeof spec == "string") return {name: spec};
3283
+ else return spec || {name: "null"};
3284
+ };
3285
+
3286
+ CodeMirror.getMode = function(options, spec) {
3287
+ var spec = CodeMirror.resolveMode(spec);
3288
+ var mfactory = modes[spec.name];
3289
+ if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3290
+ var modeObj = mfactory(options, spec);
3291
+ if (modeExtensions.hasOwnProperty(spec.name)) {
3292
+ var exts = modeExtensions[spec.name];
3293
+ for (var prop in exts) {
3294
+ if (!exts.hasOwnProperty(prop)) continue;
3295
+ if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
3296
+ modeObj[prop] = exts[prop];
3297
+ }
3298
+ }
3299
+ modeObj.name = spec.name;
3300
+
3301
+ return modeObj;
3302
+ };
3303
+
3304
+ CodeMirror.defineMode("null", function() {
3305
+ return {token: function(stream) {stream.skipToEnd();}};
3306
+ });
3307
+ CodeMirror.defineMIME("text/plain", "null");
3308
+
3309
+ var modeExtensions = CodeMirror.modeExtensions = {};
3310
+ CodeMirror.extendMode = function(mode, properties) {
3311
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3312
+ copyObj(properties, exts);
3313
+ };
3314
+
3315
+ // EXTENSIONS
3316
+
3317
+ CodeMirror.defineExtension = function(name, func) {
3318
+ CodeMirror.prototype[name] = func;
3319
+ };
3320
+ CodeMirror.defineDocExtension = function(name, func) {
3321
+ Doc.prototype[name] = func;
3322
+ };
3323
+ CodeMirror.defineOption = option;
3324
+
3325
+ var initHooks = [];
3326
+ CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3327
+
3328
+ var helpers = CodeMirror.helpers = {};
3329
+ CodeMirror.registerHelper = function(type, name, value) {
3330
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
3331
+ helpers[type][name] = value;
3332
+ };
3333
+
3334
+ // UTILITIES
3335
+
3336
+ CodeMirror.isWordChar = isWordChar;
3337
+
3338
+ // MODE STATE HANDLING
3339
+
3340
+ // Utility functions for working with state. Exported because modes
3341
+ // sometimes need to do this.
3342
+ function copyState(mode, state) {
3343
+ if (state === true) return state;
3344
+ if (mode.copyState) return mode.copyState(state);
3345
+ var nstate = {};
3346
+ for (var n in state) {
3347
+ var val = state[n];
3348
+ if (val instanceof Array) val = val.concat([]);
3349
+ nstate[n] = val;
3350
+ }
3351
+ return nstate;
3352
+ }
3353
+ CodeMirror.copyState = copyState;
3354
+
3355
+ function startState(mode, a1, a2) {
3356
+ return mode.startState ? mode.startState(a1, a2) : true;
3357
+ }
3358
+ CodeMirror.startState = startState;
3359
+
3360
+ CodeMirror.innerMode = function(mode, state) {
3361
+ while (mode.innerMode) {
3362
+ var info = mode.innerMode(state);
3363
+ if (!info || info.mode == mode) break;
3364
+ state = info.state;
3365
+ mode = info.mode;
3366
+ }
3367
+ return info || {mode: mode, state: state};
3368
+ };
3369
+
3370
+ // STANDARD COMMANDS
3371
+
3372
+ var commands = CodeMirror.commands = {
3373
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
3374
+ killLine: function(cm) {
3375
+ var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
3376
+ if (!sel && cm.getLine(from.line).length == from.ch)
3377
+ cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
3378
+ else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
3379
+ },
3380
+ deleteLine: function(cm) {
3381
+ var l = cm.getCursor().line;
3382
+ cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
3383
+ },
3384
+ delLineLeft: function(cm) {
3385
+ var cur = cm.getCursor();
3386
+ cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
3387
+ },
3388
+ undo: function(cm) {cm.undo();},
3389
+ redo: function(cm) {cm.redo();},
3390
+ goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
3391
+ goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
3392
+ goLineStart: function(cm) {
3393
+ cm.extendSelection(lineStart(cm, cm.getCursor().line));
3394
+ },
3395
+ goLineStartSmart: function(cm) {
3396
+ var cur = cm.getCursor(), start = lineStart(cm, cur.line);
3397
+ var line = cm.getLineHandle(start.line);
3398
+ var order = getOrder(line);
3399
+ if (!order || order[0].level == 0) {
3400
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
3401
+ var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
3402
+ cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
3403
+ } else cm.extendSelection(start);
3404
+ },
3405
+ goLineEnd: function(cm) {
3406
+ cm.extendSelection(lineEnd(cm, cm.getCursor().line));
3407
+ },
3408
+ goLineRight: function(cm) {
3409
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3410
+ cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
3411
+ },
3412
+ goLineLeft: function(cm) {
3413
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3414
+ cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
3415
+ },
3416
+ goLineUp: function(cm) {cm.moveV(-1, "line");},
3417
+ goLineDown: function(cm) {cm.moveV(1, "line");},
3418
+ goPageUp: function(cm) {cm.moveV(-1, "page");},
3419
+ goPageDown: function(cm) {cm.moveV(1, "page");},
3420
+ goCharLeft: function(cm) {cm.moveH(-1, "char");},
3421
+ goCharRight: function(cm) {cm.moveH(1, "char");},
3422
+ goColumnLeft: function(cm) {cm.moveH(-1, "column");},
3423
+ goColumnRight: function(cm) {cm.moveH(1, "column");},
3424
+ goWordLeft: function(cm) {cm.moveH(-1, "word");},
3425
+ goGroupRight: function(cm) {cm.moveH(1, "group");},
3426
+ goGroupLeft: function(cm) {cm.moveH(-1, "group");},
3427
+ goWordRight: function(cm) {cm.moveH(1, "word");},
3428
+ delCharBefore: function(cm) {cm.deleteH(-1, "char");},
3429
+ delCharAfter: function(cm) {cm.deleteH(1, "char");},
3430
+ delWordBefore: function(cm) {cm.deleteH(-1, "word");},
3431
+ delWordAfter: function(cm) {cm.deleteH(1, "word");},
3432
+ delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
3433
+ delGroupAfter: function(cm) {cm.deleteH(1, "group");},
3434
+ indentAuto: function(cm) {cm.indentSelection("smart");},
3435
+ indentMore: function(cm) {cm.indentSelection("add");},
3436
+ indentLess: function(cm) {cm.indentSelection("subtract");},
3437
+ insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
3438
+ defaultTab: function(cm) {
3439
+ if (cm.somethingSelected()) cm.indentSelection("add");
3440
+ else cm.replaceSelection("\t", "end", "+input");
3441
+ },
3442
+ transposeChars: function(cm) {
3443
+ var cur = cm.getCursor(), line = cm.getLine(cur.line);
3444
+ if (cur.ch > 0 && cur.ch < line.length - 1)
3445
+ cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
3446
+ Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
3447
+ },
3448
+ newlineAndIndent: function(cm) {
3449
+ operation(cm, function() {
3450
+ cm.replaceSelection("\n", "end", "+input");
3451
+ cm.indentLine(cm.getCursor().line, null, true);
3452
+ })();
3453
+ },
3454
+ toggleOverwrite: function(cm) {cm.toggleOverwrite();}
3455
+ };
3456
+
3457
+ // STANDARD KEYMAPS
3458
+
3459
+ var keyMap = CodeMirror.keyMap = {};
3460
+ keyMap.basic = {
3461
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
3462
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
3463
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
3464
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
3465
+ };
3466
+ // Note that the save and find-related commands aren't defined by
3467
+ // default. Unknown commands are simply ignored.
3468
+ keyMap.pcDefault = {
3469
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
3470
+ "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
3471
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
3472
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
3473
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
3474
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
3475
+ fallthrough: "basic"
3476
+ };
3477
+ keyMap.macDefault = {
3478
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
3479
+ "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
3480
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
3481
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
3482
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
3483
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
3484
+ fallthrough: ["basic", "emacsy"]
3485
+ };
3486
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
3487
+ keyMap.emacsy = {
3488
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
3489
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
3490
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
3491
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
3492
+ };
3493
+
3494
+ // KEYMAP DISPATCH
3495
+
3496
+ function getKeyMap(val) {
3497
+ if (typeof val == "string") return keyMap[val];
3498
+ else return val;
3499
+ }
3500
+
3501
+ function lookupKey(name, maps, handle) {
3502
+ function lookup(map) {
3503
+ map = getKeyMap(map);
3504
+ var found = map[name];
3505
+ if (found === false) return "stop";
3506
+ if (found != null && handle(found)) return true;
3507
+ if (map.nofallthrough) return "stop";
3508
+
3509
+ var fallthrough = map.fallthrough;
3510
+ if (fallthrough == null) return false;
3511
+ if (Object.prototype.toString.call(fallthrough) != "[object Array]")
3512
+ return lookup(fallthrough);
3513
+ for (var i = 0, e = fallthrough.length; i < e; ++i) {
3514
+ var done = lookup(fallthrough[i]);
3515
+ if (done) return done;
3516
+ }
3517
+ return false;
3518
+ }
3519
+
3520
+ for (var i = 0; i < maps.length; ++i) {
3521
+ var done = lookup(maps[i]);
3522
+ if (done) return done != "stop";
3523
+ }
3524
+ }
3525
+ function isModifierKey(event) {
3526
+ var name = keyNames[event.keyCode];
3527
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
3528
+ }
3529
+ function keyName(event, noShift) {
3530
+ if (opera && event.keyCode == 34 && event["char"]) return false;
3531
+ var name = keyNames[event.keyCode];
3532
+ if (name == null || event.altGraphKey) return false;
3533
+ if (event.altKey) name = "Alt-" + name;
3534
+ if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
3535
+ if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
3536
+ if (!noShift && event.shiftKey) name = "Shift-" + name;
3537
+ return name;
3538
+ }
3539
+ CodeMirror.lookupKey = lookupKey;
3540
+ CodeMirror.isModifierKey = isModifierKey;
3541
+ CodeMirror.keyName = keyName;
3542
+
3543
+ // FROMTEXTAREA
3544
+
3545
+ CodeMirror.fromTextArea = function(textarea, options) {
3546
+ if (!options) options = {};
3547
+ options.value = textarea.value;
3548
+ if (!options.tabindex && textarea.tabindex)
3549
+ options.tabindex = textarea.tabindex;
3550
+ if (!options.placeholder && textarea.placeholder)
3551
+ options.placeholder = textarea.placeholder;
3552
+ // Set autofocus to true if this textarea is focused, or if it has
3553
+ // autofocus and no other element is focused.
3554
+ if (options.autofocus == null) {
3555
+ var hasFocus = document.body;
3556
+ // doc.activeElement occasionally throws on IE
3557
+ try { hasFocus = document.activeElement; } catch(e) {}
3558
+ options.autofocus = hasFocus == textarea ||
3559
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body;
3560
+ }
3561
+
3562
+ function save() {textarea.value = cm.getValue();}
3563
+ if (textarea.form) {
3564
+ on(textarea.form, "submit", save);
3565
+ // Deplorable hack to make the submit method do the right thing.
3566
+ if (!options.leaveSubmitMethodAlone) {
3567
+ var form = textarea.form, realSubmit = form.submit;
3568
+ try {
3569
+ var wrappedSubmit = form.submit = function() {
3570
+ save();
3571
+ form.submit = realSubmit;
3572
+ form.submit();
3573
+ form.submit = wrappedSubmit;
3574
+ };
3575
+ } catch(e) {}
3576
+ }
3577
+ }
3578
+
3579
+ textarea.style.display = "none";
3580
+ var cm = CodeMirror(function(node) {
3581
+ textarea.parentNode.insertBefore(node, textarea.nextSibling);
3582
+ }, options);
3583
+ cm.save = save;
3584
+ cm.getTextArea = function() { return textarea; };
3585
+ cm.toTextArea = function() {
3586
+ save();
3587
+ textarea.parentNode.removeChild(cm.getWrapperElement());
3588
+ textarea.style.display = "";
3589
+ if (textarea.form) {
3590
+ off(textarea.form, "submit", save);
3591
+ if (typeof textarea.form.submit == "function")
3592
+ textarea.form.submit = realSubmit;
3593
+ }
3594
+ };
3595
+ return cm;
3596
+ };
3597
+
3598
+ // STRING STREAM
3599
+
3600
+ // Fed to the mode parsers, provides helper functions to make
3601
+ // parsers more succinct.
3602
+
3603
+ // The character stream used by a mode's parser.
3604
+ function StringStream(string, tabSize) {
3605
+ this.pos = this.start = 0;
3606
+ this.string = string;
3607
+ this.tabSize = tabSize || 8;
3608
+ this.lastColumnPos = this.lastColumnValue = 0;
3609
+ }
3610
+
3611
+ StringStream.prototype = {
3612
+ eol: function() {return this.pos >= this.string.length;},
3613
+ sol: function() {return this.pos == 0;},
3614
+ peek: function() {return this.string.charAt(this.pos) || undefined;},
3615
+ next: function() {
3616
+ if (this.pos < this.string.length)
3617
+ return this.string.charAt(this.pos++);
3618
+ },
3619
+ eat: function(match) {
3620
+ var ch = this.string.charAt(this.pos);
3621
+ if (typeof match == "string") var ok = ch == match;
3622
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
3623
+ if (ok) {++this.pos; return ch;}
3624
+ },
3625
+ eatWhile: function(match) {
3626
+ var start = this.pos;
3627
+ while (this.eat(match)){}
3628
+ return this.pos > start;
3629
+ },
3630
+ eatSpace: function() {
3631
+ var start = this.pos;
3632
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
3633
+ return this.pos > start;
3634
+ },
3635
+ skipToEnd: function() {this.pos = this.string.length;},
3636
+ skipTo: function(ch) {
3637
+ var found = this.string.indexOf(ch, this.pos);
3638
+ if (found > -1) {this.pos = found; return true;}
3639
+ },
3640
+ backUp: function(n) {this.pos -= n;},
3641
+ column: function() {
3642
+ if (this.lastColumnPos < this.start) {
3643
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3644
+ this.lastColumnPos = this.start;
3645
+ }
3646
+ return this.lastColumnValue;
3647
+ },
3648
+ indentation: function() {return countColumn(this.string, null, this.tabSize);},
3649
+ match: function(pattern, consume, caseInsensitive) {
3650
+ if (typeof pattern == "string") {
3651
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
3652
+ var substr = this.string.substr(this.pos, pattern.length);
3653
+ if (cased(substr) == cased(pattern)) {
3654
+ if (consume !== false) this.pos += pattern.length;
3655
+ return true;
3656
+ }
3657
+ } else {
3658
+ var match = this.string.slice(this.pos).match(pattern);
3659
+ if (match && match.index > 0) return null;
3660
+ if (match && consume !== false) this.pos += match[0].length;
3661
+ return match;
3662
+ }
3663
+ },
3664
+ current: function(){return this.string.slice(this.start, this.pos);}
3665
+ };
3666
+ CodeMirror.StringStream = StringStream;
3667
+
3668
+ // TEXTMARKERS
3669
+
3670
+ function TextMarker(doc, type) {
3671
+ this.lines = [];
3672
+ this.type = type;
3673
+ this.doc = doc;
3674
+ }
3675
+ CodeMirror.TextMarker = TextMarker;
3676
+ eventMixin(TextMarker);
3677
+
3678
+ TextMarker.prototype.clear = function() {
3679
+ if (this.explicitlyCleared) return;
3680
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
3681
+ if (withOp) startOperation(cm);
3682
+ if (hasHandler(this, "clear")) {
3683
+ var found = this.find();
3684
+ if (found) signalLater(this, "clear", found.from, found.to);
3685
+ }
3686
+ var min = null, max = null;
3687
+ for (var i = 0; i < this.lines.length; ++i) {
3688
+ var line = this.lines[i];
3689
+ var span = getMarkedSpanFor(line.markedSpans, this);
3690
+ if (span.to != null) max = lineNo(line);
3691
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
3692
+ if (span.from != null)
3693
+ min = lineNo(line);
3694
+ else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
3695
+ updateLineHeight(line, textHeight(cm.display));
3696
+ }
3697
+ if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
3698
+ var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
3699
+ if (len > cm.display.maxLineLength) {
3700
+ cm.display.maxLine = visual;
3701
+ cm.display.maxLineLength = len;
3702
+ cm.display.maxLineChanged = true;
3703
+ }
3704
+ }
3705
+
3706
+ if (min != null && cm) regChange(cm, min, max + 1);
3707
+ this.lines.length = 0;
3708
+ this.explicitlyCleared = true;
3709
+ if (this.atomic && this.doc.cantEdit) {
3710
+ this.doc.cantEdit = false;
3711
+ if (cm) reCheckSelection(cm);
3712
+ }
3713
+ if (withOp) endOperation(cm);
3714
+ };
3715
+
3716
+ TextMarker.prototype.find = function() {
3717
+ var from, to;
3718
+ for (var i = 0; i < this.lines.length; ++i) {
3719
+ var line = this.lines[i];
3720
+ var span = getMarkedSpanFor(line.markedSpans, this);
3721
+ if (span.from != null || span.to != null) {
3722
+ var found = lineNo(line);
3723
+ if (span.from != null) from = Pos(found, span.from);
3724
+ if (span.to != null) to = Pos(found, span.to);
3725
+ }
3726
+ }
3727
+ if (this.type == "bookmark") return from;
3728
+ return from && {from: from, to: to};
3729
+ };
3730
+
3731
+ TextMarker.prototype.changed = function() {
3732
+ var pos = this.find(), cm = this.doc.cm;
3733
+ if (!pos || !cm) return;
3734
+ var line = getLine(this.doc, pos.from.line);
3735
+ clearCachedMeasurement(cm, line);
3736
+ if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
3737
+ for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
3738
+ if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3739
+ break;
3740
+ }
3741
+ runInOp(cm, function() {
3742
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
3743
+ });
3744
+ }
3745
+ };
3746
+
3747
+ TextMarker.prototype.attachLine = function(line) {
3748
+ if (!this.lines.length && this.doc.cm) {
3749
+ var op = this.doc.cm.curOp;
3750
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
3751
+ (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
3752
+ }
3753
+ this.lines.push(line);
3754
+ };
3755
+ TextMarker.prototype.detachLine = function(line) {
3756
+ this.lines.splice(indexOf(this.lines, line), 1);
3757
+ if (!this.lines.length && this.doc.cm) {
3758
+ var op = this.doc.cm.curOp;
3759
+ (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
3760
+ }
3761
+ };
3762
+
3763
+ function markText(doc, from, to, options, type) {
3764
+ if (options && options.shared) return markTextShared(doc, from, to, options, type);
3765
+ if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3766
+
3767
+ var marker = new TextMarker(doc, type);
3768
+ if (type == "range" && !posLess(from, to)) return marker;
3769
+ if (options) copyObj(options, marker);
3770
+ if (marker.replacedWith) {
3771
+ marker.collapsed = true;
3772
+ marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
3773
+ if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
3774
+ }
3775
+ if (marker.collapsed) sawCollapsedSpans = true;
3776
+
3777
+ if (marker.addToHistory)
3778
+ addToHistory(doc, {from: from, to: to, origin: "markText"},
3779
+ {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
3780
+
3781
+ var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
3782
+ doc.iter(curLine, to.line + 1, function(line) {
3783
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
3784
+ updateMaxLine = true;
3785
+ var span = {from: null, to: null, marker: marker};
3786
+ size += line.text.length;
3787
+ if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
3788
+ if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
3789
+ if (marker.collapsed) {
3790
+ if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
3791
+ if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
3792
+ else updateLineHeight(line, 0);
3793
+ }
3794
+ addMarkedSpan(line, span);
3795
+ ++curLine;
3796
+ });
3797
+ if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
3798
+ if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
3799
+ });
3800
+
3801
+ if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
3802
+
3803
+ if (marker.readOnly) {
3804
+ sawReadOnlySpans = true;
3805
+ if (doc.history.done.length || doc.history.undone.length)
3806
+ doc.clearHistory();
3807
+ }
3808
+ if (marker.collapsed) {
3809
+ if (collapsedAtStart != collapsedAtEnd)
3810
+ throw new Error("Inserting collapsed marker overlapping an existing one");
3811
+ marker.size = size;
3812
+ marker.atomic = true;
3813
+ }
3814
+ if (cm) {
3815
+ if (updateMaxLine) cm.curOp.updateMaxLine = true;
3816
+ if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
3817
+ regChange(cm, from.line, to.line + 1);
3818
+ if (marker.atomic) reCheckSelection(cm);
3819
+ }
3820
+ return marker;
3821
+ }
3822
+
3823
+ // SHARED TEXTMARKERS
3824
+
3825
+ function SharedTextMarker(markers, primary) {
3826
+ this.markers = markers;
3827
+ this.primary = primary;
3828
+ for (var i = 0, me = this; i < markers.length; ++i) {
3829
+ markers[i].parent = this;
3830
+ on(markers[i], "clear", function(){me.clear();});
3831
+ }
3832
+ }
3833
+ CodeMirror.SharedTextMarker = SharedTextMarker;
3834
+ eventMixin(SharedTextMarker);
3835
+
3836
+ SharedTextMarker.prototype.clear = function() {
3837
+ if (this.explicitlyCleared) return;
3838
+ this.explicitlyCleared = true;
3839
+ for (var i = 0; i < this.markers.length; ++i)
3840
+ this.markers[i].clear();
3841
+ signalLater(this, "clear");
3842
+ };
3843
+ SharedTextMarker.prototype.find = function() {
3844
+ return this.primary.find();
3845
+ };
3846
+
3847
+ function markTextShared(doc, from, to, options, type) {
3848
+ options = copyObj(options);
3849
+ options.shared = false;
3850
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
3851
+ var widget = options.replacedWith;
3852
+ linkedDocs(doc, function(doc) {
3853
+ if (widget) options.replacedWith = widget.cloneNode(true);
3854
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
3855
+ for (var i = 0; i < doc.linked.length; ++i)
3856
+ if (doc.linked[i].isParent) return;
3857
+ primary = lst(markers);
3858
+ });
3859
+ return new SharedTextMarker(markers, primary);
3860
+ }
3861
+
3862
+ // TEXTMARKER SPANS
3863
+
3864
+ function getMarkedSpanFor(spans, marker) {
3865
+ if (spans) for (var i = 0; i < spans.length; ++i) {
3866
+ var span = spans[i];
3867
+ if (span.marker == marker) return span;
3868
+ }
3869
+ }
3870
+ function removeMarkedSpan(spans, span) {
3871
+ for (var r, i = 0; i < spans.length; ++i)
3872
+ if (spans[i] != span) (r || (r = [])).push(spans[i]);
3873
+ return r;
3874
+ }
3875
+ function addMarkedSpan(line, span) {
3876
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
3877
+ span.marker.attachLine(line);
3878
+ }
3879
+
3880
+ function markedSpansBefore(old, startCh, isInsert) {
3881
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3882
+ var span = old[i], marker = span.marker;
3883
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3884
+ if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3885
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3886
+ (nw || (nw = [])).push({from: span.from,
3887
+ to: endsAfter ? null : span.to,
3888
+ marker: marker});
3889
+ }
3890
+ }
3891
+ return nw;
3892
+ }
3893
+
3894
+ function markedSpansAfter(old, endCh, isInsert) {
3895
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3896
+ var span = old[i], marker = span.marker;
3897
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
3898
+ if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
3899
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
3900
+ (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
3901
+ to: span.to == null ? null : span.to - endCh,
3902
+ marker: marker});
3903
+ }
3904
+ }
3905
+ return nw;
3906
+ }
3907
+
3908
+ function stretchSpansOverChange(doc, change) {
3909
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
3910
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
3911
+ if (!oldFirst && !oldLast) return null;
3912
+
3913
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
3914
+ // Get the spans that 'stick out' on both sides
3915
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
3916
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
3917
+
3918
+ // Next, merge those two ends
3919
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
3920
+ if (first) {
3921
+ // Fix up .to properties of first
3922
+ for (var i = 0; i < first.length; ++i) {
3923
+ var span = first[i];
3924
+ if (span.to == null) {
3925
+ var found = getMarkedSpanFor(last, span.marker);
3926
+ if (!found) span.to = startCh;
3927
+ else if (sameLine) span.to = found.to == null ? null : found.to + offset;
3928
+ }
3929
+ }
3930
+ }
3931
+ if (last) {
3932
+ // Fix up .from in last (or move them into first in case of sameLine)
3933
+ for (var i = 0; i < last.length; ++i) {
3934
+ var span = last[i];
3935
+ if (span.to != null) span.to += offset;
3936
+ if (span.from == null) {
3937
+ var found = getMarkedSpanFor(first, span.marker);
3938
+ if (!found) {
3939
+ span.from = offset;
3940
+ if (sameLine) (first || (first = [])).push(span);
3941
+ }
3942
+ } else {
3943
+ span.from += offset;
3944
+ if (sameLine) (first || (first = [])).push(span);
3945
+ }
3946
+ }
3947
+ }
3948
+ if (sameLine && first) {
3949
+ // Make sure we didn't create any zero-length spans
3950
+ for (var i = 0; i < first.length; ++i)
3951
+ if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
3952
+ first.splice(i--, 1);
3953
+ if (!first.length) first = null;
3954
+ }
3955
+
3956
+ var newMarkers = [first];
3957
+ if (!sameLine) {
3958
+ // Fill gap with whole-line-spans
3959
+ var gap = change.text.length - 2, gapMarkers;
3960
+ if (gap > 0 && first)
3961
+ for (var i = 0; i < first.length; ++i)
3962
+ if (first[i].to == null)
3963
+ (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
3964
+ for (var i = 0; i < gap; ++i)
3965
+ newMarkers.push(gapMarkers);
3966
+ newMarkers.push(last);
3967
+ }
3968
+ return newMarkers;
3969
+ }
3970
+
3971
+ function mergeOldSpans(doc, change) {
3972
+ var old = getOldSpans(doc, change);
3973
+ var stretched = stretchSpansOverChange(doc, change);
3974
+ if (!old) return stretched;
3975
+ if (!stretched) return old;
3976
+
3977
+ for (var i = 0; i < old.length; ++i) {
3978
+ var oldCur = old[i], stretchCur = stretched[i];
3979
+ if (oldCur && stretchCur) {
3980
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
3981
+ var span = stretchCur[j];
3982
+ for (var k = 0; k < oldCur.length; ++k)
3983
+ if (oldCur[k].marker == span.marker) continue spans;
3984
+ oldCur.push(span);
3985
+ }
3986
+ } else if (stretchCur) {
3987
+ old[i] = stretchCur;
3988
+ }
3989
+ }
3990
+ return old;
3991
+ }
3992
+
3993
+ function removeReadOnlyRanges(doc, from, to) {
3994
+ var markers = null;
3995
+ doc.iter(from.line, to.line + 1, function(line) {
3996
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
3997
+ var mark = line.markedSpans[i].marker;
3998
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
3999
+ (markers || (markers = [])).push(mark);
4000
+ }
4001
+ });
4002
+ if (!markers) return null;
4003
+ var parts = [{from: from, to: to}];
4004
+ for (var i = 0; i < markers.length; ++i) {
4005
+ var mk = markers[i], m = mk.find();
4006
+ for (var j = 0; j < parts.length; ++j) {
4007
+ var p = parts[j];
4008
+ if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
4009
+ var newParts = [j, 1];
4010
+ if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
4011
+ newParts.push({from: p.from, to: m.from});
4012
+ if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
4013
+ newParts.push({from: m.to, to: p.to});
4014
+ parts.splice.apply(parts, newParts);
4015
+ j += newParts.length - 1;
4016
+ }
4017
+ }
4018
+ return parts;
4019
+ }
4020
+
4021
+ function collapsedSpanAt(line, ch) {
4022
+ var sps = sawCollapsedSpans && line.markedSpans, found;
4023
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4024
+ sp = sps[i];
4025
+ if (!sp.marker.collapsed) continue;
4026
+ if ((sp.from == null || sp.from < ch) &&
4027
+ (sp.to == null || sp.to > ch) &&
4028
+ (!found || found.width < sp.marker.width))
4029
+ found = sp.marker;
4030
+ }
4031
+ return found;
4032
+ }
4033
+ function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
4034
+ function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
4035
+
4036
+ function visualLine(doc, line) {
4037
+ var merged;
4038
+ while (merged = collapsedSpanAtStart(line))
4039
+ line = getLine(doc, merged.find().from.line);
4040
+ return line;
4041
+ }
4042
+
4043
+ function lineIsHidden(doc, line) {
4044
+ var sps = sawCollapsedSpans && line.markedSpans;
4045
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4046
+ sp = sps[i];
4047
+ if (!sp.marker.collapsed) continue;
4048
+ if (sp.from == null) return true;
4049
+ if (sp.marker.replacedWith) continue;
4050
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
4051
+ return true;
4052
+ }
4053
+ }
4054
+ function lineIsHiddenInner(doc, line, span) {
4055
+ if (span.to == null) {
4056
+ var end = span.marker.find().to, endLine = getLine(doc, end.line);
4057
+ return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
4058
+ }
4059
+ if (span.marker.inclusiveRight && span.to == line.text.length)
4060
+ return true;
4061
+ for (var sp, i = 0; i < line.markedSpans.length; ++i) {
4062
+ sp = line.markedSpans[i];
4063
+ if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
4064
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
4065
+ lineIsHiddenInner(doc, line, sp)) return true;
4066
+ }
4067
+ }
4068
+
4069
+ function detachMarkedSpans(line) {
4070
+ var spans = line.markedSpans;
4071
+ if (!spans) return;
4072
+ for (var i = 0; i < spans.length; ++i)
4073
+ spans[i].marker.detachLine(line);
4074
+ line.markedSpans = null;
4075
+ }
4076
+
4077
+ function attachMarkedSpans(line, spans) {
4078
+ if (!spans) return;
4079
+ for (var i = 0; i < spans.length; ++i)
4080
+ spans[i].marker.attachLine(line);
4081
+ line.markedSpans = spans;
4082
+ }
4083
+
4084
+ // LINE WIDGETS
4085
+
4086
+ var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4087
+ if (options) for (var opt in options) if (options.hasOwnProperty(opt))
4088
+ this[opt] = options[opt];
4089
+ this.cm = cm;
4090
+ this.node = node;
4091
+ };
4092
+ eventMixin(LineWidget);
4093
+ function widgetOperation(f) {
4094
+ return function() {
4095
+ var withOp = !this.cm.curOp;
4096
+ if (withOp) startOperation(this.cm);
4097
+ try {var result = f.apply(this, arguments);}
4098
+ finally {if (withOp) endOperation(this.cm);}
4099
+ return result;
4100
+ };
4101
+ }
4102
+ LineWidget.prototype.clear = widgetOperation(function() {
4103
+ var ws = this.line.widgets, no = lineNo(this.line);
4104
+ if (no == null || !ws) return;
4105
+ for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4106
+ if (!ws.length) this.line.widgets = null;
4107
+ var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4108
+ updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4109
+ if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4110
+ regChange(this.cm, no, no + 1);
4111
+ });
4112
+ LineWidget.prototype.changed = widgetOperation(function() {
4113
+ var oldH = this.height;
4114
+ this.height = null;
4115
+ var diff = widgetHeight(this) - oldH;
4116
+ if (!diff) return;
4117
+ updateLineHeight(this.line, this.line.height + diff);
4118
+ var no = lineNo(this.line);
4119
+ regChange(this.cm, no, no + 1);
4120
+ });
4121
+
4122
+ function widgetHeight(widget) {
4123
+ if (widget.height != null) return widget.height;
4124
+ if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
4125
+ removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
4126
+ return widget.height = widget.node.offsetHeight;
4127
+ }
4128
+
4129
+ function addLineWidget(cm, handle, node, options) {
4130
+ var widget = new LineWidget(cm, node, options);
4131
+ if (widget.noHScroll) cm.display.alignWidgets = true;
4132
+ changeLine(cm, handle, function(line) {
4133
+ var widgets = line.widgets || (line.widgets = []);
4134
+ if (widget.insertAt == null) widgets.push(widget);
4135
+ else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
4136
+ widget.line = line;
4137
+ if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4138
+ var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
4139
+ updateLineHeight(line, line.height + widgetHeight(widget));
4140
+ if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4141
+ }
4142
+ return true;
4143
+ });
4144
+ return widget;
4145
+ }
4146
+
4147
+ // LINE DATA STRUCTURE
4148
+
4149
+ // Line objects. These hold state related to a line, including
4150
+ // highlighting info (the styles array).
4151
+ var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
4152
+ this.text = text;
4153
+ attachMarkedSpans(this, markedSpans);
4154
+ this.height = estimateHeight ? estimateHeight(this) : 1;
4155
+ };
4156
+ eventMixin(Line);
4157
+
4158
+ function updateLine(line, text, markedSpans, estimateHeight) {
4159
+ line.text = text;
4160
+ if (line.stateAfter) line.stateAfter = null;
4161
+ if (line.styles) line.styles = null;
4162
+ if (line.order != null) line.order = null;
4163
+ detachMarkedSpans(line);
4164
+ attachMarkedSpans(line, markedSpans);
4165
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
4166
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
4167
+ }
4168
+
4169
+ function cleanUpLine(line) {
4170
+ line.parent = null;
4171
+ detachMarkedSpans(line);
4172
+ }
4173
+
4174
+ // Run the given mode's parser over a line, update the styles
4175
+ // array, which contains alternating fragments of text and CSS
4176
+ // classes.
4177
+ function runMode(cm, text, mode, state, f) {
4178
+ var flattenSpans = mode.flattenSpans;
4179
+ if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
4180
+ var curStart = 0, curStyle = null;
4181
+ var stream = new StringStream(text, cm.options.tabSize), style;
4182
+ if (text == "" && mode.blankLine) mode.blankLine(state);
4183
+ while (!stream.eol()) {
4184
+ if (stream.pos > cm.options.maxHighlightLength) {
4185
+ flattenSpans = false;
4186
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
4187
+ stream.pos = Math.min(text.length, stream.start + 50000);
4188
+ style = null;
4189
+ } else {
4190
+ style = mode.token(stream, state);
4191
+ }
4192
+ if (!flattenSpans || curStyle != style) {
4193
+ if (curStart < stream.start) f(stream.start, curStyle);
4194
+ curStart = stream.start; curStyle = style;
4195
+ }
4196
+ stream.start = stream.pos;
4197
+ }
4198
+ if (curStart < stream.pos) f(stream.pos, curStyle);
4199
+ }
4200
+
4201
+ function highlightLine(cm, line, state) {
4202
+ // A styles array always starts with a number identifying the
4203
+ // mode/overlays that it is based on (for easy invalidation).
4204
+ var st = [cm.state.modeGen];
4205
+ // Compute the base array of styles
4206
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
4207
+
4208
+ // Run overlays, adjust style array.
4209
+ for (var o = 0; o < cm.state.overlays.length; ++o) {
4210
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
4211
+ runMode(cm, line.text, overlay.mode, true, function(end, style) {
4212
+ var start = i;
4213
+ // Ensure there's a token end at the current position, and that i points at it
4214
+ while (at < end) {
4215
+ var i_end = st[i];
4216
+ if (i_end > end)
4217
+ st.splice(i, 1, end, st[i+1], i_end);
4218
+ i += 2;
4219
+ at = Math.min(end, i_end);
4220
+ }
4221
+ if (!style) return;
4222
+ if (overlay.opaque) {
4223
+ st.splice(start, i - start, end, style);
4224
+ i = start + 2;
4225
+ } else {
4226
+ for (; start < i; start += 2) {
4227
+ var cur = st[start+1];
4228
+ st[start+1] = cur ? cur + " " + style : style;
4229
+ }
4230
+ }
4231
+ });
4232
+ }
4233
+
4234
+ return st;
4235
+ }
4236
+
4237
+ function getLineStyles(cm, line) {
4238
+ if (!line.styles || line.styles[0] != cm.state.modeGen)
4239
+ line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
4240
+ return line.styles;
4241
+ }
4242
+
4243
+ // Lightweight form of highlight -- proceed over this line and
4244
+ // update state, but don't save a style array.
4245
+ function processLine(cm, line, state) {
4246
+ var mode = cm.doc.mode;
4247
+ var stream = new StringStream(line.text, cm.options.tabSize);
4248
+ if (line.text == "" && mode.blankLine) mode.blankLine(state);
4249
+ while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
4250
+ mode.token(stream, state);
4251
+ stream.start = stream.pos;
4252
+ }
4253
+ }
4254
+
4255
+ var styleToClassCache = {};
4256
+ function styleToClass(style) {
4257
+ if (!style) return null;
4258
+ return styleToClassCache[style] ||
4259
+ (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4260
+ }
4261
+
4262
+ function lineContent(cm, realLine, measure, copyWidgets) {
4263
+ var merged, line = realLine, empty = true;
4264
+ while (merged = collapsedSpanAtStart(line))
4265
+ line = getLine(cm.doc, merged.find().from.line);
4266
+
4267
+ var builder = {pre: elt("pre"), col: 0, pos: 0,
4268
+ measure: null, measuredSomething: false, cm: cm,
4269
+ copyWidgets: copyWidgets};
4270
+ if (line.textClass) builder.pre.className = line.textClass;
4271
+
4272
+ do {
4273
+ if (line.text) empty = false;
4274
+ builder.measure = line == realLine && measure;
4275
+ builder.pos = 0;
4276
+ builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
4277
+ if ((ie || webkit) && cm.getOption("lineWrapping"))
4278
+ builder.addToken = buildTokenSplitSpaces(builder.addToken);
4279
+ var next = insertLineContent(line, builder, getLineStyles(cm, line));
4280
+ if (measure && line == realLine && !builder.measuredSomething) {
4281
+ measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
4282
+ builder.measuredSomething = true;
4283
+ }
4284
+ if (next) line = getLine(cm.doc, next.to.line);
4285
+ } while (next);
4286
+
4287
+ if (measure && !builder.measuredSomething && !measure[0])
4288
+ measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
4289
+ if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
4290
+ builder.pre.appendChild(document.createTextNode("\u00a0"));
4291
+
4292
+ var order;
4293
+ // Work around problem with the reported dimensions of single-char
4294
+ // direction spans on IE (issue #1129). See also the comment in
4295
+ // cursorCoords.
4296
+ if (measure && ie && (order = getOrder(line))) {
4297
+ var l = order.length - 1;
4298
+ if (order[l].from == order[l].to) --l;
4299
+ var last = order[l], prev = order[l - 1];
4300
+ if (last.from + 1 == last.to && prev && last.level < prev.level) {
4301
+ var span = measure[builder.pos - 1];
4302
+ if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
4303
+ span.nextSibling);
4304
+ }
4305
+ }
4306
+
4307
+ signal(cm, "renderLine", cm, realLine, builder.pre);
4308
+ return builder.pre;
4309
+ }
4310
+
4311
+ var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4312
+ function buildToken(builder, text, style, startStyle, endStyle, title) {
4313
+ if (!text) return;
4314
+ if (!tokenSpecialChars.test(text)) {
4315
+ builder.col += text.length;
4316
+ var content = document.createTextNode(text);
4317
+ } else {
4318
+ var content = document.createDocumentFragment(), pos = 0;
4319
+ while (true) {
4320
+ tokenSpecialChars.lastIndex = pos;
4321
+ var m = tokenSpecialChars.exec(text);
4322
+ var skipped = m ? m.index - pos : text.length - pos;
4323
+ if (skipped) {
4324
+ content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
4325
+ builder.col += skipped;
4326
+ }
4327
+ if (!m) break;
4328
+ pos += skipped + 1;
4329
+ if (m[0] == "\t") {
4330
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
4331
+ content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
4332
+ builder.col += tabWidth;
4333
+ } else {
4334
+ var token = elt("span", "\u2022", "cm-invalidchar");
4335
+ token.title = "\\u" + m[0].charCodeAt(0).toString(16);
4336
+ content.appendChild(token);
4337
+ builder.col += 1;
4338
+ }
4339
+ }
4340
+ }
4341
+ if (style || startStyle || endStyle || builder.measure) {
4342
+ var fullStyle = style || "";
4343
+ if (startStyle) fullStyle += startStyle;
4344
+ if (endStyle) fullStyle += endStyle;
4345
+ var token = elt("span", [content], fullStyle);
4346
+ if (title) token.title = title;
4347
+ return builder.pre.appendChild(token);
4348
+ }
4349
+ builder.pre.appendChild(content);
4350
+ }
4351
+
4352
+ function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
4353
+ var wrapping = builder.cm.options.lineWrapping;
4354
+ for (var i = 0; i < text.length; ++i) {
4355
+ var ch = text.charAt(i), start = i == 0;
4356
+ if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
4357
+ ch = text.slice(i, i + 2);
4358
+ ++i;
4359
+ } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4360
+ builder.pre.appendChild(elt("wbr"));
4361
+ }
4362
+ var old = builder.measure[builder.pos];
4363
+ var span = builder.measure[builder.pos] =
4364
+ buildToken(builder, ch, style,
4365
+ start && startStyle, i == text.length - 1 && endStyle);
4366
+ if (old) span.leftSide = old.leftSide || old;
4367
+ // In IE single-space nodes wrap differently than spaces
4368
+ // embedded in larger text nodes, except when set to
4369
+ // white-space: normal (issue #1268).
4370
+ if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
4371
+ i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
4372
+ span.style.whiteSpace = "normal";
4373
+ builder.pos += ch.length;
4374
+ }
4375
+ if (text.length) builder.measuredSomething = true;
4376
+ }
4377
+
4378
+ function buildTokenSplitSpaces(inner) {
4379
+ function split(old) {
4380
+ var out = " ";
4381
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
4382
+ out += " ";
4383
+ return out;
4384
+ }
4385
+ return function(builder, text, style, startStyle, endStyle, title) {
4386
+ return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
4387
+ };
4388
+ }
4389
+
4390
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4391
+ var widget = !ignoreWidget && marker.replacedWith;
4392
+ if (widget) {
4393
+ if (builder.copyWidgets) widget = widget.cloneNode(true);
4394
+ builder.pre.appendChild(widget);
4395
+ if (builder.measure) {
4396
+ if (size) {
4397
+ builder.measure[builder.pos] = widget;
4398
+ } else {
4399
+ var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
4400
+ if (marker.type != "bookmark" || marker.insertLeft)
4401
+ builder.pre.insertBefore(elt, widget);
4402
+ else
4403
+ builder.pre.appendChild(elt);
4404
+ }
4405
+ builder.measuredSomething = true;
4406
+ }
4407
+ }
4408
+ builder.pos += size;
4409
+ }
4410
+
4411
+ // Outputs a number of spans to make up a line, taking highlighting
4412
+ // and marked text into account.
4413
+ function insertLineContent(line, builder, styles) {
4414
+ var spans = line.markedSpans, allText = line.text, at = 0;
4415
+ if (!spans) {
4416
+ for (var i = 1; i < styles.length; i+=2)
4417
+ builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
4418
+ return;
4419
+ }
4420
+
4421
+ var len = allText.length, pos = 0, i = 1, text = "", style;
4422
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4423
+ for (;;) {
4424
+ if (nextChange == pos) { // Update current marker set
4425
+ spanStyle = spanEndStyle = spanStartStyle = title = "";
4426
+ collapsed = null; nextChange = Infinity;
4427
+ var foundBookmark = null;
4428
+ for (var j = 0; j < spans.length; ++j) {
4429
+ var sp = spans[j], m = sp.marker;
4430
+ if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
4431
+ if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
4432
+ if (m.className) spanStyle += " " + m.className;
4433
+ if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4434
+ if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4435
+ if (m.title && !title) title = m.title;
4436
+ if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4437
+ collapsed = sp;
4438
+ } else if (sp.from > pos && nextChange > sp.from) {
4439
+ nextChange = sp.from;
4440
+ }
4441
+ if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
4442
+ }
4443
+ if (collapsed && (collapsed.from || 0) == pos) {
4444
+ buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4445
+ collapsed.marker, collapsed.from == null);
4446
+ if (collapsed.to == null) return collapsed.marker.find();
4447
+ }
4448
+ if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
4449
+ }
4450
+ if (pos >= len) break;
4451
+
4452
+ var upto = Math.min(len, nextChange);
4453
+ while (true) {
4454
+ if (text) {
4455
+ var end = pos + text.length;
4456
+ if (!collapsed) {
4457
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4458
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4459
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
4460
+ }
4461
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4462
+ pos = end;
4463
+ spanStartStyle = "";
4464
+ }
4465
+ text = allText.slice(at, at = styles[i++]);
4466
+ style = styleToClass(styles[i++]);
4467
+ }
4468
+ }
4469
+ }
4470
+
4471
+ // DOCUMENT DATA STRUCTURE
4472
+
4473
+ function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
4474
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
4475
+ function update(line, text, spans) {
4476
+ updateLine(line, text, spans, estimateHeight);
4477
+ signalLater(line, "change", line, change);
4478
+ }
4479
+
4480
+ var from = change.from, to = change.to, text = change.text;
4481
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
4482
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
4483
+
4484
+ // First adjust the line structure
4485
+ if (from.ch == 0 && to.ch == 0 && lastText == "") {
4486
+ // This is a whole-line replace. Treated specially to make
4487
+ // sure line objects move the way they are supposed to.
4488
+ for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4489
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4490
+ update(lastLine, lastLine.text, lastSpans);
4491
+ if (nlines) doc.remove(from.line, nlines);
4492
+ if (added.length) doc.insert(from.line, added);
4493
+ } else if (firstLine == lastLine) {
4494
+ if (text.length == 1) {
4495
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4496
+ } else {
4497
+ for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4498
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4499
+ added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4500
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4501
+ doc.insert(from.line + 1, added);
4502
+ }
4503
+ } else if (text.length == 1) {
4504
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
4505
+ doc.remove(from.line + 1, nlines);
4506
+ } else {
4507
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4508
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4509
+ for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4510
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4511
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4512
+ doc.insert(from.line + 1, added);
4513
+ }
4514
+
4515
+ signalLater(doc, "change", doc, change);
4516
+ setSelection(doc, selAfter.anchor, selAfter.head, null, true);
4517
+ }
4518
+
4519
+ function LeafChunk(lines) {
4520
+ this.lines = lines;
4521
+ this.parent = null;
4522
+ for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
4523
+ lines[i].parent = this;
4524
+ height += lines[i].height;
4525
+ }
4526
+ this.height = height;
4527
+ }
4528
+
4529
+ LeafChunk.prototype = {
4530
+ chunkSize: function() { return this.lines.length; },
4531
+ removeInner: function(at, n) {
4532
+ for (var i = at, e = at + n; i < e; ++i) {
4533
+ var line = this.lines[i];
4534
+ this.height -= line.height;
4535
+ cleanUpLine(line);
4536
+ signalLater(line, "delete");
4537
+ }
4538
+ this.lines.splice(at, n);
4539
+ },
4540
+ collapse: function(lines) {
4541
+ lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
4542
+ },
4543
+ insertInner: function(at, lines, height) {
4544
+ this.height += height;
4545
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
4546
+ for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
4547
+ },
4548
+ iterN: function(at, n, op) {
4549
+ for (var e = at + n; at < e; ++at)
4550
+ if (op(this.lines[at])) return true;
4551
+ }
4552
+ };
4553
+
4554
+ function BranchChunk(children) {
4555
+ this.children = children;
4556
+ var size = 0, height = 0;
4557
+ for (var i = 0, e = children.length; i < e; ++i) {
4558
+ var ch = children[i];
4559
+ size += ch.chunkSize(); height += ch.height;
4560
+ ch.parent = this;
4561
+ }
4562
+ this.size = size;
4563
+ this.height = height;
4564
+ this.parent = null;
4565
+ }
4566
+
4567
+ BranchChunk.prototype = {
4568
+ chunkSize: function() { return this.size; },
4569
+ removeInner: function(at, n) {
4570
+ this.size -= n;
4571
+ for (var i = 0; i < this.children.length; ++i) {
4572
+ var child = this.children[i], sz = child.chunkSize();
4573
+ if (at < sz) {
4574
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
4575
+ child.removeInner(at, rm);
4576
+ this.height -= oldHeight - child.height;
4577
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
4578
+ if ((n -= rm) == 0) break;
4579
+ at = 0;
4580
+ } else at -= sz;
4581
+ }
4582
+ if (this.size - n < 25) {
4583
+ var lines = [];
4584
+ this.collapse(lines);
4585
+ this.children = [new LeafChunk(lines)];
4586
+ this.children[0].parent = this;
4587
+ }
4588
+ },
4589
+ collapse: function(lines) {
4590
+ for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
4591
+ },
4592
+ insertInner: function(at, lines, height) {
4593
+ this.size += lines.length;
4594
+ this.height += height;
4595
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4596
+ var child = this.children[i], sz = child.chunkSize();
4597
+ if (at <= sz) {
4598
+ child.insertInner(at, lines, height);
4599
+ if (child.lines && child.lines.length > 50) {
4600
+ while (child.lines.length > 50) {
4601
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
4602
+ var newleaf = new LeafChunk(spilled);
4603
+ child.height -= newleaf.height;
4604
+ this.children.splice(i + 1, 0, newleaf);
4605
+ newleaf.parent = this;
4606
+ }
4607
+ this.maybeSpill();
4608
+ }
4609
+ break;
4610
+ }
4611
+ at -= sz;
4612
+ }
4613
+ },
4614
+ maybeSpill: function() {
4615
+ if (this.children.length <= 10) return;
4616
+ var me = this;
4617
+ do {
4618
+ var spilled = me.children.splice(me.children.length - 5, 5);
4619
+ var sibling = new BranchChunk(spilled);
4620
+ if (!me.parent) { // Become the parent node
4621
+ var copy = new BranchChunk(me.children);
4622
+ copy.parent = me;
4623
+ me.children = [copy, sibling];
4624
+ me = copy;
4625
+ } else {
4626
+ me.size -= sibling.size;
4627
+ me.height -= sibling.height;
4628
+ var myIndex = indexOf(me.parent.children, me);
4629
+ me.parent.children.splice(myIndex + 1, 0, sibling);
4630
+ }
4631
+ sibling.parent = me.parent;
4632
+ } while (me.children.length > 10);
4633
+ me.parent.maybeSpill();
4634
+ },
4635
+ iterN: function(at, n, op) {
4636
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4637
+ var child = this.children[i], sz = child.chunkSize();
4638
+ if (at < sz) {
4639
+ var used = Math.min(n, sz - at);
4640
+ if (child.iterN(at, used, op)) return true;
4641
+ if ((n -= used) == 0) break;
4642
+ at = 0;
4643
+ } else at -= sz;
4644
+ }
4645
+ }
4646
+ };
4647
+
4648
+ var nextDocId = 0;
4649
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
4650
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4651
+ if (firstLine == null) firstLine = 0;
4652
+
4653
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
4654
+ this.first = firstLine;
4655
+ this.scrollTop = this.scrollLeft = 0;
4656
+ this.cantEdit = false;
4657
+ this.history = makeHistory();
4658
+ this.cleanGeneration = 1;
4659
+ this.frontier = firstLine;
4660
+ var start = Pos(firstLine, 0);
4661
+ this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
4662
+ this.id = ++nextDocId;
4663
+ this.modeOption = mode;
4664
+
4665
+ if (typeof text == "string") text = splitLines(text);
4666
+ updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
4667
+ };
4668
+
4669
+ Doc.prototype = createObj(BranchChunk.prototype, {
4670
+ constructor: Doc,
4671
+ iter: function(from, to, op) {
4672
+ if (op) this.iterN(from - this.first, to - from, op);
4673
+ else this.iterN(this.first, this.first + this.size, from);
4674
+ },
4675
+
4676
+ insert: function(at, lines) {
4677
+ var height = 0;
4678
+ for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
4679
+ this.insertInner(at - this.first, lines, height);
4680
+ },
4681
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
4682
+
4683
+ getValue: function(lineSep) {
4684
+ var lines = getLines(this, this.first, this.first + this.size);
4685
+ if (lineSep === false) return lines;
4686
+ return lines.join(lineSep || "\n");
4687
+ },
4688
+ setValue: function(code) {
4689
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
4690
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
4691
+ text: splitLines(code), origin: "setValue"},
4692
+ {head: top, anchor: top}, true);
4693
+ },
4694
+ replaceRange: function(code, from, to, origin) {
4695
+ from = clipPos(this, from);
4696
+ to = to ? clipPos(this, to) : from;
4697
+ replaceRange(this, code, from, to, origin);
4698
+ },
4699
+ getRange: function(from, to, lineSep) {
4700
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
4701
+ if (lineSep === false) return lines;
4702
+ return lines.join(lineSep || "\n");
4703
+ },
4704
+
4705
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
4706
+ setLine: function(line, text) {
4707
+ if (isLine(this, line))
4708
+ replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
4709
+ },
4710
+ removeLine: function(line) {
4711
+ if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
4712
+ else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
4713
+ },
4714
+
4715
+ getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4716
+ getLineNumber: function(line) {return lineNo(line);},
4717
+
4718
+ getLineHandleVisualStart: function(line) {
4719
+ if (typeof line == "number") line = getLine(this, line);
4720
+ return visualLine(this, line);
4721
+ },
4722
+
4723
+ lineCount: function() {return this.size;},
4724
+ firstLine: function() {return this.first;},
4725
+ lastLine: function() {return this.first + this.size - 1;},
4726
+
4727
+ clipPos: function(pos) {return clipPos(this, pos);},
4728
+
4729
+ getCursor: function(start) {
4730
+ var sel = this.sel, pos;
4731
+ if (start == null || start == "head") pos = sel.head;
4732
+ else if (start == "anchor") pos = sel.anchor;
4733
+ else if (start == "end" || start === false) pos = sel.to;
4734
+ else pos = sel.from;
4735
+ return copyPos(pos);
4736
+ },
4737
+ somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
4738
+
4739
+ setCursor: docOperation(function(line, ch, extend) {
4740
+ var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
4741
+ if (extend) extendSelection(this, pos);
4742
+ else setSelection(this, pos, pos);
4743
+ }),
4744
+ setSelection: docOperation(function(anchor, head) {
4745
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
4746
+ }),
4747
+ extendSelection: docOperation(function(from, to) {
4748
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to));
4749
+ }),
4750
+
4751
+ getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
4752
+ replaceSelection: function(code, collapse, origin) {
4753
+ makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
4754
+ },
4755
+ undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
4756
+ redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
4757
+
4758
+ setExtending: function(val) {this.sel.extend = val;},
4759
+
4760
+ historySize: function() {
4761
+ var hist = this.history;
4762
+ return {undo: hist.done.length, redo: hist.undone.length};
4763
+ },
4764
+ clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
4765
+
4766
+ markClean: function() {
4767
+ this.cleanGeneration = this.changeGeneration();
4768
+ },
4769
+ changeGeneration: function() {
4770
+ this.history.lastOp = this.history.lastOrigin = null;
4771
+ return this.history.generation;
4772
+ },
4773
+ isClean: function (gen) {
4774
+ return this.history.generation == (gen || this.cleanGeneration);
4775
+ },
4776
+
4777
+ getHistory: function() {
4778
+ return {done: copyHistoryArray(this.history.done),
4779
+ undone: copyHistoryArray(this.history.undone)};
4780
+ },
4781
+ setHistory: function(histData) {
4782
+ var hist = this.history = makeHistory(this.history.maxGeneration);
4783
+ hist.done = histData.done.slice(0);
4784
+ hist.undone = histData.undone.slice(0);
4785
+ },
4786
+
4787
+ markText: function(from, to, options) {
4788
+ return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
4789
+ },
4790
+ setBookmark: function(pos, options) {
4791
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
4792
+ insertLeft: options && options.insertLeft};
4793
+ pos = clipPos(this, pos);
4794
+ return markText(this, pos, pos, realOpts, "bookmark");
4795
+ },
4796
+ findMarksAt: function(pos) {
4797
+ pos = clipPos(this, pos);
4798
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
4799
+ if (spans) for (var i = 0; i < spans.length; ++i) {
4800
+ var span = spans[i];
4801
+ if ((span.from == null || span.from <= pos.ch) &&
4802
+ (span.to == null || span.to >= pos.ch))
4803
+ markers.push(span.marker.parent || span.marker);
4804
+ }
4805
+ return markers;
4806
+ },
4807
+ getAllMarks: function() {
4808
+ var markers = [];
4809
+ this.iter(function(line) {
4810
+ var sps = line.markedSpans;
4811
+ if (sps) for (var i = 0; i < sps.length; ++i)
4812
+ if (sps[i].from != null) markers.push(sps[i].marker);
4813
+ });
4814
+ return markers;
4815
+ },
4816
+
4817
+ posFromIndex: function(off) {
4818
+ var ch, lineNo = this.first;
4819
+ this.iter(function(line) {
4820
+ var sz = line.text.length + 1;
4821
+ if (sz > off) { ch = off; return true; }
4822
+ off -= sz;
4823
+ ++lineNo;
4824
+ });
4825
+ return clipPos(this, Pos(lineNo, ch));
4826
+ },
4827
+ indexFromPos: function (coords) {
4828
+ coords = clipPos(this, coords);
4829
+ var index = coords.ch;
4830
+ if (coords.line < this.first || coords.ch < 0) return 0;
4831
+ this.iter(this.first, coords.line, function (line) {
4832
+ index += line.text.length + 1;
4833
+ });
4834
+ return index;
4835
+ },
4836
+
4837
+ copy: function(copyHistory) {
4838
+ var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
4839
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
4840
+ doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
4841
+ shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
4842
+ if (copyHistory) {
4843
+ doc.history.undoDepth = this.history.undoDepth;
4844
+ doc.setHistory(this.getHistory());
4845
+ }
4846
+ return doc;
4847
+ },
4848
+
4849
+ linkedDoc: function(options) {
4850
+ if (!options) options = {};
4851
+ var from = this.first, to = this.first + this.size;
4852
+ if (options.from != null && options.from > from) from = options.from;
4853
+ if (options.to != null && options.to < to) to = options.to;
4854
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
4855
+ if (options.sharedHist) copy.history = this.history;
4856
+ (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
4857
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
4858
+ return copy;
4859
+ },
4860
+ unlinkDoc: function(other) {
4861
+ if (other instanceof CodeMirror) other = other.doc;
4862
+ if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
4863
+ var link = this.linked[i];
4864
+ if (link.doc != other) continue;
4865
+ this.linked.splice(i, 1);
4866
+ other.unlinkDoc(this);
4867
+ break;
4868
+ }
4869
+ // If the histories were shared, split them again
4870
+ if (other.history == this.history) {
4871
+ var splitIds = [other.id];
4872
+ linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
4873
+ other.history = makeHistory();
4874
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
4875
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
4876
+ }
4877
+ },
4878
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
4879
+
4880
+ getMode: function() {return this.mode;},
4881
+ getEditor: function() {return this.cm;}
4882
+ });
4883
+
4884
+ Doc.prototype.eachLine = Doc.prototype.iter;
4885
+
4886
+ // The Doc methods that should be available on CodeMirror instances
4887
+ var dontDelegate = "iter insert remove copy getEditor".split(" ");
4888
+ for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
4889
+ CodeMirror.prototype[prop] = (function(method) {
4890
+ return function() {return method.apply(this.doc, arguments);};
4891
+ })(Doc.prototype[prop]);
4892
+
4893
+ eventMixin(Doc);
4894
+
4895
+ function linkedDocs(doc, f, sharedHistOnly) {
4896
+ function propagate(doc, skip, sharedHist) {
4897
+ if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
4898
+ var rel = doc.linked[i];
4899
+ if (rel.doc == skip) continue;
4900
+ var shared = sharedHist && rel.sharedHist;
4901
+ if (sharedHistOnly && !shared) continue;
4902
+ f(rel.doc, shared);
4903
+ propagate(rel.doc, doc, shared);
4904
+ }
4905
+ }
4906
+ propagate(doc, null, true);
4907
+ }
4908
+
4909
+ function attachDoc(cm, doc) {
4910
+ if (doc.cm) throw new Error("This document is already in use.");
4911
+ cm.doc = doc;
4912
+ doc.cm = cm;
4913
+ estimateLineHeights(cm);
4914
+ loadMode(cm);
4915
+ if (!cm.options.lineWrapping) computeMaxLength(cm);
4916
+ cm.options.mode = doc.modeOption;
4917
+ regChange(cm);
4918
+ }
4919
+
4920
+ // LINE UTILITIES
4921
+
4922
+ function getLine(chunk, n) {
4923
+ n -= chunk.first;
4924
+ while (!chunk.lines) {
4925
+ for (var i = 0;; ++i) {
4926
+ var child = chunk.children[i], sz = child.chunkSize();
4927
+ if (n < sz) { chunk = child; break; }
4928
+ n -= sz;
4929
+ }
4930
+ }
4931
+ return chunk.lines[n];
4932
+ }
4933
+
4934
+ function getBetween(doc, start, end) {
4935
+ var out = [], n = start.line;
4936
+ doc.iter(start.line, end.line + 1, function(line) {
4937
+ var text = line.text;
4938
+ if (n == end.line) text = text.slice(0, end.ch);
4939
+ if (n == start.line) text = text.slice(start.ch);
4940
+ out.push(text);
4941
+ ++n;
4942
+ });
4943
+ return out;
4944
+ }
4945
+ function getLines(doc, from, to) {
4946
+ var out = [];
4947
+ doc.iter(from, to, function(line) { out.push(line.text); });
4948
+ return out;
4949
+ }
4950
+
4951
+ function updateLineHeight(line, height) {
4952
+ var diff = height - line.height;
4953
+ for (var n = line; n; n = n.parent) n.height += diff;
4954
+ }
4955
+
4956
+ function lineNo(line) {
4957
+ if (line.parent == null) return null;
4958
+ var cur = line.parent, no = indexOf(cur.lines, line);
4959
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
4960
+ for (var i = 0;; ++i) {
4961
+ if (chunk.children[i] == cur) break;
4962
+ no += chunk.children[i].chunkSize();
4963
+ }
4964
+ }
4965
+ return no + cur.first;
4966
+ }
4967
+
4968
+ function lineAtHeight(chunk, h) {
4969
+ var n = chunk.first;
4970
+ outer: do {
4971
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
4972
+ var child = chunk.children[i], ch = child.height;
4973
+ if (h < ch) { chunk = child; continue outer; }
4974
+ h -= ch;
4975
+ n += child.chunkSize();
4976
+ }
4977
+ return n;
4978
+ } while (!chunk.lines);
4979
+ for (var i = 0, e = chunk.lines.length; i < e; ++i) {
4980
+ var line = chunk.lines[i], lh = line.height;
4981
+ if (h < lh) break;
4982
+ h -= lh;
4983
+ }
4984
+ return n + i;
4985
+ }
4986
+
4987
+ function heightAtLine(cm, lineObj) {
4988
+ lineObj = visualLine(cm.doc, lineObj);
4989
+
4990
+ var h = 0, chunk = lineObj.parent;
4991
+ for (var i = 0; i < chunk.lines.length; ++i) {
4992
+ var line = chunk.lines[i];
4993
+ if (line == lineObj) break;
4994
+ else h += line.height;
4995
+ }
4996
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
4997
+ for (var i = 0; i < p.children.length; ++i) {
4998
+ var cur = p.children[i];
4999
+ if (cur == chunk) break;
5000
+ else h += cur.height;
5001
+ }
5002
+ }
5003
+ return h;
5004
+ }
5005
+
5006
+ function getOrder(line) {
5007
+ var order = line.order;
5008
+ if (order == null) order = line.order = bidiOrdering(line.text);
5009
+ return order;
5010
+ }
5011
+
5012
+ // HISTORY
5013
+
5014
+ function makeHistory(startGen) {
5015
+ return {
5016
+ // Arrays of history events. Doing something adds an event to
5017
+ // done and clears undo. Undoing moves events from done to
5018
+ // undone, redoing moves them in the other direction.
5019
+ done: [], undone: [], undoDepth: Infinity,
5020
+ // Used to track when changes can be merged into a single undo
5021
+ // event
5022
+ lastTime: 0, lastOp: null, lastOrigin: null,
5023
+ // Used by the isClean() method
5024
+ generation: startGen || 1, maxGeneration: startGen || 1
5025
+ };
5026
+ }
5027
+
5028
+ function attachLocalSpans(doc, change, from, to) {
5029
+ var existing = change["spans_" + doc.id], n = 0;
5030
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
5031
+ if (line.markedSpans)
5032
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
5033
+ ++n;
5034
+ });
5035
+ }
5036
+
5037
+ function historyChangeFromChange(doc, change) {
5038
+ var from = { line: change.from.line, ch: change.from.ch };
5039
+ var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
5040
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
5041
+ linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
5042
+ return histChange;
5043
+ }
5044
+
5045
+ function addToHistory(doc, change, selAfter, opId) {
5046
+ var hist = doc.history;
5047
+ hist.undone.length = 0;
5048
+ var time = +new Date, cur = lst(hist.done);
5049
+
5050
+ if (cur &&
5051
+ (hist.lastOp == opId ||
5052
+ hist.lastOrigin == change.origin && change.origin &&
5053
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
5054
+ change.origin.charAt(0) == "*"))) {
5055
+ // Merge this change into the last event
5056
+ var last = lst(cur.changes);
5057
+ if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
5058
+ // Optimized case for simple insertion -- don't want to add
5059
+ // new changesets for every character typed
5060
+ last.to = changeEnd(change);
5061
+ } else {
5062
+ // Add new sub-event
5063
+ cur.changes.push(historyChangeFromChange(doc, change));
5064
+ }
5065
+ cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
5066
+ } else {
5067
+ // Can not be merged, start a new event.
5068
+ cur = {changes: [historyChangeFromChange(doc, change)],
5069
+ generation: hist.generation,
5070
+ anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
5071
+ anchorAfter: selAfter.anchor, headAfter: selAfter.head};
5072
+ hist.done.push(cur);
5073
+ hist.generation = ++hist.maxGeneration;
5074
+ while (hist.done.length > hist.undoDepth)
5075
+ hist.done.shift();
5076
+ }
5077
+ hist.lastTime = time;
5078
+ hist.lastOp = opId;
5079
+ hist.lastOrigin = change.origin;
5080
+ }
5081
+
5082
+ function removeClearedSpans(spans) {
5083
+ if (!spans) return null;
5084
+ for (var i = 0, out; i < spans.length; ++i) {
5085
+ if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
5086
+ else if (out) out.push(spans[i]);
5087
+ }
5088
+ return !out ? spans : out.length ? out : null;
5089
+ }
5090
+
5091
+ function getOldSpans(doc, change) {
5092
+ var found = change["spans_" + doc.id];
5093
+ if (!found) return null;
5094
+ for (var i = 0, nw = []; i < change.text.length; ++i)
5095
+ nw.push(removeClearedSpans(found[i]));
5096
+ return nw;
5097
+ }
5098
+
5099
+ // Used both to provide a JSON-safe object in .getHistory, and, when
5100
+ // detaching a document, to split the history in two
5101
+ function copyHistoryArray(events, newGroup) {
5102
+ for (var i = 0, copy = []; i < events.length; ++i) {
5103
+ var event = events[i], changes = event.changes, newChanges = [];
5104
+ copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
5105
+ anchorAfter: event.anchorAfter, headAfter: event.headAfter});
5106
+ for (var j = 0; j < changes.length; ++j) {
5107
+ var change = changes[j], m;
5108
+ newChanges.push({from: change.from, to: change.to, text: change.text});
5109
+ if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
5110
+ if (indexOf(newGroup, Number(m[1])) > -1) {
5111
+ lst(newChanges)[prop] = change[prop];
5112
+ delete change[prop];
5113
+ }
5114
+ }
5115
+ }
5116
+ }
5117
+ return copy;
5118
+ }
5119
+
5120
+ // Rebasing/resetting history to deal with externally-sourced changes
5121
+
5122
+ function rebaseHistSel(pos, from, to, diff) {
5123
+ if (to < pos.line) {
5124
+ pos.line += diff;
5125
+ } else if (from < pos.line) {
5126
+ pos.line = from;
5127
+ pos.ch = 0;
5128
+ }
5129
+ }
5130
+
5131
+ // Tries to rebase an array of history events given a change in the
5132
+ // document. If the change touches the same lines as the event, the
5133
+ // event, and everything 'behind' it, is discarded. If the change is
5134
+ // before the event, the event's positions are updated. Uses a
5135
+ // copy-on-write scheme for the positions, to avoid having to
5136
+ // reallocate them all on every rebase, but also avoid problems with
5137
+ // shared position objects being unsafely updated.
5138
+ function rebaseHistArray(array, from, to, diff) {
5139
+ for (var i = 0; i < array.length; ++i) {
5140
+ var sub = array[i], ok = true;
5141
+ for (var j = 0; j < sub.changes.length; ++j) {
5142
+ var cur = sub.changes[j];
5143
+ if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
5144
+ if (to < cur.from.line) {
5145
+ cur.from.line += diff;
5146
+ cur.to.line += diff;
5147
+ } else if (from <= cur.to.line) {
5148
+ ok = false;
5149
+ break;
5150
+ }
5151
+ }
5152
+ if (!sub.copied) {
5153
+ sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
5154
+ sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
5155
+ sub.copied = true;
5156
+ }
5157
+ if (!ok) {
5158
+ array.splice(0, i + 1);
5159
+ i = 0;
5160
+ } else {
5161
+ rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
5162
+ rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
5163
+ }
5164
+ }
5165
+ }
5166
+
5167
+ function rebaseHist(hist, change) {
5168
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
5169
+ rebaseHistArray(hist.done, from, to, diff);
5170
+ rebaseHistArray(hist.undone, from, to, diff);
5171
+ }
5172
+
5173
+ // EVENT OPERATORS
5174
+
5175
+ function stopMethod() {e_stop(this);}
5176
+ // Ensure an event has a stop method.
5177
+ function addStop(event) {
5178
+ if (!event.stop) event.stop = stopMethod;
5179
+ return event;
5180
+ }
5181
+
5182
+ function e_preventDefault(e) {
5183
+ if (e.preventDefault) e.preventDefault();
5184
+ else e.returnValue = false;
5185
+ }
5186
+ function e_stopPropagation(e) {
5187
+ if (e.stopPropagation) e.stopPropagation();
5188
+ else e.cancelBubble = true;
5189
+ }
5190
+ function e_defaultPrevented(e) {
5191
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
5192
+ }
5193
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
5194
+ CodeMirror.e_stop = e_stop;
5195
+ CodeMirror.e_preventDefault = e_preventDefault;
5196
+ CodeMirror.e_stopPropagation = e_stopPropagation;
5197
+
5198
+ function e_target(e) {return e.target || e.srcElement;}
5199
+ function e_button(e) {
5200
+ var b = e.which;
5201
+ if (b == null) {
5202
+ if (e.button & 1) b = 1;
5203
+ else if (e.button & 2) b = 3;
5204
+ else if (e.button & 4) b = 2;
5205
+ }
5206
+ if (mac && e.ctrlKey && b == 1) b = 3;
5207
+ return b;
5208
+ }
5209
+
5210
+ // EVENT HANDLING
5211
+
5212
+ function on(emitter, type, f) {
5213
+ if (emitter.addEventListener)
5214
+ emitter.addEventListener(type, f, false);
5215
+ else if (emitter.attachEvent)
5216
+ emitter.attachEvent("on" + type, f);
5217
+ else {
5218
+ var map = emitter._handlers || (emitter._handlers = {});
5219
+ var arr = map[type] || (map[type] = []);
5220
+ arr.push(f);
5221
+ }
5222
+ }
5223
+
5224
+ function off(emitter, type, f) {
5225
+ if (emitter.removeEventListener)
5226
+ emitter.removeEventListener(type, f, false);
5227
+ else if (emitter.detachEvent)
5228
+ emitter.detachEvent("on" + type, f);
5229
+ else {
5230
+ var arr = emitter._handlers && emitter._handlers[type];
5231
+ if (!arr) return;
5232
+ for (var i = 0; i < arr.length; ++i)
5233
+ if (arr[i] == f) { arr.splice(i, 1); break; }
5234
+ }
5235
+ }
5236
+
5237
+ function signal(emitter, type /*, values...*/) {
5238
+ var arr = emitter._handlers && emitter._handlers[type];
5239
+ if (!arr) return;
5240
+ var args = Array.prototype.slice.call(arguments, 2);
5241
+ for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
5242
+ }
5243
+
5244
+ var delayedCallbacks, delayedCallbackDepth = 0;
5245
+ function signalLater(emitter, type /*, values...*/) {
5246
+ var arr = emitter._handlers && emitter._handlers[type];
5247
+ if (!arr) return;
5248
+ var args = Array.prototype.slice.call(arguments, 2);
5249
+ if (!delayedCallbacks) {
5250
+ ++delayedCallbackDepth;
5251
+ delayedCallbacks = [];
5252
+ setTimeout(fireDelayed, 0);
5253
+ }
5254
+ function bnd(f) {return function(){f.apply(null, args);};};
5255
+ for (var i = 0; i < arr.length; ++i)
5256
+ delayedCallbacks.push(bnd(arr[i]));
5257
+ }
5258
+
5259
+ function signalDOMEvent(cm, e, override) {
5260
+ signal(cm, override || e.type, cm, e);
5261
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
5262
+ }
5263
+
5264
+ function fireDelayed() {
5265
+ --delayedCallbackDepth;
5266
+ var delayed = delayedCallbacks;
5267
+ delayedCallbacks = null;
5268
+ for (var i = 0; i < delayed.length; ++i) delayed[i]();
5269
+ }
5270
+
5271
+ function hasHandler(emitter, type) {
5272
+ var arr = emitter._handlers && emitter._handlers[type];
5273
+ return arr && arr.length > 0;
5274
+ }
5275
+
5276
+ CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5277
+
5278
+ function eventMixin(ctor) {
5279
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
5280
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
5281
+ }
5282
+
5283
+ // MISC UTILITIES
5284
+
5285
+ // Number of pixels added to scroller and sizer to hide scrollbar
5286
+ var scrollerCutOff = 30;
5287
+
5288
+ // Returned or thrown by various protocols to signal 'I'm not
5289
+ // handling this'.
5290
+ var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
5291
+
5292
+ function Delayed() {this.id = null;}
5293
+ Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
5294
+
5295
+ // Counts the column offset in a string, taking tabs into account.
5296
+ // Used mostly to find indentation.
5297
+ function countColumn(string, end, tabSize, startIndex, startValue) {
5298
+ if (end == null) {
5299
+ end = string.search(/[^\s\u00a0]/);
5300
+ if (end == -1) end = string.length;
5301
+ }
5302
+ for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
5303
+ if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
5304
+ else ++n;
5305
+ }
5306
+ return n;
5307
+ }
5308
+ CodeMirror.countColumn = countColumn;
5309
+
5310
+ var spaceStrs = [""];
5311
+ function spaceStr(n) {
5312
+ while (spaceStrs.length <= n)
5313
+ spaceStrs.push(lst(spaceStrs) + " ");
5314
+ return spaceStrs[n];
5315
+ }
5316
+
5317
+ function lst(arr) { return arr[arr.length-1]; }
5318
+
5319
+ function selectInput(node) {
5320
+ if (ios) { // Mobile Safari apparently has a bug where select() is broken.
5321
+ node.selectionStart = 0;
5322
+ node.selectionEnd = node.value.length;
5323
+ } else {
5324
+ // Suppress mysterious IE10 errors
5325
+ try { node.select(); }
5326
+ catch(_e) {}
5327
+ }
5328
+ }
5329
+
5330
+ function indexOf(collection, elt) {
5331
+ if (collection.indexOf) return collection.indexOf(elt);
5332
+ for (var i = 0, e = collection.length; i < e; ++i)
5333
+ if (collection[i] == elt) return i;
5334
+ return -1;
5335
+ }
5336
+
5337
+ function createObj(base, props) {
5338
+ function Obj() {}
5339
+ Obj.prototype = base;
5340
+ var inst = new Obj();
5341
+ if (props) copyObj(props, inst);
5342
+ return inst;
5343
+ }
5344
+
5345
+ function copyObj(obj, target) {
5346
+ if (!target) target = {};
5347
+ for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
5348
+ return target;
5349
+ }
5350
+
5351
+ function emptyArray(size) {
5352
+ for (var a = [], i = 0; i < size; ++i) a.push(undefined);
5353
+ return a;
5354
+ }
5355
+
5356
+ function bind(f) {
5357
+ var args = Array.prototype.slice.call(arguments, 1);
5358
+ return function(){return f.apply(null, args);};
5359
+ }
5360
+
5361
+ var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
5362
+ function isWordChar(ch) {
5363
+ return /\w/.test(ch) || ch > "\x80" &&
5364
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
5365
+ }
5366
+
5367
+ function isEmpty(obj) {
5368
+ for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
5369
+ return true;
5370
+ }
5371
+
5372
+ var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
5373
+
5374
+ // DOM UTILITIES
5375
+
5376
+ function elt(tag, content, className, style) {
5377
+ var e = document.createElement(tag);
5378
+ if (className) e.className = className;
5379
+ if (style) e.style.cssText = style;
5380
+ if (typeof content == "string") setTextContent(e, content);
5381
+ else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
5382
+ return e;
5383
+ }
5384
+
5385
+ function removeChildren(e) {
5386
+ for (var count = e.childNodes.length; count > 0; --count)
5387
+ e.removeChild(e.firstChild);
5388
+ return e;
5389
+ }
5390
+
5391
+ function removeChildrenAndAdd(parent, e) {
5392
+ return removeChildren(parent).appendChild(e);
5393
+ }
5394
+
5395
+ function setTextContent(e, str) {
5396
+ if (ie_lt9) {
5397
+ e.innerHTML = "";
5398
+ e.appendChild(document.createTextNode(str));
5399
+ } else e.textContent = str;
5400
+ }
5401
+
5402
+ function getRect(node) {
5403
+ return node.getBoundingClientRect();
5404
+ }
5405
+ CodeMirror.replaceGetRect = function(f) { getRect = f; };
5406
+
5407
+ // FEATURE DETECTION
5408
+
5409
+ // Detect drag-and-drop
5410
+ var dragAndDrop = function() {
5411
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
5412
+ // couldn't get it to work yet.
5413
+ if (ie_lt9) return false;
5414
+ var div = elt('div');
5415
+ return "draggable" in div || "dragDrop" in div;
5416
+ }();
5417
+
5418
+ // For a reason I have yet to figure out, some browsers disallow
5419
+ // word wrapping between certain characters *only* if a new inline
5420
+ // element is started between them. This makes it hard to reliably
5421
+ // measure the position of things, since that requires inserting an
5422
+ // extra span. This terribly fragile set of tests matches the
5423
+ // character combinations that suffer from this phenomenon on the
5424
+ // various browsers.
5425
+ function spanAffectsWrapping() { return false; }
5426
+ if (gecko) // Only for "$'"
5427
+ spanAffectsWrapping = function(str, i) {
5428
+ return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
5429
+ };
5430
+ else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
5431
+ spanAffectsWrapping = function(str, i) {
5432
+ return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5433
+ };
5434
+ else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
5435
+ spanAffectsWrapping = function(str, i) {
5436
+ if (i > 1 && str.charCodeAt(i - 1) == 45) {
5437
+ if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
5438
+ if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
5439
+ }
5440
+ return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5441
+ };
5442
+
5443
+ var knownScrollbarWidth;
5444
+ function scrollbarWidth(measure) {
5445
+ if (knownScrollbarWidth != null) return knownScrollbarWidth;
5446
+ var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
5447
+ removeChildrenAndAdd(measure, test);
5448
+ if (test.offsetWidth)
5449
+ knownScrollbarWidth = test.offsetHeight - test.clientHeight;
5450
+ return knownScrollbarWidth || 0;
5451
+ }
5452
+
5453
+ var zwspSupported;
5454
+ function zeroWidthElement(measure) {
5455
+ if (zwspSupported == null) {
5456
+ var test = elt("span", "\u200b");
5457
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
5458
+ if (measure.firstChild.offsetHeight != 0)
5459
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
5460
+ }
5461
+ if (zwspSupported) return elt("span", "\u200b");
5462
+ else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
5463
+ }
5464
+
5465
+ // See if "".split is the broken IE version, if so, provide an
5466
+ // alternative way to split lines.
5467
+ var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
5468
+ var pos = 0, result = [], l = string.length;
5469
+ while (pos <= l) {
5470
+ var nl = string.indexOf("\n", pos);
5471
+ if (nl == -1) nl = string.length;
5472
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
5473
+ var rt = line.indexOf("\r");
5474
+ if (rt != -1) {
5475
+ result.push(line.slice(0, rt));
5476
+ pos += rt + 1;
5477
+ } else {
5478
+ result.push(line);
5479
+ pos = nl + 1;
5480
+ }
5481
+ }
5482
+ return result;
5483
+ } : function(string){return string.split(/\r\n?|\n/);};
5484
+ CodeMirror.splitLines = splitLines;
5485
+
5486
+ var hasSelection = window.getSelection ? function(te) {
5487
+ try { return te.selectionStart != te.selectionEnd; }
5488
+ catch(e) { return false; }
5489
+ } : function(te) {
5490
+ try {var range = te.ownerDocument.selection.createRange();}
5491
+ catch(e) {}
5492
+ if (!range || range.parentElement() != te) return false;
5493
+ return range.compareEndPoints("StartToEnd", range) != 0;
5494
+ };
5495
+
5496
+ var hasCopyEvent = (function() {
5497
+ var e = elt("div");
5498
+ if ("oncopy" in e) return true;
5499
+ e.setAttribute("oncopy", "return;");
5500
+ return typeof e.oncopy == 'function';
5501
+ })();
5502
+
5503
+ // KEY NAMING
5504
+
5505
+ var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
5506
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
5507
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
5508
+ 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
5509
+ 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
5510
+ 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
5511
+ 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
5512
+ CodeMirror.keyNames = keyNames;
5513
+ (function() {
5514
+ // Number keys
5515
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
5516
+ // Alphabetic keys
5517
+ for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
5518
+ // Function keys
5519
+ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
5520
+ })();
5521
+
5522
+ // BIDI HELPERS
5523
+
5524
+ function iterateBidiSections(order, from, to, f) {
5525
+ if (!order) return f(from, to, "ltr");
5526
+ var found = false;
5527
+ for (var i = 0; i < order.length; ++i) {
5528
+ var part = order[i];
5529
+ if (part.from < to && part.to > from || from == to && part.to == from) {
5530
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5531
+ found = true;
5532
+ }
5533
+ }
5534
+ if (!found) f(from, to, "ltr");
5535
+ }
5536
+
5537
+ function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
5538
+ function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
5539
+
5540
+ function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
5541
+ function lineRight(line) {
5542
+ var order = getOrder(line);
5543
+ if (!order) return line.text.length;
5544
+ return bidiRight(lst(order));
5545
+ }
5546
+
5547
+ function lineStart(cm, lineN) {
5548
+ var line = getLine(cm.doc, lineN);
5549
+ var visual = visualLine(cm.doc, line);
5550
+ if (visual != line) lineN = lineNo(visual);
5551
+ var order = getOrder(visual);
5552
+ var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
5553
+ return Pos(lineN, ch);
5554
+ }
5555
+ function lineEnd(cm, lineN) {
5556
+ var merged, line;
5557
+ while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
5558
+ lineN = merged.find().to.line;
5559
+ var order = getOrder(line);
5560
+ var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
5561
+ return Pos(lineN, ch);
5562
+ }
5563
+
5564
+ function compareBidiLevel(order, a, b) {
5565
+ var linedir = order[0].level;
5566
+ if (a == linedir) return true;
5567
+ if (b == linedir) return false;
5568
+ return a < b;
5569
+ }
5570
+ var bidiOther;
5571
+ function getBidiPartAt(order, pos) {
5572
+ for (var i = 0, found; i < order.length; ++i) {
5573
+ var cur = order[i];
5574
+ if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
5575
+ if (cur.from == pos || cur.to == pos) {
5576
+ if (found == null) {
5577
+ found = i;
5578
+ } else if (compareBidiLevel(order, cur.level, order[found].level)) {
5579
+ bidiOther = found;
5580
+ return i;
5581
+ } else {
5582
+ bidiOther = i;
5583
+ return found;
5584
+ }
5585
+ }
5586
+ }
5587
+ bidiOther = null;
5588
+ return found;
5589
+ }
5590
+
5591
+ function moveInLine(line, pos, dir, byUnit) {
5592
+ if (!byUnit) return pos + dir;
5593
+ do pos += dir;
5594
+ while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
5595
+ return pos;
5596
+ }
5597
+
5598
+ // This is somewhat involved. It is needed in order to move
5599
+ // 'visually' through bi-directional text -- i.e., pressing left
5600
+ // should make the cursor go left, even when in RTL text. The
5601
+ // tricky part is the 'jumps', where RTL and LTR text touch each
5602
+ // other. This often requires the cursor offset to move more than
5603
+ // one unit, in order to visually move one unit.
5604
+ function moveVisually(line, start, dir, byUnit) {
5605
+ var bidi = getOrder(line);
5606
+ if (!bidi) return moveLogically(line, start, dir, byUnit);
5607
+ var pos = getBidiPartAt(bidi, start), part = bidi[pos];
5608
+ var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
5609
+
5610
+ for (;;) {
5611
+ if (target > part.from && target < part.to) return target;
5612
+ if (target == part.from || target == part.to) {
5613
+ if (getBidiPartAt(bidi, target) == pos) return target;
5614
+ part = bidi[pos += dir];
5615
+ return (dir > 0) == part.level % 2 ? part.to : part.from;
5616
+ } else {
5617
+ part = bidi[pos += dir];
5618
+ if (!part) return null;
5619
+ if ((dir > 0) == part.level % 2)
5620
+ target = moveInLine(line, part.to, -1, byUnit);
5621
+ else
5622
+ target = moveInLine(line, part.from, 1, byUnit);
5623
+ }
5624
+ }
5625
+ }
5626
+
5627
+ function moveLogically(line, start, dir, byUnit) {
5628
+ var target = start + dir;
5629
+ if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
5630
+ return target < 0 || target > line.text.length ? null : target;
5631
+ }
5632
+
5633
+ // Bidirectional ordering algorithm
5634
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
5635
+ // that this (partially) implements.
5636
+
5637
+ // One-char codes used for character types:
5638
+ // L (L): Left-to-Right
5639
+ // R (R): Right-to-Left
5640
+ // r (AL): Right-to-Left Arabic
5641
+ // 1 (EN): European Number
5642
+ // + (ES): European Number Separator
5643
+ // % (ET): European Number Terminator
5644
+ // n (AN): Arabic Number
5645
+ // , (CS): Common Number Separator
5646
+ // m (NSM): Non-Spacing Mark
5647
+ // b (BN): Boundary Neutral
5648
+ // s (B): Paragraph Separator
5649
+ // t (S): Segment Separator
5650
+ // w (WS): Whitespace
5651
+ // N (ON): Other Neutrals
5652
+
5653
+ // Returns null if characters are ordered as they appear
5654
+ // (left-to-right), or an array of sections ({from, to, level}
5655
+ // objects) in the order in which they occur visually.
5656
+ var bidiOrdering = (function() {
5657
+ // Character types for codepoints 0 to 0xff
5658
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
5659
+ // Character types for codepoints 0x600 to 0x6ff
5660
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
5661
+ function charType(code) {
5662
+ if (code <= 0xff) return lowTypes.charAt(code);
5663
+ else if (0x590 <= code && code <= 0x5f4) return "R";
5664
+ else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
5665
+ else if (0x700 <= code && code <= 0x8ac) return "r";
5666
+ else return "L";
5667
+ }
5668
+
5669
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
5670
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
5671
+ // Browsers seem to always treat the boundaries of block elements as being L.
5672
+ var outerType = "L";
5673
+
5674
+ return function(str) {
5675
+ if (!bidiRE.test(str)) return false;
5676
+ var len = str.length, types = [];
5677
+ for (var i = 0, type; i < len; ++i)
5678
+ types.push(type = charType(str.charCodeAt(i)));
5679
+
5680
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
5681
+ // change the type of the NSM to the type of the previous
5682
+ // character. If the NSM is at the start of the level run, it will
5683
+ // get the type of sor.
5684
+ for (var i = 0, prev = outerType; i < len; ++i) {
5685
+ var type = types[i];
5686
+ if (type == "m") types[i] = prev;
5687
+ else prev = type;
5688
+ }
5689
+
5690
+ // W2. Search backwards from each instance of a European number
5691
+ // until the first strong type (R, L, AL, or sor) is found. If an
5692
+ // AL is found, change the type of the European number to Arabic
5693
+ // number.
5694
+ // W3. Change all ALs to R.
5695
+ for (var i = 0, cur = outerType; i < len; ++i) {
5696
+ var type = types[i];
5697
+ if (type == "1" && cur == "r") types[i] = "n";
5698
+ else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
5699
+ }
5700
+
5701
+ // W4. A single European separator between two European numbers
5702
+ // changes to a European number. A single common separator between
5703
+ // two numbers of the same type changes to that type.
5704
+ for (var i = 1, prev = types[0]; i < len - 1; ++i) {
5705
+ var type = types[i];
5706
+ if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
5707
+ else if (type == "," && prev == types[i+1] &&
5708
+ (prev == "1" || prev == "n")) types[i] = prev;
5709
+ prev = type;
5710
+ }
5711
+
5712
+ // W5. A sequence of European terminators adjacent to European
5713
+ // numbers changes to all European numbers.
5714
+ // W6. Otherwise, separators and terminators change to Other
5715
+ // Neutral.
5716
+ for (var i = 0; i < len; ++i) {
5717
+ var type = types[i];
5718
+ if (type == ",") types[i] = "N";
5719
+ else if (type == "%") {
5720
+ for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
5721
+ var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
5722
+ for (var j = i; j < end; ++j) types[j] = replace;
5723
+ i = end - 1;
5724
+ }
5725
+ }
5726
+
5727
+ // W7. Search backwards from each instance of a European number
5728
+ // until the first strong type (R, L, or sor) is found. If an L is
5729
+ // found, then change the type of the European number to L.
5730
+ for (var i = 0, cur = outerType; i < len; ++i) {
5731
+ var type = types[i];
5732
+ if (cur == "L" && type == "1") types[i] = "L";
5733
+ else if (isStrong.test(type)) cur = type;
5734
+ }
5735
+
5736
+ // N1. A sequence of neutrals takes the direction of the
5737
+ // surrounding strong text if the text on both sides has the same
5738
+ // direction. European and Arabic numbers act as if they were R in
5739
+ // terms of their influence on neutrals. Start-of-level-run (sor)
5740
+ // and end-of-level-run (eor) are used at level run boundaries.
5741
+ // N2. Any remaining neutrals take the embedding direction.
5742
+ for (var i = 0; i < len; ++i) {
5743
+ if (isNeutral.test(types[i])) {
5744
+ for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
5745
+ var before = (i ? types[i-1] : outerType) == "L";
5746
+ var after = (end < len - 1 ? types[end] : outerType) == "L";
5747
+ var replace = before || after ? "L" : "R";
5748
+ for (var j = i; j < end; ++j) types[j] = replace;
5749
+ i = end - 1;
5750
+ }
5751
+ }
5752
+
5753
+ // Here we depart from the documented algorithm, in order to avoid
5754
+ // building up an actual levels array. Since there are only three
5755
+ // levels (0, 1, 2) in an implementation that doesn't take
5756
+ // explicit embedding into account, we can build up the order on
5757
+ // the fly, without following the level-based algorithm.
5758
+ var order = [], m;
5759
+ for (var i = 0; i < len;) {
5760
+ if (countsAsLeft.test(types[i])) {
5761
+ var start = i;
5762
+ for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
5763
+ order.push({from: start, to: i, level: 0});
5764
+ } else {
5765
+ var pos = i, at = order.length;
5766
+ for (++i; i < len && types[i] != "L"; ++i) {}
5767
+ for (var j = pos; j < i;) {
5768
+ if (countsAsNum.test(types[j])) {
5769
+ if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
5770
+ var nstart = j;
5771
+ for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
5772
+ order.splice(at, 0, {from: nstart, to: j, level: 2});
5773
+ pos = j;
5774
+ } else ++j;
5775
+ }
5776
+ if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
5777
+ }
5778
+ }
5779
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
5780
+ order[0].from = m[0].length;
5781
+ order.unshift({from: 0, to: m[0].length, level: 0});
5782
+ }
5783
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
5784
+ lst(order).to -= m[0].length;
5785
+ order.push({from: len - m[0].length, to: len, level: 0});
5786
+ }
5787
+ if (order[0].level != lst(order).level)
5788
+ order.push({from: len, to: len, level: order[0].level});
5789
+
5790
+ return order;
5791
+ };
5792
+ })();
5793
+
5794
+ // THE END
5795
+
5796
+ CodeMirror.version = "3.15.0";
5797
+
5798
+ return CodeMirror;
5799
+ })();
plugin-fw/assets/js/codemirror/javascript.js ADDED
@@ -0,0 +1,630 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // TODO actually recognize syntax of TypeScript constructs
2
+
3
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
4
+ var indentUnit = config.indentUnit;
5
+ var statementIndent = parserConfig.statementIndent;
6
+ var jsonMode = parserConfig.json;
7
+ var isTS = parserConfig.typescript;
8
+
9
+ // Tokenizer
10
+
11
+ var keywords = function(){
12
+ function kw(type) {return {type: type, style: "keyword"};}
13
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
14
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
15
+
16
+ var jsKeywords = {
17
+ "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
18
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19
+ "var": kw("var"), "const": kw("var"), "let": kw("var"),
20
+ "function": kw("function"), "catch": kw("catch"),
21
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
22
+ "in": operator, "typeof": operator, "instanceof": operator,
23
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
24
+ "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
25
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
26
+ };
27
+
28
+ // Extend the 'normal' keywords with the TypeScript language extensions
29
+ if (isTS) {
30
+ var type = {type: "variable", style: "variable-3"};
31
+ var tsKeywords = {
32
+ // object-like things
33
+ "interface": kw("interface"),
34
+ "extends": kw("extends"),
35
+ "constructor": kw("constructor"),
36
+
37
+ // scope modifiers
38
+ "public": kw("public"),
39
+ "private": kw("private"),
40
+ "protected": kw("protected"),
41
+ "static": kw("static"),
42
+
43
+ // types
44
+ "string": type, "number": type, "bool": type, "any": type
45
+ };
46
+
47
+ for (var attr in tsKeywords) {
48
+ jsKeywords[attr] = tsKeywords[attr];
49
+ }
50
+ }
51
+
52
+ return jsKeywords;
53
+ }();
54
+
55
+ var isOperatorChar = /[+\-*&%=<>!?|~^]/;
56
+
57
+ function readRegexp(stream) {
58
+ var escaped = false, next, inSet = false;
59
+ while ((next = stream.next()) != null) {
60
+ if (!escaped) {
61
+ if (next == "/" && !inSet) return;
62
+ if (next == "[") inSet = true;
63
+ else if (inSet && next == "]") inSet = false;
64
+ }
65
+ escaped = !escaped && next == "\\";
66
+ }
67
+ }
68
+
69
+ // Used as scratch variables to communicate multiple values without
70
+ // consing up tons of objects.
71
+ var type, content;
72
+ function ret(tp, style, cont) {
73
+ type = tp; content = cont;
74
+ return style;
75
+ }
76
+ function tokenBase(stream, state) {
77
+ var ch = stream.next();
78
+ if (ch == '"' || ch == "'") {
79
+ state.tokenize = tokenString(ch);
80
+ return state.tokenize(stream, state);
81
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
82
+ return ret("number", "number");
83
+ } else if (ch == "." && stream.match("..")) {
84
+ return ret("spread", "meta");
85
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
86
+ return ret(ch);
87
+ } else if (ch == "=" && stream.eat(">")) {
88
+ return ret("=>", "operator");
89
+ } else if (ch == "0" && stream.eat(/x/i)) {
90
+ stream.eatWhile(/[\da-f]/i);
91
+ return ret("number", "number");
92
+ } else if (/\d/.test(ch)) {
93
+ stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
94
+ return ret("number", "number");
95
+ } else if (ch == "/") {
96
+ if (stream.eat("*")) {
97
+ state.tokenize = tokenComment;
98
+ return tokenComment(stream, state);
99
+ } else if (stream.eat("/")) {
100
+ stream.skipToEnd();
101
+ return ret("comment", "comment");
102
+ } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
103
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
104
+ readRegexp(stream);
105
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
106
+ return ret("regexp", "string-2");
107
+ } else {
108
+ stream.eatWhile(isOperatorChar);
109
+ return ret("operator", "operator", stream.current());
110
+ }
111
+ } else if (ch == "`") {
112
+ state.tokenize = tokenQuasi;
113
+ return tokenQuasi(stream, state);
114
+ } else if (ch == "#") {
115
+ stream.skipToEnd();
116
+ return ret("error", "error");
117
+ } else if (isOperatorChar.test(ch)) {
118
+ stream.eatWhile(isOperatorChar);
119
+ return ret("operator", "operator", stream.current());
120
+ } else {
121
+ stream.eatWhile(/[\w\$_]/);
122
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
123
+ return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
124
+ ret("variable", "variable", word);
125
+ }
126
+ }
127
+
128
+ function tokenString(quote) {
129
+ return function(stream, state) {
130
+ var escaped = false, next;
131
+ while ((next = stream.next()) != null) {
132
+ if (next == quote && !escaped) break;
133
+ escaped = !escaped && next == "\\";
134
+ }
135
+ if (!escaped) state.tokenize = tokenBase;
136
+ return ret("string", "string");
137
+ };
138
+ }
139
+
140
+ function tokenComment(stream, state) {
141
+ var maybeEnd = false, ch;
142
+ while (ch = stream.next()) {
143
+ if (ch == "/" && maybeEnd) {
144
+ state.tokenize = tokenBase;
145
+ break;
146
+ }
147
+ maybeEnd = (ch == "*");
148
+ }
149
+ return ret("comment", "comment");
150
+ }
151
+
152
+ function tokenQuasi(stream, state) {
153
+ var escaped = false, next;
154
+ while ((next = stream.next()) != null) {
155
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
156
+ state.tokenize = tokenBase;
157
+ break;
158
+ }
159
+ escaped = !escaped && next == "\\";
160
+ }
161
+ return ret("quasi", "string-2", stream.current());
162
+ }
163
+
164
+ var brackets = "([{}])";
165
+ // This is a crude lookahead trick to try and notice that we're
166
+ // parsing the argument patterns for a fat-arrow function before we
167
+ // actually hit the arrow token. It only works if the arrow is on
168
+ // the same line as the arguments and there's no strange noise
169
+ // (comments) in between. Fallback is to only notice when we hit the
170
+ // arrow, and not declare the arguments as locals for the arrow
171
+ // body.
172
+ function findFatArrow(stream, state) {
173
+ if (state.fatArrowAt) state.fatArrowAt = null;
174
+ var arrow = stream.string.indexOf("=>", stream.start);
175
+ if (arrow < 0) return;
176
+
177
+ var depth = 0, sawSomething = false;
178
+ for (var pos = arrow - 1; pos >= 0; --pos) {
179
+ var ch = stream.string.charAt(pos);
180
+ var bracket = brackets.indexOf(ch);
181
+ if (bracket >= 0 && bracket < 3) {
182
+ if (!depth) { ++pos; break; }
183
+ if (--depth == 0) break;
184
+ } else if (bracket >= 3 && bracket < 6) {
185
+ ++depth;
186
+ } else if (/[$\w]/.test(ch)) {
187
+ sawSomething = true;
188
+ } else if (sawSomething && !depth) {
189
+ ++pos;
190
+ break;
191
+ }
192
+ }
193
+ if (sawSomething && !depth) state.fatArrowAt = pos;
194
+ }
195
+
196
+ // Parser
197
+
198
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
199
+
200
+ function JSLexical(indented, column, type, align, prev, info) {
201
+ this.indented = indented;
202
+ this.column = column;
203
+ this.type = type;
204
+ this.prev = prev;
205
+ this.info = info;
206
+ if (align != null) this.align = align;
207
+ }
208
+
209
+ function inScope(state, varname) {
210
+ for (var v = state.localVars; v; v = v.next)
211
+ if (v.name == varname) return true;
212
+ for (var cx = state.context; cx; cx = cx.prev) {
213
+ for (var v = cx.vars; v; v = v.next)
214
+ if (v.name == varname) return true;
215
+ }
216
+ }
217
+
218
+ function parseJS(state, style, type, content, stream) {
219
+ var cc = state.cc;
220
+ // Communicate our context to the combinators.
221
+ // (Less wasteful than consing up a hundred closures on every call.)
222
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
223
+
224
+ if (!state.lexical.hasOwnProperty("align"))
225
+ state.lexical.align = true;
226
+
227
+ while(true) {
228
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
229
+ if (combinator(type, content)) {
230
+ while(cc.length && cc[cc.length - 1].lex)
231
+ cc.pop()();
232
+ if (cx.marked) return cx.marked;
233
+ if (type == "variable" && inScope(state, content)) return "variable-2";
234
+ return style;
235
+ }
236
+ }
237
+ }
238
+
239
+ // Combinator utils
240
+
241
+ var cx = {state: null, column: null, marked: null, cc: null};
242
+ function pass() {
243
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
244
+ }
245
+ function cont() {
246
+ pass.apply(null, arguments);
247
+ return true;
248
+ }
249
+ function register(varname) {
250
+ function inList(list) {
251
+ for (var v = list; v; v = v.next)
252
+ if (v.name == varname) return true;
253
+ return false;
254
+ }
255
+ var state = cx.state;
256
+ if (state.context) {
257
+ cx.marked = "def";
258
+ if (inList(state.localVars)) return;
259
+ state.localVars = {name: varname, next: state.localVars};
260
+ } else {
261
+ if (inList(state.globalVars)) return;
262
+ if (parserConfig.globalVars)
263
+ state.globalVars = {name: varname, next: state.globalVars};
264
+ }
265
+ }
266
+
267
+ // Combinators
268
+
269
+ var defaultVars = {name: "this", next: {name: "arguments"}};
270
+ function pushcontext() {
271
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
272
+ cx.state.localVars = defaultVars;
273
+ }
274
+ function popcontext() {
275
+ cx.state.localVars = cx.state.context.vars;
276
+ cx.state.context = cx.state.context.prev;
277
+ }
278
+ function pushlex(type, info) {
279
+ var result = function() {
280
+ var state = cx.state, indent = state.indented;
281
+ if (state.lexical.type == "stat") indent = state.lexical.indented;
282
+ state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
283
+ };
284
+ result.lex = true;
285
+ return result;
286
+ }
287
+ function poplex() {
288
+ var state = cx.state;
289
+ if (state.lexical.prev) {
290
+ if (state.lexical.type == ")")
291
+ state.indented = state.lexical.indented;
292
+ state.lexical = state.lexical.prev;
293
+ }
294
+ }
295
+ poplex.lex = true;
296
+
297
+ function expect(wanted) {
298
+ return function(type) {
299
+ if (type == wanted) return cont();
300
+ else if (wanted == ";") return pass();
301
+ else return cont(arguments.callee);
302
+ };
303
+ }
304
+
305
+ function statement(type, value) {
306
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
307
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
308
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
309
+ if (type == "{") return cont(pushlex("}"), block, poplex);
310
+ if (type == ";") return cont();
311
+ if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
312
+ if (type == "function") return cont(functiondef);
313
+ if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
314
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
315
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
316
+ block, poplex, poplex);
317
+ if (type == "case") return cont(expression, expect(":"));
318
+ if (type == "default") return cont(expect(":"));
319
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
320
+ statement, poplex, popcontext);
321
+ if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
322
+ if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
323
+ if (type == "export") return cont(pushlex("form"), afterExport, poplex);
324
+ if (type == "import") return cont(pushlex("form"), afterImport, poplex);
325
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
326
+ }
327
+ function expression(type) {
328
+ return expressionInner(type, false);
329
+ }
330
+ function expressionNoComma(type) {
331
+ return expressionInner(type, true);
332
+ }
333
+ function expressionInner(type, noComma) {
334
+ if (cx.state.fatArrowAt == cx.stream.start) {
335
+ var body = noComma ? arrowBodyNoComma : arrowBody;
336
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
337
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
338
+ }
339
+
340
+ var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
341
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
342
+ if (type == "function") return cont(functiondef);
343
+ if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
344
+ if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
345
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
346
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
347
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
348
+ return cont();
349
+ }
350
+ function maybeexpression(type) {
351
+ if (type.match(/[;\}\)\],]/)) return pass();
352
+ return pass(expression);
353
+ }
354
+ function maybeexpressionNoComma(type) {
355
+ if (type.match(/[;\}\)\],]/)) return pass();
356
+ return pass(expressionNoComma);
357
+ }
358
+
359
+ function maybeoperatorComma(type, value) {
360
+ if (type == ",") return cont(expression);
361
+ return maybeoperatorNoComma(type, value, false);
362
+ }
363
+ function maybeoperatorNoComma(type, value, noComma) {
364
+ var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
365
+ var expr = noComma == false ? expression : expressionNoComma;
366
+ if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
367
+ if (type == "operator") {
368
+ if (/\+\+|--/.test(value)) return cont(me);
369
+ if (value == "?") return cont(expression, expect(":"), expr);
370
+ return cont(expr);
371
+ }
372
+ if (type == "quasi") { cx.cc.push(me); return quasi(value); }
373
+ if (type == ";") return;
374
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
375
+ if (type == ".") return cont(property, me);
376
+ if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
377
+ }
378
+ function quasi(value) {
379
+ if (value.slice(value.length - 2) != "${") return cont();
380
+ return cont(expression, continueQuasi);
381
+ }
382
+ function continueQuasi(type) {
383
+ if (type == "}") {
384
+ cx.marked = "string-2";
385
+ cx.state.tokenize = tokenQuasi;
386
+ return cont();
387
+ }
388
+ }
389
+ function arrowBody(type) {
390
+ findFatArrow(cx.stream, cx.state);
391
+ if (type == "{") return pass(statement);
392
+ return pass(expression);
393
+ }
394
+ function arrowBodyNoComma(type) {
395
+ findFatArrow(cx.stream, cx.state);
396
+ if (type == "{") return pass(statement);
397
+ return pass(expressionNoComma);
398
+ }
399
+ function maybelabel(type) {
400
+ if (type == ":") return cont(poplex, statement);
401
+ return pass(maybeoperatorComma, expect(";"), poplex);
402
+ }
403
+ function property(type) {
404
+ if (type == "variable") {cx.marked = "property"; return cont();}
405
+ }
406
+ function objprop(type, value) {
407
+ if (type == "variable") {
408
+ cx.marked = "property";
409
+ if (value == "get" || value == "set") return cont(getterSetter);
410
+ } else if (type == "number" || type == "string") {
411
+ cx.marked = type + " property";
412
+ } else if (type == "[") {
413
+ return cont(expression, expect("]"), afterprop);
414
+ }
415
+ if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
416
+ }
417
+ function getterSetter(type) {
418
+ if (type != "variable") return pass(afterprop);
419
+ cx.marked = "property";
420
+ return cont(functiondef);
421
+ }
422
+ function afterprop(type) {
423
+ if (type == ":") return cont(expressionNoComma);
424
+ if (type == "(") return pass(functiondef);
425
+ }
426
+ function commasep(what, end) {
427
+ function proceed(type) {
428
+ if (type == ",") {
429
+ var lex = cx.state.lexical;
430
+ if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
431
+ return cont(what, proceed);
432
+ }
433
+ if (type == end) return cont();
434
+ return cont(expect(end));
435
+ }
436
+ return function(type) {
437
+ if (type == end) return cont();
438
+ return pass(what, proceed);
439
+ };
440
+ }
441
+ function contCommasep(what, end, info) {
442
+ for (var i = 3; i < arguments.length; i++)
443
+ cx.cc.push(arguments[i]);
444
+ return cont(pushlex(end, info), commasep(what, end), poplex);
445
+ }
446
+ function block(type) {
447
+ if (type == "}") return cont();
448
+ return pass(statement, block);
449
+ }
450
+ function maybetype(type) {
451
+ if (isTS && type == ":") return cont(typedef);
452
+ }
453
+ function typedef(type) {
454
+ if (type == "variable"){cx.marked = "variable-3"; return cont();}
455
+ }
456
+ function vardef() {
457
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
458
+ }
459
+ function pattern(type, value) {
460
+ if (type == "variable") { register(value); return cont(); }
461
+ if (type == "[") return contCommasep(pattern, "]");
462
+ if (type == "{") return contCommasep(proppattern, "}");
463
+ }
464
+ function proppattern(type, value) {
465
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
466
+ register(value);
467
+ return cont(maybeAssign);
468
+ }
469
+ if (type == "variable") cx.marked = "property";
470
+ return cont(expect(":"), pattern, maybeAssign);
471
+ }
472
+ function maybeAssign(_type, value) {
473
+ if (value == "=") return cont(expressionNoComma);
474
+ }
475
+ function vardefCont(type) {
476
+ if (type == ",") return cont(vardef);
477
+ }
478
+ function maybeelse(type, value) {
479
+ if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
480
+ }
481
+ function forspec(type) {
482
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
483
+ }
484
+ function forspec1(type) {
485
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
486
+ if (type == ";") return cont(forspec2);
487
+ if (type == "variable") return cont(formaybeinof);
488
+ return pass(expression, expect(";"), forspec2);
489
+ }
490
+ function formaybeinof(_type, value) {
491
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
492
+ return cont(maybeoperatorComma, forspec2);
493
+ }
494
+ function forspec2(type, value) {
495
+ if (type == ";") return cont(forspec3);
496
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
497
+ return pass(expression, expect(";"), forspec3);
498
+ }
499
+ function forspec3(type) {
500
+ if (type != ")") cont(expression);
501
+ }
502
+ function functiondef(type, value) {
503
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
504
+ if (type == "variable") {register(value); return cont(functiondef);}
505
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
506
+ }
507
+ function funarg(type) {
508
+ if (type == "spread") return cont(funarg);
509
+ return pass(pattern, maybetype);
510
+ }
511
+ function className(type, value) {
512
+ if (type == "variable") {register(value); return cont(classNameAfter);}
513
+ }
514
+ function classNameAfter(_type, value) {
515
+ if (value == "extends") return cont(expression);
516
+ }
517
+ function objlit(type) {
518
+ if (type == "{") return contCommasep(objprop, "}");
519
+ }
520
+ function afterModule(type, value) {
521
+ if (type == "string") return cont(statement);
522
+ if (type == "variable") { register(value); return cont(maybeFrom); }
523
+ }
524
+ function afterExport(_type, value) {
525
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
526
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
527
+ return pass(statement);
528
+ }
529
+ function afterImport(type) {
530
+ if (type == "string") return cont();
531
+ return pass(importSpec, maybeFrom);
532
+ }
533
+ function importSpec(type, value) {
534
+ if (type == "{") return contCommasep(importSpec, "}");
535
+ if (type == "variable") register(value);
536
+ return cont();
537
+ }
538
+ function maybeFrom(_type, value) {
539
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
540
+ }
541
+ function arrayLiteral(type) {
542
+ if (type == "]") return cont();
543
+ return pass(expressionNoComma, maybeArrayComprehension);
544
+ }
545
+ function maybeArrayComprehension(type) {
546
+ if (type == "for") return pass(comprehension, expect("]"));
547
+ if (type == ",") return cont(commasep(expressionNoComma, "]"));
548
+ return pass(commasep(expressionNoComma, "]"));
549
+ }
550
+ function comprehension(type) {
551
+ if (type == "for") return cont(forspec, comprehension);
552
+ if (type == "if") return cont(expression, comprehension);
553
+ }
554
+
555
+ // Interface
556
+
557
+ return {
558
+ startState: function(basecolumn) {
559
+ var state = {
560
+ tokenize: tokenBase,
561
+ lastType: "sof",
562
+ cc: [],
563
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
564
+ localVars: parserConfig.localVars,
565
+ context: parserConfig.localVars && {vars: parserConfig.localVars},
566
+ indented: 0
567
+ };
568
+ if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
569
+ return state;
570
+ },
571
+
572
+ token: function(stream, state) {
573
+ if (stream.sol()) {
574
+ if (!state.lexical.hasOwnProperty("align"))
575
+ state.lexical.align = false;
576
+ state.indented = stream.indentation();
577
+ findFatArrow(stream, state);
578
+ }
579
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
580
+ var style = state.tokenize(stream, state);
581
+ if (type == "comment") return style;
582
+ state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
583
+ return parseJS(state, style, type, content, stream);
584
+ },
585
+
586
+ indent: function(state, textAfter) {
587
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
588
+ if (state.tokenize != tokenBase) return 0;
589
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
590
+ // Kludge to prevent 'maybelse' from blocking lexical scope pops
591
+ for (var i = state.cc.length - 1; i >= 0; --i) {
592
+ var c = state.cc[i];
593
+ if (c == poplex) lexical = lexical.prev;
594
+ else if (c != maybeelse) break;
595
+ }
596
+ if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
597
+ if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
598
+ lexical = lexical.prev;
599
+ var type = lexical.type, closing = firstChar == type;
600
+
601
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
602
+ else if (type == "form" && firstChar == "{") return lexical.indented;
603
+ else if (type == "form") return lexical.indented + indentUnit;
604
+ else if (type == "stat")
605
+ return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
606
+ else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
607
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
608
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
609
+ else return lexical.indented + (closing ? 0 : indentUnit);
610
+ },
611
+
612
+ electricChars: ":{}",
613
+ blockCommentStart: jsonMode ? null : "/*",
614
+ blockCommentEnd: jsonMode ? null : "*/",
615
+ lineComment: jsonMode ? null : "//",
616
+ fold: "brace",
617
+
618
+ helperType: jsonMode ? "json" : "javascript",
619
+ jsonMode: jsonMode
620
+ };
621
+ });
622
+
623
+ CodeMirror.defineMIME("text/javascript", "javascript");
624
+ CodeMirror.defineMIME("text/ecmascript", "javascript");
625
+ CodeMirror.defineMIME("application/javascript", "javascript");
626
+ CodeMirror.defineMIME("application/ecmascript", "javascript");
627
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
628
+ CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
629
+ CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
630
+ CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
plugin-fw/assets/js/metabox.js ADDED
@@ -0,0 +1,354 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ $('.metaboxes-tab').each(function () {
12
+ $('.tabs-panel', this).hide();
13
+
14
+ var active_tab = wpCookies.get('active_metabox_tab');
15
+ if (active_tab == null) {
16
+ active_tab = $('ul.metaboxes-tabs li:first-child a', this).attr('href');
17
+ } else {
18
+ active_tab = '#' + active_tab;
19
+ }
20
+
21
+ $(active_tab).show();
22
+
23
+ $('.metaboxes-tabs a', this).click(function (e) {
24
+ if ($(this).parent().hasClass('tabs')) {
25
+ e.preventDefault();
26
+ return;
27
+ }
28
+
29
+ var t = $(this).attr('href');
30
+ $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
31
+ $(this).closest('.metaboxes-tab').find('.tabs-panel').slideUp('fast');
32
+ $(t).delay(350).slideDown('fast');
33
+
34
+ return false;
35
+ });
36
+ });
37
+
38
+ //upload
39
+ var _custom_media = true,
40
+ _orig_send_attachment = wp.media.editor.send.attachment;
41
+
42
+ $(document).on('click', '.metaboxes-tab .upload_button', function(e) {
43
+ var send_attachment_bkp = wp.media.editor.send.attachment;
44
+ var button = $(this);
45
+ if( typeof button.attr('id') != 'undefined' ) {
46
+
47
+ var id = button.attr('id').replace('-button', '');
48
+ _custom_media = true;
49
+ wp.media.editor.send.attachment = function(props, attachment){
50
+ if ( _custom_media ) {
51
+ if( $("#"+id).is('input[type=text]') ) {
52
+ $("#"+id).val(attachment.url);
53
+ } else {
54
+ $("#"+id + '_custom').val(attachment.url);
55
+ }
56
+ } else {
57
+ return _orig_send_attachment.apply( this, [props, attachment] );
58
+ };
59
+ }
60
+
61
+ wp.media.editor.open(button);
62
+ return false;
63
+ }
64
+
65
+ });
66
+
67
+ $('.metaboxes-tab .add_media').on('click', function(){
68
+ _custom_media = false;
69
+ });
70
+
71
+ //colorpicker
72
+ $('.metaboxes-tab .panel-colorpicker').wpColorPicker({
73
+ onInit: function(){ console.log('test');},
74
+ change: function(event, ui){
75
+ },
76
+ clear: function(){
77
+ var input = $(this);
78
+ input.val(input.data('default-color'));
79
+ input.change();
80
+ }
81
+ });
82
+
83
+
84
+ $('.metaboxes-tab .panel-colorpicker').each( function() {
85
+ var select_label = $(this).data('variations-label');
86
+ $(this).parent().parent().find('a.wp-color-result').attr('title', select_label);
87
+ });
88
+
89
+ //datepicker
90
+ $('.metaboxes-tab .panel-datepicker').each( function() {
91
+ $(this).datepicker();
92
+ });
93
+
94
+
95
+ // select
96
+ var select_value = function() {
97
+ var value = '';
98
+
99
+ if( $(this).attr('multiple')){
100
+ $(this).children("option:selected").each(function(i,v){
101
+ if( i != 0)
102
+ value += ', ';
103
+
104
+ value += $(v).text();
105
+ });
106
+
107
+ if( value == '' ){
108
+ $(this).children().children("option:selected").each(function(i,v){
109
+ if( i != 0)
110
+ value += ', ';
111
+
112
+ value += $(v).text();
113
+ });
114
+ }
115
+ }
116
+ else{
117
+ value = $(this).children("option:selected").text();
118
+
119
+ if( value == '' )
120
+ value = $(this).children().children("option:selected").text();
121
+ }
122
+
123
+
124
+ if ( $(this).parent().find('span').length <= 0 ) {
125
+ $(this).before('<span></span>');
126
+ }
127
+
128
+ $(this).parent().children('span').replaceWith('<span>'+value +'</span>');
129
+ };
130
+ $('.metaboxes-tab .select_wrapper select').not('.chosen').each(select_value).change(select_value);
131
+
132
+ //Open select multiple
133
+ $('.metaboxes-tab .select_wrapper').click( function(e){
134
+ e.stopPropagation();
135
+ $(this).find('select[multiple]').not('.chosen').toggle();
136
+ });
137
+ //Stops click propagation on select, to prevent select hide
138
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').click( function(e){
139
+ e.stopPropagation();
140
+ });
141
+ //Hides select on window click
142
+ $(window).click(function(){
143
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').hide();
144
+ })
145
+
146
+ //on-off
147
+ $('.metaboxes-tab .onoff_container span').on('click', function(){
148
+
149
+ var input = $( this ).prev( 'input' );
150
+ var checked = input.prop( 'checked' );
151
+
152
+ if( checked ) {
153
+ input.prop( 'checked', false ).attr( 'value', 'no' ).removeClass('onoffchecked');
154
+ } else {
155
+ input.prop( 'checked', true ).attr( 'value', 'yes' ).addClass('onoffchecked');
156
+ }
157
+
158
+ input.change();
159
+ });
160
+
161
+ //chosen
162
+ $('.metaboxes-tab .chosen .select_wrapper select').chosen();
163
+
164
+
165
+ $('.metaboxes-tab .slider_container .ui-slider-horizontal').each(function(){
166
+ var val = $(this).data('val');
167
+ var minValue = $(this).data('min');
168
+ var maxValue = $(this).data('max');
169
+ var step = $(this).data('step');
170
+ var labels = $(this).data('labels');
171
+
172
+ $(this).slider({
173
+ value: val,
174
+ min: minValue,
175
+ max: maxValue,
176
+ range: 'min',
177
+ step: step,
178
+
179
+ slide: function( event, ui ) {
180
+ $(this).find('input').val( ui.value );
181
+ $(this).siblings('.feedback').find('strong' ).text( ui.value + labels );
182
+ }
183
+ });
184
+ });
185
+
186
+
187
+ var act_page_option = $('#_active_page_options-container').parent().html();
188
+ $('#_active_page_options-container').parent().remove();
189
+ $(act_page_option).insertAfter('#yit-post-setting .handlediv');
190
+ $(act_page_option).insertAfter('#yit-page-setting .handlediv');
191
+
192
+
193
+ $('#_active_page_options-container').on('click', function(){
194
+ if( $('#_active_page_options').is(":checked") ){
195
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 1 , 'pointer-events' : 'auto' } );
196
+ }else{
197
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 0.5 , 'pointer-events' : 'none' } );
198
+ }
199
+ }).click();
200
+
201
+
202
+ //dependencies handler
203
+ $('.metaboxes-tab [data-field]').each(function(){
204
+ var t = $(this);
205
+
206
+ var field = '#' + t.data('field'),
207
+ dep = '#' + t.data('dep'),
208
+ value = t.data('value');
209
+
210
+
211
+ dependencies_handler( field, dep, value.toString() );
212
+
213
+ $(dep).on('change', function(){
214
+ dependencies_handler( field, dep, value.toString() );
215
+ }).change();
216
+ });
217
+
218
+ //Handle dependencies.
219
+ function dependencies_handler ( id, deps, values ) {
220
+ var result = true;
221
+
222
+
223
+ //Single dependency
224
+ if( typeof( deps ) == 'string' ) {
225
+ if( deps.substr( 0, 6 ) == ':radio' )
226
+ {deps = deps + ':checked'; }
227
+
228
+ var val = $( deps ).val();
229
+
230
+ if( $(deps).attr('type') == 'checkbox'){
231
+ var thisCheck = $(deps);
232
+ if ( thisCheck.is ( ':checked' ) ) {
233
+ val = 'yes';
234
+ }
235
+ else {
236
+ val = 'no';
237
+ }
238
+ }
239
+
240
+ var values = values.split( ',' );
241
+
242
+ for( var i = 0; i < values.length; i++ ) {
243
+ if( val != values[i] )
244
+ { result = false; }
245
+ else
246
+ { result = true; break; }
247
+ }
248
+ }
249
+
250
+ if( !result ) {
251
+ $( id + '-container' ).parent().hide();
252
+ } else {
253
+ $( id + '-container' ).parent().show();
254
+ }
255
+ };
256
+
257
+ // Image gallery
258
+ $(document).on('click', '.image-gallery-button', function (e) {
259
+ var $t = $(this),
260
+ $container = $t.closest('.image-gallery'),
261
+ $image_gallery_ids = $container.find('.image_gallery_ids'),
262
+ attachment_ids = $image_gallery_ids.val(),
263
+ $gallery_images_wrapper = $container.find('ul.slides-wrapper');
264
+
265
+
266
+ // Create the media frame.
267
+ var image_gallery_frame = wp.media.frames.image_gallery = wp.media({
268
+ // Set the title of the modal.
269
+ title : $t.data('choose'),
270
+ button: {
271
+ text: $t.data('update')
272
+ },
273
+ states: [
274
+ new wp.media.controller.Library({
275
+ title : $t.data('choose'),
276
+ filterable: 'all',
277
+ multiple : true
278
+ })
279
+ ]
280
+ });
281
+
282
+ // When an image is selected, run a callback.
283
+ image_gallery_frame.on('select', function () {
284
+ var selection = image_gallery_frame.state().get('selection');
285
+ selection.map(function (attachment) {
286
+ attachment = attachment.toJSON();
287
+
288
+ if (attachment.id) {
289
+ attachment_ids = attachment_ids ? attachment_ids + "," + attachment.id : attachment.id;
290
+ $gallery_images_wrapper.append('<li class="image" data-attachment_id="' + attachment.id + '"><img src="' + attachment.sizes.thumbnail.url + '"/><ul class="actions"><li><a href="#" class="delete" title="' + $t.data('delete') + '">x</a></li></ul></li>');
291
+ }
292
+ });
293
+
294
+ $image_gallery_ids.val(attachment_ids);
295
+ });
296
+
297
+ image_gallery_frame.open();
298
+
299
+ });
300
+
301
+ // Image ordering
302
+ $('.image-gallery ul.slides-wrapper').each(function(){
303
+ var $t = $(this);
304
+ $t.sortable({
305
+ items : 'li.image',
306
+ cursor : 'move',
307
+ scrollSensitivity : 40,
308
+ forcePlaceholderSize: true,
309
+ forceHelperSize : false,
310
+ helper : 'clone',
311
+ opacity : 0.65,
312
+ start : function (event, ui) {
313
+ ui.item.css('background-color', '#f6f6f6');
314
+ },
315
+ stop : function (event, ui) {
316
+ ui.item.removeAttr('style');
317
+ },
318
+ update : function (event, ui) {
319
+ var attachment_ids = '';
320
+
321
+ $t.find('li.image').css('cursor', 'default').each(function () {
322
+ var attachment_id = $(this).attr('data-attachment_id');
323
+ attachment_ids = attachment_ids + attachment_id + ',';
324
+ });
325
+
326
+ $t.closest('.image-gallery').find('.image_gallery_ids').val(attachment_ids);
327
+ }
328
+ });
329
+ });
330
+
331
+ // Remove images
332
+ $('.image-gallery ul.slides-wrapper').on( 'click', 'a.delete', function() {
333
+
334
+ var $wrapper = $(this).closest('.image-gallery'),
335
+ $gallery = $(this).closest('.image-gallery ul.slides-wrapper'),
336
+ $image_gallery_ids = $wrapper.find('.image_gallery_ids'),
337
+ attachment_ids = '';
338
+
339
+ $(this).closest('li.image').remove();
340
+
341
+ $gallery.find('li.image').css('cursor','default').each(function() {
342
+ var attachment_id = $(this).attr( 'data-attachment_id' );
343
+ attachment_ids = attachment_ids + attachment_id + ',';
344
+ });
345
+
346
+ $image_gallery_ids.val( attachment_ids );
347
+
348
+ return false;
349
+ });
350
+
351
+
352
+
353
+
354
+ })(jQuery);
plugin-fw/assets/js/metabox.min.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(a){function k(b,c,d){var e=!0;if("string"==typeof c){":radio"==c.substr(0,6)&&(c+=":checked");var g=a(c).val();"checkbox"==a(c).attr("type")&&(g=a(c).is(":checked")?"yes":"no");d=d.split(",");for(c=0;c<d.length;c++)if(g!=d[c])e=!1;else{e=!0;break}}e?a(b+"-container").parent().show():a(b+"-container").parent().hide()}a(".metaboxes-tab").each(function(){a(".tabs-panel",this).hide();var b=wpCookies.get("active_metabox_tab"),b=null==b?a("ul.metaboxes-tabs li:first-child a",this).attr("href"):
2
+ "#"+b;a(b).show();a(".metaboxes-tabs a",this).click(function(b){if(a(this).parent().hasClass("tabs"))b.preventDefault();else return b=a(this).attr("href"),a(this).parent().addClass("tabs").siblings("li").removeClass("tabs"),a(this).closest(".metaboxes-tab").find(".tabs-panel").slideUp("fast"),a(b).delay(350).slideDown("fast"),!1})});var h=!0,l=wp.media.editor.send.attachment;a(document).on("click",".metaboxes-tab .upload_button",function(b){b=a(this);var c=b.attr("id").replace("-button","");h=!0;
3
+ wp.media.editor.send.attachment=function(b,e){if(h)a("#"+c).is("input[type=text]")?a("#"+c).val(e.url):a("#"+c+"_custom").val(e.url);else return l.apply(this,[b,e])};wp.media.editor.open(b);return!1});a(".metaboxes-tab .add_media").on("click",function(){h=!1});a(".metaboxes-tab .panel-colorpicker").wpColorPicker({onInit:function(){console.log("test")},change:function(a,c){},clear:function(){var b=a(this);b.val(b.data("default-color"));b.change()}});a(".metaboxes-tab .panel-colorpicker").each(function(){var b=
4
+ a(this).data("variations-label");a(this).parent().parent().find("a.wp-color-result").attr("title",b)});a(".metaboxes-tab .panel-datepicker").each(function(){a(this).datepicker()});var f=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()}),""==b&&a(this).children().children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));
5
+ 0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+"</span>")};a(".metaboxes-tab .select_wrapper select").not(".chosen").each(f).change(f);a(".metaboxes-tab .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").hide()});
6
+ a(".metaboxes-tab .onoff_container span").on("click",function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".metaboxes-tab .chosen .select_wrapper select").chosen();a(".metaboxes-tab .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),d=a(this).data("max"),e=a(this).data("step"),g=a(this).data("labels");
7
+ a(this).slider({value:b,min:c,max:d,range:"min",step:e,slide:function(b,c){a(this).find("input").val(c.value);a(this).siblings(".feedback").find("strong").text(c.value+g)}})});f=a("#_active_page_options-container").parent().html();a("#_active_page_options-container").parent().remove();a(f).insertAfter("#yit-post-setting .handlediv");a(f).insertAfter("#yit-page-setting .handlediv");a("#_active_page_options-container").on("click",function(){a("#_active_page_options").is(":checked")?a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:1,
8
+ "pointer-events":"auto"}):a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:.5,"pointer-events":"none"})}).click();a(".metaboxes-tab [data-field]").each(function(){var b=a(this),c="#"+b.data("field"),d="#"+b.data("dep"),e=b.data("value");k(c,d,e.toString());a(d).on("change",function(){k(c,d,e.toString())}).change()});a(document).on("click",".image-gallery-button",function(b){var c=a(this);b=c.closest(".image-gallery");var d=b.find(".image_gallery_ids"),
9
+ e=d.val(),g=b.find("ul.slides-wrapper"),f=wp.media.frames.image_gallery=wp.media({title:c.data("choose"),button:{text:c.data("update")},states:[new wp.media.controller.Library({title:c.data("choose"),filterable:"all",multiple:!0})]});f.on("select",function(){f.state().get("selection").map(function(a){a=a.toJSON();a.id&&(e=e?e+","+a.id:a.id,g.append('<li class="image" data-attachment_id="'+a.id+'"><img src="'+a.sizes.thumbnail.url+'"/><ul class="actions"><li><a href="#" class="delete" title="'+c.data("delete")+
10
+ '">x</a></li></ul></li>'))});d.val(e)});f.open()});a(".image-gallery ul.slides-wrapper").each(function(){var b=a(this);b.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")},update:function(c,d){var e="";b.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");e=e+b+","});
11
+ b.closest(".image-gallery").find(".image_gallery_ids").val(e)}})});a(".image-gallery ul.slides-wrapper").on("click","a.delete",function(){var b=a(this).closest(".image-gallery"),c=a(this).closest(".image-gallery ul.slides-wrapper"),b=b.find(".image_gallery_ids"),d="";a(this).closest("li.image").remove();c.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");d=d+b+","});b.val(d);return!1})})(jQuery);
plugin-fw/assets/js/multisite-updater.js ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ var plugins_menu_item = $( '#menu-plugins' ),
12
+ update = plugins_menu_item.find('.update-plugins'),
13
+ count = update.find(".update-count").text(),
14
+ registered = plugins.registered,
15
+ activated = plugins.activated;
16
+
17
+ if( count == 0 || count == ''){
18
+ var update_row = '<span class="update-plugins"><span class="plugin-count"></span></span>';
19
+ count = 0;
20
+ plugins_menu_item.find( '.wp-menu-name').append( update_row );
21
+ }
22
+
23
+ /**
24
+ * Add the plugin update rows for old plugins
25
+ */
26
+ update_plugins_row( registered, activated, count, plugins );
27
+
28
+ /**
29
+ *
30
+ * Add the update plugin rows for old plugin
31
+ *
32
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
33
+ *
34
+ * @param registered Registred plugins
35
+ * @param activated Activated plugins
36
+ * @param count Number of old plugins
37
+ * @param localize Localize strings array
38
+ *
39
+ * @return void
40
+ */
41
+ function update_plugins_row( registered, activated, count, localize ){
42
+ for( var init in registered ){
43
+ var plugin = registered[init];
44
+ for( var headers in plugin ){
45
+
46
+ if( headers == 'slug' || version_compare( plugin[headers].Version, plugin[headers].Latest, '>=' ) ) {
47
+ continue;
48
+ }
49
+
50
+ count = parseInt(count) + 1;
51
+ $(".plugin-count").empty().html(count);
52
+
53
+ var regex = new RegExp(' ', 'g'),
54
+ info = plugin[headers],
55
+ name = '' + info.Name,
56
+ id = name.replace(regex, '-').trim(),
57
+ row = '#' + id.toLowerCase();
58
+
59
+ $(row).addClass("update");
60
+
61
+ var html = '<tr class="plugin-update-tr">' +
62
+ '<td colspan="3" class="plugin-update colspanchange">' +
63
+ '<div class="update-message">' + localize.strings.new_version.replace( '%plugin_name%', name ) +
64
+ '<a class="thickbox" href="' + localize.details_url[init] + '">' + localize.strings.latest.replace( '%latest%', plugin[headers].Latest ) + '</a>';
65
+
66
+ if( typeof activated[init] == "undefined" ) {
67
+
68
+ html = html +
69
+ ' <em>' + localize.strings.unavailable + '</em>' +
70
+ localize.strings.activate.replace( '%activate_link%', localize.licence_activation_url ).replace( '%plugin_name%', name );
71
+ } else {
72
+ html = html +
73
+ '. <a href="' + localize.update_url[init] + '">' + localize.strings.update_now + '</a>';
74
+ }
75
+
76
+ if( typeof localize.changelogs[init] != 'undefined' ){
77
+ html = html + localize.changelogs[init];
78
+ }
79
+
80
+ html = html +
81
+ '</div>' +
82
+ '</td>' +
83
+ '</tr>';
84
+
85
+ $(html).insertAfter(row);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param v1 Version 1
93
+ * @param v2 Version 2
94
+ * @param operator Compare type
95
+ * @returns bool
96
+ *
97
+ * @see php.js library http://phpjs.org/
98
+ */
99
+ function version_compare(v1, v2, operator) {
100
+ // discuss at: http://phpjs.org/functions/version_compare/
101
+ // original by: Philippe Jausions (http://pear.php.net/user/jausions)
102
+ // original by: Aidan Lister (http://aidanlister.com/)
103
+ // reimplemented by: Kankrelune (http://www.webfaktory.info/)
104
+ // improved by: Brett Zamir (http://brett-zamir.me)
105
+ // improved by: Scott Baker
106
+ // improved by: Theriault
107
+ // example 1: version_compare('8.2.5rc', '8.2.5a');
108
+ // returns 1: 1
109
+ // example 2: version_compare('8.2.50', '8.2.52', '<');
110
+ // returns 2: true
111
+ // example 3: version_compare('5.3.0-dev', '5.3.0');
112
+ // returns 3: -1
113
+ // example 4: version_compare('4.1.0.52','4.01.0.51');
114
+ // returns 4: 1
115
+
116
+ this.php_js = this.php_js || {};
117
+ this.php_js.ENV = this.php_js.ENV || {};
118
+ // END REDUNDANT
119
+ // Important: compare must be initialized at 0.
120
+ var i = 0,
121
+ x = 0,
122
+ compare = 0,
123
+ // vm maps textual PHP versions to negatives so they're less than 0.
124
+ // PHP currently defines these as CASE-SENSITIVE. It is important to
125
+ // leave these as negatives so that they can come before numerical versions
126
+ // and as if no letters were there to begin with.
127
+ // (1alpha is < 1 and < 1.1 but > 1dev1)
128
+ // If a non-numerical value can't be mapped to this table, it receives
129
+ // -7 as its value.
130
+ vm = {
131
+ 'dev' : -6,
132
+ 'alpha': -5,
133
+ 'a' : -5,
134
+ 'beta' : -4,
135
+ 'b' : -4,
136
+ 'RC' : -3,
137
+ 'rc' : -3,
138
+ '#' : -2,
139
+ 'p' : 1,
140
+ 'pl' : 1
141
+ },
142
+ // This function will be called to prepare each version argument.
143
+ // It replaces every _, -, and + with a dot.
144
+ // It surrounds any nonsequence of numbers/dots with dots.
145
+ // It replaces sequences of dots with a single dot.
146
+ // version_compare('4..0', '4.0') == 0
147
+ // Important: A string of 0 length needs to be converted into a value
148
+ // even less than an unexisting value in vm (-7), hence [-8].
149
+ // It's also important to not strip spaces because of this.
150
+ // version_compare('', ' ') == 1
151
+ prepVersion = function (v) {
152
+ v = ('' + v)
153
+ .replace(/[_\-+]/g, '.');
154
+ v = v.replace(/([^.\d]+)/g, '.$1.')
155
+ .replace(/\.{2,}/g, '.');
156
+ return (!v.length ? [-8] : v.split('.'));
157
+ };
158
+ // This converts a version component to a number.
159
+ // Empty component becomes 0.
160
+ // Non-numerical component becomes a negative number.
161
+ // Numerical component becomes itself as an integer.
162
+ numVersion = function (v) {
163
+ return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
164
+ };
165
+ v1 = prepVersion(v1);
166
+ v2 = prepVersion(v2);
167
+ x = Math.max(v1.length, v2.length);
168
+ for (i = 0; i < x; i++) {
169
+ if (v1[i] == v2[i]) {
170
+ continue;
171
+ }
172
+ v1[i] = numVersion(v1[i]);
173
+ v2[i] = numVersion(v2[i]);
174
+ if (v1[i] < v2[i]) {
175
+ compare = -1;
176
+ break;
177
+ } else if (v1[i] > v2[i]) {
178
+ compare = 1;
179
+ break;
180
+ }
181
+ }
182
+ if (!operator) {
183
+ return compare;
184
+ }
185
+
186
+ // Important: operator is CASE-SENSITIVE.
187
+ // "No operator" seems to be treated as "<."
188
+ // Any other values seem to make the function return null.
189
+ switch (operator) {
190
+ case '>':
191
+ case 'gt':
192
+ return (compare > 0);
193
+ case '>=':
194
+ case 'ge':
195
+ return (compare >= 0);
196
+ case '<=':
197
+ case 'le':
198
+ return (compare <= 0);
199
+ case '==':
200
+ case '=':
201
+ case 'eq':
202
+ return (compare === 0);
203
+ case '<>':
204
+ case '!=':
205
+ case 'ne':
206
+ return (compare !== 0);
207
+ case '':
208
+ case '<':
209
+ case 'lt':
210
+ return (compare < 0);
211
+ default:
212
+ return null;
213
+ }
214
+ }
215
+
216
+ })(jQuery);
plugin-fw/assets/js/multisite-updater.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ (function(m){function n(c,d,k){this.php_js=this.php_js||{};this.php_js.ENV=this.php_js.ENV||{};var a=0,e=0,b=0,f={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},a=function(a){a=(""+a).replace(/[_\-+]/g,".");a=a.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,".");return a.length?a.split("."):[-8]};numVersion=function(a){return a?isNaN(a)?f[a]||-7:parseInt(a,10):0};c=a(c);d=a(d);e=Math.max(c.length,d.length);for(a=0;a<e;a++)if(c[a]!=d[a])if(c[a]=numVersion(c[a]),d[a]=numVersion(d[a]),
2
+ c[a]<d[a]){b=-1;break}else if(c[a]>d[a]){b=1;break}if(!k)return b;switch(k){case ">":case "gt":return 0<b;case ">=":case "ge":return 0<=b;case "<=":case "le":return 0>=b;case "==":case "=":case "eq":return 0===b;case "<>":case "!=":case "ne":return 0!==b;case "":case "<":case "lt":return 0>b;default:return null}}var l=m("#menu-plugins"),g=l.find(".update-plugins").find(".update-count").text(),p=plugins.registered,q=plugins.activated;if(0==g||""==g)g=0,l.find(".wp-menu-name").append('<span class="update-plugins"><span class="plugin-count"></span></span>');
3
+ (function(c,d,k,a){for(var e in c){var b=c[e],f;for(f in b)if("slug"!=f&&!n(b[f].Version,b[f].Latest,">=")){k=parseInt(k)+1;m(".plugin-count").empty().html(k);var g=""+b[f].Name,l="#"+g.replace(RegExp(" ","g"),"-").trim().toLowerCase();m(l).addClass("update");var h='<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message">'+a.strings.new_version.replace("%plugin_name%",g)+'<a class="thickbox" href="'+a.details_url[e]+'">'+a.strings.latest.replace("%latest%",
4
+ b[f].Latest)+"</a>",h="undefined"==typeof d[e]?h+" <em>"+a.strings.unavailable+"</em>"+a.strings.activate.replace("%activate_link%",a.licence_activation_url).replace("%plugin_name%",g):h+'. <a href="'+a.update_url[e]+'">'+a.strings.update_now+"</a>";"undefined"!=typeof a.changelogs[e]&&(h+=a.changelogs[e]);h+="</div></td></tr>";m(h).insertAfter(l)}}})(p,q,g,plugins)})(jQuery);
plugin-fw/assets/js/panel.spinner.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Spinner for jQuery (version 0.1)
3
+ Copyright (c) 2012 Simone D'Amico
4
+ http://simonedamico.com/
5
+
6
+ Licensed under the MIT license:
7
+ http://www.opensource.org/licenses/mit-license.php
8
+
9
+ Any and all use of this script must be accompanied by this copyright/license notice in its present form.
10
+
11
+ */
12
+ (function($){
13
+ $.fn.spinner = function(params) {
14
+
15
+ //private methods
16
+ var _createButton = function( buttonClass, buttonLabel ) {
17
+ return $('<button/>', {
18
+ 'class' : buttonClass + ' spinner-button',
19
+ text : buttonLabel
20
+ });
21
+ };
22
+
23
+ var _createBody = function(input) {
24
+ //create wrapper
25
+ var wrapper = input.wrap('<div class="spinner-wrapper"></div>').parent();
26
+
27
+ //create spinner buttons
28
+ var plus = _createButton('button-plus', '+').appendTo(wrapper).show(),
29
+ minus = _createButton('button-minus', '-').appendTo(wrapper).show();
30
+
31
+ return wrapper;
32
+ };
33
+
34
+ var _buttonClick = function( e ) {
35
+ var input = e.data.input,
36
+ params = e.data.params,
37
+ button = $(this),
38
+ value = parseFloat(input.val());
39
+
40
+ if( button.hasClass('button-plus') ) {
41
+ if( params.max != null ) {
42
+ if( ( value + params.interval ) <= params.max ) {
43
+ input.val( value + params.interval );
44
+ } else {
45
+ input.val( params.max );
46
+ }
47
+ } else {
48
+ input.val( value + params.interval );
49
+ }
50
+ } else if( button.hasClass('button-minus') ) {
51
+ if( params.min != null ) {
52
+ if( ( value - params.interval ) >= params.min ) {
53
+ input.val( value - params.interval );
54
+ } else {
55
+ input.val( params.min );
56
+ }
57
+ } else {
58
+ input.val( value - params.interval );
59
+ }
60
+ }
61
+
62
+ input.change(); e.preventDefault();
63
+ };
64
+
65
+ var _validateContent = function( e ) {
66
+ var value = parseFloat( $(this).val() );
67
+
68
+ if( params.max != null && value >= params.max ) {
69
+ $(this).val(params.max);
70
+ } else if( value <= params.min || isNaN( value ) ) {
71
+ $(this).val(params.min ? params.min : 0);
72
+ } else {
73
+ $(this).val(value);
74
+ }
75
+ };
76
+
77
+
78
+ //public methods
79
+ var methods = {
80
+ init : function( params ) {
81
+
82
+ var params = $.extend({
83
+ min: null,
84
+ max: null,
85
+ interval: 1,
86
+ defaultValue: 0,
87
+ mouseWheel: true,
88
+ largeInterval: 10
89
+ }, params);
90
+
91
+ var self = this,
92
+ t = $(this),
93
+ data = t.data('spinner');
94
+
95
+ return this.each(function(){
96
+ //check if the plugin hasn't already been initialized
97
+ //and it's an input[type=text] element
98
+ if( !data && t.is(':text') ) {
99
+ //initialize the value
100
+ if( params.defaultValue ) {
101
+ t.val( params.defaultValue );
102
+ }
103
+
104
+ //create the spinner body
105
+ var wrapper = _createBody(t);
106
+
107
+ //event handlers
108
+ //var mouseWheelEventName = $.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel';
109
+
110
+ wrapper.find('.spinner-button')
111
+ .bind('click.spinner', { params: params, input: t }, _buttonClick);
112
+
113
+ t.bind('blur.spinner', _validateContent)
114
+ //.bind('keyup.spinner', _validateKey)
115
+ //.bind(mouseWheelEventName, _inputMousewheel);
116
+
117
+ //register field data
118
+ t.data('spinner', {
119
+ target: self
120
+ });
121
+ }
122
+ });
123
+ },
124
+
125
+ destroy : function( params) {
126
+ console.log('destroy', params);
127
+ }
128
+ };
129
+
130
+ //execute the plugin
131
+ if ( methods[params] ) {
132
+ return methods[params].apply( this, Array.prototype.slice.call( arguments, 1 ));
133
+ } else if ( typeof params === 'object' || ! params ) {
134
+ return methods.init.apply( this, arguments );
135
+ } else {
136
+ $.error( 'Method ' + params + ' does not exist' );
137
+ }
138
+ };
139
+ })(jQuery);
plugin-fw/assets/js/panel.spinner.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ (function(d){d.fn.spinner=function(c){var h=function(b,e){return d("<button/>",{"class":b+" spinner-button",text:e})},k=function(b){var e=b.data.input,a=b.data.params,c=d(this),f=parseFloat(e.val());c.hasClass("button-plus")?null!=a.max?f+a.interval<=a.max?e.val(f+a.interval):e.val(a.max):e.val(f+a.interval):c.hasClass("button-minus")&&(null!=a.min?f-a.interval>=a.min?e.val(f-a.interval):e.val(a.min):e.val(f-a.interval));e.change();b.preventDefault()},l=function(b){b=parseFloat(d(this).val());null!=
2
+ c.max&&b>=c.max?d(this).val(c.max):b<=c.min||isNaN(b)?d(this).val(c.min?c.min:0):d(this).val(b)},g={init:function(b){b=d.extend({min:null,max:null,interval:1,defaultValue:0,mouseWheel:!0,largeInterval:10},b);var c=this,a=d(this),g=a.data("spinner");return this.each(function(){if(!g&&a.is(":text")){b.defaultValue&&a.val(b.defaultValue);var d=a.wrap('<div class="spinner-wrapper"></div>').parent();h("button-plus","+").appendTo(d).show();h("button-minus","-").appendTo(d).show();d.find(".spinner-button").bind("click.spinner",
3
+ {params:b,input:a},k);a.bind("blur.spinner",l);a.data("spinner",{target:c})}})},destroy:function(b){console.log("destroy",b)}};if(g[c])return g[c].apply(this,Array.prototype.slice.call(arguments,1));if("object"!==typeof c&&c)d.error("Method "+c+" does not exist");else return g.init.apply(this,arguments)}})(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ // open media box
15
+ $('.wrap h2').on( 'click', 'a.multi-uploader', function(event){
16
+ event.preventDefault();
17
+
18
+ var file_frame,
19
+ button = $(this),
20
+ selected = false;
21
+
22
+ // spinner
23
+ button.next('span.spinner').css( 'display', 'inline-block' );
24
+
25
+ // If the media frame already exists, reopen it.
26
+ if ( file_frame ) {
27
+ file_frame.open();
28
+ return;
29
+ }
30
+
31
+ // Create the media frame.
32
+ file_frame = wp.media.frames.file_frame = wp.media({
33
+ title: button.data( 'uploader_title' ),
34
+ button: {
35
+ text: button.data( 'uploader_button_text' )
36
+ },
37
+ library: {
38
+ type: 'image'
39
+ },
40
+ multiple: true // Set to true to allow multiple files to be selected
41
+ });
42
+
43
+ // When an image is selected, run a callback.
44
+ file_frame.on( 'select', function() {
45
+ var selection = file_frame.state().get('selection'),
46
+ images = [];
47
+
48
+ selection.map( function( attachment ) {
49
+ attachment = attachment.toJSON();
50
+
51
+ // Do something with attachment.id and/or attachment.url here
52
+ images.push( { id: attachment.id, url: attachment.url, title: attachment.title } );
53
+ });
54
+
55
+ // make AJAX request
56
+ $.post( ajaxurl, {
57
+ images: images,
58
+ post_type: typenow,
59
+ action: 'yit_cptu_multiuploader'
60
+ }, function( data ){
61
+ location.reload();
62
+ });
63
+
64
+ button.next('span.spinner').css( 'display', 'inline-block' );
65
+
66
+ // flag
67
+ selected = true;
68
+ });
69
+
70
+ // when close
71
+ file_frame.on( 'close', function() {
72
+ if ( ! selected ) button.next('span.spinner').hide();
73
+ });
74
+
75
+ // Finally, open the modal
76
+ file_frame.open();
77
+ });
78
+
79
+ })(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ (function(c){c(".wrap h2").on("click","a.multi-uploader",function(f){f.preventDefault();var a,b=c(this),d=!1;b.next("span.spinner").css("display","inline-block");a||(a=wp.media.frames.file_frame=wp.media({title:b.data("uploader_title"),button:{text:b.data("uploader_button_text")},library:{type:"image"},multiple:!0}),a.on("select",function(){var e=[];a.state().get("selection").map(function(a){a=a.toJSON();e.push({id:a.id,url:a.url,title:a.title})});c.post(ajaxurl,{images:e,post_type:typenow,action:"yit_cptu_multiuploader"},
2
+ function(a){location.reload()});b.next("span.spinner").css("display","inline-block");d=!0}),a.on("close",function(){d||b.next("span.spinner").hide()}));a.open()})})(jQuery);
plugin-fw/assets/js/yit-cptu-sortable-posts.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ $("#the-list").sortable({
15
+ items : 'tr',
16
+ axis : 'y',
17
+ helper : function(e, ui) {
18
+ ui.children().children().each(function() {
19
+ $(this).width( $(this).width() );
20
+ });
21
+ return ui;
22
+ },
23
+ update : function(e, ui) {
24
+ $.post( ajaxurl, {
25
+ action: 'cpt_sort_posts',
26
+ order: $("#the-list").sortable("serialize"),
27
+ post_type: typenow
28
+ });
29
+ }
30
+ });
31
+
32
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.js ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+
11
+ (function ($) {
12
+
13
+ // select
14
+ var select_value = function () {
15
+
16
+ var value = '';
17
+
18
+ if ($(this).attr('multiple')) {
19
+ $(this).children("option:selected").each(function (i, v) {
20
+ if (i != 0)
21
+ value += ', ';
22
+
23
+ value += $(v).text();
24
+ });
25
+
26
+ if (value == '') {
27
+ $(this).children().children("option:selected").each(function (i, v) {
28
+ if (i != 0)
29
+ value += ', ';
30
+
31
+ value += $(v).text();
32
+ });
33
+ }
34
+ }
35
+ else {
36
+ value = $(this).children("option:selected").text();
37
+
38
+ if (value == '')
39
+ value = $(this).children().children("option:selected").text();
40
+ }
41
+
42
+
43
+ if ($(this).parent().find('span').length <= 0) {
44
+ $(this).before('<span></span>');
45
+ }
46
+
47
+ $(this).parent().children('span').replaceWith('<span>' + value + '</span>');
48
+ };
49
+ $('.plugin-option .select_wrapper select').not('.chosen').each(select_value).change(select_value);
50
+
51
+ //Open select multiple
52
+ $('.plugin-option .select_wrapper').click(function (e) {
53
+ e.stopPropagation();
54
+ $(this).find('select[multiple]').not('.chosen').toggle();
55
+ });
56
+ //Stops click propagation on select, to prevent select hide
57
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').click(function (e) {
58
+ e.stopPropagation();
59
+ });
60
+ //Hides select on window click
61
+ $(window).click(function () {
62
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').hide();
63
+ })
64
+ //chosen
65
+ $('.plugin-option .chosen .select_wrapper select').chosen();
66
+
67
+ // on-off
68
+ $('.plugin-option .on_off_container span').on('click', function () {
69
+ var input = $(this).prev('input');
70
+ var checked = input.prop('checked');
71
+
72
+ if (checked) {
73
+ input.prop('checked', false).attr('value', 'no').removeClass('onoffchecked');
74
+ } else {
75
+ input.prop('checked', true).attr('value', 'yes').addClass('onoffchecked');
76
+ }
77
+
78
+ input.change();
79
+ });
80
+
81
+
82
+ //slider
83
+ $('.plugin-option .slider_container .ui-slider-horizontal').each(function () {
84
+ var val = $(this).data('val');
85
+ var minValue = $(this).data('min');
86
+ var maxValue = $(this).data('max');
87
+ var step = $(this).data('step');
88
+ var labels = $(this).data('labels');
89
+
90
+ $(this).slider({
91
+ value: val,
92
+ min : minValue,
93
+ max : maxValue,
94
+ range: 'min',
95
+ step : step,
96
+
97
+ slide: function (event, ui) {
98
+ $(this).find('input').val(ui.value);
99
+ $(this).siblings('.feedback').find('strong').text(ui.value + labels);
100
+ }
101
+ });
102
+ });
103
+
104
+
105
+ if (typeof wp !== 'undefined' && typeof wp.media !== 'undefined') {
106
+
107
+ //upload
108
+ var _custom_media = true,
109
+ _orig_send_attachment = wp.media.editor.send.attachment;
110
+
111
+ // preview
112
+ $('.plugin-option .upload_img_url').change(function () {
113
+ var url = $(this).val();
114
+ var re = new RegExp("(http|ftp|https)://[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)");
115
+
116
+ var preview = $(this).parents().siblings('.upload_img_preview');
117
+ if (re.test(url)) {
118
+ preview.html('<img src="' + url + '" style="max-width:600px; max-height:300px;" />');
119
+ } else {
120
+ preview.html('');
121
+ }
122
+ }).trigger( 'change' );
123
+
124
+ $( document ).on( 'click', '.plugin-option .upload_button', function(e) {
125
+ e.preventDefault();
126
+
127
+ var t = $(this),
128
+ custom_uploader,
129
+ id = t.attr('id').replace(/-button$/, '');
130
+
131
+ //If the uploader object has already been created, reopen the dialog
132
+ if (custom_uploader) {
133
+ custom_uploader.open();
134
+ return;
135
+ }
136
+
137
+ var custom_uploader_states = [
138
+ // Main states.
139
+ new wp.media.controller.Library({
140
+ library: wp.media.query(),
141
+ multiple: false,
142
+ title: 'Choose Image',
143
+ priority: 20,
144
+ filterable: 'uploaded'
145
+ })
146
+ ];
147
+
148
+ // Create the media frame.
149
+ custom_uploader = wp.media.frames.downloadable_file = wp.media({
150
+ // Set the title of the modal.
151
+ title: 'Choose Image',
152
+ library: {
153
+ type: ''
154
+ },
155
+ button: {
156
+ text: 'Choose Image'
157
+ },
158
+ multiple: false,
159
+ states: custom_uploader_states
160
+ });
161
+
162
+
163
+ //When a file is selected, grab the URL and set it as the text field's value
164
+ custom_uploader.on( 'select' , function() {
165
+ var attachment = custom_uploader.state().get( 'selection' ).first().toJSON();
166
+
167
+ $("#" + id).val( attachment.url );
168
+ $('.plugin-option .upload_img_url').trigger('change');
169
+ });
170
+
171
+ //Open the uploader dialog
172
+ custom_uploader.open();
173
+ });
174
+ }
175
+
176
+ $('.plugin-option .add_media').on('click', function () {
177
+ _custom_media = false;
178
+ });
179
+
180
+ //dependencies handler
181
+ $('[data-field]').each(function () {
182
+ var t = $(this);
183
+
184
+ var field = '#' + t.data('field'),
185
+ dep = '#' + t.data('dep'),
186
+ value = t.data('value');
187
+
188
+ $(dep).on('change',function () {
189
+ dependencies_handler(field, dep, value.toString());
190
+ }).change();
191
+ });
192
+
193
+ //Handle dependencies.
194
+ function dependencies_handler(id, deps, values) {
195
+ var result = true;
196
+
197
+ //Single dependency
198
+ if (typeof( deps ) == 'string') {
199
+ if (deps.substr(0, 6) == ':radio') {
200
+ deps = deps + ':checked';
201
+ }
202
+
203
+ var values = values.split(',');
204
+
205
+ for (var i = 0; i < values.length; i++) {
206
+
207
+ if ($(deps).val() != values[i]) {
208
+ result = false;
209
+ }
210
+ else {
211
+ result = true;
212
+ break;
213
+ }
214
+ }
215
+ }
216
+
217
+ if (!result) {
218
+ $(id + '-container').closest('tr').hide();
219
+ } else {
220
+ $(id + '-container').closest('tr').show();
221
+ }
222
+ };
223
+
224
+ //connected list
225
+ $('.rm_connectedlist').each(function () {
226
+ var ul = $(this).find('ul');
227
+ var input = $(this).find(':hidden');
228
+ var sortable = ul.sortable({
229
+ connectWith: ul,
230
+ update : function (event, ui) {
231
+ var value = {};
232
+
233
+ ul.each(function () {
234
+ var options = {};
235
+
236
+ $(this).children().each(function () {
237
+ options[ $(this).data('option') ] = $(this).text();
238
+ });
239
+
240
+ value[ $(this).data('list') ] = options;
241
+ });
242
+
243
+ input.val((JSON.stringify(value)).replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'));
244
+ }
245
+ }).disableSelection();
246
+ });
247
+
248
+ $(document).ready(function () {
249
+
250
+ $('.yith-video-link').click(function (event) {
251
+ event.preventDefault();
252
+ var target = $(this).data('video-id');
253
+
254
+ $('.' + target).dialog({
255
+ dialogClass : 'wp-dialog yit-dialog yit-video-dialog',
256
+ modal : true,
257
+ closeOnEscape: true,
258
+ width : 'auto',
259
+ resizable : false,
260
+ draggable : false,
261
+ create : function (event, ui) {
262
+ $(this).css("maxWidth", "853px");
263
+ },
264
+ open : function (event, ui) {
265
+
266
+ $('.ui-widget-overlay').bind('click', function () {
267
+ $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close');
268
+ });
269
+
270
+ }
271
+
272
+ });
273
+
274
+ $('.ui-dialog :button').blur();
275
+
276
+ });
277
+ });
278
+
279
+ //codemirror
280
+ $(document).ready(function () {
281
+ $('.codemirror').each(function (i, v) {
282
+ var editor = CodeMirror.fromTextArea(v, {
283
+ lineNumbers : 1,
284
+ mode : 'javascript',
285
+ showCursorWhenSelecting: true
286
+ })
287
+
288
+ $(v).data('codemirrorInstance', editor);
289
+ })
290
+ })
291
+
292
+ //google analytics generation
293
+ $(document).ready(function () {
294
+ $('.google-analytic-generate').click(function () {
295
+ var editor = $('#' + $(this).data('textarea')).data('codemirrorInstance');
296
+ var gatc = $('#' + $(this).data('input')).val();
297
+ var basename = $(this).data('basename');
298
+
299
+ var text = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n";
300
+ text += "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\n";
301
+ text += "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";
302
+ text += "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";
303
+ text += "ga('create', '" + gatc + "', '" + basename + "');\n";
304
+ text += "ga('send', 'pageview');\n";
305
+ editor.replaceRange(
306
+ text,
307
+ editor.getCursor('start'),
308
+ editor.getCursor('end')
309
+ )
310
+ })
311
+ })
312
+
313
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ (function(a){var l=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()}),""==b&&a(this).children().children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+
2
+ "</span>")};a(".plugin-option .select_wrapper select").not(".chosen").each(l).change(l);a(".plugin-option .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".plugin-option .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".plugin-option .select_wrapper select[multiple]").not(".chosen").hide()});a(".plugin-option .chosen .select_wrapper select").chosen();a(".plugin-option .on_off_container span").on("click",
3
+ function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".plugin-option .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),d=a(this).data("max"),e=a(this).data("step"),f=a(this).data("labels");a(this).slider({value:b,min:c,max:d,range:"min",step:e,slide:function(b,c){a(this).find("input").val(c.value);
4
+ a(this).siblings(".feedback").find("strong").text(c.value+f)}})});"undefined"!==typeof wp&&"undefined"!==typeof wp.media&&(a(".plugin-option .upload_img_url").change(function(){var b=a(this).val(),c=a(this).parents().siblings(".upload_img_preview");/(http|ftp|https):\/\/[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)/.test(b)?c.html('<img src="'+b+'" style="max-width:600px; max-height:300px;" />'):c.html("")}).trigger("change"),a(document).on("click",".plugin-option .upload_button",function(b){b.preventDefault();
5
+ var c,d=a(this).attr("id").replace(/-button$/,"");c||(b=[new wp.media.controller.Library({library:wp.media.query(),multiple:!1,title:"Choose Image",priority:20,filterable:"uploaded"})],c=wp.media.frames.downloadable_file=wp.media({title:"Choose Image",library:{type:""},button:{text:"Choose Image"},multiple:!1,states:b}),c.on("select",function(){var b=c.state().get("selection").first().toJSON();a("#"+d).val(b.url);a(".plugin-option .upload_img_url").trigger("change")}));c.open()}));a(".plugin-option .add_media").on("click",
6
+ function(){});a("[data-field]").each(function(){var b=a(this),c="#"+b.data("field"),d="#"+b.data("dep"),e=b.data("value");a(d).on("change",function(){var b=d,g=e.toString(),h=!0;if("string"==typeof b){":radio"==b.substr(0,6)&&(b+=":checked");for(var g=g.split(","),k=0;k<g.length;k++)if(a(b).val()!=g[k])h=!1;else{h=!0;break}}h?a(c+"-container").closest("tr").show():a(c+"-container").closest("tr").hide()}).change()});a(".rm_connectedlist").each(function(){var b=a(this).find("ul"),c=a(this).find(":hidden");
7
+ b.sortable({connectWith:b,update:function(d,e){var f={};b.each(function(){var b={};a(this).children().each(function(){b[a(this).data("option")]=a(this).text()});f[a(this).data("list")]=b});c.val(JSON.stringify(f).replace(/[\\"']/g,"\\$&").replace(/\u0000/g,"\\0"))}}).disableSelection()});a(document).ready(function(){a(".yith-video-link").click(function(b){b.preventDefault();b=a(this).data("video-id");a("."+b).dialog({dialogClass:"wp-dialog yit-dialog yit-video-dialog",modal:!0,closeOnEscape:!0,width:"auto",
8
+ resizable:!1,draggable:!1,create:function(b,d){a(this).css("maxWidth","853px")},open:function(b,d){a(".ui-widget-overlay").bind("click",function(){a(this).siblings(".ui-dialog").find(".ui-dialog-content").dialog("close")})}});a(".ui-dialog :button").blur()})});a(document).ready(function(){a(".codemirror").each(function(b,c){var d=CodeMirror.fromTextArea(c,{lineNumbers:1,mode:"javascript",showCursorWhenSelecting:!0});a(c).data("codemirrorInstance",d)})});a(document).ready(function(){a(".google-analytic-generate").click(function(){var b=
9
+ a("#"+a(this).data("textarea")).data("codemirrorInstance"),c=a("#"+a(this).data("input")).val(),d=a(this).data("basename"),e;e="(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";e+="})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";e+="ga('create', '"+c+"', '"+d+"');\n";e+="ga('send', 'pageview');\n";
10
+ b.replaceRange(e,b.getCursor("start"),b.getCursor("end"))})})})(jQuery);
plugin-fw/assets/js/yit-wp-pointer.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready( function($) {
2
+
3
+ var pointers = custom_pointer.pointers[0],
4
+ options = pointers.options,
5
+ target = $(pointers.target),
6
+ pointer_id = pointers.pointer_id;
7
+
8
+ $(target).find('.wp-submenu li a').each(function () {
9
+
10
+ var t = $(this),
11
+ href = t.attr('href');
12
+
13
+ href = href.replace('admin.php?page=', '');
14
+
15
+ if( href == pointer_id ){
16
+
17
+ var selected_plugin_row = t.add( target ),
18
+ top_level_menu = target.find( pointers.target.replace( '#', '.' ) );
19
+
20
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
21
+
22
+ t.pointer({
23
+ pointerClass: 'yit-wp-pointer',
24
+ content : options.content,
25
+ position: options.position,
26
+ open : function () {
27
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
28
+ top_level_menu.addClass( 'yit-pointer' );
29
+ },
30
+
31
+
32
+ close : function () {
33
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
34
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
35
+ top_level_menu.removeClass( 'yit-pointer' );
36
+
37
+ $.ajax({
38
+ type : 'POST',
39
+ url : ajaxurl,
40
+ data : {
41
+ "action" : "dismiss-wp-pointer",
42
+ "pointer": pointer_id
43
+ },
44
+ success: function (response) {
45
+ }
46
+ });
47
+
48
+ }
49
+ }).pointer('open');
50
+ } else if( 'yith_default_pointer' == pointer_id ) {
51
+
52
+ var selected_plugin_row = t.add( target ),
53
+ top_level_menu = target.find( pointers.target.replace( '#', '.' )),
54
+ yit_plugins = $( pointers.target );
55
+
56
+ yit_plugins.addClass('wp-has-current-submenu');
57
+
58
+ top_level_menu.pointer({
59
+ pointerClass: 'yit-wp-pointer',
60
+ content : options.content,
61
+ position: options.position,
62
+
63
+ open : function () {
64
+ yit_plugins.addClass( 'yit-pointer-selected-row' );
65
+ },
66
+
67
+ close : function () {
68
+ yit_plugins.removeClass( 'yit-pointer-selected-row wp-has-current-submenu' );
69
+
70
+ $.ajax({
71
+ type : 'POST',
72
+ url : ajaxurl,
73
+ data : {
74
+ "action" : "dismiss-wp-pointer",
75
+ "pointer": pointer_id
76
+ },
77
+ success: function (response) {
78
+ }
79
+ });
80
+ }
81
+ }).pointer('open');
82
+ }
83
+ });
84
+ });
plugin-fw/assets/js/yit-wp-pointer.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ jQuery(document).ready(function(b){var c=custom_pointer.pointers[0],d=c.options,a=b(c.target),e=c.pointer_id;b(a).find(".wp-submenu li a").each(function(){var f=b(this),h=f.attr("href"),h=h.replace("admin.php?page=","");if(h==e){var k=f.add(a),g=a.find(c.target.replace("#","."));a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");f.pointer({pointerClass:"yit-wp-pointer",content:d.content,position:d.position,open:function(){console.log("here");k.toggleClass("yit-pointer-selected-row");
2
+ g.addClass("yit-pointer")},close:function(){a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");k.toggleClass("yit-pointer-selected-row");g.removeClass("yit-pointer");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}else if("yith_default_pointer"==e){var k=f.add(a),g=a.find(c.target.replace("#",".")),l=b(c.target);l.addClass("wp-has-current-submenu");g.pointer({pointerClass:"yit-wp-pointer",content:d.content,
3
+ position:d.position,open:function(){l.addClass("yit-pointer-selected-row")},close:function(){l.removeClass("yit-pointer-selected-row wp-has-current-submenu");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}})});
plugin-fw/languages/yith-plugin-fw-it_IT.mo ADDED
Binary file
plugin-fw/languages/yith-plugin-fw-it_IT.po ADDED
@@ -0,0 +1,988 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2015 YIThemes
2
+ # This file is distributed under the same license as the YITH Plugin Starter package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: YITH Plugin Starter 1.0.0 Plugin FW\n"
6
+ "Report-Msgid-Bugs-To: Your Inspiration Themes <plugins@yithemes.com>\n"
7
+ "POT-Creation-Date: 2015-05-11 17:13+0100\n"
8
+ "PO-Revision-Date: 2015-05-11 17:15+0100\n"
9
+ "Last-Translator: \n"
10
+ "Language-Team: Your Inspiration Themes <info@yithemes.com>\n"
11
+ "Language: en\n"
12
+ "MIME-Version: 1.0\n"
13
+ "Content-Type: text/plain; charset=utf-8\n"
14
+ "Content-Transfer-Encoding: 8bit\n"
15
+ "X-Generator: Poedit 1.7.3\n"
16
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;"
17
+ "_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;"
18
+ "esc_html_x:1,2c\n"
19
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
+ "X-Poedit-SourceCharset: UTF-8\n"
21
+ "X-Poedit-Basepath: ../\n"
22
+ "X-Textdomain-Support: yes\n"
23
+ "X-Poedit-SearchPath-0: .\n"
24
+
25
+ #: lib/yit-cpt-unlimited.php:460 lib/yit-cpt-unlimited.php:574
26
+ #: lib/yit-cpt-unlimited.php:719 lib/yit-cpt-unlimited.php:1632
27
+ #, php-format
28
+ msgid "Add %s"
29
+ msgstr "Aggiungi %s"
30
+
31
+ #: lib/yit-cpt-unlimited.php:461 lib/yit-cpt-unlimited.php:575
32
+ #, php-format
33
+ msgid "Add New %s"
34
+ msgstr "Aggiungi nuovo %s"
35
+
36
+ #: lib/yit-cpt-unlimited.php:462 lib/yit-cpt-unlimited.php:576
37
+ #: lib/yit-cpt-unlimited.php:1267 lib/yit-cpt-unlimited.php:1304
38
+ #, php-format
39
+ msgid "Edit %s"
40
+ msgstr "Modifica %s"
41
+
42
+ #: lib/yit-cpt-unlimited.php:463 lib/yit-cpt-unlimited.php:577
43
+ #, php-format
44
+ msgid "New %s"
45
+ msgstr "Nuovo %s"
46
+
47
+ #: lib/yit-cpt-unlimited.php:464 lib/yit-cpt-unlimited.php:578
48
+ #, php-format
49
+ msgid "All %s"
50
+ msgstr "Tutti %s"
51
+
52
+ #: lib/yit-cpt-unlimited.php:465 lib/yit-cpt-unlimited.php:579
53
+ #: lib/yit-cpt-unlimited.php:1251 lib/yit-cpt-unlimited.php:1305
54
+ #, php-format
55
+ msgid "View %s"
56
+ msgstr "Visualizza %s"
57
+
58
+ #: lib/yit-cpt-unlimited.php:466 lib/yit-cpt-unlimited.php:580
59
+ #, php-format
60
+ msgid "Search %s"
61
+ msgstr "Cerca %s"
62
+
63
+ #: lib/yit-cpt-unlimited.php:467 lib/yit-cpt-unlimited.php:581
64
+ #, php-format
65
+ msgid "No %s found"
66
+ msgstr "Nessun %s trovato"
67
+
68
+ #: lib/yit-cpt-unlimited.php:468 lib/yit-cpt-unlimited.php:582
69
+ #, php-format
70
+ msgid "No %s found in Trash"
71
+ msgstr "Nessun %s trovato nel cestino"
72
+
73
+ #: lib/yit-cpt-unlimited.php:625
74
+ #, php-format
75
+ msgctxt "taxonomy general name"
76
+ msgid "%s Categories"
77
+ msgstr "%s Categorie"
78
+
79
+ #: lib/yit-cpt-unlimited.php:626
80
+ msgctxt "taxonomy singular name"
81
+ msgid "Category"
82
+ msgstr "Categoria"
83
+
84
+ #: lib/yit-cpt-unlimited.php:627
85
+ msgid "Search Categories"
86
+ msgstr "Cerca categorie"
87
+
88
+ #: lib/yit-cpt-unlimited.php:628
89
+ msgid "All Categories"
90
+ msgstr "Tutte le categorie"
91
+
92
+ #: lib/yit-cpt-unlimited.php:629
93
+ msgid "Parent Category"
94
+ msgstr "Categoria genitore"
95
+
96
+ #: lib/yit-cpt-unlimited.php:630
97
+ msgid "Parent Category:"
98
+ msgstr "Categoria genitore:"
99
+
100
+ #: lib/yit-cpt-unlimited.php:631
101
+ msgid "Edit Category"
102
+ msgstr "Modifica categoria"
103
+
104
+ #: lib/yit-cpt-unlimited.php:632
105
+ msgid "Update Category"
106
+ msgstr "Aggiorna categoria"
107
+
108
+ #: lib/yit-cpt-unlimited.php:633
109
+ msgid "Add New Category"
110
+ msgstr "Aggiungi nuova categoria"
111
+
112
+ #: lib/yit-cpt-unlimited.php:634
113
+ msgid "New Category Name"
114
+ msgstr "Nuovo nome categoria"
115
+
116
+ #: lib/yit-cpt-unlimited.php:635
117
+ msgid "Category"
118
+ msgstr "Categoria"
119
+
120
+ #: lib/yit-cpt-unlimited.php:724
121
+ msgid "Categories"
122
+ msgstr "Categorie"
123
+
124
+ #: lib/yit-cpt-unlimited.php:1042
125
+ #, php-format
126
+ msgid "%s Settings"
127
+ msgstr "Impostazioni %s"
128
+
129
+ #: lib/yit-cpt-unlimited.php:1048 lib/yit-cpt-unlimited.php:1196
130
+ #: lib/yit-cpt-unlimited.php:1202 lib/yit-plugin-panel.php:64
131
+ msgid "Settings"
132
+ msgstr "Impostazioni"
133
+
134
+ #: lib/yit-cpt-unlimited.php:1051
135
+ msgid "Type"
136
+ msgstr "Tipologia"
137
+
138
+ #: lib/yit-cpt-unlimited.php:1052
139
+ msgid "Layout for this "
140
+ msgstr "Layout per questo"
141
+
142
+ #: lib/yit-cpt-unlimited.php:1058
143
+ msgid "Rewrite"
144
+ msgstr "Riscrivi"
145
+
146
+ #: lib/yit-cpt-unlimited.php:1059
147
+ msgid ""
148
+ "Univocal identification name in the URL for each product (slug from post if empty)"
149
+ msgstr ""
150
+ "Nome identificativo univoco nell'URL per singolo prodotto (usa slug dal post se "
151
+ "vuoto)"
152
+
153
+ #: lib/yit-cpt-unlimited.php:1064
154
+ msgid "Label in Singular"
155
+ msgstr "Etichetta singolare"
156
+
157
+ #: lib/yit-cpt-unlimited.php:1065
158
+ msgid "Set a label in singular (title of portfolio if empty)"
159
+ msgstr "Imposta un'etichetta singolare (titolo del portfolio se vuoto)"
160
+
161
+ #: lib/yit-cpt-unlimited.php:1070
162
+ msgid "Label in Plural"
163
+ msgstr "Etichetta plurale"
164
+
165
+ #: lib/yit-cpt-unlimited.php:1071
166
+ msgid "Set a label in plural (title of portfolio if empty)"
167
+ msgstr "Imposta un'etichetta plurale (titolo del portfolio se vuoto)"
168
+
169
+ #: lib/yit-cpt-unlimited.php:1076
170
+ msgid "Taxonomy"
171
+ msgstr "Tassonomia"
172
+
173
+ #: lib/yit-cpt-unlimited.php:1077
174
+ msgid ""
175
+ "If you want to use categories in the portfolio, set a name for taxonomy. Name "
176
+ "should be a slug (must not contain capital letters nor spaces) and must not be "
177
+ "more than 32 characters long (database structure restriction)."
178
+ msgstr ""
179
+ "Se vuoi aggiungere delle categorie nel portfolio, imposta un nome per la "
180
+ "tassonomia. Il nome dovrà essere in forma di slug (non deve contenere caratteri "
181
+ "maiuscoli né spazi) e non più lungo di 32 caratteri (restrizione di database)."
182
+
183
+ #: lib/yit-cpt-unlimited.php:1082
184
+ msgid "Taxonomy Rewrite"
185
+ msgstr "Riscrivi tassonomia"
186
+
187
+ #: lib/yit-cpt-unlimited.php:1083
188
+ msgid "Set univocal name for each category page URL."
189
+ msgstr "Imposta un nome univoco per l'URL della pagina di ciascuna categoria."
190
+
191
+ #: lib/yit-cpt-unlimited.php:1088
192
+ msgid "Single layout"
193
+ msgstr "Layout singolo"
194
+
195
+ #: lib/yit-cpt-unlimited.php:1089
196
+ msgid "Layout for single page of this portfolio"
197
+ msgstr "Layout per pagina singola per questo portfolio"
198
+
199
+ #: lib/yit-cpt-unlimited.php:1130
200
+ msgid "layout settings"
201
+ msgstr "impostazioni di layout"
202
+
203
+ #: lib/yit-cpt-unlimited.php:1222 lib/yit-cpt-unlimited.php:1235
204
+ msgid "Quick links"
205
+ msgstr "Link rapidi"
206
+
207
+ #: lib/yit-cpt-unlimited.php:1475
208
+ #, php-format
209
+ msgid "Show frontend of the %s"
210
+ msgstr "Mostra front end di %s"
211
+
212
+ #: lib/yit-cpt-unlimited.php:1482 templates/metaboxes/types/customtabs.php:46
213
+ #: templates/metaboxes/types/customtabs.php:90
214
+ msgid "Name"
215
+ msgstr "Nome"
216
+
217
+ #: lib/yit-cpt-unlimited.php:1631
218
+ #, php-format
219
+ msgid "Add %s from images"
220
+ msgstr "Aggiungi %s dalla immagini"
221
+
222
+ #: lib/yit-cpt-unlimited.php:1633
223
+ msgid "Add with multiupload"
224
+ msgstr "Aggiungi con caricamento multiplo"
225
+
226
+ #: lib/yit-plugin-panel-wc.php:295
227
+ msgid "The changes you have made will be lost if you leave this page."
228
+ msgstr "Perderai tutti i cambiamenti effettuati se lasci questa pagina."
229
+
230
+ #: lib/yit-plugin-panel.php:63
231
+ msgid "Plugin Settings"
232
+ msgstr "Impostazioni plugin"
233
+
234
+ #: lib/yit-plugin-panel.php:95 lib/yit-plugin-subpanel.php:101
235
+ msgid "YIT Plugins"
236
+ msgstr "Plugin YIT"
237
+
238
+ #: lib/yit-plugin-panel.php:292 lib/yit-plugin-subpanel.php:142
239
+ #: templates/panel/woocommerce/woocommerce-form.php:5
240
+ msgid "Save Changes"
241
+ msgstr "Salva modifiche"
242
+
243
+ #: lib/yit-plugin-panel.php:295 templates/panel/woocommerce/woocommerce-form.php:8
244
+ msgid "If you continue with this action, you will reset all options in this page."
245
+ msgstr ""
246
+ "Se prosegui con questa azione, tutte le opzioni di questa pagina saranno "
247
+ "reimpostate."
248
+
249
+ #: lib/yit-plugin-panel.php:297 lib/yit-plugin-subpanel.php:147
250
+ msgid "Reset to Default"
251
+ msgstr "Ripristina impostazioni iniziali"
252
+
253
+ #: lib/yit-plugin-panel.php:297 lib/yit-plugin-subpanel.php:147
254
+ #: templates/panel/woocommerce/woocommerce-form.php:10
255
+ msgid "Are you sure?"
256
+ msgstr "Sei sicuro?"
257
+
258
+ #: lib/yit-plugin-panel.php:431
259
+ msgid "The element you have entered already exists. Please, enter another name."
260
+ msgstr "L'elemento inserito esiste già. Per favore, inserisci un altro nome."
261
+
262
+ #: lib/yit-plugin-panel.php:432
263
+ msgid "Settings saved"
264
+ msgstr "Impostazioni salvate"
265
+
266
+ #: lib/yit-plugin-panel.php:433
267
+ msgid "Settings reset"
268
+ msgstr "Impostazioni azzerate"
269
+
270
+ #: lib/yit-plugin-panel.php:434
271
+ msgid "Element deleted correctly."
272
+ msgstr "Elemento rimosso correttamente."
273
+
274
+ #: lib/yit-plugin-panel.php:435 lib/yit-plugin-panel.php:436
275
+ msgid "Element updated correctly."
276
+ msgstr "Elemento aggiornato correttamente."
277
+
278
+ #: lib/yit-plugin-panel.php:437
279
+ msgid "Database imported correctly."
280
+ msgstr "Database importato correttamente."
281
+
282
+ #: lib/yit-plugin-panel.php:438
283
+ msgid "An error has occurred during import. Please try again."
284
+ msgstr "Si è verificato un errore durante l'importazione. Prova di nuovo."
285
+
286
+ #: lib/yit-plugin-panel.php:439
287
+ msgid "The added file is not valid."
288
+ msgstr "Il file aggiunto non è valido."
289
+
290
+ #: lib/yit-plugin-panel.php:440
291
+ msgid "Sorry, import is disabled."
292
+ msgstr "Ci dispiace, l'importazione è disabilitata."
293
+
294
+ #: lib/yit-plugin-panel.php:441
295
+ msgid "Sorting successful."
296
+ msgstr "Ordinamento effettuato con successo."
297
+
298
+ #: lib/yit-plugin-subpanel.php:145
299
+ msgid ""
300
+ "If you continue with this action, you will reset all the options in this page."
301
+ msgstr ""
302
+ "Se prosegui con questa azione, tutte le opzioni di questa pagina saranno "
303
+ "reimpostate."
304
+
305
+ #: lib/yit-pointers.php:70
306
+ msgid "Plugins Activated"
307
+ msgstr "Plugin attivati"
308
+
309
+ #: lib/yit-pointers.php:71
310
+ msgid ""
311
+ "From now on, you can find all plugin options in YIT Plugin menu.\n"
312
+ " For each plugin installed, customization "
313
+ "settings will be available as a new entry in YIT Plugin menu."
314
+ msgstr ""
315
+ "Da ora in poi, puoi trovare tutte le opzioni dei tuoi plugin nel menu Plugin YIT.\n"
316
+ "Troverai le impostazioni di personalizzazione sotto una nuova voce nel menu Plugin "
317
+ "YIT."
318
+
319
+ #: lib/yit-pointers.php:73 lib/yit-pointers.php:89
320
+ msgid "Discover all our plugins available on:"
321
+ msgstr "Scopri tutti i plugin disponibili su:"
322
+
323
+ #: lib/yit-pointers.php:74 lib/yit-pointers.php:90
324
+ msgid "and"
325
+ msgstr "e"
326
+
327
+ #: lib/yit-pointers.php:84
328
+ msgid "Plugins Upgraded"
329
+ msgstr "Plugin aggiornati"
330
+
331
+ # Any time you install one of our plugins, a new entry will be added to this menu.\n
332
+ #: lib/yit-pointers.php:85
333
+ msgid ""
334
+ "From now on, you can find all options of your plugins in YIT Plugin menu.\n"
335
+ " Any time one of our plugins is updated, a new "
336
+ "entry will be added to this menu.\n"
337
+ " For example, after the update, plugin options "
338
+ "(such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search, etc.)\n"
339
+ " will be moved from previous location to YIT "
340
+ "Plugin tab."
341
+ msgstr ""
342
+ "Da ora in poi, troverai tutte le opzioni dei tuoi plugin nel menu Plugin YIT.\n"
343
+ "Ogni volta che aggiornerai i nostri plugin, troverai una nuova voce in questo "
344
+ "menu.\n"
345
+ "Per esempio, dopo l'aggiornamento, le opzioni del plugin (come per esempio quelle "
346
+ "di YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search etc.)\n"
347
+ "saranno trasferite nella scheda Plugin YIT."
348
+
349
+ #: lib/yit-upgrade.php:123
350
+ msgid "There is a new version of %plugin_name% available."
351
+ msgstr "Una nuova versione di %plugin_name% è disponibile."
352
+
353
+ #: lib/yit-upgrade.php:124
354
+ msgid "View version %latest% details."
355
+ msgstr "Visualizza i dettagli della versione %latest%."
356
+
357
+ #: lib/yit-upgrade.php:125
358
+ msgid "Automatic update is unavailable for this plugin,"
359
+ msgstr "L'aggiornamento automatico non è disponibile per questo plugin,"
360
+
361
+ #: lib/yit-upgrade.php:126
362
+ msgid "please <a href=\"%activate_link%\">activate</a> your copy of %plugin_name%."
363
+ msgstr ""
364
+ "per favore, <a href=\"%activate_link%\">attiva</a> la tua copia di %plugin_name%."
365
+
366
+ #: lib/yit-upgrade.php:127
367
+ msgid "Update now."
368
+ msgstr "Aggiorna adesso."
369
+
370
+ #: lib/yit-upgrade.php:230
371
+ msgid "Yithemes Repository"
372
+ msgstr "Repository YIThemes"
373
+
374
+ #: lib/yit-upgrade.php:264
375
+ msgid "Invalid URL Provided."
376
+ msgstr "L'URL inserito non è valido."
377
+
378
+ #: lib/yit-upgrade.php:277
379
+ msgid "Could not create Temporary file."
380
+ msgstr "Non è stato possibile creare il file temporaneo."
381
+
382
+ #: lib/yit-upgrade.php:419
383
+ #, php-format
384
+ msgid ""
385
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
386
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>."
387
+ msgstr ""
388
+ "È disponibile una nuova versione di %1$s. <a href=\"%2$s\" class=\"thickbox yit-"
389
+ "changelog-button\" title=\"%3$s\">Visualizza i dettagli della versione %4$s</a>."
390
+
391
+ #: lib/yit-upgrade.php:421
392
+ #, php-format
393
+ msgid ""
394
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
395
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You have to "
396
+ "activate the plugin on a single site of the network to benefit from automatic "
397
+ "updates.</em>"
398
+ msgstr ""
399
+ "È disponibile una nuova versioni di %1$s. <a href=\"%2$s\" class=\"thickbox yit-"
400
+ "changelog-button\" title=\"%3$s\">Visualizza i dettagli della versione %4$s</a>. "
401
+ "<em>Per poter usufruire degli aggiornamenti automatici è necessario attivare il "
402
+ "plugin su un solo sito.</em>"
403
+
404
+ #: lib/yit-upgrade.php:423
405
+ #, php-format
406
+ msgid ""
407
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
408
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>Automatic "
409
+ "update is unavailable for this plugin, please <a href=\"%5$s\" title=\"Licence "
410
+ "activation\">activate</a> your copy of %6s.</em>"
411
+ msgstr ""
412
+ "È disponibile una nuova versioni di %1$s. <a href=\"%2$s\" class=\"thickbox yit-"
413
+ "changelog-button\" title=\"%3$s\">Visualizza i dettagli della versione %4$s</a>. "
414
+ "<em>Gli aggiornamenti automatici non sono disponibili per questo plugi, per "
415
+ "favore, <a href=\"%5$s\" title=\"Licence activation\">attiva</a> la tua copia di "
416
+ "%6s.</em>"
417
+
418
+ #: lib/yit-upgrade.php:425
419
+ #, php-format
420
+ msgid ""
421
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
422
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a href=\"%5$s"
423
+ "\">update now</a>."
424
+ msgstr ""
425
+ "È disponibile una nuova versioni di %1$s. <a href=\"%2$s\" class=\"thickbox yit-"
426
+ "changelog-button\" title=\"%3$s\">Visualizza i dettagli della versione %4$s</a> "
427
+ "oppure <a href=\"%5$s\">aggiorna adesso</a>."
428
+
429
+ #: lib/yit-upgrade.php:498
430
+ msgid "You can't update the plugins for this site."
431
+ msgstr "Non è possibile aggiornare i plugin per questo sito."
432
+
433
+ #: lib/yit-upgrade.php:502
434
+ msgid "You do not have sufficient permissions to update the plugins for this site."
435
+ msgstr ""
436
+ "Non sei in possesso delle autorizzazioni necessarie per aggiornare i plugin in "
437
+ "questo sito."
438
+
439
+ #: lib/yit-upgrade.php:509
440
+ msgid "Update Plugin"
441
+ msgstr "Aggiorna plugin"
442
+
443
+ #: licence/lib/yit-licence.php:161
444
+ #, php-format
445
+ msgctxt "%s = field name"
446
+ msgid "%s field cannot be empty"
447
+ msgstr "Il campo %s non può essere vuoto"
448
+
449
+ #: licence/lib/yit-licence.php:162
450
+ #, php-format
451
+ msgid "%s and %s fields cannot be empty"
452
+ msgstr "I campi %s e %s non possono essere vuoti"
453
+
454
+ #: licence/lib/yit-licence.php:163
455
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
456
+ msgstr "Impossibile contattare il server remoto, prova più tardi. Grazie!"
457
+
458
+ #: licence/lib/yit-licence.php:548
459
+ msgid "Invalid Request"
460
+ msgstr "Richiesta non valida"
461
+
462
+ #: licence/lib/yit-licence.php:549
463
+ msgid "Invalid licence key"
464
+ msgstr "Chiave di licenza non valida"
465
+
466
+ #: licence/lib/yit-licence.php:550
467
+ msgid "Software has been deactivated"
468
+ msgstr "Il software è stato disattivato"
469
+
470
+ #: licence/lib/yit-licence.php:551
471
+ msgid "Maximum number of activations exceeded"
472
+ msgstr "Hai raggiunto il numero massimo di attivazioni"
473
+
474
+ #: licence/lib/yit-licence.php:552
475
+ msgid "Invalid instance ID"
476
+ msgstr "Istanza ID non valida"
477
+
478
+ #: licence/lib/yit-licence.php:553
479
+ msgid "Invalid security key"
480
+ msgstr "Chiave di sicurezza non valida"
481
+
482
+ #: licence/lib/yit-licence.php:554
483
+ msgid "Licence key has expired"
484
+ msgstr "Questa chiave di licenza è scaduta"
485
+
486
+ #: licence/lib/yit-licence.php:555
487
+ msgid "Licence key has been banned"
488
+ msgstr "Questa chiave di licenza è stata bloccata"
489
+
490
+ #: licence/lib/yit-plugin-licence.php:64 licence/lib/yit-plugin-licence.php:65
491
+ #: licence/lib/yit-theme-licence.php:64 licence/lib/yit-theme-licence.php:65
492
+ #: licence/lib/yit-theme-licence.php:107 licence/lib/yit-theme-licence.php:108
493
+ msgid "Licence Activation"
494
+ msgstr "Attivazione licenza"
495
+
496
+ #: licence/lib/yit-theme-licence.php:115 licence/lib/yit-theme-licence.php:116
497
+ #, php-format
498
+ msgid "%s"
499
+ msgstr "%s"
500
+
501
+ #: licence/templates/panel/activation/activation-panel.php:19
502
+ msgid "Yithemes Licence Activation"
503
+ msgstr "Attivazione licenza YIThemes"
504
+
505
+ #: licence/templates/panel/activation/activation-panel.php:23
506
+ msgid ""
507
+ "I cannot find the license key for activating the theme I have bought some time "
508
+ "ago. Where can I find it?"
509
+ msgstr ""
510
+ "Non riesco a trovare la chiave di licenza per l'attivazione del tema che ho "
511
+ "acquistato diverso tempo fa. Dove posso trovarla?"
512
+
513
+ #: licence/templates/panel/activation/activation-panel.php:26
514
+ msgid ""
515
+ "If you have purchased one of our products before 27 January 2015, you can benefit "
516
+ "from support and updates (the services offered with the license)\n"
517
+ " until 27 January 2016 and you do not have to purchase it again to get "
518
+ "a new license key, because, before this date, your license used to be activated "
519
+ "automatically by our system.\n"
520
+ " After 27 January 2016, instead, if you want to benefit from support "
521
+ "and updates you have to buy a new license and activate it through the license key "
522
+ "you will be\n"
523
+ " provided with and that you can find in your YIThemes account, in "
524
+ "section \"My licenses\"."
525
+ msgstr ""
526
+ "Se hai acquistato un nostro prodotto prima del 27 gennaio 2015 potrai accedere al "
527
+ "supporto e scaricare gli aggiornamenti fino al 27 gennaio 2016 e non avrai bisogno "
528
+ "di una chiave di licenza,\n"
529
+ "in quanto la tua licenza prima di questa data veniva attivata in modo automatico "
530
+ "dal nostro sistema.\n"
531
+ "Dopo il 27 gennaio 2016, invece, per poter usufruire del servizio di supporto e "
532
+ "degli aggiornamenti dovrai riacquistare il prodotto e\n"
533
+ "attivarlo con la chiave di licenza che ti sarà fornita e che puoi trovare sul tuo "
534
+ "account YIThemes, alla voce \"Le mie licenze\"."
535
+
536
+ #: licence/templates/panel/activation/activation-panel.php:37
537
+ msgid ""
538
+ "Have you updated your licenses? Have you asked for an extension? Update "
539
+ "information concerning your products."
540
+ msgstr ""
541
+ "Hai aggiornato la tua licenza? Hai richiesto un'estensione? Aggiorna le "
542
+ "informazioni dei tuoi prodotti."
543
+
544
+ #: licence/templates/panel/activation/activation-panel.php:39
545
+ msgid "Update licence information"
546
+ msgstr "Aggiorna le informazioni di licenza"
547
+
548
+ #: licence/templates/panel/activation/activation-panel.php:49
549
+ msgid "Products to be activated"
550
+ msgstr "Prodotti da attivare"
551
+
552
+ #: licence/templates/panel/activation/activation-panel.php:68
553
+ msgid "Activate"
554
+ msgstr "Attiva"
555
+
556
+ #: licence/templates/panel/activation/activation-panel.php:87
557
+ msgid "Activated"
558
+ msgstr "Attivato"
559
+
560
+ #: licence/templates/panel/activation/activation-panel.php:91
561
+ #: licence/templates/panel/activation/activation-panel.php:123
562
+ #: licence/templates/panel/activation/activation-panel.php:147
563
+ msgid "Product Name"
564
+ msgstr "Nome prodotto"
565
+
566
+ #: licence/templates/panel/activation/activation-panel.php:92
567
+ #: licence/templates/panel/activation/activation-panel.php:124
568
+ #: licence/templates/panel/activation/activation-panel.php:148
569
+ #: templates/metaboxes/types/contactform.php:148
570
+ #: templates/metaboxes/types/contactform.php:340
571
+ msgid "Email"
572
+ msgstr "Email"
573
+
574
+ #: licence/templates/panel/activation/activation-panel.php:93
575
+ #: licence/templates/panel/activation/activation-panel.php:125
576
+ #: licence/templates/panel/activation/activation-panel.php:149
577
+ msgid "Licence Key"
578
+ msgstr "Chiave di licenza"
579
+
580
+ #: licence/templates/panel/activation/activation-panel.php:94
581
+ #: licence/templates/panel/activation/activation-panel.php:150
582
+ msgid "Expires"
583
+ msgstr "Scadenza"
584
+
585
+ #: licence/templates/panel/activation/activation-panel.php:95
586
+ msgid "Remaining"
587
+ msgstr "Tempo rimanente"
588
+
589
+ #: licence/templates/panel/activation/activation-panel.php:96
590
+ #: licence/templates/panel/activation/activation-panel.php:109
591
+ #: licence/templates/panel/activation/activation-panel.php:151
592
+ #: licence/templates/panel/activation/activation-panel.php:161
593
+ msgid "Renew"
594
+ msgstr "Rinnova"
595
+
596
+ #: licence/templates/panel/activation/activation-panel.php:107
597
+ #, php-format
598
+ msgid "%1s out of %2s"
599
+ msgstr "%1s di %2s"
600
+
601
+ #: licence/templates/panel/activation/activation-panel.php:119
602
+ msgid "Banned"
603
+ msgstr "Bloccato"
604
+
605
+ #: licence/templates/panel/activation/activation-panel.php:143
606
+ msgid "Expired"
607
+ msgstr "Non più valido"
608
+
609
+ #: templates/metaboxes/types/ajax-products.php:23
610
+ msgid "Search for a product"
611
+ msgstr "Cerca un prodotto"
612
+
613
+ #: templates/metaboxes/types/categories.php:36
614
+ msgid "No categories."
615
+ msgstr "Nessuna categoria"
616
+
617
+ #: templates/metaboxes/types/categories.php:42
618
+ msgid "+ Add New Category"
619
+ msgstr "+ Aggiungi nuova categoria"
620
+
621
+ #: templates/metaboxes/types/categories.php:46
622
+ msgid "Add"
623
+ msgstr "Aggiungi"
624
+
625
+ #: templates/metaboxes/types/contactform.php:7
626
+ msgid "Text Input"
627
+ msgstr "Text input"
628
+
629
+ #: templates/metaboxes/types/contactform.php:8
630
+ msgid "Checkbox"
631
+ msgstr "Checkbox"
632
+
633
+ #: templates/metaboxes/types/contactform.php:9
634
+ msgid "Select"
635
+ msgstr "Select"
636
+
637
+ #: templates/metaboxes/types/contactform.php:10
638
+ msgid "Textarea"
639
+ msgstr "Textarea"
640
+
641
+ #: templates/metaboxes/types/contactform.php:11
642
+ msgid "Radio Input"
643
+ msgstr "Radio input"
644
+
645
+ #: templates/metaboxes/types/contactform.php:12
646
+ msgid "Password Field"
647
+ msgstr "Campo password"
648
+
649
+ #: templates/metaboxes/types/contactform.php:13
650
+ msgid "File Upload"
651
+ msgstr "Carica file"
652
+
653
+ #: templates/metaboxes/types/contactform.php:47
654
+ msgid "Theme Icon"
655
+ msgstr "Icona tema"
656
+
657
+ #: templates/metaboxes/types/contactform.php:48
658
+ msgid "Custom Icon"
659
+ msgstr "Icona personalizzata"
660
+
661
+ #: templates/metaboxes/types/contactform.php:49
662
+ #: templates/metaboxes/types/responsivesliders.php:24
663
+ msgid "None"
664
+ msgstr "Nessuno"
665
+
666
+ #: templates/metaboxes/types/contactform.php:60
667
+ msgid "Add field"
668
+ msgstr "Aggiungi campo"
669
+
670
+ #: templates/metaboxes/types/contactform.php:69
671
+ #: templates/metaboxes/types/contactform.php:261
672
+ #: templates/metaboxes/types/customtabs.php:37
673
+ #: templates/metaboxes/types/customtabs.php:82
674
+ msgid "Remove"
675
+ msgstr "Rimuovi"
676
+
677
+ #: templates/metaboxes/types/contactform.php:70
678
+ #: templates/metaboxes/types/contactform.php:262
679
+ msgid "Click to toggle"
680
+ msgstr "Fai clic per aprire/chiudere"
681
+
682
+ #: templates/metaboxes/types/contactform.php:77
683
+ #: templates/metaboxes/types/contactform.php:269
684
+ msgid "Field Title"
685
+ msgstr "Titolo campo"
686
+
687
+ #: templates/metaboxes/types/contactform.php:81
688
+ #: templates/metaboxes/types/contactform.php:273
689
+ msgid "Insert the title for the field."
690
+ msgstr "Inserisci il titolo per il campo"
691
+
692
+ #: templates/metaboxes/types/contactform.php:86
693
+ #: templates/metaboxes/types/contactform.php:278
694
+ msgid "Data Name"
695
+ msgstr "Nome dati"
696
+
697
+ #: templates/metaboxes/types/contactform.php:90
698
+ #: templates/metaboxes/types/contactform.php:282
699
+ msgid ""
700
+ "REQUIRED: Field identification name to be entered into email body. <strong>Note:</"
701
+ "strong>Use only lowercase characters and underscores."
702
+ msgstr ""
703
+ "RICHIESTO: Nome identificativo del campo da inserire nel corpo dell'email. "
704
+ "<strong>Nota:</strong>Puoi utilizzare solamente caratteri minuscoli e underscore."
705
+
706
+ #: templates/metaboxes/types/contactform.php:95
707
+ #: templates/metaboxes/types/contactform.php:287
708
+ msgid "Field Type"
709
+ msgstr "Tipologia campo"
710
+
711
+ #: templates/metaboxes/types/contactform.php:103
712
+ #: templates/metaboxes/types/contactform.php:295
713
+ msgid "Select the type for this field."
714
+ msgstr "Seleziona il tipo di campo."
715
+
716
+ #: templates/metaboxes/types/contactform.php:108
717
+ #: templates/metaboxes/types/contactform.php:300
718
+ msgid "Checked"
719
+ msgstr "Selezionato"
720
+
721
+ #: templates/metaboxes/types/contactform.php:112
722
+ #: templates/metaboxes/types/contactform.php:304
723
+ msgid "Select this option if you want this field appears as already checked."
724
+ msgstr "Seleziona questa opzione se vuoi che il campo appaia già selezionato."
725
+
726
+ #: templates/metaboxes/types/contactform.php:117
727
+ #: templates/metaboxes/types/contactform.php:309
728
+ msgid "Add options "
729
+ msgstr "Aggiungi opzioni"
730
+
731
+ #: templates/metaboxes/types/contactform.php:118
732
+ #: templates/metaboxes/types/contactform.php:310
733
+ msgid "Add option"
734
+ msgstr "Aggiungi opzione"
735
+
736
+ #: templates/metaboxes/types/contactform.php:121
737
+ #: templates/metaboxes/types/contactform.php:313
738
+ #: templates/metaboxes/types/contactform.php:436
739
+ msgid "Selected"
740
+ msgstr "Selezionato"
741
+
742
+ #: templates/metaboxes/types/contactform.php:124
743
+ #: templates/metaboxes/types/contactform.php:316
744
+ #: templates/metaboxes/types/contactform.php:436
745
+ msgid "Delete option"
746
+ msgstr "Cancella opzione"
747
+
748
+ #: templates/metaboxes/types/contactform.php:130
749
+ #: templates/metaboxes/types/contactform.php:322
750
+ msgid "Error Message"
751
+ msgstr "Messaggio di errore"
752
+
753
+ #: templates/metaboxes/types/contactform.php:134
754
+ #: templates/metaboxes/types/contactform.php:326
755
+ msgid "Insert the error message for validation."
756
+ msgstr "Inserisci il messaggio di errore per la validazione"
757
+
758
+ #: templates/metaboxes/types/contactform.php:139
759
+ #: templates/metaboxes/types/contactform.php:331
760
+ msgid "Required"
761
+ msgstr "Obbligatorio"
762
+
763
+ #: templates/metaboxes/types/contactform.php:143
764
+ #: templates/metaboxes/types/contactform.php:335
765
+ msgid "Select this option if it must be required."
766
+ msgstr "Seleziona questa opzione se deve essere obbligatoria."
767
+
768
+ #: templates/metaboxes/types/contactform.php:152
769
+ #: templates/metaboxes/types/contactform.php:344
770
+ msgid "Select this option if the email must be valid."
771
+ msgstr "Seleziona questa opzione se l'email inserita deve essere esistente."
772
+
773
+ #: templates/metaboxes/types/contactform.php:157
774
+ #: templates/metaboxes/types/contactform.php:349
775
+ msgid "Reply To"
776
+ msgstr "Rispondi a"
777
+
778
+ #: templates/metaboxes/types/contactform.php:161
779
+ #: templates/metaboxes/types/contactform.php:353
780
+ msgid "Select this if it is the email you can reply to."
781
+ msgstr "Seleziona questo se è l'email a cui poter rispondere. "
782
+
783
+ #: templates/metaboxes/types/contactform.php:166
784
+ #: templates/metaboxes/types/contactform.php:358
785
+ msgid "Class"
786
+ msgstr "Classe"
787
+
788
+ #: templates/metaboxes/types/contactform.php:170
789
+ #: templates/metaboxes/types/contactform.php:362
790
+ msgid "Insert additional class(es) (separated by commas) for more personalization."
791
+ msgstr ""
792
+ "Inserisci una o più classi (separate da virgole) per una ulteriore "
793
+ "personalizzazione."
794
+
795
+ #: templates/metaboxes/types/contactform.php:175
796
+ #: templates/metaboxes/types/contactform.php:367
797
+ msgid "Icon"
798
+ msgstr "Icona"
799
+
800
+ #: templates/metaboxes/types/contactform.php:203
801
+ #: templates/metaboxes/types/contactform.php:391
802
+ #: templates/metaboxes/types/icon-list.php:69
803
+ #: templates/metaboxes/types/select-icon.php:33
804
+ #: templates/metaboxes/types/upload.php:21 templates/panel/types/upload.php:31
805
+ #: templates/panel/woocommerce/woocommerce-upload.php:35
806
+ msgid "Upload"
807
+ msgstr "Carica"
808
+
809
+ #: templates/metaboxes/types/contactform.php:209
810
+ #: templates/metaboxes/types/contactform.php:397
811
+ #: templates/metaboxes/types/icon-list.php:75
812
+ #: templates/metaboxes/types/select-icon.php:39
813
+ msgid "Image preview"
814
+ msgstr "Anteprima immagine"
815
+
816
+ #: templates/metaboxes/types/contactform.php:217
817
+ #: templates/metaboxes/types/contactform.php:405
818
+ msgid "Insert an icon for more personalization."
819
+ msgstr "Inserisci un'icona per ulteriore personalizzazione."
820
+
821
+ #: templates/metaboxes/types/contactform.php:222
822
+ #: templates/metaboxes/types/contactform.php:409
823
+ msgid "Width"
824
+ msgstr "Larghezza"
825
+
826
+ #: templates/metaboxes/types/contactform.php:247
827
+ #: templates/metaboxes/types/contactform.php:421
828
+ msgid "Set field length."
829
+ msgstr "Seleziona lunghezza campo."
830
+
831
+ #: templates/metaboxes/types/customtabs.php:28
832
+ msgid "Close all"
833
+ msgstr "Chiudi tutti"
834
+
835
+ #: templates/metaboxes/types/customtabs.php:28
836
+ msgid "Expand all"
837
+ msgstr "Espandi tutti"
838
+
839
+ #: templates/metaboxes/types/customtabs.php:52
840
+ #: templates/metaboxes/types/customtabs.php:95
841
+ msgid "Value"
842
+ msgstr "Valore"
843
+
844
+ #: templates/metaboxes/types/customtabs.php:53
845
+ #: templates/metaboxes/types/customtabs.php:96
846
+ msgid "Content of the tab. (HTML is supported)"
847
+ msgstr "Contenuto della scheda (codice HTML supportato)."
848
+
849
+ #: templates/metaboxes/types/customtabs.php:65
850
+ msgid "Add custom product tab"
851
+ msgstr "Aggiungi scheda prodotto personalizzata"
852
+
853
+ #: templates/metaboxes/types/customtabs.php:107
854
+ msgid "Do you want to remove the custom tab?"
855
+ msgstr "Vuoi rimuovere la scheda personalizzata?"
856
+
857
+ #: templates/metaboxes/types/icon-list.php:89
858
+ #, php-format
859
+ msgid "(Default: %s <img src=\"%s\"/>)"
860
+ msgstr "(Default: %s <img src=\"%s\"/>)"
861
+
862
+ #: templates/metaboxes/types/icon-list.php:91
863
+ #, php-format
864
+ msgid "(Default: <i %s></i> )"
865
+ msgstr "(Default: <i %s></i> )"
866
+
867
+ #: templates/metaboxes/types/image-gallery.php:40
868
+ #: templates/metaboxes/types/image-gallery.php:45
869
+ #: templates/metaboxes/types/images.php:38 templates/metaboxes/types/images.php:64
870
+ msgid "Delete image"
871
+ msgstr "Rimuovi immagine"
872
+
873
+ #: templates/metaboxes/types/image-gallery.php:45
874
+ msgid "Add Images to Gallery"
875
+ msgstr "Aggiungi immagini alla galleria"
876
+
877
+ #: templates/metaboxes/types/image-gallery.php:45
878
+ msgid "Add to gallery"
879
+ msgstr "Aggiungi alla galleria"
880
+
881
+ #: templates/metaboxes/types/image-gallery.php:45
882
+ msgid "Add images"
883
+ msgstr "Aggiungi immagini"
884
+
885
+ #: templates/metaboxes/types/image-gallery.php:45
886
+ msgid "Delete"
887
+ msgstr "Rimuovi"
888
+
889
+ #: templates/metaboxes/types/images.php:42
890
+ msgid "Upload new images"
891
+ msgstr "Carica nuove immagini"
892
+
893
+ #: templates/metaboxes/types/images.php:75
894
+ msgid "Are you sure you want to remove this image?"
895
+ msgstr "Confermi di voler rimuovere questa immagine?"
896
+
897
+ #: templates/metaboxes/types/sidebar-layout.php:25
898
+ #: templates/metaboxes/types/sidebars.php:36
899
+ msgid "Left sidebar"
900
+ msgstr "Barra laterale sinistra"
901
+
902
+ #: templates/metaboxes/types/sidebar-layout.php:28
903
+ #: templates/metaboxes/types/sidebars.php:42
904
+ #: templates/metaboxes/types/sidebars.php:45
905
+ msgid "No sidebar"
906
+ msgstr "Nessuna barra laterale"
907
+
908
+ #: templates/metaboxes/types/sidebar-layout.php:31
909
+ #: templates/metaboxes/types/sidebars.php:39
910
+ msgid "Right sidebar"
911
+ msgstr "Barra laterale destra"
912
+
913
+ #: templates/metaboxes/types/sidebar-layout.php:34
914
+ #: templates/metaboxes/types/sidebars.php:53
915
+ #: templates/metaboxes/types/sidebars.php:64
916
+ msgid "Choose a sidebar"
917
+ msgstr "Scegli una barra laterale"
918
+
919
+ #: templates/metaboxes/types/sidebars.php:51
920
+ msgid "Left Sidebar"
921
+ msgstr "Barra laterale sinistra"
922
+
923
+ #: templates/metaboxes/types/sidebars.php:62
924
+ msgid "Right Sidebar"
925
+ msgstr "Barra laterale destra"
926
+
927
+ #: templates/metaboxes/types/typography.php:42
928
+ msgid "px"
929
+ msgstr "px"
930
+
931
+ #: templates/metaboxes/types/typography.php:43
932
+ msgid "em"
933
+ msgstr "em"
934
+
935
+ #: templates/metaboxes/types/typography.php:44
936
+ msgid "pt"
937
+ msgstr "pt"
938
+
939
+ #: templates/metaboxes/types/typography.php:45
940
+ msgid "rem"
941
+ msgstr "rem"
942
+
943
+ #: templates/metaboxes/types/typography.php:59
944
+ #: templates/metaboxes/types/typography.php:153
945
+ #: templates/metaboxes/types/typography.php:217
946
+ msgid "Web fonts"
947
+ msgstr "Web fonts"
948
+
949
+ #: templates/metaboxes/types/typography.php:71
950
+ msgid "Google fonts"
951
+ msgstr "Google fonts"
952
+
953
+ #: templates/metaboxes/types/typography.php:96
954
+ msgid "Regular"
955
+ msgstr "Normale"
956
+
957
+ #: templates/metaboxes/types/typography.php:97
958
+ msgid "Bold"
959
+ msgstr "Grassetto"
960
+
961
+ #: templates/metaboxes/types/typography.php:98
962
+ msgid "Extra bold"
963
+ msgstr "Extra bold"
964
+
965
+ #: templates/metaboxes/types/typography.php:99
966
+ msgid "Italic"
967
+ msgstr "Corsivo"
968
+
969
+ #: templates/metaboxes/types/typography.php:100
970
+ msgid "Italic bold"
971
+ msgstr "Grassetto corsivo"
972
+
973
+ #: templates/panel/woocommerce/woocommerce-form.php:10
974
+ msgid "Reset Defaults"
975
+ msgstr "Ripristina impostazioni iniziali"
976
+
977
+ #~ msgid "%field_1% and %field_2% fields cannot be empty"
978
+ #~ msgstr "I campi %field_1% e %field_2% non possono essere vuoti"
979
+
980
+ #~ msgctxt "%field% = field name"
981
+ #~ msgid "%field% field cannot be empty"
982
+ #~ msgstr "Il campo %field% non può essere vuoto"
983
+
984
+ #~ msgid "%field% testo cannot be empty"
985
+ #~ msgstr "Il campo %field% non può essere vuoto"
986
+
987
+ #~ msgid "%field% field cannot be empty"
988
+ #~ msgstr "Il campo %field% non può essere vuoto"
plugin-fw/languages/yith-plugin-fw.pot ADDED
@@ -0,0 +1,920 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2015 YIThemes
2
+ # This file is distributed under the same license as the YITH Plugin Starter package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: YITH Plugin Starter 1.0.0 Plugin FW\n"
6
+ "Report-Msgid-Bugs-To: Your Inspiration Themes <plugins@yithemes.com>\n"
7
+ "POT-Creation-Date: 2015-05-05 10:38+0100\n"
8
+ "PO-Revision-Date: 2015-05-05 10:38+0100\n"
9
+ "Last-Translator: \n"
10
+ "Language-Team: Your Inspiration Themes <info@yithemes.com>\n"
11
+ "Language: en\n"
12
+ "MIME-Version: 1.0\n"
13
+ "Content-Type: text/plain; charset=utf-8\n"
14
+ "Content-Transfer-Encoding: 8bit\n"
15
+ "X-Generator: Poedit 1.7.6\n"
16
+ "X-Poedit-KeywordsList: __;_e;_x:1,2c;_ex:1,2c;_n:1,2;_nx:1,2,4c;_n_noop:1,2;"
17
+ "_nx_noop:1,2,3c;esc_attr__;esc_html__;esc_attr_e;esc_html_e;esc_attr_x:1,2c;"
18
+ "esc_html_x:1,2c\n"
19
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
+ "X-Poedit-SourceCharset: UTF-8\n"
21
+ "X-Poedit-Basepath: ../\n"
22
+ "X-Textdomain-Support: yes\n"
23
+ "X-Poedit-SearchPath-0: .\n"
24
+
25
+ #: lib/yit-cpt-unlimited.php:460 lib/yit-cpt-unlimited.php:574
26
+ #: lib/yit-cpt-unlimited.php:719 lib/yit-cpt-unlimited.php:1632
27
+ #, php-format
28
+ msgid "Add %s"
29
+ msgstr ""
30
+
31
+ #: lib/yit-cpt-unlimited.php:461 lib/yit-cpt-unlimited.php:575
32
+ #, php-format
33
+ msgid "Add New %s"
34
+ msgstr ""
35
+
36
+ #: lib/yit-cpt-unlimited.php:462 lib/yit-cpt-unlimited.php:576
37
+ #: lib/yit-cpt-unlimited.php:1267 lib/yit-cpt-unlimited.php:1304
38
+ #, php-format
39
+ msgid "Edit %s"
40
+ msgstr ""
41
+
42
+ #: lib/yit-cpt-unlimited.php:463 lib/yit-cpt-unlimited.php:577
43
+ #, php-format
44
+ msgid "New %s"
45
+ msgstr ""
46
+
47
+ #: lib/yit-cpt-unlimited.php:464 lib/yit-cpt-unlimited.php:578
48
+ #, php-format
49
+ msgid "All %s"
50
+ msgstr ""
51
+
52
+ #: lib/yit-cpt-unlimited.php:465 lib/yit-cpt-unlimited.php:579
53
+ #: lib/yit-cpt-unlimited.php:1251 lib/yit-cpt-unlimited.php:1305
54
+ #, php-format
55
+ msgid "View %s"
56
+ msgstr ""
57
+
58
+ #: lib/yit-cpt-unlimited.php:466 lib/yit-cpt-unlimited.php:580
59
+ #, php-format
60
+ msgid "Search %s"
61
+ msgstr ""
62
+
63
+ #: lib/yit-cpt-unlimited.php:467 lib/yit-cpt-unlimited.php:581
64
+ #, php-format
65
+ msgid "No %s found"
66
+ msgstr ""
67
+
68
+ #: lib/yit-cpt-unlimited.php:468 lib/yit-cpt-unlimited.php:582
69
+ #, php-format
70
+ msgid "No %s found in Trash"
71
+ msgstr ""
72
+
73
+ #: lib/yit-cpt-unlimited.php:625
74
+ #, php-format
75
+ msgctxt "taxonomy general name"
76
+ msgid "%s Categories"
77
+ msgstr ""
78
+
79
+ #: lib/yit-cpt-unlimited.php:626
80
+ msgctxt "taxonomy singular name"
81
+ msgid "Category"
82
+ msgstr ""
83
+
84
+ #: lib/yit-cpt-unlimited.php:627
85
+ msgid "Search Categories"
86
+ msgstr ""
87
+
88
+ #: lib/yit-cpt-unlimited.php:628
89
+ msgid "All Categories"
90
+ msgstr ""
91
+
92
+ #: lib/yit-cpt-unlimited.php:629
93
+ msgid "Parent Category"
94
+ msgstr ""
95
+
96
+ #: lib/yit-cpt-unlimited.php:630
97
+ msgid "Parent Category:"
98
+ msgstr ""
99
+
100
+ #: lib/yit-cpt-unlimited.php:631
101
+ msgid "Edit Category"
102
+ msgstr ""
103
+
104
+ #: lib/yit-cpt-unlimited.php:632
105
+ msgid "Update Category"
106
+ msgstr ""
107
+
108
+ #: lib/yit-cpt-unlimited.php:633
109
+ msgid "Add New Category"
110
+ msgstr ""
111
+
112
+ #: lib/yit-cpt-unlimited.php:634
113
+ msgid "New Category Name"
114
+ msgstr ""
115
+
116
+ #: lib/yit-cpt-unlimited.php:635
117
+ msgid "Category"
118
+ msgstr ""
119
+
120
+ #: lib/yit-cpt-unlimited.php:724
121
+ msgid "Categories"
122
+ msgstr ""
123
+
124
+ #: lib/yit-cpt-unlimited.php:1042
125
+ #, php-format
126
+ msgid "%s Settings"
127
+ msgstr ""
128
+
129
+ #: lib/yit-cpt-unlimited.php:1048 lib/yit-cpt-unlimited.php:1196
130
+ #: lib/yit-cpt-unlimited.php:1202 lib/yit-plugin-panel.php:64
131
+ msgid "Settings"
132
+ msgstr ""
133
+
134
+ #: lib/yit-cpt-unlimited.php:1051
135
+ msgid "Type"
136
+ msgstr ""
137
+
138
+ #: lib/yit-cpt-unlimited.php:1052
139
+ msgid "Layout for this "
140
+ msgstr ""
141
+
142
+ #: lib/yit-cpt-unlimited.php:1058
143
+ msgid "Rewrite"
144
+ msgstr ""
145
+
146
+ #: lib/yit-cpt-unlimited.php:1059
147
+ msgid ""
148
+ "Univocal identification name in the URL for each product (slug from post if empty)"
149
+ msgstr ""
150
+
151
+ #: lib/yit-cpt-unlimited.php:1064
152
+ msgid "Label in Singular"
153
+ msgstr ""
154
+
155
+ #: lib/yit-cpt-unlimited.php:1065
156
+ msgid "Set a label in singular (title of portfolio if empty)"
157
+ msgstr ""
158
+
159
+ #: lib/yit-cpt-unlimited.php:1070
160
+ msgid "Label in Plural"
161
+ msgstr ""
162
+
163
+ #: lib/yit-cpt-unlimited.php:1071
164
+ msgid "Set a label in plural (title of portfolio if empty)"
165
+ msgstr ""
166
+
167
+ #: lib/yit-cpt-unlimited.php:1076
168
+ msgid "Taxonomy"
169
+ msgstr ""
170
+
171
+ #: lib/yit-cpt-unlimited.php:1077
172
+ msgid ""
173
+ "If you want to use categories in the portfolio, set a name for taxonomy. Name "
174
+ "should be a slug (must not contain capital letters nor spaces) and must not be "
175
+ "more than 32 characters long (database structure restriction)."
176
+ msgstr ""
177
+
178
+ #: lib/yit-cpt-unlimited.php:1082
179
+ msgid "Taxonomy Rewrite"
180
+ msgstr ""
181
+
182
+ #: lib/yit-cpt-unlimited.php:1083
183
+ msgid "Set univocal name for each category page URL."
184
+ msgstr ""
185
+
186
+ #: lib/yit-cpt-unlimited.php:1088
187
+ msgid "Single layout"
188
+ msgstr ""
189
+
190
+ #: lib/yit-cpt-unlimited.php:1089
191
+ msgid "Layout for single page of this portfolio"
192
+ msgstr ""
193
+
194
+ #: lib/yit-cpt-unlimited.php:1130
195
+ msgid "layout settings"
196
+ msgstr ""
197
+
198
+ #: lib/yit-cpt-unlimited.php:1222 lib/yit-cpt-unlimited.php:1235
199
+ msgid "Quick links"
200
+ msgstr ""
201
+
202
+ #: lib/yit-cpt-unlimited.php:1475
203
+ #, php-format
204
+ msgid "Show frontend of the %s"
205
+ msgstr ""
206
+
207
+ #: lib/yit-cpt-unlimited.php:1482 templates/metaboxes/types/customtabs.php:46
208
+ #: templates/metaboxes/types/customtabs.php:90
209
+ msgid "Name"
210
+ msgstr ""
211
+
212
+ #: lib/yit-cpt-unlimited.php:1631
213
+ #, php-format
214
+ msgid "Add %s from images"
215
+ msgstr ""
216
+
217
+ #: lib/yit-cpt-unlimited.php:1633
218
+ msgid "Add with multiupload"
219
+ msgstr ""
220
+
221
+ #: lib/yit-plugin-panel-wc.php:295
222
+ msgid "The changes you have made will be lost if you leave this page."
223
+ msgstr ""
224
+
225
+ #: lib/yit-plugin-panel.php:63
226
+ msgid "Plugin Settings"
227
+ msgstr ""
228
+
229
+ #: lib/yit-plugin-panel.php:95 lib/yit-plugin-subpanel.php:101
230
+ msgid "YIT Plugins"
231
+ msgstr ""
232
+
233
+ #: lib/yit-plugin-panel.php:292 lib/yit-plugin-subpanel.php:142
234
+ #: templates/panel/woocommerce/woocommerce-form.php:5
235
+ msgid "Save Changes"
236
+ msgstr ""
237
+
238
+ #: lib/yit-plugin-panel.php:295 templates/panel/woocommerce/woocommerce-form.php:8
239
+ msgid "If you continue with this action, you will reset all options in this page."
240
+ msgstr ""
241
+
242
+ #: lib/yit-plugin-panel.php:297 lib/yit-plugin-subpanel.php:147
243
+ msgid "Reset to Default"
244
+ msgstr ""
245
+
246
+ #: lib/yit-plugin-panel.php:297 lib/yit-plugin-subpanel.php:147
247
+ #: templates/panel/woocommerce/woocommerce-form.php:10
248
+ msgid "Are you sure?"
249
+ msgstr ""
250
+
251
+ #: lib/yit-plugin-panel.php:431
252
+ msgid "The element you have entered already exists. Please, enter another name."
253
+ msgstr ""
254
+
255
+ #: lib/yit-plugin-panel.php:432
256
+ msgid "Settings saved"
257
+ msgstr ""
258
+
259
+ #: lib/yit-plugin-panel.php:433
260
+ msgid "Settings reset"
261
+ msgstr ""
262
+
263
+ #: lib/yit-plugin-panel.php:434
264
+ msgid "Element deleted correctly."
265
+ msgstr ""
266
+
267
+ #: lib/yit-plugin-panel.php:435 lib/yit-plugin-panel.php:436
268
+ msgid "Element updated correctly."
269
+ msgstr ""
270
+
271
+ #: lib/yit-plugin-panel.php:437
272
+ msgid "Database imported correctly."
273
+ msgstr ""
274
+
275
+ #: lib/yit-plugin-panel.php:438
276
+ msgid "An error has occurred during import. Please try again."
277
+ msgstr ""
278
+
279
+ #: lib/yit-plugin-panel.php:439
280
+ msgid "The added file is not valid."
281
+ msgstr ""
282
+
283
+ #: lib/yit-plugin-panel.php:440
284
+ msgid "Sorry, import is disabled."
285
+ msgstr ""
286
+
287
+ #: lib/yit-plugin-panel.php:441
288
+ msgid "Sorting successful."
289
+ msgstr ""
290
+
291
+ #: lib/yit-plugin-subpanel.php:145
292
+ msgid ""
293
+ "If you continue with this action, you will reset all the options in this page."
294
+ msgstr ""
295
+
296
+ #: lib/yit-pointers.php:70
297
+ msgid "Plugins Activated"
298
+ msgstr ""
299
+
300
+ #: lib/yit-pointers.php:71
301
+ msgid ""
302
+ "From now on, you can find all plugin options in YIT Plugin menu.\n"
303
+ " For each plugin installed, customization "
304
+ "settings will be available as a new entry in YIT Plugin menu."
305
+ msgstr ""
306
+
307
+ #: lib/yit-pointers.php:73 lib/yit-pointers.php:89
308
+ msgid "Discover all our plugins available on:"
309
+ msgstr ""
310
+
311
+ #: lib/yit-pointers.php:74 lib/yit-pointers.php:90
312
+ msgid "and"
313
+ msgstr ""
314
+
315
+ #: lib/yit-pointers.php:84
316
+ msgid "Plugins Upgraded"
317
+ msgstr ""
318
+
319
+ #: lib/yit-pointers.php:85
320
+ msgid ""
321
+ "From now on, you can find all options of your plugins in YIT Plugin menu.\n"
322
+ " Any time one of our plugins is updated, a new "
323
+ "entry will be added to this menu.\n"
324
+ " For example, after the update, plugin options "
325
+ "(such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search, etc.)\n"
326
+ " will be moved from previous location to YIT "
327
+ "Plugin tab."
328
+ msgstr ""
329
+
330
+ #: lib/yit-upgrade.php:123
331
+ msgid "There is a new version of %plugin_name% available."
332
+ msgstr ""
333
+
334
+ #: lib/yit-upgrade.php:124
335
+ msgid "View version %latest% details."
336
+ msgstr ""
337
+
338
+ #: lib/yit-upgrade.php:125
339
+ msgid "Automatic update is unavailable for this plugin,"
340
+ msgstr ""
341
+
342
+ #: lib/yit-upgrade.php:126
343
+ msgid "please <a href=\"%activate_link%\">activate</a> your copy of %plugin_name%."
344
+ msgstr ""
345
+
346
+ #: lib/yit-upgrade.php:127
347
+ msgid "Update now."
348
+ msgstr ""
349
+
350
+ #: lib/yit-upgrade.php:230
351
+ msgid "Yithemes Repository"
352
+ msgstr ""
353
+
354
+ #: lib/yit-upgrade.php:264
355
+ msgid "Invalid URL Provided."
356
+ msgstr ""
357
+
358
+ #: lib/yit-upgrade.php:277
359
+ msgid "Could not create Temporary file."
360
+ msgstr ""
361
+
362
+ #: lib/yit-upgrade.php:419
363
+ #, php-format
364
+ msgid ""
365
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
366
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>."
367
+ msgstr ""
368
+
369
+ #: lib/yit-upgrade.php:421
370
+ #, php-format
371
+ msgid ""
372
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
373
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You have to "
374
+ "activate the plugin on a single site of the network to benefit from automatic "
375
+ "updates.</em>"
376
+ msgstr ""
377
+
378
+ #: lib/yit-upgrade.php:423
379
+ #, php-format
380
+ msgid ""
381
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
382
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>Automatic "
383
+ "update is unavailable for this plugin, please <a href=\"%5$s\" title=\"Licence "
384
+ "activation\">activate</a> your copy of %6s.</em>"
385
+ msgstr ""
386
+
387
+ #: lib/yit-upgrade.php:425
388
+ #, php-format
389
+ msgid ""
390
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox yit-"
391
+ "changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a href=\"%5$s"
392
+ "\">update now</a>."
393
+ msgstr ""
394
+
395
+ #: lib/yit-upgrade.php:498
396
+ msgid "You can't update the plugins for this site."
397
+ msgstr ""
398
+
399
+ #: lib/yit-upgrade.php:502
400
+ msgid "You do not have sufficient permissions to update the plugins for this site."
401
+ msgstr ""
402
+
403
+ #: lib/yit-upgrade.php:509
404
+ msgid "Update Plugin"
405
+ msgstr ""
406
+
407
+ #: licence/lib/yit-licence.php:161
408
+ #, php-format
409
+ msgid "%field% field cannot be empty"
410
+ msgstr ""
411
+
412
+ #: licence/lib/yit-licence.php:162
413
+ msgid "%field_1% and %field_2% fields cannot be empty"
414
+ msgstr ""
415
+
416
+ #: licence/lib/yit-licence.php:163
417
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
418
+ msgstr ""
419
+
420
+ #: licence/lib/yit-licence.php:548
421
+ msgid "Invalid Request"
422
+ msgstr ""
423
+
424
+ #: licence/lib/yit-licence.php:549
425
+ msgid "Invalid licence key"
426
+ msgstr ""
427
+
428
+ #: licence/lib/yit-licence.php:550
429
+ msgid "Software has been deactivated"
430
+ msgstr ""
431
+
432
+ #: licence/lib/yit-licence.php:551
433
+ msgid "Maximum number of activations exceeded"
434
+ msgstr ""
435
+
436
+ #: licence/lib/yit-licence.php:552
437
+ msgid "Invalid instance ID"
438
+ msgstr ""
439
+
440
+ #: licence/lib/yit-licence.php:553
441
+ msgid "Invalid security key"
442
+ msgstr ""
443
+
444
+ #: licence/lib/yit-licence.php:554
445
+ msgid "Licence key has expired"
446
+ msgstr ""
447
+
448
+ #: licence/lib/yit-licence.php:555
449
+ msgid "Licence key has been banned"
450
+ msgstr ""
451
+
452
+ #: licence/lib/yit-plugin-licence.php:64 licence/lib/yit-plugin-licence.php:65
453
+ #: licence/lib/yit-theme-licence.php:64 licence/lib/yit-theme-licence.php:65
454
+ #: licence/lib/yit-theme-licence.php:107 licence/lib/yit-theme-licence.php:108
455
+ msgid "Licence Activation"
456
+ msgstr ""
457
+
458
+ #: licence/lib/yit-theme-licence.php:115 licence/lib/yit-theme-licence.php:116
459
+ #, php-format
460
+ msgid "%s"
461
+ msgstr ""
462
+
463
+ #: licence/templates/panel/activation/activation-panel.php:19
464
+ msgid "Yithemes Licence Activation"
465
+ msgstr ""
466
+
467
+ #: licence/templates/panel/activation/activation-panel.php:23
468
+ msgid ""
469
+ "I cannot find the license key for activating the theme I have bought some time "
470
+ "ago. Where can I find it?"
471
+ msgstr ""
472
+
473
+ #: licence/templates/panel/activation/activation-panel.php:26
474
+ msgid ""
475
+ "If you have purchased one of our products before 27 January 2015, you can benefit "
476
+ "from support and updates (the services offered with the license)\n"
477
+ " until 27 January 2016 and you do not have to purchase it again to get "
478
+ "a new license key, because, before this date, your license used to be activated "
479
+ "automatically by our system.\n"
480
+ " After 27 January 2016, instead, if you want to benefit from support "
481
+ "and updates you have to buy a new license and activate it through the license key "
482
+ "you will be\n"
483
+ " provided with and that you can find in your YIThemes account, in "
484
+ "section \"My licenses\"."
485
+ msgstr ""
486
+
487
+ #: licence/templates/panel/activation/activation-panel.php:37
488
+ msgid ""
489
+ "Have you updated your licenses? Have you asked for an extension? Update "
490
+ "information concerning your products."
491
+ msgstr ""
492
+
493
+ #: licence/templates/panel/activation/activation-panel.php:39
494
+ msgid "Update licence information"
495
+ msgstr ""
496
+
497
+ #: licence/templates/panel/activation/activation-panel.php:49
498
+ msgid "Products to be activated"
499
+ msgstr ""
500
+
501
+ #: licence/templates/panel/activation/activation-panel.php:68
502
+ msgid "Activate"
503
+ msgstr ""
504
+
505
+ #: licence/templates/panel/activation/activation-panel.php:87
506
+ msgid "Activated"
507
+ msgstr ""
508
+
509
+ #: licence/templates/panel/activation/activation-panel.php:91
510
+ #: licence/templates/panel/activation/activation-panel.php:123
511
+ #: licence/templates/panel/activation/activation-panel.php:147
512
+ msgid "Product Name"
513
+ msgstr ""
514
+
515
+ #: licence/templates/panel/activation/activation-panel.php:92
516
+ #: licence/templates/panel/activation/activation-panel.php:124
517
+ #: licence/templates/panel/activation/activation-panel.php:148
518
+ #: templates/metaboxes/types/contactform.php:148
519
+ #: templates/metaboxes/types/contactform.php:340
520
+ msgid "Email"
521
+ msgstr ""
522
+
523
+ #: licence/templates/panel/activation/activation-panel.php:93
524
+ #: licence/templates/panel/activation/activation-panel.php:125
525
+ #: licence/templates/panel/activation/activation-panel.php:149
526
+ msgid "Licence Key"
527
+ msgstr ""
528
+
529
+ #: licence/templates/panel/activation/activation-panel.php:94
530
+ #: licence/templates/panel/activation/activation-panel.php:150
531
+ msgid "Expires"
532
+ msgstr ""
533
+
534
+ #: licence/templates/panel/activation/activation-panel.php:95
535
+ msgid "Remaining"
536
+ msgstr ""
537
+
538
+ #: licence/templates/panel/activation/activation-panel.php:96
539
+ #: licence/templates/panel/activation/activation-panel.php:109
540
+ #: licence/templates/panel/activation/activation-panel.php:151
541
+ #: licence/templates/panel/activation/activation-panel.php:161
542
+ msgid "Renew"
543
+ msgstr ""
544
+
545
+ #: licence/templates/panel/activation/activation-panel.php:107
546
+ #, php-format
547
+ msgid "%1s out of %2s"
548
+ msgstr ""
549
+
550
+ #: licence/templates/panel/activation/activation-panel.php:119
551
+ msgid "Banned"
552
+ msgstr ""
553
+
554
+ #: licence/templates/panel/activation/activation-panel.php:143
555
+ msgid "Expired"
556
+ msgstr ""
557
+
558
+ #: templates/metaboxes/types/ajax-products.php:23
559
+ msgid "Search for a product"
560
+ msgstr ""
561
+
562
+ #: templates/metaboxes/types/categories.php:36
563
+ msgid "No categories."
564
+ msgstr ""
565
+
566
+ #: templates/metaboxes/types/categories.php:42
567
+ msgid "+ Add New Category"
568
+ msgstr ""
569
+
570
+ #: templates/metaboxes/types/categories.php:46
571
+ msgid "Add"
572
+ msgstr ""
573
+
574
+ #: templates/metaboxes/types/contactform.php:7
575
+ msgid "Text Input"
576
+ msgstr ""
577
+
578
+ #: templates/metaboxes/types/contactform.php:8
579
+ msgid "Checkbox"
580
+ msgstr ""
581
+
582
+ #: templates/metaboxes/types/contactform.php:9
583
+ msgid "Select"
584
+ msgstr ""
585
+
586
+ #: templates/metaboxes/types/contactform.php:10
587
+ msgid "Textarea"
588
+ msgstr ""
589
+
590
+ #: templates/metaboxes/types/contactform.php:11
591
+ msgid "Radio Input"
592
+ msgstr ""
593
+
594
+ #: templates/metaboxes/types/contactform.php:12
595
+ msgid "Password Field"
596
+ msgstr ""
597
+
598
+ #: templates/metaboxes/types/contactform.php:13
599
+ msgid "File Upload"
600
+ msgstr ""
601
+
602
+ #: templates/metaboxes/types/contactform.php:47
603
+ msgid "Theme Icon"
604
+ msgstr ""
605
+
606
+ #: templates/metaboxes/types/contactform.php:48
607
+ msgid "Custom Icon"
608
+ msgstr ""
609
+
610
+ #: templates/metaboxes/types/contactform.php:49
611
+ #: templates/metaboxes/types/responsivesliders.php:24
612
+ msgid "None"
613
+ msgstr ""
614
+
615
+ #: templates/metaboxes/types/contactform.php:60
616
+ msgid "Add field"
617
+ msgstr ""
618
+
619
+ #: templates/metaboxes/types/contactform.php:69
620
+ #: templates/metaboxes/types/contactform.php:261
621
+ #: templates/metaboxes/types/customtabs.php:37
622
+ #: templates/metaboxes/types/customtabs.php:82
623
+ msgid "Remove"
624
+ msgstr ""
625
+
626
+ #: templates/metaboxes/types/contactform.php:70
627
+ #: templates/metaboxes/types/contactform.php:262
628
+ msgid "Click to toggle"
629
+ msgstr ""
630
+
631
+ #: templates/metaboxes/types/contactform.php:77
632
+ #: templates/metaboxes/types/contactform.php:269
633
+ msgid "Title Field"
634
+ msgstr ""
635
+
636
+ #: templates/metaboxes/types/contactform.php:81
637
+ #: templates/metaboxes/types/contactform.php:273
638
+ msgid "Insert the title for the field."
639
+ msgstr ""
640
+
641
+ #: templates/metaboxes/types/contactform.php:86
642
+ #: templates/metaboxes/types/contactform.php:278
643
+ msgid "Data Name"
644
+ msgstr ""
645
+
646
+ #: templates/metaboxes/types/contactform.php:90
647
+ #: templates/metaboxes/types/contactform.php:282
648
+ msgid ""
649
+ "REQUIRED: Field identification name to be entered into email body. <strong>Note:</"
650
+ "strong>Use only lowercase characters and underscores."
651
+ msgstr ""
652
+
653
+ #: templates/metaboxes/types/contactform.php:95
654
+ #: templates/metaboxes/types/contactform.php:287
655
+ msgid "Type field"
656
+ msgstr ""
657
+
658
+ #: templates/metaboxes/types/contactform.php:103
659
+ #: templates/metaboxes/types/contactform.php:295
660
+ msgid "Select the type for this field."
661
+ msgstr ""
662
+
663
+ #: templates/metaboxes/types/contactform.php:108
664
+ #: templates/metaboxes/types/contactform.php:300
665
+ msgid "Checked"
666
+ msgstr ""
667
+
668
+ #: templates/metaboxes/types/contactform.php:112
669
+ #: templates/metaboxes/types/contactform.php:304
670
+ msgid "Select this option if you want this field appears as already checked."
671
+ msgstr ""
672
+
673
+ #: templates/metaboxes/types/contactform.php:117
674
+ #: templates/metaboxes/types/contactform.php:309
675
+ msgid "Add options "
676
+ msgstr ""
677
+
678
+ #: templates/metaboxes/types/contactform.php:118
679
+ #: templates/metaboxes/types/contactform.php:310
680
+ msgid "Add option"
681
+ msgstr ""
682
+
683
+ #: templates/metaboxes/types/contactform.php:121
684
+ #: templates/metaboxes/types/contactform.php:313
685
+ #: templates/metaboxes/types/contactform.php:436
686
+ msgid "Selected"
687
+ msgstr ""
688
+
689
+ #: templates/metaboxes/types/contactform.php:124
690
+ #: templates/metaboxes/types/contactform.php:316
691
+ #: templates/metaboxes/types/contactform.php:436
692
+ msgid "Delete option"
693
+ msgstr ""
694
+
695
+ #: templates/metaboxes/types/contactform.php:130
696
+ #: templates/metaboxes/types/contactform.php:322
697
+ msgid "Error Message"
698
+ msgstr ""
699
+
700
+ #: templates/metaboxes/types/contactform.php:134
701
+ #: templates/metaboxes/types/contactform.php:326
702
+ msgid "Insert the error message for validation."
703
+ msgstr ""
704
+
705
+ #: templates/metaboxes/types/contactform.php:139
706
+ #: templates/metaboxes/types/contactform.php:331
707
+ msgid "Required"
708
+ msgstr ""
709
+
710
+ #: templates/metaboxes/types/contactform.php:143
711
+ #: templates/metaboxes/types/contactform.php:335
712
+ msgid "Select this option if it must be required."
713
+ msgstr ""
714
+
715
+ #: templates/metaboxes/types/contactform.php:152
716
+ #: templates/metaboxes/types/contactform.php:344
717
+ msgid "Select this option if the email must be valid."
718
+ msgstr ""
719
+
720
+ #: templates/metaboxes/types/contactform.php:157
721
+ #: templates/metaboxes/types/contactform.php:349
722
+ msgid "Reply To"
723
+ msgstr ""
724
+
725
+ #: templates/metaboxes/types/contactform.php:161
726
+ #: templates/metaboxes/types/contactform.php:353
727
+ msgid "Select this if it is the email you can reply to."
728
+ msgstr ""
729
+
730
+ #: templates/metaboxes/types/contactform.php:166
731
+ #: templates/metaboxes/types/contactform.php:358
732
+ msgid "Class"
733
+ msgstr ""
734
+
735
+ #: templates/metaboxes/types/contactform.php:170
736
+ #: templates/metaboxes/types/contactform.php:362
737
+ msgid "Insert additional class(es) (separated by commas) for more personalization."
738
+ msgstr ""
739
+
740
+ #: templates/metaboxes/types/contactform.php:175
741
+ #: templates/metaboxes/types/contactform.php:367
742
+ msgid "Icon"
743
+ msgstr ""
744
+
745
+ #: templates/metaboxes/types/contactform.php:203
746
+ #: templates/metaboxes/types/contactform.php:391
747
+ #: templates/metaboxes/types/icon-list.php:69
748
+ #: templates/metaboxes/types/select-icon.php:33
749
+ #: templates/metaboxes/types/upload.php:21 templates/panel/types/upload.php:31
750
+ #: templates/panel/woocommerce/woocommerce-upload.php:35
751
+ msgid "Upload"
752
+ msgstr ""
753
+
754
+ #: templates/metaboxes/types/contactform.php:209
755
+ #: templates/metaboxes/types/contactform.php:397
756
+ #: templates/metaboxes/types/icon-list.php:75
757
+ #: templates/metaboxes/types/select-icon.php:39
758
+ msgid "Image preview"
759
+ msgstr ""
760
+
761
+ #: templates/metaboxes/types/contactform.php:217
762
+ #: templates/metaboxes/types/contactform.php:405
763
+ msgid "Insert an icon for more personalization."
764
+ msgstr ""
765
+
766
+ #: templates/metaboxes/types/contactform.php:222
767
+ #: templates/metaboxes/types/contactform.php:409
768
+ msgid "Width"
769
+ msgstr ""
770
+
771
+ #: templates/metaboxes/types/contactform.php:247
772
+ #: templates/metaboxes/types/contactform.php:421
773
+ msgid "Set field length."
774
+ msgstr ""
775
+
776
+ #: templates/metaboxes/types/customtabs.php:28
777
+ msgid "Close all"
778
+ msgstr ""
779
+
780
+ #: templates/metaboxes/types/customtabs.php:28
781
+ msgid "Expand all"
782
+ msgstr ""
783
+
784
+ #: templates/metaboxes/types/customtabs.php:52
785
+ #: templates/metaboxes/types/customtabs.php:95
786
+ msgid "Value"
787
+ msgstr ""
788
+
789
+ #: templates/metaboxes/types/customtabs.php:53
790
+ #: templates/metaboxes/types/customtabs.php:96
791
+ msgid "Content of the tab. (HTML is supported)"
792
+ msgstr ""
793
+
794
+ #: templates/metaboxes/types/customtabs.php:65
795
+ msgid "Add custom product tab"
796
+ msgstr ""
797
+
798
+ #: templates/metaboxes/types/customtabs.php:107
799
+ msgid "Do you want to remove the custom tab?"
800
+ msgstr ""
801
+
802
+ #: templates/metaboxes/types/icon-list.php:89
803
+ #, php-format
804
+ msgid "(Default: %s <img src=\"%s\"/>)"
805
+ msgstr ""
806
+
807
+ #: templates/metaboxes/types/icon-list.php:91
808
+ #, php-format
809
+ msgid "(Default: <i %s></i> )"
810
+ msgstr ""
811
+
812
+ #: templates/metaboxes/types/image-gallery.php:40
813
+ #: templates/metaboxes/types/image-gallery.php:45
814
+ #: templates/metaboxes/types/images.php:38 templates/metaboxes/types/images.php:64
815
+ msgid "Delete image"
816
+ msgstr ""
817
+
818
+ #: templates/metaboxes/types/image-gallery.php:45
819
+ msgid "Add Images to Gallery"
820
+ msgstr ""
821
+
822
+ #: templates/metaboxes/types/image-gallery.php:45
823
+ msgid "Add to gallery"
824
+ msgstr ""
825
+
826
+ #: templates/metaboxes/types/image-gallery.php:45
827
+ msgid "Add images"
828
+ msgstr ""
829
+
830
+ #: templates/metaboxes/types/image-gallery.php:45
831
+ msgid "Delete"
832
+ msgstr ""
833
+
834
+ #: templates/metaboxes/types/images.php:42
835
+ msgid "Upload new images"
836
+ msgstr ""
837
+
838
+ #: templates/metaboxes/types/images.php:75
839
+ msgid "Are you sure you want to remove this image?"
840
+ msgstr ""
841
+
842
+ #: templates/metaboxes/types/sidebar-layout.php:25
843
+ #: templates/metaboxes/types/sidebars.php:36
844
+ msgid "Left sidebar"
845
+ msgstr ""
846
+
847
+ #: templates/metaboxes/types/sidebar-layout.php:28
848
+ #: templates/metaboxes/types/sidebars.php:42
849
+ #: templates/metaboxes/types/sidebars.php:45
850
+ msgid "No sidebar"
851
+ msgstr ""
852
+
853
+ #: templates/metaboxes/types/sidebar-layout.php:31
854
+ #: templates/metaboxes/types/sidebars.php:39
855
+ msgid "Right sidebar"
856
+ msgstr ""
857
+
858
+ #: templates/metaboxes/types/sidebar-layout.php:34
859
+ #: templates/metaboxes/types/sidebars.php:53
860
+ #: templates/metaboxes/types/sidebars.php:64
861
+ msgid "Choose a sidebar"
862
+ msgstr ""
863
+
864
+ #: templates/metaboxes/types/sidebars.php:51
865
+ msgid "Left Sidebar"
866
+ msgstr ""
867
+
868
+ #: templates/metaboxes/types/sidebars.php:62
869
+ msgid "Right Sidebar"
870
+ msgstr ""
871
+
872
+ #: templates/metaboxes/types/typography.php:42
873
+ msgid "px"
874
+ msgstr ""
875
+
876
+ #: templates/metaboxes/types/typography.php:43
877
+ msgid "em"
878
+ msgstr ""
879
+
880
+ #: templates/metaboxes/types/typography.php:44
881
+ msgid "pt"
882
+ msgstr ""
883
+
884
+ #: templates/metaboxes/types/typography.php:45
885
+ msgid "rem"
886
+ msgstr ""
887
+
888
+ #: templates/metaboxes/types/typography.php:59
889
+ #: templates/metaboxes/types/typography.php:153
890
+ #: templates/metaboxes/types/typography.php:217
891
+ msgid "Web fonts"
892
+ msgstr ""
893
+
894
+ #: templates/metaboxes/types/typography.php:71
895
+ msgid "Google fonts"
896
+ msgstr ""
897
+
898
+ #: templates/metaboxes/types/typography.php:96
899
+ msgid "Regular"
900
+ msgstr ""
901
+
902
+ #: templates/metaboxes/types/typography.php:97
903
+ msgid "Bold"
904
+ msgstr ""
905
+
906
+ #: templates/metaboxes/types/typography.php:98
907
+ msgid "Extra bold"
908
+ msgstr ""
909
+
910
+ #: templates/metaboxes/types/typography.php:99
911
+ msgid "Italic"
912
+ msgstr ""
913
+
914
+ #: templates/metaboxes/types/typography.php:100
915
+ msgid "Italic bold"
916
+ msgstr ""
917
+
918
+ #: templates/panel/woocommerce/woocommerce-form.php:10
919
+ msgid "Reset Defaults"
920
+ msgstr ""
plugin-fw/lib/yit-cpt-unlimited.php ADDED
@@ -0,0 +1,1775 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if (!defined('ABSPATH')) {exit('Direct access forbidden.');
11
+ }
12
+
13
+ /**
14
+ * Manage the custom post types as Portfolio, Contact Forms and similar (called CPTU)
15
+ *
16
+ * @class YIT_CPT_Unlimited
17
+ * @package Yithemes
18
+ * @since 2.0.0
19
+ * @author Your Inspiration Themes
20
+ *
21
+ */
22
+
23
+ class YIT_CPT_Unlimited {
24
+
25
+ /**
26
+ * @var string The name of main post type of CPTU
27
+ * @since 1.0
28
+ */
29
+ protected $_name = '';
30
+
31
+ /**
32
+ * @var string The prefix of each post type created by the post of main CPTU
33
+ * @since 1.0
34
+ */
35
+ protected $_prefix_cpt = '';
36
+
37
+ /**
38
+ * @var string The labels defined for the main CPTU
39
+ * @since 1.0
40
+ */
41
+ protected $_labels = '';
42
+
43
+ /**
44
+ * @var string The configuration arguments of post type
45
+ * @since 1.0
46
+ */
47
+ protected $_args = '';
48
+
49
+ /**
50
+ * @var array All post types created by the post of main CPTU
51
+ * @since 1.0
52
+ */
53
+ public $post_types = array();
54
+
55
+ /**
56
+ * @var array $layouts Array with all portfolio layouts available for this site
57
+ * @since 1.0
58
+ */
59
+ public $layouts = array();
60
+
61
+ /**
62
+ * @var string $template_path The pathname of template folder
63
+ * @since 1.0
64
+ */
65
+ protected $template_path = '';
66
+
67
+ /**
68
+ * @var string $template_url The URL of template folder
69
+ * @since 1.0
70
+ */
71
+ protected $template_url = '';
72
+
73
+ /**
74
+ * @var int $_index Unique sequential ID to differentiate same shortcodes in the same page
75
+ */
76
+ public $index = 0;
77
+
78
+ /**
79
+ * @var string $_layout Temporary attribute to load automatically the settings for each layout
80
+ * @since 1.0
81
+ */
82
+ private $_layout = '';
83
+
84
+
85
+ /**
86
+ * Constructor
87
+ *
88
+ * Accept an array of arguments to define the characteristics of CPTU to register.
89
+ *
90
+ * @since 1.0
91
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
92
+ */
93
+ public function __construct( $args = array() ) {
94
+
95
+ $defaults = array(
96
+ 'name' => '',
97
+ 'post_type_prefix' => '',
98
+ 'labels' => array(
99
+ 'main_name' => '',
100
+ 'singular' => '',
101
+ 'plural' => '',
102
+ 'menu' => ''
103
+ ),
104
+ 'manage_layouts' => false,
105
+ 'add_multiuploader' => false,
106
+ 'sortable' => false,
107
+ 'has_single' => false,
108
+ 'has_taxonomy' => false,
109
+ 'label_item_sing' => '',
110
+ 'label_item_plur' => '',
111
+ 'shortcode_name' => '',
112
+ 'shortcode_icon' => '', // URL or icon name from http://melchoyce.github.io/dashicons/
113
+ 'layout_option' => '_type' // the option ID of layout metabox
114
+ );
115
+ $this->_args = wp_parse_args( $args, $defaults );
116
+
117
+ // fix labels
118
+ if ( empty( $this->_args['labels']['main_name'] ) ) {
119
+ $this->_args['labels']['main_name'] = $this->_args['labels']['singular'];
120
+ }
121
+ if ( empty( $this->_args['labels']['menu'] ) ) {
122
+ $this->_args['labels']['menu'] = $this->_args['labels']['singular'];
123
+ }
124
+
125
+ /* populate */
126
+ $this->_name = $this->_args['name'];
127
+ $this->_prefix_cpt = $this->_args['post_type_prefix'];
128
+ $this->_labels = $this->_args['labels'];
129
+
130
+ add_action( 'init', array( $this, 'register_post_type' ) );
131
+ add_action( 'init', array( $this, 'register_cptu_post_types' ) );
132
+
133
+ add_action( 'save_post', array( $this, 'rewrite_flush') );
134
+
135
+ // admin interface
136
+ add_action( 'admin_head', array( $this, 'add_cptu_menu_item' ) );
137
+ add_action( 'admin_init', array( $this, 'add_quick_links_metaboxes' ) );
138
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
139
+
140
+ // metaboxes
141
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_cptu' ), 2 );
142
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_item_fields' ), 2 );
143
+
144
+ // multiuploader
145
+ if ( $this->_args['add_multiuploader'] ) {
146
+ add_action( 'admin_footer', array( $this, 'add_button_multiuploader' ) );
147
+ add_action( 'wp_ajax_yit_cptu_multiuploader', array( $this, 'post_multiuploader' ) );
148
+ }
149
+
150
+ // layouts
151
+ if ( $this->_args['manage_layouts'] ) {
152
+ // get all layouts available
153
+ $this->get_layouts();
154
+ }
155
+
156
+ // single layout
157
+ if ( $this->_args['has_single'] ) {
158
+ add_action( 'yit_loop', array( $this, 'single_template' ) );
159
+ add_action( 'wp', array( $this, 'single_template_config' ) );
160
+
161
+ if ( defined('DOING_AJAX') && DOING_AJAX ) {
162
+ add_action( 'init', array( $this, 'single_template_config' ) );
163
+ }
164
+ }
165
+
166
+ // archive template
167
+ add_action( 'wp', array( $this, 'archive_template' ) );
168
+
169
+ // enqueue the assets of each layout
170
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
171
+
172
+ // add the shortcode, used to show the frontend
173
+ if ( ! empty( $this->_args['shortcode_name'] ) ) {
174
+ add_shortcode( $this->_args['shortcode_name'], array( &$this, 'add_shortcode' ) );
175
+ add_filter( 'yit_shortcode_' . $this->_args['shortcode_name'] . '_icon', array( $this, 'shortcode_icon') );
176
+ add_filter( 'yit-shortcode-plugin-init', array( $this, 'add_shortcode_to_box' ) );
177
+ }
178
+
179
+ // add sortable feature
180
+ if ( $this->_args['sortable'] ) {
181
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_sortable_assets' ) );
182
+ add_action( 'wp_ajax_cpt_sort_posts', array( $this, 'sort_posts' ) );
183
+ add_action( 'admin_init', array( $this, 'init_menu_order' ) );
184
+ add_filter( 'pre_get_posts', array( $this, 'filter_active' ) );
185
+ add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
186
+ add_filter( 'get_next_post_where', array( $this, 'sorted_next_post_where' ) );
187
+ add_filter( 'get_previous_post_where', array( $this, 'sorted_prev_post_where' ) );
188
+ add_filter( 'get_next_post_sort', array( $this, 'sorted_next_post_sort' ) );
189
+ add_filter( 'get_previous_post_sort', array( $this, 'sorted_prev_post_sort' ) );
190
+ }
191
+
192
+ // add default columns to post type table list
193
+ add_filter( 'manage_edit-' . $this->_name . '_columns', array( $this, 'cptu_define_columns' ) );
194
+ add_action( 'manage_' . $this->_name . '_posts_custom_column' , array( $this, 'cptu_change_columns' ), 10, 2 );
195
+
196
+ // add required post type for wordpress importer
197
+ add_filter( 'wp_import_post_data_raw', array( $this, 'add_importer_required_post_type' ) );
198
+ add_filter( 'wp_import_terms', array( $this, 'add_importer_required_taxonomy' ) );
199
+ add_action( 'wp_import_set_post_terms', array( $this, 'recount_terms_post' ), 10, 3 );
200
+
201
+ }
202
+
203
+ /**
204
+ * Enqueue the assets for the sortable feature
205
+ *
206
+ * @return void
207
+ * @since 1.0
208
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
209
+ */
210
+ public function admin_sortable_assets() {
211
+ global $post;
212
+
213
+ if ( ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
214
+ return;
215
+ }
216
+
217
+ wp_enqueue_script( 'yit-cptu-sortable-posts', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cptu-sortable-posts.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0', true );
218
+ }
219
+
220
+ public function init_menu_order( $post_types = array() ) {
221
+ global $wpdb;
222
+
223
+ if ( empty( $post_types ) ) {
224
+ $post_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_type FROM $wpdb->posts WHERE post_type LIKE %s", str_replace( '_', '\_', $this->_prefix_cpt ) . '%' ) );
225
+ } elseif ( ! is_array( $post_types ) ) {
226
+ $post_types = array( $post_types );
227
+ }
228
+
229
+ foreach ( $post_types as $post_type ) {
230
+ $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future') AND menu_order = 0" );
231
+
232
+ if ( empty( $count ) ) {
233
+ continue;
234
+ }
235
+
236
+ $sql = "SELECT ID
237
+ FROM $wpdb->posts
238
+ WHERE post_type = '" . $post_type . "'
239
+ AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
240
+ ORDER BY post_date DESC
241
+ ";
242
+
243
+ $results = $wpdb->get_results( $sql );
244
+
245
+ foreach ( $results as $key => $result ) {
246
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $key + 1 ), array( 'ID' => $result->ID ) );
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Save the order of posts from sortable feature
253
+ *
254
+ * @return void
255
+ * @since 1.0
256
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
257
+ */
258
+ public function sort_posts() {
259
+ global $wpdb;
260
+
261
+ parse_str( $_REQUEST['order'], $data );
262
+
263
+ if ( is_array( $data ) ) {
264
+ //$this->init_menu_order( $_REQUEST['post_type'] );
265
+
266
+ $id_arr = array( );
267
+ foreach ( $data as $key => $values ) {
268
+ foreach ( $values as $position => $id ) {
269
+ $id_arr[] = $id;
270
+ }
271
+ }
272
+
273
+
274
+ $menu_order_arr = array( );
275
+ foreach ( $id_arr as $key => $id ) {
276
+ $results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . $id );
277
+ foreach ( $results as $result ) {
278
+ $menu_order_arr[] = $result->menu_order;
279
+ }
280
+ }
281
+
282
+ sort( $menu_order_arr );
283
+
284
+ foreach ( $data as $key => $values ) {
285
+ foreach ( $values as $position => $id ) {
286
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_order_arr[$position] ), array( 'ID' => $id ) );
287
+ }
288
+ }
289
+ }
290
+
291
+ die();
292
+ }
293
+
294
+ public function filter_active( $wp_query ) {
295
+ if ( is_admin() && isset( $wp_query->query['suppress_filters'] ) )
296
+ $wp_query->query['suppress_filters'] = false;
297
+ if ( is_admin() && isset( $wp_query->query_vars['suppress_filters'] ) )
298
+ $wp_query->query_vars['suppress_filters'] = false;
299
+ return $wp_query;
300
+ }
301
+
302
+ public function pre_get_posts( $wp_query ) {
303
+ if ( is_admin() && !defined( 'DOING_AJAX' ) ) {
304
+ if ( isset( $wp_query->query['post_type'] ) ) {
305
+ $post_types = (array) $wp_query->query['post_type'];
306
+ foreach ( $post_types as $post_type ) {
307
+ if ( $this->_is_valid( $post_type ) ) {
308
+ $wp_query->set( 'orderby', 'menu_order' );
309
+ $wp_query->set( 'order', 'ASC' );
310
+ }
311
+ }
312
+ }
313
+
314
+ } else {
315
+
316
+ $active = false;
317
+
318
+ if ( isset( $wp_query->query['suppress_filters'] ) || isset( $wp_query->query['post_type'] ) ) {
319
+ $post_types = (array) $wp_query->query['post_type'];
320
+ foreach ( $post_types as $post_type ) {
321
+ if ( $this->_is_valid( $post_type ) ) {
322
+ $active = true;
323
+ }
324
+ }
325
+ }
326
+
327
+ if ( $active ) {
328
+ if ( !isset( $wp_query->query['orderby'] ) || $wp_query->query['orderby'] == 'post_date' )
329
+ $wp_query->set( 'orderby', 'menu_order' );
330
+ if ( !isset( $wp_query->query['order'] ) || $wp_query->query['order'] == 'DESC' )
331
+ $wp_query->set( 'order', 'ASC' );
332
+ }
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Filters where clause for get next post
338
+ *
339
+ * @param $where
340
+ *
341
+ * @return string
342
+ * @since 1.0
343
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
344
+ */
345
+ public function sorted_next_post_where( $where ){
346
+ global $post;
347
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
348
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
349
+ }
350
+ else{
351
+ $post = get_post();
352
+ }
353
+
354
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
355
+ return $where;
356
+ }
357
+
358
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
359
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
360
+
361
+ return $result;
362
+ }
363
+
364
+ /**
365
+ * Filters where clause for get prev post
366
+ *
367
+ * @param $where
368
+ *
369
+ * @return string
370
+ * @since 1.0
371
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
372
+ */
373
+ public function sorted_prev_post_where( $where ){
374
+ global $post;
375
+
376
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
377
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
378
+ }
379
+ else{
380
+ $post = get_post();
381
+ }
382
+
383
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
384
+ return $where;
385
+ }
386
+
387
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
388
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
389
+
390
+ return $result;
391
+ }
392
+
393
+ /**
394
+ * Filters sort clause for get next post
395
+ *
396
+ * @param $sort
397
+ *
398
+ * @return string
399
+ * @since 1.0
400
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
401
+ */
402
+ public function sorted_next_post_sort( $sort ){
403
+ global $post;
404
+
405
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
406
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
407
+ }
408
+ else{
409
+ $post = get_post();
410
+ }
411
+
412
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
413
+ return $sort;
414
+ }
415
+
416
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
417
+ return $result;
418
+ }
419
+
420
+ /**
421
+ * Filters sort clause for get prev post
422
+ *
423
+ * @param $sort
424
+ *
425
+ * @return string
426
+ * @since 1.0
427
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
428
+ */
429
+ public function sorted_prev_post_sort( $sort ){
430
+ global $post;
431
+
432
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
433
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
434
+ }
435
+ else{
436
+ $post = get_post();
437
+ }
438
+
439
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
440
+ return $sort;
441
+ }
442
+
443
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
444
+ return $result;
445
+ }
446
+
447
+ /**
448
+ * Register post type
449
+ *
450
+ * Register the post type for the creation of portfolios
451
+ *
452
+ * @return void
453
+ * @since 1.0
454
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
455
+ */
456
+ public function register_post_type() {
457
+ $labels = array(
458
+ 'name' => ucfirst( $this->_labels['main_name'] ),
459
+ 'singular_name' => ucfirst( $this->_labels['singular'] ),
460
+ 'add_new' => sprintf( __( 'Add %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
461
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
462
+ 'edit_item' => sprintf( __( 'Edit %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
463
+ 'new_item' => sprintf( __( 'New %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
464
+ 'all_items' => sprintf( __( 'All %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
465
+ 'view_item' => sprintf( __( 'View %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ),
466
+ 'search_items' => sprintf( __( 'Search %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
467
+ 'not_found' => sprintf( __( 'No %s found', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
468
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yith-plugin-fw' ), ucfirst( $this->_labels['plural'] ) ),
469
+ 'parent_item_colon' => '',
470
+ 'menu_name' => ucfirst( $this->_labels['menu'] )
471
+ );
472
+
473
+ $args = array(
474
+ 'labels' => apply_filters( 'yit_' . $this->_name . '_labels', $labels ),
475
+ 'public' => false,
476
+ 'publicly_queryable' => false,
477
+ 'show_ui' => true,
478
+ 'show_in_menu' => true,
479
+ 'query_var' => false,
480
+ 'capability_type' => 'post',
481
+ 'hierarchical' => false,
482
+ 'menu_position' => null,
483
+ 'supports' => array( 'title' )
484
+ );
485
+
486
+ if ( ! empty( $this->_args['menu_icon'] ) ) {
487
+ $args['menu_icon'] = $this->_args['menu_icon'];
488
+ }
489
+
490
+ register_post_type( $this->_name, apply_filters( 'yit_' . $this->_name . '_args', $args ) );
491
+ }
492
+
493
+ /**
494
+ * Retrieve the values configured inside the custom post type
495
+ *
496
+ * @param $post /WP_Query The post where get the arguments configured in the cpt
497
+ *
498
+ * @return array
499
+ * @since 1.0
500
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
501
+ */
502
+ protected function _cpt_args( $post ) {
503
+ if ( ! isset( $post->ID ) ) {
504
+ return;
505
+ }
506
+
507
+ $args = apply_filters( 'yit_cptu_register_post_type_args', array(
508
+ 'layout' => get_post_meta( $post->ID, $this->_args['layout_option'], true ),
509
+ 'rewrite' => get_post_meta( $post->ID, '_rewrite', true ),
510
+ 'label_singular' => ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $post->ID, '_label_singular', true ),
511
+ 'label_plural' => ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $post->ID, '_label_plural', true ),
512
+ 'taxonomy' => get_post_meta( $post->ID, '_taxonomy', true ),
513
+ 'taxonomy_rewrite' => get_post_meta( $post->ID, '_taxonomy_rewrite', true ),
514
+ ), $this->_name, $post );
515
+
516
+ $title = $post->post_title;
517
+
518
+ if ( empty( $args['label_singular'] ) ) {
519
+ $args['label_singular'] = $title;
520
+ }
521
+
522
+ if ( empty( $args['label_plural'] ) ) {
523
+ $args['label_plural'] = $title;
524
+ }
525
+
526
+ return $args;
527
+ }
528
+
529
+ /**
530
+ * Retrieve the post types created for this CPTU
531
+ *
532
+ * @return array The link changed
533
+ * @since 1.0
534
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
535
+ */
536
+ public function get_post_types() {
537
+ if ( ! empty( $this->post_types ) ) {
538
+ return $this->post_types;
539
+ }
540
+
541
+ $args = array(
542
+ 'post_type' => $this->_name,
543
+ 'posts_per_page' => -1,
544
+ 'post_status' => 'publish'
545
+ );
546
+ $this->post_types = get_posts( $args );
547
+
548
+ return $this->post_types;
549
+ }
550
+
551
+ /**
552
+ * Register portfolio post types
553
+ *
554
+ * Register the post types for each portfolio created by admin
555
+ *
556
+ * @return void
557
+ * @since 1.0
558
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
559
+ */
560
+ public function register_cptu_post_types() {
561
+ $post_types = $this->get_post_types();
562
+ $pts = array();
563
+
564
+ foreach ( $post_types as $pt ) {
565
+
566
+ extract( $this->_cpt_args( $pt ) );
567
+
568
+ $name = $pt->post_name;
569
+ $title = $pt->post_title;
570
+
571
+ $labels = array(
572
+ 'name' => $title,
573
+ 'singular_name' => $label_singular,
574
+ 'add_new' => sprintf( __( 'Add %s', 'yith-plugin-fw' ), $label_singular ),
575
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yith-plugin-fw' ), $label_singular ),
576
+ 'edit_item' => sprintf( __( 'Edit %s', 'yith-plugin-fw' ), $label_singular ),
577
+ 'new_item' => sprintf( __( 'New %s', 'yith-plugin-fw' ), $label_singular ),
578
+ 'all_items' => sprintf( __( 'All %s', 'yith-plugin-fw' ), $label_plural ),
579
+ 'view_item' => sprintf( __( 'View %s', 'yith-plugin-fw' ), $label_singular ),
580
+ 'search_items' => sprintf( __( 'Search %s', 'yith-plugin-fw' ), $label_plural ),
581
+ 'not_found' => sprintf( __( 'No %s found', 'yith-plugin-fw' ), $label_plural ),
582
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yith-plugin-fw' ), $label_plural ),
583
+ 'parent_item_colon' => '',
584
+ 'menu_name' => $title
585
+ );
586
+
587
+ $args = array(
588
+ 'labels' => apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_labels', $labels ),
589
+ 'public' => true,
590
+ 'publicly_queryable' => true,
591
+ 'show_ui' => true,
592
+ 'show_in_menu' => false,
593
+ 'query_var' => true,
594
+ 'capability_type' => 'post',
595
+ 'hierarchical' => false,
596
+ 'menu_position' => null,
597
+ 'supports' => array( 'title', 'editor', 'thumbnail' )
598
+ );
599
+
600
+ if ( ! $this->_args['has_single'] ) {
601
+ $args['public'] = false;
602
+ $args['publicly_queryable'] = false;
603
+ $args['query_var'] = false;
604
+ }
605
+
606
+ if ( $this->_args['manage_layouts'] && isset($this->layouts[ $layout ]) && ! $this->layouts[ $layout ]['support']['description'] ) {
607
+ unset( $args['supports'][1] ); // remove 'editor'
608
+ }
609
+
610
+ if ( ! empty( $rewrite ) ) {
611
+ $args['rewrite'] = array( 'slug' => $rewrite );
612
+ }
613
+
614
+ // register post type
615
+ $post_type = yit_avoid_duplicate( str_replace( '-', '_', substr( $this->_prefix_cpt . $name, 0, 16) ), $post_types );
616
+ register_post_type( $post_type, apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_args', $args, $pt ) ); // save the post type in post meta
617
+
618
+ update_post_meta( $pt->ID, '_post_type', $post_type );
619
+ $pts[] = $post_type;
620
+
621
+ // register taxonomy
622
+ if ( $this->_args['has_taxonomy'] && ! empty( $taxonomy ) ) {
623
+
624
+ $labels = array(
625
+ 'name' => sprintf( _x( '%s Categories', 'taxonomy general name', 'yith-plugin-fw' ), $label_singular ),
626
+ 'singular_name' => _x( 'Category', 'taxonomy singular name', 'yith-plugin-fw' ),
627
+ 'search_items' => __( 'Search Categories', 'yith-plugin-fw' ),
628
+ 'all_items' => __( 'All Categories', 'yith-plugin-fw' ),
629
+ 'parent_item' => __( 'Parent Category', 'yith-plugin-fw' ),
630
+ 'parent_item_colon' => __( 'Parent Category:', 'yith-plugin-fw' ),
631
+ 'edit_item' => __( 'Edit Category', 'yith-plugin-fw' ),
632
+ 'update_item' => __( 'Update Category', 'yith-plugin-fw' ),
633
+ 'add_new_item' => __( 'Add New Category', 'yith-plugin-fw' ),
634
+ 'new_item_name' => __( 'New Category Name', 'yith-plugin-fw' ),
635
+ 'menu_name' => __( 'Category', 'yith-plugin-fw' ),
636
+ );
637
+
638
+ $args = array(
639
+ 'hierarchical' => true,
640
+ 'labels' => $labels,
641
+ 'show_ui' => true,
642
+ 'show_admin_column' => true,
643
+ 'query_var' => true,
644
+ );
645
+
646
+ if ( ! empty( $taxonomy_rewrite ) ) {
647
+ $args['rewrite'] = array( 'slug' => $taxonomy_rewrite );
648
+ }
649
+
650
+ register_taxonomy( substr( $taxonomy, 0, 32 ), $post_type, $args );
651
+
652
+ }
653
+
654
+ }
655
+
656
+ wp_cache_set( 'yit_cptu_post_types', $post_types );
657
+ }
658
+
659
+ /**
660
+ * Flush Rewrite Rules
661
+ *
662
+ * rewrite rules when a cpt unlimited is saved
663
+ *
664
+ * @return void
665
+ * @since 1.0
666
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
667
+ */
668
+
669
+ public function rewrite_flush( $post ){
670
+
671
+ if ( isset( $post ) && $this->_is_valid( get_post_type( intval( $post ) ) ) ) {
672
+ flush_rewrite_rules();
673
+ }
674
+
675
+ }
676
+
677
+ /**
678
+ * Add the item for each portfolio under "Portfolios"
679
+ *
680
+ * @return void
681
+ * @since 1.0
682
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
683
+ */
684
+ public function add_cptu_menu_item() {
685
+ global $submenu, $post, $parent_file, $pagenow;
686
+
687
+ // get current post type
688
+ if ( isset( $post->post_type ) ) {
689
+ $post_type = $post->post_type;
690
+ } else if ( isset( $_REQUEST['post_type'] ) ) {
691
+ $post_type = $_REQUEST['post_type'];
692
+ } else {
693
+ return;
694
+ }
695
+
696
+ $item = 'edit.php?post_type=' . $this->_name;
697
+
698
+ // add new items
699
+ if ( strpos( $post_type, $this->_prefix_cpt ) !== false ) {
700
+ global $wpdb;
701
+ $portfolio = $wpdb->get_row( $wpdb->prepare( "SELECT p.* FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post_type, $this->_name ) );
702
+
703
+ if ( ! isset( $portfolio->ID ) ) {
704
+ return;
705
+ }
706
+
707
+ $label_singular = ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $portfolio->ID, '_label_singular', true );
708
+ $label_plural = ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $portfolio->ID, '_label_plural', true );
709
+
710
+ if ( empty( $label_plural ) ) {
711
+ $label_plural = $portfolio->post_title;
712
+ }
713
+
714
+ if ( empty( $label_singular ) ) {
715
+ $label_singular = $portfolio->post_title;
716
+ }
717
+
718
+ $submenu[ $item ][15] = array( ucfirst( $label_plural ), 'edit_posts', 'edit.php?post_type=' . $post_type );
719
+ $submenu[ $item ][20] = array( sprintf( __('Add %s', 'yith-plugin-fw'), ucfirst( $label_singular ) ), 'edit_posts', 'post-new.php?post_type=' . $post_type );
720
+
721
+ global $wp_taxonomies;
722
+ $taxonomy = get_post_meta( $portfolio->ID, '_taxonomy', true );
723
+ if ( isset( $wp_taxonomies[ $taxonomy ] ) ) {
724
+ $submenu[ $item ][25] = array( __('Categories', 'yith-plugin-fw'), 'edit_posts', 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type );
725
+ }
726
+ }
727
+
728
+ // set the parent item inside the single of each post type
729
+ if ( $pagenow == 'post.php' && isset( $_GET['post'] ) && $this->_is_valid( get_post_type( intval( $_GET['post'] ) ) ) ) {
730
+ $parent_file = 'edit.php?post_type=' . $this->_name;
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Locate folder of CPTU templates, if there isn't a layouts management
736
+ *
737
+ * @return string
738
+ * @since 1.0
739
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
740
+ */
741
+ public function template_path() {
742
+ if ( ! empty( $this->template_path ) ) {
743
+ return $this->template_path;
744
+ }
745
+
746
+ // paths
747
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
748
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
749
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
750
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
751
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
752
+
753
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
754
+ $path = ${$var};
755
+
756
+ if ( file_exists( $path ) ) {
757
+ $this->template_path = $path;
758
+ }
759
+ }
760
+
761
+ return $this->template_path;
762
+ }
763
+
764
+ /**
765
+ * Locate folder of CPTU templates, if there isn't a layouts management
766
+ *
767
+ * @return string
768
+ * @since 1.0
769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
770
+ */
771
+ public function template_url() {
772
+ if ( ! empty( $this->template_url ) ) {
773
+ return $this->template_path;
774
+ }
775
+
776
+ $this->template_url = str_replace( array(
777
+ get_stylesheet_directory(),
778
+ get_template_directory(),
779
+ $this->_args['plugin_path']
780
+ ), array(
781
+ get_stylesheet_directory_uri(),
782
+ get_template_directory_uri(),
783
+ $this->_args['plugin_url']
784
+ ), $this->template_path() );
785
+
786
+ return $this->template_url;
787
+ }
788
+
789
+ /**
790
+ * Retrieve all layouts to manage by custom post type added in the site in this order:
791
+ * 1. Child theme (if exists)
792
+ * 2. Theme
793
+ * 3. Plugin
794
+ *
795
+ * It also load the config.php file of each layout
796
+ *
797
+ * @return void
798
+ * @since 1.0
799
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
800
+ */
801
+ public function get_layouts() {
802
+
803
+ // paths
804
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
805
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
806
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
807
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
808
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
809
+
810
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
811
+ $path = ${$var};
812
+
813
+ if ( file_exists( $path ) ) {
814
+ foreach ( scandir( $path ) as $scan ) {
815
+ if ( ! isset( $this->layouts[$scan] ) && is_dir( $path . $scan ) && ! in_array( $scan, array( '.', '..', '.svn' ) ) && $scan[0] != '_' ) {
816
+ $this->layouts[$scan] = array(
817
+ 'name' => ucfirst( str_replace( '-', ' ', $scan ) ),
818
+ 'path' => $path . $scan,
819
+ 'url' => str_replace( array(
820
+ get_stylesheet_directory(),
821
+ get_template_directory(),
822
+ $this->_args['plugin_path']
823
+ ), array(
824
+ get_stylesheet_directory_uri(),
825
+ get_template_directory_uri(),
826
+ $this->_args['plugin_url']
827
+ ), $path . $scan ),
828
+ 'css' => array(),
829
+ 'js' => array(),
830
+ 'support' => array(
831
+ 'description' => true
832
+ ),
833
+ 'columns' => array()
834
+ );
835
+
836
+ // set the vars for config.php
837
+ $layout = $scan;
838
+ $this->_layout = $layout; // temporary attribute to load automatically the configuration inside the config.php, for this layout
839
+
840
+ // TODO Fare in modo di caricare il file config.php soltanto quando realmente serve
841
+ if ( ! in_array( $scan, array( 'single' ) ) && file_exists( $path . $scan . '/config.php' ) ) {
842
+ include_once( $path . $scan . '/config.php' );
843
+ }
844
+ }
845
+ }
846
+ }
847
+
848
+ }
849
+ }
850
+
851
+ /**
852
+ * Say if you want to set description for the current layout or not. This method must be used only inside the
853
+ * config.php file of layout
854
+ *
855
+ * @param $v string 'yes' or 'no'
856
+ *
857
+ * @return void
858
+ * @since 1.0
859
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
860
+ */
861
+ public function add_description_field( $v ) {
862
+ $this->layouts[ $this->_layout ]['support']['description'] = $v == 'yes' ? true : false;
863
+ }
864
+
865
+ /**
866
+ * Add the extra fields for the specific layout type of portfolio
867
+ *
868
+ * @param array $fields The fields to add
869
+ *
870
+ * @return void
871
+ * @since 1.0
872
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
873
+ */
874
+ public function add_layout_fields( $fields = array() ) {
875
+ // change the ID
876
+ foreach ( $fields as $id => $val ) {
877
+ unset( $fields[ $id ] );
878
+ $id = $this->_layout . '_' . $id;
879
+ $fields[ $id ] = $val;
880
+ }
881
+
882
+ $this->layouts[ $this->_layout ]['fields'] = $fields;
883
+ }
884
+
885
+ /**
886
+ * Add fields to add to the metabox of each item of each post type created
887
+ *
888
+ * @param array $fields The fields to add
889
+ *
890
+ * @return void
891
+ * @since 1.0
892
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
893
+ */
894
+ public function add_item_fields( $fields = array() ) {
895
+ // change the ID
896
+ foreach ( $fields as $id => $val ) {
897
+ unset( $fields[ $id ] );
898
+ //$id = $this->_layout . '_' . $id;
899
+ $fields[ $id ] = $val;
900
+ }
901
+ $this->layouts[ $this->_layout ]['item_fields'] = $fields;
902
+ }
903
+
904
+ /**
905
+ * Add columns to the table list
906
+ *
907
+ * @param array $columns The columns to add in the table list
908
+ *
909
+ * @return void
910
+ * @since 1.0
911
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
912
+ */
913
+ public function add_table_columns( $columns ) {
914
+ $this->layouts[ $this->_layout ]['columns'] = $columns;
915
+ }
916
+
917
+ /**
918
+ * Enqueue the css files of layout
919
+ *
920
+ * @param string $handle Name of the stylesheet.
921
+ * @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
922
+ * @param array $deps An array of registered style handles this stylesheet depends on. Default empty array.
923
+ * @param string|bool $ver String specifying the stylesheet version number, if it has one. This parameter is used
924
+ * to ensure that the correct version is sent to the client regardless of caching, and so
925
+ * should be included if a version number is available and makes sense for the stylesheet.
926
+ * @param string $media Optional. The media for which this stylesheet has been defined.
927
+ * Default 'all'. Accepts 'all', 'aural', 'braille', 'handheld', 'projection', 'print',
928
+ * 'screen', 'tty', or 'tv'.
929
+ *
930
+ * @return void
931
+ * @since 1.0
932
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
933
+ */
934
+ public function enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
935
+ $this->layouts[ $this->_layout ]['css'][] = compact( 'handle', 'src', 'deps', 'ver', 'media' );
936
+ }
937
+
938
+ /**
939
+ * Enqueue the js files of layout
940
+ *
941
+ * @param string $handle Name of the script.
942
+ * @param string|bool $src Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
943
+ * @param array $deps An array of registered handles this script depends on. Default empty array.
944
+ * @param string|bool $ver Optional. String specifying the script version number, if it has one. This parameter
945
+ * is used to ensure that the correct version is sent to the client regardless of caching,
946
+ * and so should be included if a version number is available and makes sense for the script.
947
+ * @param bool $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
948
+ * Default 'false'. Accepts 'false' or 'true'.
949
+ *
950
+ * @return void
951
+ * @since 1.0
952
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
953
+ */
954
+ public function enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
955
+ $this->layouts[ $this->_layout ]['js'][] = compact( 'handle', 'src', 'deps', 'ver', 'in_footer' );
956
+ }
957
+
958
+ /**
959
+ * Enqueue the assets for the frontend
960
+ *
961
+ * @return void
962
+ * @since 1.0
963
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
964
+ */
965
+ public function frontend_assets() {
966
+ global $post;
967
+
968
+ // not single
969
+ if ( ! is_single() || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
970
+ $posts = get_posts(array(
971
+ 'post_type' => $this->_name,
972
+ 'posts_per_page' => -1,
973
+ 'post_status' => 'publish',
974
+ 'fields' => 'ids'
975
+ ));
976
+
977
+ $enqueued = array();
978
+
979
+ foreach ( $posts as $post_id ) {
980
+ $layout = get_post_meta( $post_id, $this->_args['layout_option'], true );
981
+
982
+ if ( in_array( $layout, array( $enqueued ) ) || ! isset( $this->layouts[ $layout ]['css'] ) ) {
983
+ continue;
984
+ }
985
+
986
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
987
+ if ( empty( $asset ) ) {
988
+ continue;
989
+ }
990
+ yit_enqueue_style( $asset['handle'], empty( $asset['src'] ) ? false : $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
991
+ }
992
+
993
+ $enqueued[] = $layout;
994
+ }
995
+ }
996
+
997
+ // load assets of single template
998
+ else {
999
+ $layout = 'single';
1000
+
1001
+ if ( ! isset( $this->layouts[ $layout ]['css'] ) ) {
1002
+ return;
1003
+ }
1004
+
1005
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
1006
+ if ( empty( $asset ) ) {
1007
+ continue;
1008
+ }
1009
+ yit_enqueue_style( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
1010
+ }
1011
+ }
1012
+
1013
+ }
1014
+
1015
+ /**
1016
+ * Register Metaboxes options
1017
+ *
1018
+ * Add the metabox for the portfolio settings
1019
+ *
1020
+ * @return void
1021
+ * @since 1.0
1022
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1023
+ */
1024
+ public function add_metabox_cptu() {
1025
+
1026
+ // Reorganize layouts
1027
+ if ( $this->_args['manage_layouts'] ) {
1028
+ $layouts = array();
1029
+ foreach ( $this->layouts as $layout_id => $layout ) {
1030
+ if ( 'single' == $layout_id ) {
1031
+ continue;
1032
+ }
1033
+ $layouts[ $layout_id ] = $layout['name'];
1034
+ }
1035
+
1036
+ $layouts = apply_filters( 'yit_cptu_' . $this->_name . '_layout_values', $layouts );
1037
+ }
1038
+
1039
+ $single_layouts = apply_filters( 'yit_cptu_' . $this->_name . '_single_layout_values', array() );
1040
+
1041
+ $metabox_args = array(
1042
+ 'label' => sprintf( __( '%s Settings', 'yith-plugin-fw' ), $this->_labels['singular'] ),
1043
+ 'pages' => $this->_name, //or array( 'post-type1', 'post-type2')
1044
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1045
+ 'priority' => 'default',
1046
+ 'tabs' => array(
1047
+ 'settings' => array(
1048
+ 'label' => __( 'Settings', 'yith-plugin-fw' ),
1049
+ 'fields' => apply_filters( 'yit_cptu_fields', array(
1050
+ 'type' => array(
1051
+ 'label' => __( 'Type', 'yith-plugin-fw' ),
1052
+ 'desc' => __( 'Layout for this '.strtolower( $this->_labels['singular'] ) , 'yith-plugin-fw' ),
1053
+ 'type' => 'select',
1054
+ 'options' => isset( $layouts ) ? $layouts : array(),
1055
+ 'std' => '' ),
1056
+
1057
+ 'rewrite' => array(
1058
+ 'label' => __( 'Rewrite', 'yith-plugin-fw' ),
1059
+ 'desc' => __( 'Univocal identification name in the URL for each product (slug from post if empty)', 'yith-plugin-fw' ),
1060
+ 'type' => 'text',
1061
+ 'std' => '' ),
1062
+
1063
+ 'label_singular' => array(
1064
+ 'label' => __( 'Label in Singular', 'yith-plugin-fw' ),
1065
+ 'desc' => __( 'Set a label in singular (title of portfolio if empty)', 'yith-plugin-fw' ),
1066
+ 'type' => 'text',
1067
+ 'std' => '' ),
1068
+
1069
+ 'label_plural' => array(
1070
+ 'label' => __( 'Label in Plural', 'yith-plugin-fw' ),
1071
+ 'desc' => __( 'Set a label in plural (title of portfolio if empty)', 'yith-plugin-fw' ),
1072
+ 'type' => 'text',
1073
+ 'std' => '' ),
1074
+
1075
+ 'taxonomy' => array(
1076
+ 'label' => __( 'Taxonomy', 'yith-plugin-fw' ),
1077
+ 'desc' => __( 'If you want to use categories in the portfolio, set a name for taxonomy. Name should be a slug (must not contain capital letters nor spaces) and must not be more than 32 characters long (database structure restriction).', 'yith-plugin-fw' ),
1078
+ 'type' => 'text',
1079
+ 'std' => '' ),
1080
+
1081
+ 'taxonomy_rewrite' => array(
1082
+ 'label' => __( 'Taxonomy Rewrite', 'yith-plugin-fw' ),
1083
+ 'desc' => __( 'Set univocal name for each category page URL.', 'yith-plugin-fw' ),
1084
+ 'type' => 'text',
1085
+ 'std' => '' ),
1086
+
1087
+ 'single_layout' => array(
1088
+ 'label' => __( 'Single layout', 'yith-plugin-fw' ),
1089
+ 'desc' => __( 'Layout for single page of this portfolio', 'yith-plugin-fw' ),
1090
+ 'type' => 'select',
1091
+ 'options' => $single_layouts,
1092
+ 'std' => '' ),
1093
+ ) )
1094
+ )
1095
+ )
1096
+
1097
+ );
1098
+
1099
+ if ( ! $this->_args['has_single'] ) {
1100
+ unset( $metabox_args['tabs']['settings']['fields']['rewrite'] );
1101
+ }
1102
+
1103
+ if ( ! $this->_args['has_taxonomy'] ) {
1104
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy'] );
1105
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy_rewrite'] );
1106
+ }
1107
+
1108
+ if ( ! empty( $this->_args['label_item_sing'] ) ) {
1109
+ unset( $metabox_args['tabs']['settings']['fields']['label_singular'] );
1110
+ }
1111
+
1112
+ if ( ! empty( $this->_args['label_item_plur'] ) ) {
1113
+ unset( $metabox_args['tabs']['settings']['fields']['label_plural'] );
1114
+ }
1115
+
1116
+ if ( $this->_args['manage_layouts'] ) {
1117
+
1118
+ if ( count( $layouts ) < 1 ) {
1119
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1120
+ }
1121
+
1122
+ // Layouts options
1123
+ foreach ( $this->layouts as $layout => $args ) {
1124
+ if ( ! isset( $args['fields'] ) ) {
1125
+ continue;
1126
+ }
1127
+
1128
+ // Section title
1129
+ $metabox_args['tabs']['settings']['fields'][ $layout . '_title' ] = array(
1130
+ 'desc' => $args['name'] . ' ' . __( 'layout settings', 'yith-plugin-fw' ),
1131
+ 'type' => 'title',
1132
+ 'deps' => array(
1133
+ 'ids' => '_type',
1134
+ 'values' => $layout
1135
+ )
1136
+ );
1137
+
1138
+ // Options
1139
+ foreach( $args['fields'] as $field_id => $field ) {
1140
+ $metabox_args['tabs']['settings']['fields'][ $field_id ] = $field;
1141
+ $metabox_args['tabs']['settings']['fields'][ $field_id ]['deps'] = array(
1142
+ 'ids' => '_type',
1143
+ 'values' => $layout
1144
+ );
1145
+ }
1146
+ }
1147
+ }else {
1148
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1149
+ }
1150
+
1151
+ if( count( $single_layouts ) < 1 ){
1152
+ unset( $metabox_args['tabs']['settings']['fields']['single_layout'] );
1153
+ }
1154
+
1155
+ // undo if tab empty
1156
+ if ( empty( $metabox_args['tabs']['settings']['fields'] ) ) {
1157
+ return;
1158
+ }
1159
+
1160
+ $metabox = YIT_Metabox( $this->_name . '_cptu_settings' );
1161
+ $metabox->init( $metabox_args );
1162
+ }
1163
+
1164
+ /**
1165
+ * Register Metaboxes options
1166
+ *
1167
+ * Add the metabox for the portfolio settings
1168
+ *
1169
+ * @return void
1170
+ * @since 1.0
1171
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1172
+ */
1173
+ public function add_metabox_item_fields() {
1174
+ global $pagenow, $post_type;
1175
+
1176
+ // get the actual post type, to add the metabox only if necessary
1177
+ if ( $pagenow == 'post.php' && isset( $_REQUEST['post'] ) ) {
1178
+ $post_type = get_post_type( intval( $_REQUEST['post'] ) );
1179
+ }
1180
+ elseif( $pagenow == 'post.php' && isset( $_REQUEST['post_ID'] ) ){
1181
+ $post_type = get_post_type( intval( $_REQUEST['post_ID'] ) );
1182
+ }
1183
+ elseif ( $pagenow == 'post-new.php' && isset( $_REQUEST['post_type'] ) ) {
1184
+ $post_type = $_REQUEST['post_type'];
1185
+ } else {
1186
+ return;
1187
+ }
1188
+
1189
+ $layout = get_post_meta( $this->_get_id_by_name( $post_type ), $this->_args['layout_option'], true );
1190
+
1191
+ if ( empty( $this->layouts[ $layout ]['item_fields'] ) ) {
1192
+ return;
1193
+ }
1194
+
1195
+ $metabox_args = array(
1196
+ 'label' => __( 'Settings', 'yith-plugin-fw' ),
1197
+ 'pages' => $post_type, //or array( 'post-type1', 'post-type2')
1198
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1199
+ 'priority' => 'default',
1200
+ 'tabs' => array(
1201
+ 'settings' => array(
1202
+ 'label' => __( 'Settings', 'yith-plugin-fw' ),
1203
+ 'fields' => $this->layouts[ $layout ]['item_fields']
1204
+ )
1205
+ )
1206
+ );
1207
+
1208
+ $metabox = YIT_Metabox( $post_type . '_item_fields' );
1209
+ $metabox->init( $metabox_args );
1210
+
1211
+ }
1212
+
1213
+ /**
1214
+ * Add quick links inside the editing page of CPTU and Custom Post Types
1215
+ *
1216
+ * @return void
1217
+ * @since 1.0
1218
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1219
+ */
1220
+ public function add_quick_links_metaboxes() {
1221
+ // CPTU
1222
+ add_meta_box( $this->_name . '_quick_links', __( 'Quick links', 'yith-plugin-fw' ), array( $this, 'quick_links_cptu_inner' ), $this->_name, 'side', 'high' );
1223
+
1224
+ // CPTs
1225
+ $args = array(
1226
+ 'post_type' => $this->_name,
1227
+ 'posts_per_page' => -1,
1228
+ 'post_status' => 'publish'
1229
+ );
1230
+ $post_types = get_posts( $args );
1231
+
1232
+ foreach ( $post_types as $post ) {
1233
+ $post_type = get_post_meta( $post->ID, '_post_type', true );
1234
+ extract( $this->_cpt_args( $post ) );
1235
+ add_meta_box( $post->post_type . '_quick_links', __( 'Quick links', 'yith-plugin-fw' ), array( $this, 'quick_links_cpt_inner' ), $post_type, 'side', 'high' );
1236
+ }
1237
+ }
1238
+
1239
+ /**
1240
+ * Link to: "View Items", inside the CPTU
1241
+ *
1242
+ * @param $post
1243
+ *
1244
+ * @return void
1245
+ * @since 1.0
1246
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1247
+ */
1248
+ public function quick_links_cptu_inner( $post ) {
1249
+ extract( $this->_cpt_args( $post ) );
1250
+ ?>
1251
+ <a href="<?php echo admin_url( 'edit.php?post_type=' . get_post_meta( $post->ID, '_post_type', true ) ) ?>"><?php printf( __( 'View %s', 'yith-plugin-fw' ), $label_plural ) ?></a>
1252
+ <?php
1253
+ }
1254
+
1255
+ /**
1256
+ * Link to: "Edit %s", inside the CPTU
1257
+ *
1258
+ * @param $post
1259
+ *
1260
+ * @return void
1261
+ * @since 1.0
1262
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1263
+ */
1264
+ public function quick_links_cpt_inner( $post ) {
1265
+ $post = get_post( $this->_get_id_by_name( $post->post_type ) );
1266
+ ?>
1267
+ <a href="<?php echo admin_url( "post.php?post={$post->ID}&action=edit" ) ?>"><?php printf( __( 'Edit %s', 'yith-plugin-fw' ), $post->post_title ) ?></a>
1268
+ <?php
1269
+ }
1270
+
1271
+ /**
1272
+ * Define the columns to use in the list table of main sliders post type
1273
+ *
1274
+ * @param $columns array The columns used in the list table
1275
+ *
1276
+ * @return array
1277
+ * @since 1.0
1278
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1279
+ */
1280
+ public function cptu_define_columns( $columns ) {
1281
+ unset( $columns['date'] );
1282
+
1283
+ $columns['actions'] = '';
1284
+
1285
+ return $columns;
1286
+ }
1287
+
1288
+ /**
1289
+ * Change the content of each column of the table list
1290
+ *
1291
+ * @param $column string The current column
1292
+ * @param $post_id int The current post ID
1293
+ *
1294
+ * @return void
1295
+ * @since 1.0
1296
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1297
+ */
1298
+ public function cptu_change_columns( $column, $post_id ) {
1299
+ $post = get_post( $post_id );
1300
+ extract( $this->_cpt_args( $post ) );
1301
+
1302
+ switch ( $column ) {
1303
+ case 'actions' :
1304
+ echo '<a href="' . admin_url( "post.php?post={$post_id}&action=edit" ) . '" class="button-secondary">' . sprintf( __( 'Edit %s', 'yith-plugin-fw' ), ucfirst( $this->_labels['singular'] ) ) . '</a> ';
1305
+ echo '<a href="' . admin_url( 'edit.php?post_type=' . get_post_meta( $post_id, '_post_type', true ) ) . '" class="button-secondary">' . sprintf( __( 'View %s', 'yith-plugin-fw' ), $label_plural ) . '</a> ';
1306
+ break;
1307
+ }
1308
+ }
1309
+
1310
+ /**
1311
+ * Retrieve the path of layout specified in parameter
1312
+ *
1313
+ * @param $layout
1314
+ * @param $file string The file to find
1315
+ *
1316
+ * @return bool|string
1317
+ * @since 1.0
1318
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1319
+ */
1320
+ public function locate_file( $layout, $file = '' ) {
1321
+ if ( ! $this->_args['manage_layouts'] ) {
1322
+ return $this->template_path(). '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1323
+ }
1324
+
1325
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1326
+ $layout = 'default';
1327
+ }
1328
+
1329
+ return $this->layouts[ $layout ]['path'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1330
+ }
1331
+
1332
+ /**
1333
+ * Retrieve the URL of layout specified in parameter
1334
+ *
1335
+ * @param $layout
1336
+ * @param $file string The file to find
1337
+ *
1338
+ * @return bool|string
1339
+ * @since 1.0
1340
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1341
+ */
1342
+ public function locate_url( $layout, $file = '' ) {
1343
+ if ( ! $this->_args['manage_layouts'] ) {
1344
+ return $this->template_url();
1345
+
1346
+ }
1347
+
1348
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1349
+ $layout = 'default';
1350
+ }
1351
+
1352
+ return $this->layouts[ $layout ]['url'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1353
+ }
1354
+
1355
+ /**
1356
+ * Retrieve the post ID relative to the post of post type
1357
+ *
1358
+ * @param $name string
1359
+ *
1360
+ * @return mixed
1361
+ * @since 1.0
1362
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1363
+ */
1364
+ protected function _get_id_by_name( $name ) {
1365
+ global $wpdb;
1366
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1367
+ }
1368
+
1369
+ /**
1370
+ * Retrieve the post_type of portfolio by portfolio name
1371
+ *
1372
+ * @param $name string
1373
+ *
1374
+ * @return mixed
1375
+ * @since 1.0
1376
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1377
+ */
1378
+ protected function _get_post_type_by_name( $name ) {
1379
+ global $wpdb;
1380
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.meta_value FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_name = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1381
+ }
1382
+
1383
+ /**
1384
+ * The shortcode used to show the frontend
1385
+ *
1386
+ * @param array $atts
1387
+ * @param null $content
1388
+ *
1389
+ * @return string|null
1390
+ * @since 1.0
1391
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1392
+ */
1393
+ public function add_shortcode( $atts, $content = null ) {
1394
+ $atts = wp_parse_args( $atts, array(
1395
+ 'name' => null,
1396
+ 'cat' => array(),
1397
+ 'posts_per_page' => false,
1398
+ 'style' => null,
1399
+ ) );
1400
+
1401
+ // don't show the slider if 'name' is empty or is 'none'
1402
+ if ( empty( $atts['name'] ) || 'none' == $atts['name'] ) return null;
1403
+
1404
+ // compatibility fix: remove prefix if exists in portfolio object
1405
+ if( function_exists( 'YIT_Portfolio' ) && method_exists( YIT_Portfolio(), 'is' ) && YIT_Portfolio()->is( $atts['name'] ) ){
1406
+ $atts['name'] = str_replace( YIT_Portfolio()->post_type_prefix, '', $atts['name'] );
1407
+ }
1408
+
1409
+ // pass vars to template
1410
+ $atts['post_type'] = $this->_get_post_type_by_name( $atts['name'] );
1411
+ $atts['layout'] = $this->_args['manage_layouts'] ? get_post_meta( $this->_get_id_by_name( $atts['post_type'] ), $this->_args['layout_option'], true ) : '';
1412
+ extract( apply_filters( 'yit_cptu_frontend_vars', $atts, $this->_name ) );
1413
+
1414
+ // add the javascript assets
1415
+ if ( $this->_args['manage_layouts'] && isset( $this->layouts[ $layout ]['js'] ) && ! empty( $this->layouts[ $layout ]['js'] ) ) {
1416
+ foreach ( $this->layouts[ $layout ]['js'] as $asset ) {
1417
+ if ( empty( $asset ) ) continue;
1418
+
1419
+ if ( empty( $asset['src'] ) ) {
1420
+ wp_enqueue_script( $asset['handle'] );
1421
+ continue;
1422
+ }
1423
+
1424
+ yit_enqueue_script( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1425
+ }
1426
+ }
1427
+
1428
+ // Unique sequential index to differentiate more cpt in the same page
1429
+ ++$this->index;
1430
+
1431
+ ob_start();
1432
+
1433
+ include( $this->locate_file( $layout, 'markup' ) );
1434
+
1435
+ return ob_get_clean();
1436
+
1437
+ }
1438
+
1439
+ /**
1440
+ * Shortcode icon
1441
+ *
1442
+ * Return the shortcode icone to display on shortcode panel
1443
+ *
1444
+ * @param $icon_url string Icone url found by yit_shortcode plugin
1445
+ *
1446
+ * @return string
1447
+ * @since 1.0.0
1448
+ * @author Antonino Scarfi' <antonio.scarfi@yithemes.it>
1449
+ */
1450
+ public function shortcode_icon( $icon_url ) {
1451
+ return ! empty( $this->_args['shortcode_icon'] ) ? $this->_args['shortcode_icon'] : $icon_url;
1452
+ }
1453
+
1454
+ /**
1455
+ * Return an array with cptu options to shortcode panel
1456
+ *
1457
+ * All definition settings to add cptu shortcode to Yit Shortcode Panel
1458
+ *
1459
+ * @param array $shortcodes
1460
+ *
1461
+ * @return array
1462
+ * @since 1.0
1463
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1464
+ */
1465
+ public function add_shortcode_to_box( $shortcodes ) {
1466
+ $post_types = array();
1467
+
1468
+ foreach ( $this->get_post_types() as $post ) {
1469
+ $post_types[ $post->post_name ] = $post->post_title;
1470
+ }
1471
+
1472
+ $args = array(
1473
+ $this->_args['shortcode_name'] => array(
1474
+ 'title' => $this->_labels['singular'],
1475
+ 'description' => sprintf( __( 'Show frontend of the %s', 'yith-plugin-fw' ), $this->_labels['main_name'] ),
1476
+ 'tab' => 'cpt',
1477
+ 'create' => false,
1478
+ 'has_content' => false,
1479
+ 'in_visual_composer' => true,
1480
+ 'attributes' => array(
1481
+ 'name' => array(
1482
+ 'title' => __( 'Name', 'yith-plugin-fw' ),
1483
+ 'type' => 'select',
1484
+ 'options' => $post_types,
1485
+ 'std' => ''
1486
+ ),
1487
+ )
1488
+ )
1489
+ );
1490
+
1491
+ return array_merge( $shortcodes, $args );
1492
+ }
1493
+
1494
+ /**
1495
+ * Check the post type passed in parameter, if is generated by this CPTU
1496
+ *
1497
+ * @param $post_type string The post type to check
1498
+ *
1499
+ * @return bool
1500
+ * @since 1.0
1501
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1502
+ */
1503
+ protected function _is_valid( $post_type ) {
1504
+ return (bool)( strpos( $post_type, $this->_args['post_type_prefix'] ) !== false );
1505
+ }
1506
+
1507
+ /**
1508
+ * Add as a valid post type all cptu when importing dummy data
1509
+ *
1510
+ * @param $post array The post object
1511
+ *
1512
+ * @return array
1513
+ * @since 1.0
1514
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1515
+ */
1516
+ public function add_importer_required_post_type( $post ){
1517
+ global $wp_post_types, $wp_taxonomies;
1518
+
1519
+ if( strpos( $post['post_type'], $this->_prefix_cpt ) === FALSE ){
1520
+ return $post;
1521
+ }
1522
+
1523
+ if( ! isset( $wp_post_types[ $post['post_type'] ] ) ){
1524
+ $wp_post_types[ $post['post_type'] ] = array(
1525
+ 'name' => ''
1526
+ );
1527
+ }
1528
+
1529
+ if( ! empty( $post['terms'] ) ){
1530
+ foreach( $post['terms'] as $term ){
1531
+ if( ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1532
+ $wp_taxonomies[ $term['domain'] ] = array(
1533
+ 'name' => ''
1534
+ );
1535
+ }
1536
+ }
1537
+ }
1538
+
1539
+
1540
+ return $post;
1541
+ }
1542
+
1543
+ /**
1544
+ * Add taxonomy when importing dummy data
1545
+ *
1546
+ * @param $terms array Array of terms
1547
+ *
1548
+ * @return array
1549
+ * @since 1.0
1550
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1551
+ */
1552
+ public function add_importer_required_taxonomy( $terms ){
1553
+ global $wp_taxonomies;
1554
+
1555
+ if( ! empty( $terms ) ){
1556
+ foreach ( $terms as $term ) {
1557
+ if( isset( $term['domain'] ) && ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1558
+ $wp_taxonomies[ $term['domain'] ] = array(
1559
+ 'name' => ''
1560
+ );
1561
+ }
1562
+ }
1563
+ }
1564
+
1565
+ return $terms;
1566
+ }
1567
+
1568
+ /**
1569
+ * Force terms recount for imported taxonomy
1570
+ *
1571
+ * @param $tt_ids array Terms ids
1572
+ * @param $ids array Post ids
1573
+ * @param $tax string Taxonomy name
1574
+ *
1575
+ * @return void
1576
+ * @since 1.0
1577
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1578
+ */
1579
+ public function recount_terms_post( $tt_ids, $ids, $tax ){
1580
+ wp_update_term_count( $tt_ids, $tax );
1581
+ }
1582
+
1583
+ // ### ASSETS ###
1584
+
1585
+ /**
1586
+ * Enqueue the assets for the admin
1587
+ *
1588
+ * @return void
1589
+ * @since 1.0
1590
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1591
+ */
1592
+ public function admin_assets() {
1593
+ wp_enqueue_media();
1594
+ wp_enqueue_script( 'yit-cptu', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cpt-unlimited.js', array('jquery'), '', true );
1595
+ }
1596
+
1597
+ /**
1598
+ * Add the button to the top of the list table page of CPTU
1599
+ *
1600
+ * @return void
1601
+ * @since 1.0
1602
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1603
+ */
1604
+ public function add_button_multiuploader() {
1605
+ global $pagenow, $post_type, $wpdb;
1606
+
1607
+ if( $pagenow != 'edit.php' ){
1608
+ return;
1609
+ }
1610
+
1611
+ $cptu = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_type FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s", '_post_type', $post_type ) );
1612
+
1613
+ $post = get_post( $this->_get_id_by_name( $post_type ) );
1614
+ if ( empty( $post ) ) {
1615
+ return;
1616
+ }
1617
+ extract( $this->_cpt_args( $post ) );
1618
+
1619
+ if ( $cptu != $this->_name || ! $this->_is_valid( $post_type ) ) {
1620
+ return;
1621
+ }
1622
+ ?>
1623
+ <script>
1624
+ (function($) {
1625
+ "use strict";
1626
+ // Author code here
1627
+
1628
+ var button = $('<a />', {
1629
+ href: '#',
1630
+ class: 'multi-uploader add-new-h2',
1631
+ 'data-uploader_title': '<?php printf( __( 'Add %s from images', 'yith-plugin-fw' ), $label_plural ) ?>',
1632
+ 'data-uploader_button_text': '<?php printf( __( 'Add %s', 'yith-plugin-fw' ), $label_plural ) ?>'
1633
+ }).text('<?php _e( 'Upload multiple files', 'yith-plugin-fw' ) ?>');
1634
+
1635
+ var spinner = $('<span />', {
1636
+ class: 'spinner',
1637
+ style: 'float: none;'
1638
+ });
1639
+
1640
+ button.appendTo('.wrap h2').after(spinner);
1641
+
1642
+ })(jQuery);
1643
+ </script>
1644
+ <?php
1645
+ }
1646
+
1647
+ /**
1648
+ * Add more posts by multiupload
1649
+ *
1650
+ * @return void
1651
+ * @since 1.0
1652
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1653
+ */
1654
+ public function post_multiuploader() {
1655
+ if ( ! isset( $_REQUEST['images'] ) || ! isset( $_REQUEST['post_type'] ) && $this->_is_valid( $_REQUEST['post_type'] ) ) {
1656
+ return;
1657
+ }
1658
+
1659
+ foreach ( $_REQUEST['images'] as $the ) {
1660
+
1661
+ // Create post object
1662
+ $arg = array(
1663
+ 'post_title' => $the['title'],
1664
+ 'post_type' => $_REQUEST['post_type']
1665
+ );
1666
+ $post_id = wp_insert_post( $arg );
1667
+
1668
+ set_post_thumbnail( $post_id, $the['id'] );
1669
+
1670
+ }
1671
+
1672
+ die();
1673
+ }
1674
+
1675
+
1676
+ // ###### SINGLE TEMPLATE ######
1677
+
1678
+ /**
1679
+ * Load the single template file
1680
+ *
1681
+ * @return void
1682
+ * @since 1.0
1683
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1684
+ */
1685
+ public function single_template() {
1686
+ global $post, $wpdb;
1687
+
1688
+ // if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1689
+ // $post = get_post( $_REQUEST['post_id'] );
1690
+ // }
1691
+
1692
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1693
+ return;
1694
+ }
1695
+
1696
+ // add the javascript assets
1697
+ if ( $this->_args['manage_layouts'] ) {
1698
+ foreach ( $this->layouts[ 'single' ]['js'] as $asset ) {
1699
+ yit_enqueue_script( $asset['handle'], $this->locate_url( 'single' ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1700
+ }
1701
+ }
1702
+
1703
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1704
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1705
+
1706
+ include( $this->locate_file( 'single', 'markup' ) );
1707
+ }
1708
+
1709
+ /**
1710
+ * Load a file for the configuration of single template page of portfolio
1711
+ *
1712
+ * @return void
1713
+ * @since 1.0
1714
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1715
+ */
1716
+ public function single_template_config() {
1717
+ global $post, $wpdb;
1718
+
1719
+ if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1720
+ $post = get_post( $_REQUEST['post_id'] );
1721
+ }
1722
+
1723
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1724
+ return;
1725
+ }
1726
+
1727
+ $this->_layout = 'single';
1728
+ $path = $this->locate_file( 'single', 'config' );
1729
+
1730
+ if ( file_exists( $path ) ) {
1731
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1732
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1733
+
1734
+ include( $path );
1735
+ }
1736
+ }
1737
+
1738
+
1739
+ // ########################## ARCHIVE TEMPLATE ###############################
1740
+
1741
+
1742
+ /**
1743
+ * Load the template for archive page
1744
+ *
1745
+ * @return void
1746
+ * @since 1.0
1747
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1748
+ */
1749
+ public function archive_template() {
1750
+ global $wp_query;
1751
+
1752
+
1753
+ // check if we are in archive template
1754
+ if ( !( ! is_admin() && is_archive() && isset($wp_query->post) && $this->_is_valid( $wp_query->post->post_type ) ) ) {
1755
+ return;
1756
+ }
1757
+
1758
+ // remove the action from loop of theme
1759
+ remove_action( 'yit_content_loop', 'yit_content_loop', 10 );
1760
+ add_action( 'yit_content_loop', array( $this, 'archive_template_loop' ), 10 );
1761
+
1762
+ }
1763
+
1764
+ /**
1765
+ * Load loop for the archive template
1766
+ *
1767
+ * @return void
1768
+ * @since 1.0
1769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1770
+ */
1771
+ public function archive_template_loop() {
1772
+ echo $this->add_shortcode( array( 'name' => $GLOBALS['wp_query']->post->post_type ) );
1773
+ }
1774
+
1775
+ }
plugin-fw/lib/yit-metabox.php ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ } // Exit if accessed directly
15
+
16
+ if ( ! class_exists( 'YIT_Metabox' ) ) {
17
+ /**
18
+ * YIT Metabox
19
+ *
20
+ * the metabox can be created using this code
21
+ * <code>
22
+ * $args1 = array(
23
+ * 'label' => __( 'Metabox Label', 'yith-plugin-fw' ),
24
+ * 'pages' => 'page', //or array( 'post-type1', 'post-type2')
25
+ * 'context' => 'normal', //('normal', 'advanced', or 'side')
26
+ * 'priority' => 'default',
27
+ * 'tabs' => array(
28
+ * 'settings' => array( //tab
29
+ * 'label' => __( 'Settings', 'yith-plugin-fw' ),
30
+ * 'fields' => array(
31
+ * 'meta_checkbox' => array(
32
+ * 'label' => __( 'Show title', 'yith-plugin-fw' ),
33
+ * 'desc' => __( 'Choose whether to show title of the page or not.', 'yith-plugin-fw' ),
34
+ * 'type' => 'checkbox',
35
+ * 'private' => false,
36
+ * 'std' => '1'),
37
+ * ),
38
+ * ),
39
+ * );
40
+ *
41
+ * $metabox1 = YIT_Metabox( 'yit-metabox-id' );
42
+ * $metabox1->init( $args );
43
+ * </code>
44
+ *
45
+ * @class YIT_Metaboxes
46
+ * @package Yithemes
47
+ * @since 1.0.0
48
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
49
+ *
50
+ */
51
+
52
+ class YIT_Metabox {
53
+
54
+ /**
55
+ * @var string the id of metabox
56
+ *
57
+ * @since 1.0
58
+ */
59
+
60
+ public $id;
61
+
62
+ /**
63
+ * @var array An array where are saved all metabox settings options
64
+ *
65
+ * @since 1.0
66
+ */
67
+ private $options = array();
68
+
69
+ /**
70
+ * @var array An array where are saved all tabs of metabox
71
+ *
72
+ * @since 1.0
73
+ */
74
+ private $tabs = array();
75
+
76
+ /**
77
+ * @var object The single instance of the class
78
+ * @since 1.0
79
+ */
80
+ protected static $_instance = array();
81
+
82
+ /**
83
+ * Main Instance
84
+ *
85
+ * @static
86
+ *
87
+ * @param $id
88
+ *
89
+ * @return object Main instance
90
+ *
91
+ * @since 1.0
92
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
93
+ */
94
+ public static function instance( $id ) {
95
+ if ( ! isset( self::$_instance[$id] ) ) {
96
+ self::$_instance[$id] = new self( $id );
97
+ }
98
+ return self::$_instance[$id];
99
+ }
100
+
101
+ /**
102
+ * Constructor
103
+ *
104
+ * @param string $id
105
+ *
106
+ * @return \YIT_Metabox
107
+ * @since 1.0
108
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
109
+ */
110
+ function __construct( $id = '' ) {
111
+ $this->id = $id;
112
+
113
+ }
114
+
115
+
116
+ /**
117
+ * Init
118
+ *
119
+ * set options and tabs, add actions to register metabox, scripts and save data
120
+ *
121
+ * @param array $options
122
+ *
123
+ * @return void
124
+ * @since 1.0
125
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
126
+ */
127
+ public function init( $options = array() ) {
128
+
129
+ $this->set_options( $options );
130
+ $this->set_tabs();
131
+
132
+
133
+ add_action( 'add_meta_boxes', array( $this, 'register_metabox' ) );
134
+ add_action( 'save_post', array( $this, 'save_postdata' ) );
135
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 15 );
136
+
137
+ }
138
+
139
+ /**
140
+ * Enqueue script and styles in admin side
141
+ *
142
+ * Add style and scripts to administrator
143
+ *
144
+ * @return void
145
+ * @since 1.0
146
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
147
+ */
148
+ public function enqueue() {
149
+
150
+ wp_enqueue_media();
151
+ wp_enqueue_style( 'wp-color-picker' );
152
+ wp_enqueue_style( 'yit-plugin-metaboxes', YIT_CORE_PLUGIN_URL . '/assets/css/metaboxes.css' );
153
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
154
+ wp_enqueue_script( 'jquery-ui-datepicker' );
155
+ wp_enqueue_script( 'yit-spinner', YIT_CORE_PLUGIN_URL . '/assets/js/panel.spinner.js', array( 'jquery' ), '0.0.1', true );
156
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
157
+ wp_enqueue_script( 'ajax-chosen', yit_load_js_file( YIT_CORE_PLUGIN_URL . '/assets/js/chosen/ajax-chosen.jquery.js' ), array( 'jquery' ), '1.1.0', true );
158
+ wp_enqueue_script( 'yit-metabox', YIT_CORE_PLUGIN_URL . '/assets/js/metabox.js', array( 'jquery', 'wp-color-picker' ), '1.0.0', true );
159
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
160
+
161
+
162
+ }
163
+
164
+ /**
165
+ * Set Options
166
+ *
167
+ * Set the variable options
168
+ *
169
+ * @param array $options
170
+ *
171
+ * @return void
172
+ * @since 1.0
173
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
174
+ */
175
+ public function set_options( $options = array() ) {
176
+ $this->options = $options;
177
+
178
+ }
179
+
180
+ /**
181
+ * Set Tabs
182
+ *
183
+ * Set the variable tabs
184
+ *
185
+ * @internal param array $tabs
186
+ *
187
+ * @return void
188
+ * @since 1.0
189
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
190
+ */
191
+ public function set_tabs() {
192
+ if ( ! isset( $this->options['tabs'] ) ) {
193
+ return;
194
+ }
195
+ $this->tabs = $this->options['tabs'] ;
196
+ if( isset($this->tabs['settings']['fields']) ){
197
+ $this->tabs['settings']['fields'] = array_filter( $this->tabs['settings']['fields'] );
198
+ }
199
+ }
200
+
201
+
202
+ /**
203
+ * Add Tab
204
+ *
205
+ * Add a tab inside the metabox
206
+ *
207
+ * @internal param array $tabs
208
+ *
209
+ * @param array $tab the new tab to add to the metabox
210
+ * @param string $where tell where insert the tab if after or before a $refer
211
+ * @param null $refer an existent tab inside metabox
212
+ *
213
+ * @return void
214
+ * @since 1.0
215
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
216
+ */
217
+ public function add_tab( $tab, $where = 'after', $refer = null ) {
218
+ if ( ! is_null( $refer ) ) {
219
+ $ref_pos = array_search( $refer, array_keys( $this->tabs ) );
220
+ if ( $ref_pos !== false ) {
221
+ if ( $where == 'after' ) {
222
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos + 1, true ) +
223
+ $tab +
224
+ array_slice( $this->tabs, $ref_pos + 1, count( $this->tabs ) - 1, true );
225
+ }
226
+ else {
227
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos, true ) +
228
+ $tab +
229
+ array_slice( $this->tabs, $ref_pos, count( $this->tabs ), true );
230
+ }
231
+ }
232
+ }
233
+ else {
234
+ $this->tabs = array_merge( $tab, $this->tabs );
235
+ }
236
+
237
+ }
238
+
239
+ /**
240
+ * Remove Tab
241
+ *
242
+ * Remove a tab from the tabs of metabox
243
+ *
244
+ * @internal param array $tabs
245
+ *
246
+ * @param $id_tab
247
+ *
248
+ * @return void
249
+ * @since 1.0
250
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
251
+ */
252
+ public function remove_tab( $id_tab ) {
253
+ if ( isset( $this->tabs[$id_tab] ) ) {
254
+ unset ( $this->tabs[$id_tab] );
255
+ }
256
+ }
257
+
258
+
259
+ /**
260
+ * Add Field
261
+ *
262
+ * Add a field inside a tab of metabox
263
+ *
264
+ * @internal param array $tabs
265
+ *
266
+ * @param string $tab_id the id of the tabs where add the field
267
+ * @param array $args the field to add
268
+ * @param string $where tell where insert the field if after or before a $refer
269
+ * @param null $refer an existent field inside tab
270
+ *
271
+ * @return void
272
+ * @since 1.0
273
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
274
+ */
275
+ public function add_field( $tab_id, $args, $where = 'after', $refer = null ) {
276
+ if ( isset( $this->tabs[$tab_id] ) ) {
277
+
278
+ $cf = $this->tabs[$tab_id]['fields'];
279
+ if ( ! is_null( $refer ) ) {
280
+ $ref_pos = array_search( $refer, array_keys( $cf ) );
281
+ if ( $ref_pos !== false ) {
282
+ if ( $where == 'after' ) {
283
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos + 1, true ) +
284
+ $args +
285
+ array_slice( $cf, $ref_pos, count( $cf ) - 1, true );
286
+
287
+ } elseif ( $where == 'before' ) {
288
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos, true ) +
289
+ $args +
290
+ array_slice( $cf, $ref_pos, count( $cf ), true );
291
+
292
+ }
293
+ }
294
+ }
295
+ else {
296
+ if ( $where == 'first' ) {
297
+ $this->tabs[$tab_id]['fields'] = $args + $cf;
298
+
299
+ } else {
300
+ $this->tabs[$tab_id]['fields'] = array_merge( $this->tabs[$tab_id]['fields'], $args );
301
+ }
302
+ }
303
+
304
+ }
305
+
306
+
307
+ }
308
+
309
+ /**
310
+ * Remove Field
311
+ *
312
+ * Remove a field from the metabox, search inside the tabs and remove it if exists
313
+ *
314
+ * @param $id_field
315
+ *
316
+ * @return void
317
+ * @since 1.0
318
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
319
+ */
320
+ public function remove_field( $id_field ) {
321
+ foreach ( $this->tabs as $tab_name => $tab ) {
322
+ if ( isset( $tab['fields'][$id_field] ) ) {
323
+ unset ( $this->tabs[$tab_name]['fields'][$id_field] );
324
+ }
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Reorder tabs
330
+ *
331
+ * Order the tabs and fields and set id and name to each field
332
+ *
333
+ * @internal param $id_field
334
+ *
335
+ * @return void
336
+ * @since 1.0
337
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
338
+ */
339
+ public function reorder_tabs() {
340
+ foreach ( $this->tabs as $tab_name => $tab ) {
341
+ foreach ( $tab['fields'] as $id_field => $field ) {
342
+ $this->tabs[$tab_name]['fields'][$id_field]['private'] = ( isset( $field['private'] ) ) ? $field['private'] : true;
343
+ $this->tabs[$tab_name]['fields'][$id_field]['id'] = $this->get_option_metabox_id( $id_field, $this->tabs[$tab_name]['fields'][$id_field]['private'] );
344
+ $this->tabs[$tab_name]['fields'][$id_field]['name'] = $this->get_option_metabox_name( $this->tabs[$tab_name]['fields'][$id_field]['id'] );
345
+ }
346
+ }
347
+
348
+ }
349
+
350
+
351
+ /**
352
+ * Get Option Metabox ID
353
+ *
354
+ * return the id of the field
355
+ *
356
+ * @param string $id_field
357
+ * @param bool $private if private add an _befor the id
358
+ *
359
+ * @return string
360
+ * @since 1.0
361
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
362
+ */
363
+ public function get_option_metabox_id( $id_field, $private = true ) {
364
+ if ( $private ) {
365
+ return '_' . $id_field;
366
+ }
367
+ else {
368
+ return $id_field;
369
+ }
370
+ }
371
+
372
+ /**
373
+ * Get Option Metabox Name
374
+ *
375
+ * return the name of the field, this name will be used as attribute name of the input field
376
+ *
377
+ * @param string $id_field
378
+ * @param bool $private if private add an _befor the id
379
+ *
380
+ * @return string
381
+ * @since 1.0
382
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
383
+ */
384
+ public function get_option_metabox_name( $id_field, $private = true ) {
385
+ $db_name = apply_filters( 'yit_metaboxes_option_main_name', 'yit_metaboxes' );
386
+ $return = $db_name . '[';
387
+
388
+ if ( ! strpos( $id_field, '[' ) ) {
389
+ return $return . $id_field . ']';
390
+ }
391
+ $return .= substr( $id_field, 0, strpos( $id_field, '[' ) );
392
+ $return .= ']';
393
+ $return .= substr( $id_field, strpos( $id_field, '[' ) );
394
+
395
+ return $return;
396
+ }
397
+
398
+ /**
399
+ * Register the metabox
400
+ *
401
+ * call the wp function add_metabox to add the metabox
402
+ *
403
+ *
404
+ * @return void
405
+ * @since 1.0
406
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
407
+ */
408
+ public function register_metabox( $post_type ) {
409
+ if( in_array( $post_type, (array) $this->options['pages'] ) ){
410
+ add_meta_box( $this->id, $this->options['label'], array( $this, 'show' ), $post_type, $this->options['context'], $this->options['priority'] );
411
+ }
412
+ }
413
+
414
+ /**
415
+ * Show metabox
416
+ *
417
+ * show the html of metabox
418
+ *
419
+ *
420
+ * @return void
421
+ * @since 1.0
422
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
423
+ */
424
+ public function show() {
425
+ $this->reorder_tabs();
426
+
427
+ yit_plugin_get_template( YIT_CORE_PLUGIN_PATH, 'metaboxes/tab.php', array( 'tabs' => $this->tabs ) );
428
+ }
429
+
430
+ /**
431
+ * Save Post Data
432
+ *
433
+ * Save the post data in the database when save the post
434
+ *
435
+ * @param $post_id
436
+ *
437
+ * @return int
438
+ * @since 1.0
439
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
440
+ */
441
+ public function save_postdata( $post_id ) {
442
+
443
+
444
+
445
+ if ( ! isset( $_POST['yit_metaboxes_nonce'] ) || ! wp_verify_nonce( $_POST['yit_metaboxes_nonce'], 'metaboxes-fields-nonce' ) ) {
446
+ return $post_id;
447
+ }
448
+
449
+
450
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
451
+ return $post_id;
452
+ }
453
+
454
+ if ( isset( $_POST['post_type'] ) ) {
455
+ $post_type = $_POST['post_type'];
456
+ }
457
+ else {
458
+ return $post_id;
459
+ }
460
+
461
+ if ( 'page' == $post_type ) {
462
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
463
+ return $post_id;
464
+ }
465
+ }
466
+ else {
467
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
468
+ return $post_id;
469
+ }
470
+ }
471
+
472
+ $this->reorder_tabs();
473
+
474
+
475
+ foreach ( $this->tabs as $tab ) {
476
+
477
+ foreach ( $tab['fields'] as $field ) {
478
+
479
+ if ( in_array( $field['type'], array( 'title' ) ) ) {
480
+ continue;
481
+ }
482
+
483
+ if ( isset( $_POST['yit_metaboxes'][$field['id']] ) ) {
484
+
485
+ add_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']], true ) || update_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']] );
486
+ }
487
+ elseif ( in_array( $field['type'], array( 'onoff', 'checkbox' ) ) ) {
488
+ add_post_meta( $post_id, $field['id'], '0', true ) || update_post_meta( $post_id, $field['id'], '0' );
489
+ }
490
+ else {
491
+ delete_post_meta( $post_id, $field['id'] );
492
+ }
493
+ }
494
+ }
495
+
496
+ }
497
+
498
+ /**
499
+ * Remove Fields
500
+ *
501
+ * Remove a fields list from the metabox, search inside the tabs and remove it if exists
502
+ *
503
+ * @param $id_fields
504
+ *
505
+ * @return void
506
+ * @since 2.0.0
507
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
508
+ */
509
+ public function remove_fields( $id_fields ) {
510
+ foreach ( $id_fields as $k => $field ) {
511
+ $this->remove_field( $field );
512
+ }
513
+ }
514
+ }
515
+ }
516
+
517
+ if ( ! function_exists( 'YIT_Metabox' ) ) {
518
+
519
+ /**
520
+ * Main instance of plugin
521
+ *
522
+ * @param $id
523
+ *
524
+ * @return \YIT_Metabox
525
+ * @since 1.0
526
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
527
+ */
528
+
529
+
530
+ function YIT_Metabox( $id ) {
531
+ return YIT_Metabox::instance( $id );
532
+ }
533
+ }
534
+
535
+
536
+
537
+
plugin-fw/lib/yit-plugin-common.php ADDED
@@ -0,0 +1,1260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! class_exists( 'YIT_Plugin_Common' ) ) :
12
+
13
+ /**
14
+ * Core configuration class
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ class YIT_Plugin_Common {
19
+
20
+ /**
21
+ * Config array
22
+ *
23
+ * @var array
24
+ */
25
+ protected static $_config = array(
26
+ 'slider' => array( 'nivo', 'elegant' ),
27
+
28
+
29
+ 'awesome_icons' => array(
30
+ '' => 'no-icon',
31
+ 'f042' => 'adjust',
32
+ 'f170' => 'adn',
33
+ 'f037' => 'align-center',
34
+ 'f039' => 'align-justify',
35
+ 'f036' => 'align-left',
36
+ 'f038' => 'align-right',
37
+ 'f0f9' => 'ambulance',
38
+ 'f13d' => 'anchor',
39
+ 'f17b' => 'android',
40
+ 'f103' => 'angle-double-down',
41
+ 'f100' => 'angle-double-left',
42
+ 'f101' => 'angle-double-right',
43
+ 'f102' => 'angle-double-up',
44
+ 'f107' => 'angle-down',
45
+ 'f104' => 'angle-left',
46
+ 'f105' => 'angle-right',
47
+ 'f106' => 'angle-up',
48
+ 'f179' => 'apple',
49
+ 'f187' => 'archive',
50
+ 'f0ab' => 'arrow-circle-down',
51
+ 'f0a8' => 'arrow-circle-left',
52
+ 'f01a' => 'arrow-circle-o-down',
53
+ 'f190' => 'arrow-circle-o-left',
54
+ 'f18e' => 'arrow-circle-o-right',
55
+ 'f01b' => 'arrow-circle-o-up',
56
+ 'f0a9' => 'arrow-circle-right',
57
+ 'f0aa' => 'arrow-circle-up',
58
+ 'f063' => 'arrow-down',
59
+ 'f060' => 'arrow-left',
60
+ 'f061' => 'arrow-right',
61
+ 'f062' => 'arrow-up',
62
+ 'f047' => 'arrows',
63
+ 'f0b2' => 'arrows-alt',
64
+ 'f07e' => 'arrows-h',
65
+ 'f07d' => 'arrows-v',
66
+ 'f069' => 'asterisk',
67
+ 'f04a' => 'backward',
68
+ 'f05e' => 'ban',
69
+ 'f080' => 'bar-chart-o',
70
+ 'f02a' => 'barcode',
71
+ 'f0c9' => 'bars',
72
+ 'f0fc' => 'beer',
73
+ 'f0f3' => 'bell',
74
+ 'f0a2' => 'bell-o',
75
+ 'f171' => 'bitbucket',
76
+ 'f172' => 'bitbucket-square',
77
+ 'f032' => 'bold',
78
+ 'f0e7' => 'bolt',
79
+ 'f02d' => 'book',
80
+ 'f02e' => 'bookmark',
81
+ 'f097' => 'bookmark-o',
82
+ 'f0b1' => 'briefcase',
83
+ 'f15a' => 'btc',
84
+ 'f188' => 'bug',
85
+ 'f0f7' => 'building-o',
86
+ 'f0a1' => 'bullhorn',
87
+ 'f140' => 'bullseye',
88
+ 'f073' => 'calendar',
89
+ 'f133' => 'calendar-o',
90
+ 'f030' => 'camera',
91
+ 'f083' => 'camera-retro',
92
+ 'f0d7' => 'caret-down',
93
+ 'f0d9' => 'caret-left',
94
+ 'f0da' => 'caret-right',
95
+ 'f150' => 'caret-square-o-down',
96
+ 'f191' => 'caret-square-o-left',
97
+ 'f152' => 'caret-square-o-right',
98
+ 'f151' => 'caret-square-o-up',
99
+ 'f0d8' => 'caret-up',
100
+ 'f0a3' => 'certificate',
101
+ 'f127' => 'chain-broken',
102
+ 'f00c' => 'check',
103
+ 'f058' => 'check-circle',
104
+ 'f05d' => 'check-circle-o',
105
+ 'f14a' => 'check-square',
106
+ 'f046' => 'check-square-o',
107
+ 'f13a' => 'chevron-circle-down',
108
+ 'f137' => 'chevron-circle-left',
109
+ 'f138' => 'chevron-circle-right',
110
+ 'f139' => 'chevron-circle-up',
111
+ 'f078' => 'chevron-down',
112
+ 'f053' => 'chevron-left',
113
+ 'f054' => 'chevron-right',
114
+ 'f077' => 'chevron-up',
115
+ 'f10c' => 'circle-o',
116
+ 'f0ea' => 'clipboard',
117
+ 'f017' => 'clock-o',
118
+ 'f0c2' => 'cloud',
119
+ 'f0ed' => 'cloud-download',
120
+ 'f0ee' => 'cloud-upload',
121
+ 'f121' => 'code',
122
+ 'f126' => 'code-fork',
123
+ 'f0f4' => 'coffee',
124
+ 'f013' => 'cog',
125
+ 'f085' => 'cogs',
126
+ 'f0db' => 'columns',
127
+ 'f075' => 'comment',
128
+ 'f0e5' => 'comment-o',
129
+ 'f086' => 'comments',
130
+ 'f0e6' => 'comments-o',
131
+ 'f14e' => 'compass',
132
+ 'f066' => 'compress',
133
+ 'f09d' => 'credit-card',
134
+ 'f125' => 'crop',
135
+ 'f05b' => 'crosshairs',
136
+ 'f13c' => 'css3',
137
+ 'f0f5' => 'cutlery',
138
+ 'f108' => 'desktop',
139
+ 'f192' => 'dot-circle-o',
140
+ 'f019' => 'download',
141
+ 'f17d' => 'dribbble',
142
+ 'f16b' => 'dropbox',
143
+ 'f052' => 'eject',
144
+ 'f141' => 'ellipsis-h',
145
+ 'f142' => 'ellipsis-v',
146
+ 'f0e0' => 'envelope',
147
+ 'f003' => 'envelope-o',
148
+ 'f12d' => 'eraser',
149
+ 'f153' => 'eur',
150
+ 'f0ec' => 'exchange',
151
+ 'f12a' => 'exclamation',
152
+ 'f06a' => 'exclamation-circle',
153
+ 'f071' => 'exclamation-triangle',
154
+ 'f065' => 'expand',
155
+ 'f08e' => 'external-link',
156
+ 'f14c' => 'external-link-square',
157
+ 'f06e' => 'eye',
158
+ 'f070' => 'eye-slash',
159
+ 'f09a' => 'facebook',
160
+ 'f082' => 'facebook-square',
161
+ 'f049' => 'fast-backward',
162
+ 'f050' => 'fast-forward',
163
+ 'f182' => 'female',
164
+ 'f0fb' => 'fighter-jet',
165
+ 'f15b' => 'file',
166
+ 'f016' => 'file-o',
167
+ 'f15c' => 'file-text',
168
+ 'f0f6' => 'file-text-o',
169
+ 'f0c5' => 'files-o',
170
+ 'f008' => 'film',
171
+ 'f0b0' => 'filter',
172
+ 'f06d' => 'fire',
173
+ 'f134' => 'fire-extinguisher',
174
+ 'f024' => 'flag',
175
+ 'f11e' => 'flag-checkered',
176
+ 'f11d' => 'flag-o',
177
+ 'f0c3' => 'flask',
178
+ 'f16e' => 'flickr',
179
+ 'f0c7' => 'floppy-o',
180
+ 'f07b' => 'folder',
181
+ 'f114' => 'folder-o',
182
+ 'f07c' => 'folder-open',
183
+ 'f115' => 'folder-open-o',
184
+ 'f031' => 'font',
185
+ 'f04e' => 'forward',
186
+ 'f180' => 'foursquare',
187
+ 'f119' => 'frown-o',
188
+ 'f11b' => 'gamepad',
189
+ 'f0e3' => 'gavel',
190
+ 'f154' => 'gbp',
191
+ 'f06b' => 'gift',
192
+ 'f09b' => 'github',
193
+ 'f113' => 'github-alt',
194
+ 'f092' => 'github-square',
195
+ 'f184' => 'gittip',
196
+ 'f000' => 'glass',
197
+ 'f0ac' => 'globe',
198
+ 'f0d5' => 'google-plus',
199
+ 'f0d4' => 'google-plus-square',
200
+ 'f0fd' => 'h-square',
201
+ 'f0a7' => 'hand-o-down',
202
+ 'f0a5' => 'hand-o-left',
203
+ 'f0a4' => 'hand-o-right',
204
+ 'f0a6' => 'hand-o-up',
205
+ 'f0a0' => 'hdd-o',
206
+ 'f025' => 'headphones',
207
+ 'f004' => 'heart',
208
+ 'f08a' => 'heart-o',
209
+ 'f015' => 'home',
210
+ 'f0f8' => 'hospital-o',
211
+ 'f13b' => 'html5',
212
+ 'f01c' => 'inbox',
213
+ 'f03c' => 'indent',
214
+ 'f129' => 'info',
215
+ 'f05a' => 'info-circle',
216
+ 'f156' => 'inr',
217
+ 'f16d' => 'instagram',
218
+ 'f033' => 'italic',
219
+ 'f157' => 'jpy',
220
+ 'f084' => 'key',
221
+ 'f11c' => 'keyboard-o',
222
+ 'f159' => 'krw',
223
+ 'f109' => 'laptop',
224
+ 'f06c' => 'leaf',
225
+ 'f094' => 'lemon-o',
226
+ 'f149' => 'level-down',
227
+ 'f148' => 'level-up',
228
+ 'f0eb' => 'lightbulb-o',
229
+ 'f0c1' => 'link',
230
+ 'f0e1' => 'linkedin',
231
+ 'f08c' => 'linkedin-square',
232
+ 'f17c' => 'linux',
233
+ 'f03a' => 'list',
234
+ 'f022' => 'list-alt',
235
+ 'f0cb' => 'list-ol',
236
+ 'f0ca' => 'list-ul',
237
+ 'f124' => 'location-arrow',
238
+ 'f023' => 'lock',
239
+ 'f175' => 'long-arrow-down',
240
+ 'f177' => 'long-arrow-left',
241
+ 'f178' => 'long-arrow-right',
242
+ 'f176' => 'long-arrow-up',
243
+ 'f0d0' => 'magic',
244
+ 'f076' => 'magnet',
245
+ 'f122' => 'mail-reply-all',
246
+ 'f183' => 'male',
247
+ 'f041' => 'map-marker',
248
+ 'f136' => 'maxcdn',
249
+ 'f0fa' => 'medkit',
250
+ 'f11a' => 'meh-o',
251
+ 'f130' => 'microphone',
252
+ 'f131' => 'microphone-slash',
253
+ 'f068' => 'minus',
254
+ 'f056' => 'minus-circle',
255
+ 'f146' => 'minus-square',
256
+ 'f147' => 'minus-square-o',
257
+ 'f10b' => 'mobile',
258
+ 'f0d6' => 'money',
259
+ 'f186' => 'moon-o',
260
+ 'f001' => 'music',
261
+ 'f03b' => 'outdent',
262
+ 'f18c' => 'pagelines',
263
+ 'f0c6' => 'paperclip',
264
+ 'f04c' => 'pause',
265
+ 'f040' => 'pencil',
266
+ 'f14b' => 'pencil-square',
267
+ 'f044' => 'pencil-square-o',
268
+ 'f095' => 'phone',
269
+ 'f098' => 'phone-square',
270
+ 'f03e' => 'picture-o',
271
+ 'f0d2' => 'pinterest',
272
+ 'f0d3' => 'pinterest-square',
273
+ 'f072' => 'plane',
274
+ 'f04b' => 'play',
275
+ 'f144' => 'play-circle',
276
+ 'f01d' => 'play-circle-o',
277
+ 'f067' => 'plus',
278
+ 'f055' => 'plus-circle',
279
+ 'f0fe' => 'plus-square',
280
+ 'f196' => 'plus-square-o',
281
+ 'f011' => 'power-off',
282
+ 'f02f' => 'print',
283
+ 'f12e' => 'puzzle-piece',
284
+ 'f029' => 'qrcode',
285
+ 'f128' => 'question',
286
+ 'f059' => 'question-circle',
287
+ 'f10d' => 'quote-left',
288
+ 'f10e' => 'quote-right',
289
+ 'f074' => 'random',
290
+ 'f021' => 'refresh',
291
+ 'f18b' => 'renren',
292
+ 'f01e' => 'repeat',
293
+ 'f112' => 'reply',
294
+ 'f122' => 'reply-all',
295
+ 'f079' => 'retweet',
296
+ 'f018' => 'road',
297
+ 'f135' => 'rocket',
298
+ 'f09e' => 'rss',
299
+ 'f143' => 'rss-square',
300
+ 'f158' => 'rub',
301
+ 'f0c4' => 'scissors',
302
+ 'f002' => 'search',
303
+ 'f010' => 'search-minus',
304
+ 'f00e' => 'search-plus',
305
+ 'f064' => 'share',
306
+ 'f14d' => 'share-square',
307
+ 'f045' => 'share-square-o',
308
+ 'f132' => 'shield',
309
+ 'f07a' => 'shopping-cart',
310
+ 'f090' => 'sign-in',
311
+ 'f08b' => 'sign-out',
312
+ 'f012' => 'signal',
313
+ 'f0e8' => 'sitemap',
314
+ 'f17e' => 'skype',
315
+ 'f118' => 'smile-o',
316
+ 'f0dc' => 'sort',
317
+ 'f15d' => 'sort-alpha-asc',
318
+ 'f15e' => 'sort-alpha-desc',
319
+ 'f160' => 'sort-amount-asc',
320
+ 'f161' => 'sort-amount-desc',
321
+ 'f0dd' => 'sort-asc',
322
+ 'f0de' => 'sort-desc',
323
+ 'f162' => 'sort-numeric-asc',
324
+ 'f163' => 'sort-numeric-desc',
325
+ 'f110' => 'spinner',
326
+ 'f0c8' => 'square',
327
+ 'f096' => 'square-o',
328
+ 'f18d' => 'stack-exchange',
329
+ 'f16c' => 'stack-overflow',
330
+ 'f005' => 'star',
331
+ 'f089' => 'star-half',
332
+ 'f123' => 'star-half-o',
333
+ 'f006' => 'star-o',
334
+ 'f048' => 'step-backward',
335
+ 'f051' => 'step-forward',
336
+ 'f0f1' => 'stethoscope',
337
+ 'f04d' => 'stop',
338
+ 'f0cc' => 'strikethrough',
339
+ 'f12c' => 'subscript',
340
+ 'f0f2' => 'suitcase',
341
+ 'f185' => 'sun-o',
342
+ 'f12b' => 'superscript',
343
+ 'f0ce' => 'table',
344
+ 'f10a' => 'tablet',
345
+ 'f0e4' => 'tachometer',
346
+ 'f02b' => 'tag',
347
+ 'f02c' => 'tags',
348
+ 'f0ae' => 'tasks',
349
+ 'f120' => 'terminal',
350
+ 'f034' => 'text-height',
351
+ 'f035' => 'text-width',
352
+ 'f00a' => 'th',
353
+ 'f009' => 'th-large',
354
+ 'f00b' => 'th-list',
355
+ 'f08d' => 'thumb-tack',
356
+ 'f165' => 'thumbs-down',
357
+ 'f088' => 'thumbs-o-down',
358
+ 'f087' => 'thumbs-o-up',
359
+ 'f164' => 'thumbs-up',
360
+ 'f145' => 'ticket',
361
+ 'f00d' => 'times',
362
+ 'f057' => 'times-circle',
363
+ 'f05c' => 'times-circle-o',
364
+ 'f043' => 'tint',
365
+ 'f014' => 'trash-o',
366
+ 'f181' => 'trello',
367
+ 'f091' => 'trophy',
368
+ 'f0d1' => 'truck',
369
+ 'f195' => 'try',
370
+ 'f173' => 'tumblr',
371
+ 'f174' => 'tumblr-square',
372
+ 'f099' => 'twitter',
373
+ 'f081' => 'twitter-square',
374
+ 'f0e9' => 'umbrella',
375
+ 'f0cd' => 'underline',
376
+ 'f0e2' => 'undo',
377
+ 'f09c' => 'unlock',
378
+ 'f13e' => 'unlock-alt',
379
+ 'f093' => 'upload',
380
+ 'f155' => 'usd',
381
+ 'f007' => 'user',
382
+ 'f0f0' => 'user-md',
383
+ 'f0c0' => 'users',
384
+ 'f03d' => 'video-camera',
385
+ 'f194' => 'vimeo-square',
386
+ 'f189' => 'vk',
387
+ 'f027' => 'volume-down',
388
+ 'f026' => 'volume-off',
389
+ 'f028' => 'volume-up',
390
+ 'f18a' => 'weibo',
391
+ 'f193' => 'wheelchair',
392
+ 'f17a' => 'windows',
393
+ 'f0ad' => 'wrench',
394
+ 'f168' => 'xing',
395
+ 'f169' => 'xing-square',
396
+ 'f167' => 'youtube',
397
+ 'f16a' => 'youtube-play',
398
+ 'f166' => 'youtube-square'
399
+ ),
400
+ 'awesome_icons2' => array(
401
+ '\f042' => 'adjust',
402
+ '\f170' => 'adn',
403
+ '\f037' => 'align-center',
404
+ '\f039' => 'align-justify',
405
+ '\f036' => 'align-left',
406
+ '\f038' => 'align-right',
407
+ '\f0f9' => 'ambulance',
408
+ '\f13d' => 'anchor',
409
+ '\f17b' => 'android',
410
+ '\f209' => 'angellist',
411
+ '\f103' => 'angle-double-down',
412
+ '\f100' => 'angle-double-left',
413
+ '\f101' => 'angle-double-right',
414
+ '\f102' => 'angle-double-up',
415
+ '\f107' => 'angle-down',
416
+ '\f104' => 'angle-left',
417
+ '\f105' => 'angle-right',
418
+ '\f106' => 'angle-up',
419
+ '\f179' => 'apple',
420
+ '\f187' => 'archive',
421
+ '\f1fe' => 'area-chart',
422
+ '\f0ab' => 'arrow-circle-down',
423
+ '\f0a8' => 'arrow-circle-left',
424
+ '\f01a' => 'arrow-circle-o-down',
425
+ '\f190' => 'arrow-circle-o-left',
426
+ '\f18e' => 'arrow-circle-o-right',
427
+ '\f01b' => 'arrow-circle-o-up',
428
+ '\f0a9' => 'arrow-circle-right',
429
+ '\f0aa' => 'arrow-circle-up',
430
+ '\f063' => 'arrow-down',
431
+ '\f060' => 'arrow-left',
432
+ '\f061' => 'arrow-right',
433
+ '\f062' => 'arrow-up',
434
+ '\f047' => 'arrows',
435
+ '\f0b2' => 'arrows-alt',
436
+ '\f07e' => 'arrows-h',
437
+ '\f07d' => 'arrows-v',
438
+ '\f069' => 'asterisk',
439
+ '\f1fa' => 'at',
440
+ '\f1b9' => 'automobile',
441
+ '\f04a' => 'backward',
442
+ '\f05e' => 'ban',
443
+ '\f19c' => 'bank',
444
+ '\f080' => 'bar-chart',
445
+ '\f080' => 'bar-chart-o',
446
+ '\f02a' => 'barcode',
447
+ '\f0c9' => 'bars',
448
+ '\f236' => 'bed',
449
+ '\f0fc' => 'beer',
450
+ '\f1b4' => 'behance',
451
+ '\f1b5' => 'behance-square',
452
+ '\f0f3' => 'bell',
453
+ '\f0a2' => 'bell-o',
454
+ '\f1f6' => 'bell-slash',
455
+ '\f1f7' => 'bell-slash-o',
456
+ '\f206' => 'bicycle',
457
+ '\f1e5' => 'binoculars',
458
+ '\f1fd' => 'birthday-cake',
459
+ '\f171' => 'bitbucket',
460
+ '\f172' => 'bitbucket-square',
461
+ '\f15a' => 'bitcoin',
462
+ '\f032' => 'bold',
463
+ '\f0e7' => 'bolt',
464
+ '\f1e2' => 'bomb',
465
+ '\f02d' => 'book',
466
+ '\f02e' => 'bookmark',
467
+ '\f097' => 'bookmark-o',
468
+ '\f0b1' => 'briefcase',
469
+ '\f15a' => 'btc',
470
+ '\f188' => 'bug',
471
+ '\f1ad' => 'building',
472
+ '\f0f7' => 'building-o',
473
+ '\f0a1' => 'bullhorn',
474
+ '\f140' => 'bullseye',
475
+ '\f207' => 'bus',
476
+ '\f20d' => 'buysellads',
477
+ '\f1ba' => 'cab',
478
+ '\f1ec' => 'calculator',
479
+ '\f073' => 'calendar',
480
+ '\f133' => 'calendar-o',
481
+ '\f030' => 'camera',
482
+ '\f083' => 'camera-retro',
483
+ '\f1b9' => 'car',
484
+ '\f0d7' => 'caret-down',
485
+ '\f0d9' => 'caret-left',
486
+ '\f0da' => 'caret-right',
487
+ '\f150' => 'caret-square-o-down',
488
+ '\f191' => 'caret-square-o-left',
489
+ '\f152' => 'caret-square-o-right',
490
+ '\f151' => 'caret-square-o-up',
491
+ '\f0d8' => 'caret-up',
492
+ '\f218' => 'cart-arrow-down',
493
+ '\f217' => 'cart-plus',
494
+ '\f20a' => 'cc',
495
+ '\f1f3' => 'cc-amex',
496
+ '\f1f2' => 'cc-discover',
497
+ '\f1f1' => 'cc-mastercard',
498
+ '\f1f4' => 'cc-paypal',
499
+ '\f1f5' => 'cc-stripe',
500
+ '\f1f0' => 'cc-visa',
501
+ '\f0a3' => 'certificate',
502
+ '\f0c1' => 'chain',
503
+ '\f127' => 'chain-broken',
504
+ '\f00c' => 'check',
505
+ '\f058' => 'check-circle',
506
+ '\f05d' => 'check-circle-o',
507
+ '\f14a' => 'check-square',
508
+ '\f046' => 'check-square-o',
509
+ '\f13a' => 'chevron-circle-down',
510
+ '\f137' => 'chevron-circle-left',
511
+ '\f138' => 'chevron-circle-right',
512
+ '\f139' => 'chevron-circle-up',
513
+ '\f078' => 'chevron-down',
514
+ '\f053' => 'chevron-left',
515
+ '\f054' => 'chevron-right',
516
+ '\f077' => 'chevron-up',
517
+ '\f1ae' => 'child',
518
+ '\f111' => 'circle',
519
+ '\f10c' => 'circle-o',
520
+ '\f1ce' => 'circle-o-notch',
521
+ '\f1db' => 'circle-thin',
522
+ '\f0ea' => 'clipboard',
523
+ '\f017' => 'clock-o',
524
+ '\f00d' => 'close',
525
+ '\f0c2' => 'cloud',
526
+ '\f0ed' => 'cloud-download',
527
+ '\f0ee' => 'cloud-upload',
528
+ '\f157' => 'cny',
529
+ '\f121' => 'code',
530
+ '\f126' => 'code-fork',
531
+ '\f1cb' => 'codepen',
532
+ '\f0f4' => 'coffee',
533
+ '\f013' => 'cog',
534
+ '\f085' => 'cogs',
535
+ '\f0db' => 'columns',
536
+ '\f075' => 'comment',
537
+ '\f0e5' => 'comment-o',
538
+ '\f086' => 'comments',
539
+ '\f0e6' => 'comments-o',
540
+ '\f14e' => 'compass',
541
+ '\f066' => 'compress',
542
+ '\f20e' => 'connectdevelop',
543
+ '\f0c5' => 'copy',
544
+ '\f1f9' => 'copyright',
545
+ '\f09d' => 'credit-card',
546
+ '\f125' => 'crop',
547
+ '\f05b' => 'crosshairs',
548
+ '\f13c' => 'css3',
549
+ '\f1b2' => 'cube',
550
+ '\f1b3' => 'cubes',
551
+ '\f0c4' => 'cut',
552
+ '\f0f5' => 'cutlery',
553
+ '\f0e4' => 'dashboard',
554
+ '\f210' => 'dashcube',
555
+ '\f1c0' => 'database',
556
+ '\f03b' => 'dedent',
557
+ '\f1a5' => 'delicious',
558
+ '\f108' => 'desktop',
559
+ '\f1bd' => 'deviantart',
560
+ '\f219' => 'diamond',
561
+ '\f1a6' => 'digg',
562
+ '\f155' => 'dollar',
563
+ '\f192' => 'dot-circle-o',
564
+ '\f019' => 'download',
565
+ '\f17d' => 'dribbble',
566
+ '\f16b' => 'dropbox',
567
+ '\f1a9' => 'drupal',
568
+ '\f044' => 'edit',
569
+ '\f052' => 'eject',
570
+ '\f141' => 'ellipsis-h',
571
+ '\f142' => 'ellipsis-v',
572
+ '\f1d1' => 'empire',
573
+ '\f0e0' => 'envelope',
574
+ '\f003' => 'envelope-o',
575
+ '\f199' => 'envelope-square',
576
+ '\f12d' => 'eraser',
577
+ '\f153' => 'eur',
578
+ '\f153' => 'euro',
579
+ '\f0ec' => 'exchange',
580
+ '\f12a' => 'exclamation',
581
+ '\f06a' => 'exclamation-circle',
582
+ '\f071' => 'exclamation-triangle',
583
+ '\f065' => 'expand',
584
+ '\f08e' => 'external-link',
585
+ '\f14c' => 'external-link-square',
586
+ '\f06e' => 'eye',
587
+ '\f070' => 'eye-slash',
588
+ '\f1fb' => 'eyedropper',
589
+ '\f09a' => 'facebook',
590
+ '\f09a' => 'facebook-f',
591
+ '\f230' => 'facebook-official',
592
+ '\f082' => 'facebook-square',
593
+ '\f049' => 'fast-backward',
594
+ '\f050' => 'fast-forward',
595
+ '\f1ac' => 'fax',
596
+ '\f182' => 'female',
597
+ '\f0fb' => 'fighter-jet',
598
+ '\f15b' => 'file',
599
+ '\f1c6' => 'file-archive-o',
600
+ '\f1c7' => 'file-audio-o',
601
+ '\f1c9' => 'file-code-o',
602
+ '\f1c3' => 'file-excel-o',
603
+ '\f1c5' => 'file-image-o',
604
+ '\f1c8' => 'file-movie-o',
605
+ '\f016' => 'file-o',
606
+ '\f1c1' => 'file-pdf-o',
607
+ '\f1c5' => 'file-photo-o',
608
+ '\f1c5' => 'file-picture-o',
609
+ '\f1c4' => 'file-powerpoint-o',
610
+ '\f1c7' => 'file-sound-o',
611
+ '\f15c' => 'file-text',
612
+ '\f0f6' => 'file-text-o',
613
+ '\f1c8' => 'file-video-o',
614
+ '\f1c2' => 'file-word-o',
615
+ '\f1c6' => 'file-zip-o',
616
+ '\f0c5' => 'files-o',
617
+ '\f008' => 'film',
618
+ '\f0b0' => 'filter',
619
+ '\f06d' => 'fire',
620
+ '\f134' => 'fire-extinguisher',
621
+ '\f024' => 'flag',
622
+ '\f11e' => 'flag-checkered',
623
+ '\f11d' => 'flag-o',
624
+ '\f0e7' => 'flash',
625
+ '\f0c3' => 'flask',
626
+ '\f16e' => 'flickr',
627
+ '\f0c7' => 'floppy-o',
628
+ '\f07b' => 'folder',
629
+ '\f114' => 'folder-o',
630
+ '\f07c' => 'folder-open',
631
+ '\f115' => 'folder-open-o',
632
+ '\f031' => 'font',
633
+ '\f211' => 'forumbee',
634
+ '\f04e' => 'forward',
635
+ '\f180' => 'foursquare',
636
+ '\f119' => 'frown-o',
637
+ '\f1e3' => 'futbol-o',
638
+ '\f11b' => 'gamepad',
639
+ '\f0e3' => 'gavel',
640
+ '\f154' => 'gbp',
641
+ '\f1d1' => 'ge',
642
+ '\f013' => 'gear',
643
+ '\f085' => 'gears',
644
+ '\f1db' => 'genderless',
645
+ '\f06b' => 'gift',
646
+ '\f1d3' => 'git',
647
+ '\f1d2' => 'git-square',
648
+ '\f09b' => 'github',
649
+ '\f113' => 'github-alt',
650
+ '\f092' => 'github-square',
651
+ '\f184' => 'gittip',
652
+ '\f000' => 'glass',
653
+ '\f0ac' => 'globe',
654
+ '\f1a0' => 'google',
655
+ '\f0d5' => 'google-plus',
656
+ '\f0d4' => 'google-plus-square',
657
+ '\f1ee' => 'google-wallet',
658
+ '\f19d' => 'graduation-cap',
659
+ '\f184' => 'gratipay',
660
+ '\f0c0' => 'group',
661
+ '\f0fd' => 'h-square',
662
+ '\f1d4' => 'hacker-news',
663
+ '\f0a7' => 'hand-o-down',
664
+ '\f0a5' => 'hand-o-left',
665
+ '\f0a4' => 'hand-o-right',
666
+ '\f0a6' => 'hand-o-up',
667
+ '\f0a0' => 'hdd-o',
668
+ '\f1dc' => 'header',
669
+ '\f025' => 'headphones',
670
+ '\f004' => 'heart',
671
+ '\f08a' => 'heart-o',
672
+ '\f21e' => 'heartbeat',
673
+ '\f1da' => 'history',
674
+ '\f015' => 'home',
675
+ '\f0f8' => 'hospital-o',
676
+ '\f236' => 'hotel',
677
+ '\f13b' => 'html5',
678
+ '\f20b' => 'ils',
679
+ '\f03e' => 'image',
680
+ '\f01c' => 'inbox',
681
+ '\f03c' => 'indent',
682
+ '\f129' => 'info',
683
+ '\f05a' => 'info-circle',
684
+ '\f156' => 'inr',
685
+ '\f16d' => 'instagram',
686
+ '\f19c' => 'institution',
687
+ '\f208' => 'ioxhost',
688
+ '\f033' => 'italic',
689
+ '\f1aa' => 'joomla',
690
+ '\f157' => 'jpy',
691
+ '\f1cc' => 'jsfiddle',
692
+ '\f084' => 'key',
693
+ '\f11c' => 'keyboard-o',
694
+ '\f159' => 'krw',
695
+ '\f1ab' => 'language',
696
+ '\f109' => 'laptop',
697
+ '\f202' => 'lastfm',
698
+ '\f203' => 'lastfm-square',
699
+ '\f06c' => 'leaf',
700
+ '\f212' => 'leanpub',
701
+ '\f0e3' => 'legal',
702
+ '\f094' => 'lemon-o',
703
+ '\f149' => 'level-down',
704
+ '\f148' => 'level-up',
705
+ '\f1cd' => 'life-bouy',
706
+ '\f1cd' => 'life-buoy',
707
+ '\f1cd' => 'life-ring',
708
+ '\f1cd' => 'life-saver',
709
+ '\f0eb' => 'lightbulb-o',
710
+ '\f201' => 'line-chart',
711
+ '\f0c1' => 'link',
712
+ '\f0e1' => 'linkedin',
713
+ '\f08c' => 'linkedin-square',
714
+ '\f17c' => 'linux',
715
+ '\f03a' => 'list',
716
+ '\f022' => 'list-alt',
717
+ '\f0cb' => 'list-ol',
718
+ '\f0ca' => 'list-ul',
719
+ '\f124' => 'location-arrow',
720
+ '\f023' => 'lock',
721
+ '\f175' => 'long-arrow-down',
722
+ '\f177' => 'long-arrow-left',
723
+ '\f178' => 'long-arrow-right',
724
+ '\f176' => 'long-arrow-up',
725
+ '\f0d0' => 'magic',
726
+ '\f076' => 'magnet',
727
+ '\f064' => 'mail-forward',
728
+ '\f112' => 'mail-reply',
729
+ '\f122' => 'mail-reply-all',
730
+ '\f183' => 'male',
731
+ '\f041' => 'map-marker',
732
+ '\f222' => 'mars',
733
+ '\f227' => 'mars-double',
734
+ '\f229' => 'mars-stroke',
735
+ '\f22b' => 'mars-stroke-h',
736
+ '\f22a' => 'mars-stroke-v',
737
+ '\f136' => 'maxcdn',
738
+ '\f20c' => 'meanpath',
739
+ '\f23a' => 'medium',
740
+ '\f0fa' => 'medkit',
741
+ '\f11a' => 'meh-o',
742
+ '\f223' => 'mercury',
743
+ '\f130' => 'microphone',
744
+ '\f131' => 'microphone-slash',
745
+ '\f068' => 'minus',
746
+ '\f056' => 'minus-circle',
747
+ '\f146' => 'minus-square',
748
+ '\f147' => 'minus-square-o',
749
+ '\f10b' => 'mobile',
750
+ '\f10b' => 'mobile-phone',
751
+ '\f0d6' => 'money',
752
+ '\f186' => 'moon-o',
753
+ '\f19d' => 'mortar-board',
754
+ '\f21c' => 'motorcycle',
755
+ '\f001' => 'music',
756
+ '\f0c9' => 'navicon',
757
+ '\f22c' => 'neuter',
758
+ '\f1ea' => 'newspaper-o',
759
+ '\f19b' => 'openid',
760
+ '\f03b' => 'outdent',
761
+ '\f18c' => 'pagelines',
762
+ '\f1fc' => 'paint-brush',
763
+ '\f1d8' => 'paper-plane',
764
+ '\f1d9' => 'paper-plane-o',
765
+ '\f0c6' => 'paperclip',
766
+ '\f1dd' => 'paragraph',
767
+ '\f0ea' => 'paste',
768
+ '\f04c' => 'pause',
769
+ '\f1b0' => 'paw',
770
+ '\f1ed' => 'paypal',
771
+ '\f040' => 'pencil',
772
+ '\f14b' => 'pencil-square',
773
+ '\f044' => 'pencil-square-o',
774
+ '\f095' => 'phone',
775
+ '\f098' => 'phone-square',
776
+ '\f03e' => 'photo',
777
+ '\f03e' => 'picture-o',
778
+ '\f200' => 'pie-chart',
779
+ '\f1a7' => 'pied-piper',
780
+ '\f1a8' => 'pied-piper-alt',
781
+ '\f0d2' => 'pinterest',
782
+ '\f231' => 'pinterest-p',
783
+ '\f0d3' => 'pinterest-square',
784
+ '\f072' => 'plane',
785
+ '\f04b' => 'play',
786
+ '\f144' => 'play-circle',
787
+ '\f01d' => 'play-circle-o',
788
+ '\f1e6' => 'plug',
789
+ '\f067' => 'plus',
790
+ '\f055' => 'plus-circle',
791
+ '\f0fe' => 'plus-square',
792
+ '\f196' => 'plus-square-o',
793
+ '\f011' => 'power-off',
794
+ '\f02f' => 'print',
795
+ '\f12e' => 'puzzle-piece',
796
+ '\f1d6' => 'qq',
797
+ '\f029' => 'qrcode',
798
+ '\f128' => 'question',
799
+ '\f059' => 'question-circle',
800
+ '\f10d' => 'quote-left',
801
+ '\f10e' => 'quote-right',
802
+ '\f1d0' => 'ra',
803
+ '\f074' => 'random',
804
+ '\f1d0' => 'rebel',
805
+ '\f1b8' => 'recycle',
806
+ '\f1a1' => 'reddit',
807
+ '\f1a2' => 'reddit-square',
808
+ '\f021' => 'refresh',
809
+ '\f00d' => 'remove',
810
+ '\f18b' => 'renren',
811
+ '\f0c9' => 'reorder',
812
+ '\f01e' => 'repeat',
813
+ '\f112' => 'reply',
814
+ '\f122' => 'reply-all',
815
+ '\f079' => 'retweet',
816
+ '\f157' => 'rmb',
817
+ '\f018' => 'road',
818
+ '\f135' => 'rocket',
819
+ '\f0e2' => 'rotate-left',
820
+ '\f01e' => 'rotate-right',
821
+ '\f158' => 'rouble',
822
+ '\f09e' => 'rss',
823
+ '\f143' => 'rss-square',
824
+ '\f158' => 'rub',
825
+ '\f158' => 'ruble',
826
+ '\f156' => 'rupee',
827
+ '\f0c7' => 'save',
828
+ '\f0c4' => 'scissors',
829
+ '\f002' => 'search',
830
+ '\f010' => 'search-minus',
831
+ '\f00e' => 'search-plus',
832
+ '\f213' => 'sellsy',
833
+ '\f1d8' => 'send',
834
+ '\f1d9' => 'send-o',
835
+ '\f233' => 'server',
836
+ '\f064' => 'share',
837
+ '\f1e0' => 'share-alt',
838
+ '\f1e1' => 'share-alt-square',
839
+ '\f14d' => 'share-square',
840
+ '\f045' => 'share-square-o',
841
+ '\f20b' => 'shekel',
842
+ '\f20b' => 'sheqel',
843
+ '\f132' => 'shield',
844
+ '\f21a' => 'ship',
845
+ '\f214' => 'shirtsinbulk',
846
+ '\f07a' => 'shopping-cart',
847
+ '\f090' => 'sign-in',
848
+ '\f08b' => 'sign-out',
849
+ '\f012' => 'signal',
850
+ '\f215' => 'simplybuilt',
851
+ '\f0e8' => 'sitemap',
852
+ '\f216' => 'skyatlas',
853
+ '\f17e' => 'skype',
854
+ '\f198' => 'slack',
855
+ '\f1de' => 'sliders',
856
+ '\f1e7' => 'slideshare',
857
+ '\f118' => 'smile-o',
858
+ '\f1e3' => 'soccer-ball-o',
859
+ '\f0dc' => 'sort',
860
+ '\f15d' => 'sort-alpha-asc',
861
+ '\f15e' => 'sort-alpha-desc',
862
+ '\f160' => 'sort-amount-asc',
863
+ '\f161' => 'sort-amount-desc',
864
+ '\f0de' => 'sort-asc',
865
+ '\f0dd' => 'sort-desc',
866
+ '\f0dd' => 'sort-down',
867
+ '\f162' => 'sort-numeric-asc',
868
+ '\f163' => 'sort-numeric-desc',
869
+ '\f0de' => 'sort-up',
870
+ '\f1be' => 'soundcloud',
871
+ '\f197' => 'space-shuttle',
872
+ '\f110' => 'spinner',
873
+ '\f1b1' => 'spoon',
874
+ '\f1bc' => 'spotify',
875
+ '\f0c8' => 'square',
876
+ '\f096' => 'square-o',
877
+ '\f18d' => 'stack-exchange',
878
+ '\f16c' => 'stack-overflow',
879
+ '\f005' => 'star',
880
+ '\f089' => 'star-half',
881
+ '\f123' => 'star-half-empty',
882
+ '\f123' => 'star-half-full',
883
+ '\f123' => 'star-half-o',
884
+ '\f006' => 'star-o',
885
+ '\f1b6' => 'steam',
886
+ '\f1b7' => 'steam-square',
887
+ '\f048' => 'step-backward',
888
+ '\f051' => 'step-forward',
889
+ '\f0f1' => 'stethoscope',
890
+ '\f04d' => 'stop',
891
+ '\f21d' => 'street-view',
892
+ '\f0cc' => 'strikethrough',
893
+ '\f1a4' => 'stumbleupon',
894
+ '\f1a3' => 'stumbleupon-circle',
895
+ '\f12c' => 'subscript',
896
+ '\f239' => 'subway',
897
+ '\f0f2' => 'suitcase',
898
+ '\f185' => 'sun-o',
899
+ '\f12b' => 'superscript',
900
+ '\f1cd' => 'support',
901
+ '\f0ce' => 'table',
902
+ '\f10a' => 'tablet',
903
+ '\f0e4' => 'tachometer',
904
+ '\f02b' => 'tag',
905
+ '\f02c' => 'tags',
906
+ '\f0ae' => 'tasks',
907
+ '\f1ba' => 'taxi',
908
+ '\f1d5' => 'tencent-weibo',
909
+ '\f120' => 'terminal',
910
+ '\f034' => 'text-height',
911
+ '\f035' => 'text-width',
912
+ '\f00a' => 'th',
913
+ '\f009' => 'th-large',
914
+ '\f00b' => 'th-list',
915
+ '\f08d' => 'thumb-tack',
916
+ '\f165' => 'thumbs-down',
917
+ '\f088' => 'thumbs-o-down',
918
+ '\f087' => 'thumbs-o-up',
919
+ '\f164' => 'thumbs-up',
920
+ '\f145' => 'ticket',
921
+ '\f00d' => 'times',
922
+ '\f057' => 'times-circle',
923
+ '\f05c' => 'times-circle-o',
924
+ '\f043' => 'tint',
925
+ '\f150' => 'toggle-down',
926
+ '\f191' => 'toggle-left',
927
+ '\f204' => 'toggle-off',
928
+ '\f205' => 'toggle-on',
929
+ '\f152' => 'toggle-right',
930
+ '\f151' => 'toggle-up',
931
+ '\f238' => 'train',
932
+ '\f224' => 'transgender',
933
+ '\f225' => 'transgender-alt',
934
+ '\f1f8' => 'trash',
935
+ '\f014' => 'trash-o',
936
+ '\f1bb' => 'tree',
937
+ '\f181' => 'trello',
938
+ '\f091' => 'trophy',
939
+ '\f0d1' => 'truck',
940
+ '\f195' => 'try',
941
+ '\f1e4' => 'tty',
942
+ '\f173' => 'tumblr',
943
+ '\f174' => 'tumblr-square',
944
+ '\f195' => 'turkish-lira',
945
+ '\f1e8' => 'twitch',
946
+ '\f099' => 'twitter',
947
+ '\f081' => 'twitter-square',
948
+ '\f0e9' => 'umbrella',
949
+ '\f0cd' => 'underline',
950
+ '\f0e2' => 'undo',
951
+ '\f19c' => 'university',
952
+ '\f127' => 'unlink',
953
+ '\f09c' => 'unlock',
954
+ '\f13e' => 'unlock-alt',
955
+ '\f0dc' => 'unsorted',
956
+ '\f093' => 'upload',
957
+ '\f155' => 'usd',
958
+ '\f007' => 'user',
959
+ '\f0f0' => 'user-md',
960
+ '\f234' => 'user-plus',
961
+ '\f21b' => 'user-secret',
962
+ '\f235' => 'user-times',
963
+ '\f0c0' => 'users',
964
+ '\f221' => 'venus',
965
+ '\f226' => 'venus-double',
966
+ '\f228' => 'venus-mars',
967
+ '\f237' => 'viacoin',
968
+ '\f03d' => 'video-camera',
969
+ '\f194' => 'vimeo-square',
970
+ '\f1ca' => 'vine',
971
+ '\f189' => 'vk',
972
+ '\f027' => 'volume-down',
973
+ '\f026' => 'volume-off',
974
+ '\f028' => 'volume-up',
975
+ '\f071' => 'warning',
976
+ '\f1d7' => 'wechat',
977
+ '\f18a' => 'weibo',
978
+ '\f1d7' => 'weixin',
979
+ '\f232' => 'whatsapp',
980
+ '\f193' => 'wheelchair',
981
+ '\f1eb' => 'wifi',
982
+ '\f17a' => 'windows',
983
+ '\f159' => 'won',
984
+ '\f19a' => 'wordpress',
985
+ '\f0ad' => 'wrench',
986
+ '\f168' => 'xing',
987
+ '\f169' => 'xing-square',
988
+ '\f19e' => 'yahoo',
989
+ '\f1e9' => 'yelp',
990
+ '\f157' => 'yen',
991
+ '\f167' => 'youtube',
992
+ '\f16a' => 'youtube-play',
993
+ '\f166' => 'youtube-square',
994
+ ),
995
+
996
+ 'awesome_icons_socials' =>array(
997
+ 'f170' => 'adn',
998
+ 'f17b' => 'android',
999
+ 'f179' => 'apple',
1000
+ 'f171' => 'bitbucket',
1001
+ 'f171' => 'bitbucket-square',
1002
+ 'f02e' => 'bookmark',
1003
+ 'f097' => 'bookmark-o',
1004
+ 'f15a' => 'btc',
1005
+ 'f13c' => 'css3',
1006
+ 'f17d' => 'dribble',
1007
+ 'f16b' => 'dropbox',
1008
+ 'f09a' => 'facebook',
1009
+ 'f082' => 'facebook-square',
1010
+ 'f16e' => 'flickr',
1011
+ 'f180' => 'foursquare',
1012
+ 'f09b'=> 'github' ,
1013
+ 'f113'=> 'github-alt',
1014
+ 'f092' => 'github-square',
1015
+ 'f184' => 'gittip',
1016
+ 'f0d5' => 'google-plus',
1017
+ 'f0d4' => 'google-plus-square',
1018
+ 'f13b' => 'html5',
1019
+ 'f16d' => 'instagram',
1020
+ 'f0e1' => 'linkedin',
1021
+ 'f08c' => 'linkedin-square',
1022
+ 'f17c' => 'Linux',
1023
+ 'f136' => 'maxcdn',
1024
+ 'f18c' => 'pagelines',
1025
+ 'f0d2' => 'pinterest',
1026
+ 'f0d3' => 'pinterest-square',
1027
+ 'f18b' => 'renren',
1028
+ 'f09e' => 'rss',
1029
+ 'f17e' => 'skype',
1030
+ 'f18d' => 'stack-exchange',
1031
+ 'f16c' => 'stack-overflow',
1032
+ 'f181' => 'trello',
1033
+ 'f173' => 'tumblr',
1034
+ 'f174' => 'Tumblr Square',
1035
+ 'f099' => 'twitter',
1036
+ 'f081' => 'twitter-square',
1037
+ 'f194' => 'vimeo-square',
1038
+ 'f189' => 'vk',
1039
+ 'f18a' => 'weibo',
1040
+ 'f17a' => 'windows',
1041
+ 'f168' => 'xing',
1042
+ 'f169' => 'xing-square',
1043
+ 'f167' => 'youtube'
1044
+ ),
1045
+ 'header_backgrounds' => array(),
1046
+ 'body_backgrounds' => array(),
1047
+
1048
+ // tags used in theme options (e.g. %tag%) to have some common informations
1049
+ 'tag' => array( //'themeurl' => get_template_directory_uri()
1050
+ ),
1051
+
1052
+ 'cycle_fx' => array(
1053
+ 'blindX' => 'blindX', 'blindY' => 'blindY', 'blindZ' => 'blindZ', 'cover' => 'cover', 'curtainX' => 'curtainX',
1054
+ 'curtainY' => 'curtainY', 'fade' => 'fade', 'fadeZoom' => 'fadeZoom', 'growX' => 'growX', 'growY' => 'growY',
1055
+ 'scrollUp' => 'scrollUp', 'scrollDown' => 'scrollDown', 'scrollLeft' => 'scrollLeft', 'scrollRight' => 'scrollRight', 'scrollHorz' => 'scrollHorz',
1056
+ 'shuffle' => 'shuffle', 'slideX' => 'slideX', 'slideY' => 'slideY', 'toss' => 'toss', 'turnUp' => 'turnUp',
1057
+ 'turnLeft' => 'turnLeft', 'turnRight' => 'turnRight', 'uncover' => 'uncover', 'wipe' => 'wipe', 'zoom' => 'zoom',
1058
+ 'none' => 'none', 'turnDown' => 'turnDown', 'scrollVert' => 'scrollVert'
1059
+ ),
1060
+
1061
+ 'animate' => array(
1062
+ '' => "none",
1063
+ "bounce" => "bounce",
1064
+ "flash" =>"flash",
1065
+ "pulse" =>"pulse",
1066
+ //"rubberBand"=>"rubberBand",
1067
+ "shake" =>"shake",
1068
+ "swing"=>"swing",
1069
+ "tada" =>"tada",
1070
+ "wobble"=>"wobble",
1071
+ "bounceIn"=>"bounceIn",
1072
+ "bounceInDown"=>"bounceInDown",
1073
+ "bounceInLeft"=>"bounceInLeft",
1074
+ "bounceInRight"=>"bounceInRight",
1075
+ "bounceInUp"=>"bounceInUp",
1076
+ "fadeIn"=>"fadeIn",
1077
+ "fadeInDown"=>"fadeInDown",
1078
+ "fadeInDownBig"=>"fadeInDownBig",
1079
+ "fadeInLeft"=>"fadeInLeft",
1080
+ "fadeInLeftBig"=>"fadeInLeftBig",
1081
+ "fadeInRight"=>"fadeInRight",
1082
+ "fadeInRightBig"=>"fadeInRightBig",
1083
+ "fadeInUp"=>"fadeInUp",
1084
+ "fadeInUpBig"=>"fadeInUpBig",
1085
+ "flip"=>"flip",
1086
+ "flipInX"=>"flipInX",
1087
+ "flipInY"=>"flipInY",
1088
+ "lightSpeedIn"=>"lightSpeedIn",
1089
+ "rotateIn"=>"rotateIn",
1090
+ "rotateInDownLeft"=>"rotateInDownLeft",
1091
+ "rotateInDownRight"=>"rotateInDownRight",
1092
+ "rotateInUpLeft"=>"rotateInUpLeft",
1093
+ "rotateInUpRight"=>"rotateInUpRight",
1094
+ //"slideInDown"=>"slideInDown",
1095
+ //"slideInLeft"=>"slideInLeft",
1096
+ //"slideInRight"=>"slideInRight",
1097
+ "rollIn"=>"rollIn",
1098
+ ),
1099
+
1100
+ 'easings' => array(
1101
+ FALSE => 'none',
1102
+ 'easeInQuad' => 'easeInQuad',
1103
+ 'easeOutQuad' => 'easeOutQuad',
1104
+ 'easeInOutQuad' => 'easeInOutQuad',
1105
+ 'easeInCubic' => 'easeInCubic',
1106
+ 'easeOutCubic' => 'easeOutCubic',
1107
+ 'easeInOutCubic' => 'easeInOutCubic',
1108
+ 'easeInQuart' => 'easeInQuart',
1109
+ 'easeOutQuart' => 'easeOutQuart',
1110
+ 'easeInOutQuart' => 'easeInOutQuart',
1111
+ 'easeInQuint' => 'easeInQuint',
1112
+ 'easeOutQuint' => 'easeOutQuint',
1113
+ 'easeInOutQuint' => 'easeInOutQuint',
1114
+ 'easeInSine' => 'easeInSine',
1115
+ 'easeOutSine' => 'easeOutSine',
1116
+ 'easeInOutSine' => 'easeInOutSine',
1117
+ 'easeInExpo' => 'easeInExpo',
1118
+ 'easeOutExpo' => 'easeOutExpo',
1119
+ 'easeInOutExpo' => 'easeInOutExpo',
1120
+ 'easeInCirc' => 'easeInCirc',
1121
+ 'easeOutCirc' => 'easeOutCirc',
1122
+ 'easeInOutCirc' => 'easeInOutCirc',
1123
+ 'easeInElastic' => 'easeInElastic',
1124
+ 'easeOutElastic' => 'easeOutElastic',
1125
+ 'easeInOutElastic' => 'easeInOutElastic',
1126
+ 'easeInBack' => 'easeInBack',
1127
+ 'easeOutBack' => 'easeOutBack',
1128
+ 'easeInOutBack' => 'easeInOutBack',
1129
+ 'easeInBounce' => 'easeInBounce',
1130
+ 'easeOutBounce' => 'easeOutBounce',
1131
+ 'easeInOutBounce' => 'easeInOutBounce'
1132
+ )
1133
+ );
1134
+
1135
+ /**
1136
+ * Get configuration array
1137
+ *
1138
+ * @return array
1139
+ */
1140
+ public static function load() {
1141
+ self::_loadThemeInfo();
1142
+ //ksort( self::$_config['awesome_icons'] );
1143
+
1144
+ return self::$_config;
1145
+ }
1146
+
1147
+ /**
1148
+ * Return theme data
1149
+ *
1150
+ * First the method checks if the wp_get_theme() function exists (WP 3.4.0 at least).
1151
+ * If not, the method calls the deprecated function get_template_directory()
1152
+ *
1153
+ * @return array
1154
+ */
1155
+ protected static function _loadThemeInfo() {
1156
+ $theme = wp_get_theme();
1157
+
1158
+ self::$_config['theme'] = array(
1159
+ 'name' => $theme->Name,
1160
+ 'description' => $theme->Description,
1161
+ 'author' => $theme->Author,
1162
+ 'authoruri' => $theme->{'Author URI'},
1163
+ 'version' => $theme->Version,
1164
+ 'template' => $theme->Template,
1165
+ 'status' => $theme->Status,
1166
+ 'tags' => $theme->Tags
1167
+ );
1168
+ }
1169
+
1170
+
1171
+ public function init() {
1172
+ self::$_config['header_backgrounds'] = apply_filters( 'yit_header_backgrounds', self::$_config['header_backgrounds'] );
1173
+ self::$_config['body_backgrounds'] = apply_filters( 'yit_body_backgrounds', self::$_config['body_backgrounds'] );
1174
+ }
1175
+
1176
+ /**
1177
+ * Return the font awesome array icon
1178
+ *
1179
+ * @return string Array
1180
+ * @access public
1181
+ * @since 1.0.0
1182
+ */
1183
+ public static function get_awesome_icons() {
1184
+ return self::$_config['awesome_icons'];
1185
+ }
1186
+
1187
+ /**
1188
+ * Return the font awesome array socials icon
1189
+ *
1190
+ * @return string Array
1191
+ * @access public
1192
+ * @since 1.0.0
1193
+ */
1194
+ public static function get_awesome_icons_socials() {
1195
+ return self::$_config['awesome_icons_socials'];
1196
+ }
1197
+
1198
+
1199
+ /**
1200
+ * Return the list of icons
1201
+ *
1202
+ * @return string Array
1203
+ * @access public
1204
+ * @since 1.0.0
1205
+ */
1206
+ public static function get_icon_list() {
1207
+
1208
+ $standard_icon_list = array(
1209
+ 'FontAwesome' => self::$_config['awesome_icons2']
1210
+ );
1211
+
1212
+ return apply_filters( 'yit_icon_list', $standard_icon_list );
1213
+ }
1214
+
1215
+ /**
1216
+ * Return the data of icon
1217
+ *
1218
+ * @return string Array
1219
+ * @access public
1220
+ * @since 1.0.0
1221
+ */
1222
+ public static function get_icon( $icon ) {
1223
+
1224
+ $icon_list = self::get_icon_list();
1225
+ $icon_data = '';
1226
+ if ( $icon != '' ) {
1227
+ $ic = explode( ':', $icon );
1228
+ $icon_code = array_search( $ic[1], $icon_list[$ic[0]] );
1229
+
1230
+ if( $icon_code ){
1231
+ $icon_code = ( strpos( $icon_code, '\\' ) === 0 ) ? '&#x' . substr( $icon_code, 1 ) . ';' : $icon_code;
1232
+ }
1233
+
1234
+ $icon_data = 'data-font="' . $ic[0] . '" data-key="' . $ic[1] . '" data-icon="' . $icon_code . '"';
1235
+ }
1236
+
1237
+ return $icon_data;
1238
+ }
1239
+
1240
+
1241
+ /*
1242
+ * Return the code of the relative awesome class name
1243
+ *
1244
+ * @return string
1245
+ * @access public
1246
+ * @since 1.0.0
1247
+ */
1248
+ public static function get_awesome_icons_code_by_value($class){
1249
+ $awesome_icons=self::$_config['awesome_icons'];
1250
+ foreach($awesome_icons as $key => $value){
1251
+ if($class==$value) {
1252
+ return $key;
1253
+ }
1254
+ }
1255
+
1256
+ return "";
1257
+ }
1258
+ }
1259
+
1260
+ endif;
plugin-fw/lib/yit-plugin-gradients.php ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Your Inspiration Themes
4
+ *
5
+ * In this files there is a collection of a functions useful for the core
6
+ * of the framework.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Your Inspiration Themes
10
+ * @author Your Inspiration Themes Team <info@yithemes.com>
11
+ *
12
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
13
+ * that is bundled with this package in the file LICENSE.txt.
14
+ * It is also available through the world-wide-web at this URL:
15
+ * http://www.gnu.org/licenses/gpl-3.0.txt
16
+ */
17
+
18
+ /**
19
+ * Handles colors
20
+ *
21
+ * @since 1.0
22
+ */
23
+ /**
24
+ * Generates CSS 3 gradients for all browsers.
25
+ *
26
+ * @since 1.0
27
+ */
28
+
29
+ if ( ! class_exists( 'YIT_Gradients' ) ) {
30
+
31
+ class YIT_Gradients {
32
+
33
+ /**
34
+ * An array of colors to use for a gradient.
35
+ *
36
+ * @var array
37
+ * @since 1.0
38
+ */
39
+ public $colors_gradient = array();
40
+
41
+ /**
42
+ * Set properties
43
+ *
44
+ * @param string $key
45
+ * @param $value
46
+ *
47
+ * @internal param array $colors_gradient
48
+ * @return void
49
+ * @since 1.0
50
+ */
51
+ public function set( $key, $value ) {
52
+ if ( property_exists( $this, $key ) ) {
53
+ $this->{$key} = $value;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Get properties
59
+ *
60
+ * @param string $key
61
+ *
62
+ * @return mixed
63
+ * @since 1.0
64
+ */
65
+ public function get( $key ) {
66
+ if ( property_exists( $this, $key ) ) {
67
+ return $this->{$key};
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Add a color to use in a gradient.
73
+ *
74
+ * @param string $color
75
+ * @param int $position
76
+ *
77
+ * @return void
78
+ * @since 1.0
79
+ */
80
+ public function add_color_gradient( $color, $position ) {
81
+ $the_color['color'] = $color;
82
+ $the_color['position'] = $position;
83
+
84
+ array_push( $this->colors_gradient, $the_color );
85
+ }
86
+
87
+ /**
88
+ * Generate the CSS code for a gradient.
89
+ *
90
+ * @param string $role
91
+ * @param string $direction
92
+ *
93
+ * @return string|bool
94
+ * @since 1.0
95
+ */
96
+ public function gradient( $role, $direction ) {
97
+ if ( ! empty( $this->colors_gradient ) ) {
98
+
99
+ $css = array(
100
+ 'old' => $this->_make_old_gradient( $this->colors_gradient[0]['color'] ), //old browser
101
+ 'ff3' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'moz' ), //firefox 3.6+
102
+ 'chr_saf4' => $this->_make_chr_saf4_gradient( $this->colors_gradient, $direction ), //chrome and safari4+
103
+ 'chr10_saf5' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'webkit' ), //chrome10+ and safari5+
104
+ 'opera' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'o' ), //opera11.10+
105
+ 'ie10' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'ms' ), //internet explorer 10+
106
+ 'w3c' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'w3c' ), //w3c
107
+ 'ie6_9' => $this->_make_ie6_gradient( $this->colors_gradient, $direction ) //ie6-9
108
+ );
109
+
110
+ $css = $role . '{' . implode( ';', $css ) . '}';
111
+
112
+ $this->colors_gradient = array();
113
+
114
+ return $css;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Reverse a gradient. This method should be used only before calling ::make_gradient(). Otherwise it will not works.
120
+ *
121
+ * @return void
122
+ * @since 1.0
123
+ */
124
+ public function reverse_gradient() {
125
+ $colors_gradient = array_reverse( $this->get( 'colors_gradient' ) );
126
+
127
+ for ( $i = 0; $i < count( $colors_gradient ); $i ++ ) {
128
+ $colors_gradient[$i]['position'] = 100 - $colors_gradient[$i]['position'];
129
+ }
130
+
131
+ $this->set( 'colors_gradient', $colors_gradient );
132
+ }
133
+
134
+ /**
135
+ * Generate the CSS code for a gradient.
136
+ *
137
+ * @param string $role
138
+ * @param string $direction
139
+ *
140
+ * @return string|bool
141
+ * @since 1.0
142
+ */
143
+ public function get_gradient( $role, $direction ) {
144
+ return $this->gradient( $role, $direction );
145
+ }
146
+
147
+ /**
148
+ * Generate the CSS code for a gradient.
149
+ *
150
+ * @param string $role
151
+ * @param string $direction
152
+ *
153
+ * @return void
154
+ * @since 1.0
155
+ */
156
+ public function the_gradient( $role, $direction ) {
157
+ echo $this->get_gradient( $role, $direction );
158
+ }
159
+
160
+ /**
161
+ * Generate the CSS code for a gradient.
162
+ *
163
+ * @param string $role
164
+ * @param string $from
165
+ * @param string $to
166
+ * @param string $direction
167
+ *
168
+ * @return string|bool
169
+ * @since 1.0
170
+ */
171
+ public function gradient_from_to( $role, $from, $to, $direction ) {
172
+
173
+ $colors = array(
174
+ array(
175
+ 'color' => $from,
176
+ 'position' => 0
177
+ ),
178
+ array(
179
+ 'color' => $to,
180
+ 'position' => 100
181
+ ),
182
+ );
183
+
184
+ $this->set( 'colors_gradient', $colors );
185
+ return $this->get_gradient( $role, $direction );
186
+ }
187
+
188
+ /**
189
+ * Generate the CSS code for a gradient.
190
+ *
191
+ * @param string $role
192
+ * @param string $color
193
+ * @param string $direction
194
+ * @param int|string $factor
195
+ *
196
+ * @return string|bool
197
+ * @since 1.0
198
+ */
199
+ public function gradient_darker( $role, $color, $direction, $factor = 30 ) {
200
+
201
+ $colors = array(
202
+ array(
203
+ 'color' => $color,
204
+ 'position' => 0
205
+ ),
206
+ array(
207
+ 'color' => $this->hex_darker( $color, $factor ),
208
+ 'position' => 100
209
+ ),
210
+ );
211
+
212
+ $this->set( 'colors_gradient', $colors );
213
+ return $this->get_gradient( $role, $direction );
214
+ }
215
+
216
+ /**
217
+ * Generate the CSS code for a gradient.
218
+ *
219
+ * @param string $role
220
+ * @param string $color
221
+ * @param string $direction
222
+ * @param int|string $factor
223
+ *
224
+ * @return string|bool
225
+ * @since 1.0
226
+ */
227
+ public function gradient_lighter( $role, $color, $direction, $factor = 30 ) {
228
+
229
+ $colors = array(
230
+ array(
231
+ 'color' => $color,
232
+ 'position' => 0
233
+ ),
234
+ array(
235
+ 'color' => $this->hex_lighter( $color, $factor ),
236
+ 'position' => 100
237
+ ),
238
+ );
239
+
240
+ $this->set( 'colors_gradient', $colors );
241
+ return $this->get_gradient( $role, $direction );
242
+ }
243
+
244
+ /**
245
+ * Generate the CSS code for a gradient that not supports gradients (add only a background color).
246
+ *
247
+ * @param $color
248
+ *
249
+ * @internal param string $role
250
+ * @return string|bool
251
+ * @access private
252
+ * @since 1.0
253
+ */
254
+ private function _make_old_gradient( $color ) {
255
+ return 'background:' . $color;
256
+ }
257
+
258
+ /**
259
+ * Generate the CSS code for a gradient in IE6-9.
260
+ *
261
+ * @param $colors
262
+ * @param $direction
263
+ *
264
+ * @internal param string $role
265
+ * @return string|bool
266
+ * @access private
267
+ * @since 1.0
268
+ */
269
+ private function _make_ie6_gradient( $colors, $direction ) {
270
+ $css = 'filter:progid:DXImageTransform.Microsoft.gradient(';
271
+ $css .= 'startColorstr=\'' . $colors[0]['color'] . '\',';
272
+ $css .= 'endColorstr=\'' . $colors[count( $colors ) - 1]['color'] . '\',';
273
+
274
+ if ( $direction == 'horizontal' ) {
275
+ $css .= 'GradientType=1';
276
+ }
277
+ else {
278
+ $css .= 'GradientType=0';
279
+ } //vertical
280
+
281
+ $css .= ')';
282
+
283
+ return $css;
284
+ }
285
+
286
+ /**
287
+ * Make the CSS 3 for a gradient in modern browsers( FF3.6+, Chrome, Safari5+, Opera11.10+, IE10+ )
288
+ *
289
+ * @param array $colors
290
+ * @param string $direction
291
+ * @param $browser
292
+ *
293
+ * @return string
294
+ * @access private
295
+ * @since 1.0
296
+ */
297
+ private function _make_modern_gradient( $colors, $direction, $browser ) {
298
+ $css = 'background:';
299
+
300
+ //Add the browser suffix
301
+ if ( $browser != 'w3c' ) {
302
+ $browser = '-' . $browser . '-';
303
+ }
304
+ else {
305
+ $browser = '';
306
+ }
307
+
308
+ switch ( $direction ) {
309
+ case 'vertical' :
310
+ $css .= $browser . 'linear-gradient(top,';
311
+ break;
312
+ case 'horizontal' :
313
+ $css .= $browser . 'linear-gradient(left,';
314
+ break;
315
+ case 'diagonal-bottom':
316
+ $css .= $browser . 'linear-gradient(-45deg,';
317
+ break;
318
+ case 'diagonal-top' :
319
+ $css .= $browser . 'linear-gradient(45deg,';
320
+ break;
321
+ case 'radial' :
322
+ $css .= $browser . 'radial-gradient(center, ellipse cover,';
323
+ break;
324
+ }
325
+
326
+ foreach ( $colors as $stop ) {
327
+ $css .= $stop['color'] . ' ' . $stop['position'] . '%, ';
328
+ }
329
+
330
+ $css = rtrim( $css );
331
+ $css = rtrim( $css, ',' );
332
+ $css .= ')';
333
+
334
+ return $css;
335
+ }
336
+
337
+ /**
338
+ * Make the CSS 3 for a gradient in Chrome and Safari 4+
339
+ *
340
+ * @param array $colors
341
+ * @param string $direction
342
+ *
343
+ * @return string
344
+ * @access private
345
+ * @since 1.0
346
+ */
347
+ private function _make_chr_saf4_gradient( $colors, $direction ) {
348
+ $css = 'background:';
349
+
350
+ switch ( $direction ) {
351
+ case 'vertical' :
352
+ $css .= '-webkit-gradient(linear,left top,left bottom,';
353
+ break;
354
+ case 'horizontal' :
355
+ $css .= '-webkit-gradient(linear,left top,right top,';
356
+ break;
357
+ case 'diagonal-bottom':
358
+ $css .= '-webkit-gradient(linear,left top,right bottom,';
359
+ break;
360
+ case 'diagonal-top' :
361
+ $css .= '-webkit-gradient(linear,left bottom,right top,';
362
+ break;
363
+ case 'radial' :
364
+ $css .= '-webkit-gradient(radial,center center, 0px, center center, 100%,';
365
+ break;
366
+ }
367
+
368
+ foreach ( $colors as $stop ) {
369
+ $css .= 'color-stop(' . $stop['position'] . '%, ' . $stop['color'] . '), ';
370
+ }
371
+
372
+ $css = rtrim( $css );
373
+ $css = rtrim( $css, ',' );
374
+ $css .= ')';
375
+
376
+ return $css;
377
+ }
378
+
379
+
380
+ /**
381
+ * Return an instance of the model called
382
+ *
383
+ * @param string $class The name of class that I want the instance
384
+ *
385
+ * @since 2.0.0
386
+ * @author Simone D'Amico <simone.damico@yithemes.com>
387
+ * @return mixed
388
+ */
389
+ public function getModel( $class ) {
390
+ return YIT_Registry::get_instance()->$class;
391
+ }
392
+
393
+
394
+ /**
395
+ * Return a color darker then $color.
396
+ *
397
+ * @param string $color
398
+ * @param int $factor
399
+ *
400
+ * @return string
401
+ * @since 1.0
402
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
403
+ */
404
+ public function hex_darker( $color, $factor = 30 ) {
405
+ $color = str_replace( '#', '', $color );
406
+
407
+ $base['R'] = hexdec( substr( $color, 0, 2 ) );
408
+ $base['G'] = hexdec( substr( $color, 2, 2 ) );
409
+ $base['B'] = hexdec( substr( $color, 4, 2 ) );
410
+
411
+ $color = '#';
412
+
413
+ foreach ( $base as $k => $v ) {
414
+ $amount = $v / 100;
415
+ $amount = round( $amount * $factor );
416
+ $new_decimal = $v - $amount;
417
+
418
+ $new_hex_component = dechex( $new_decimal );
419
+
420
+ if ( strlen( $new_hex_component ) < 2 ) {
421
+ $new_hex_component = "0" . $new_hex_component;
422
+ }
423
+
424
+ $color .= $new_hex_component;
425
+ }
426
+
427
+ return $color;
428
+ }
429
+
430
+ /**
431
+ * Return a color lighter then $color.
432
+ *
433
+ * @param string $color
434
+ * @param int $factor
435
+ *
436
+ * @return string
437
+ * @since 1.0
438
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
439
+ */
440
+ public function hex_lighter( $color, $factor = 30 ) {
441
+ $color = str_replace( '#', '', $color );
442
+
443
+ $base['R'] = hexdec( $color{0} . $color{1} );
444
+ $base['G'] = hexdec( $color{2} . $color{3} );
445
+ $base['B'] = hexdec( $color{4} . $color{5} );
446
+
447
+ $color = '#';
448
+
449
+ foreach ( $base as $k => $v ) {
450
+ $amount = 255 - $v;
451
+ $amount = $amount / 100;
452
+ $amount = round( $amount * $factor );
453
+ $new_decimal = $v + $amount;
454
+
455
+ $new_hex_component = dechex( $new_decimal );
456
+
457
+ if ( strlen( $new_hex_component ) < 2 ) {
458
+ $new_hex_component = "0" . $new_hex_component;
459
+ }
460
+
461
+ $color .= $new_hex_component;
462
+ }
463
+
464
+ return $color;
465
+ }
466
+
467
+ /**
468
+ * Detect if we must use a color darker or lighter then the background.
469
+ *
470
+ * @param string $color
471
+ * @param string $dark
472
+ * @param string $light
473
+ *
474
+ * @return string
475
+ * @since 1.0
476
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
477
+ */
478
+ public function light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
479
+ $hex = str_replace( '#', '', $color );
480
+
481
+ $c_r = hexdec( substr( $hex, 0, 2 ) );
482
+ $c_g = hexdec( substr( $hex, 2, 2 ) );
483
+ $c_b = hexdec( substr( $hex, 4, 2 ) );
484
+ $brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
485
+
486
+ return ( $brightness > 155 ) ? $dark : $light;
487
+ }
488
+
489
+ /**
490
+ * Detect if we must use a color darker or lighter then the background.
491
+ *
492
+ * @param $hex
493
+ *
494
+ * @internal param string $color
495
+ * @return string
496
+ * @since 1.0
497
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
498
+ */
499
+ public function hex2rgb( $hex ) {
500
+ $hex = str_replace( "#", "", $hex );
501
+
502
+ if ( strlen( $hex ) == 3 ) {
503
+ $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
504
+ $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
505
+ $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
506
+ }
507
+ else {
508
+ $r = hexdec( substr( $hex, 0, 2 ) );
509
+ $g = hexdec( substr( $hex, 2, 2 ) );
510
+ $b = hexdec( substr( $hex, 4, 2 ) );
511
+ }
512
+ $rgb = array( $r, $g, $b );
513
+ //return implode(",", $rgb); // returns the rgb values separated by commas
514
+ return $rgb; // returns an array with the rgb values
515
+ }
516
+
517
+ /**
518
+ * Magic method for this class
519
+ *
520
+ * @param $name string The name of magic property
521
+ *
522
+ * @since 2.0.0
523
+ * @author Simone D'Amico <simone.damico@yithemes.com>
524
+ * @return mixed
525
+ */
526
+ public function __get( $name ) {
527
+ if ( $name == 'request' ) {
528
+ if ( ! $this->_request instanceof YIT_Request ) {
529
+ $this->_request = YIT_Registry::get_instance()->request;
530
+ }
531
+
532
+ return $this->_request;
533
+ }
534
+ }
535
+ }
536
+ }
plugin-fw/lib/yit-plugin-panel-wc.php ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
16
+ /**
17
+ * YIT Plugin Panel for WooCommerce
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
26
+ */
27
+
28
+ class YIT_Plugin_Panel_WooCommerce extends YIT_Plugin_Panel {
29
+
30
+ /**
31
+ * @var string version of class
32
+ */
33
+ public $version = '1.0.0';
34
+
35
+ /**
36
+ * @var array a setting list of parameters
37
+ */
38
+ public $settings = array();
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ protected $_tabs_path_files;
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
50
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
51
+ */
52
+ public function __construct( $args = array() ) {
53
+
54
+ if ( ! empty( $args ) ) {
55
+ $this->settings = $args;
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ if( isset( $this->settings['create_menu_page'] ) && $this->settings[ 'create_menu_page'] ){
59
+ $this->add_menu_page();
60
+ }
61
+ add_action( 'admin_init', array( $this, 'set_default_options') );
62
+ add_action( 'admin_menu', array( $this, 'add_setting_page' ) );
63
+ add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
64
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
65
+ add_action( 'admin_init', array( $this, 'woocommerce_update_options' ) );
66
+ add_filter( 'woocommerce_screen_ids', array( $this, 'add_allowed_screen_id' ) );
67
+
68
+ /* Add VideoBox and InfoBox */
69
+ add_action( 'woocommerce_admin_field_boxinfo', array( $this, 'add_infobox' ), 10, 1 );
70
+ add_action( 'woocommerce_admin_field_videobox', array( $this, 'add_videobox' ), 10, 1 );
71
+ }
72
+ }
73
+
74
+
75
+ /**
76
+ * Show a tabbed panel to setting page
77
+ *
78
+ * a callback function called by add_setting_page => add_submenu_page
79
+ *
80
+ * @return void
81
+ * @since 1.0
82
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
83
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
84
+ */
85
+ public function yit_panel() {
86
+ $additional_info = array(
87
+ 'current_tab' => $this->get_current_tab(),
88
+ 'available_tabs' => $this->settings['admin-tabs'],
89
+ 'default_tab' => $this->get_available_tabs( true ), //get default tabs
90
+ 'page' => $this->settings['page']
91
+ );
92
+
93
+ $additional_info = apply_filters( 'yith_admin_tab_params', $additional_info );
94
+ $additional_info['additional_info'] = $additional_info;
95
+
96
+ extract( $additional_info );
97
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-panel.php' );
98
+ }
99
+
100
+ /**
101
+ * Show a input fields to upload images
102
+ *
103
+ *
104
+ * @return void
105
+ * @since 1.0
106
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
107
+ */
108
+
109
+ public function yit_upload_update( $option_value ) {
110
+ return $option_value;
111
+ }
112
+
113
+ /**
114
+ * Show a input fields to upload images
115
+ *
116
+ *
117
+ * @return void
118
+ * @since 1.0
119
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
120
+ */
121
+
122
+ public function yit_upload( $args = array() ) {
123
+ if ( ! empty( $args ) ) {
124
+ $args['value'] = ( get_option($args['id'])) ? get_option($args['id']) : $args['default'];
125
+ extract( $args );
126
+
127
+ include( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-upload.php' );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Add the plugin woocommerce page settings in the screen ids of woocommerce
133
+ *
134
+ * @param $screen_ids
135
+ *
136
+ * @return mixed
137
+ * @since 1.0.0
138
+ * @author Antonino Scarfì <antonino.scarfi@yithemes.com>
139
+ */
140
+ public function add_allowed_screen_id( $screen_ids ) {
141
+ global $admin_page_hooks;
142
+
143
+ if ( ! isset( $admin_page_hooks[ $this->settings['parent_page'] ] ) ) {
144
+ return $screen_ids;
145
+ }
146
+
147
+ $screen_ids[] = $admin_page_hooks[ $this->settings['parent_page'] ] . '_page_' . $this->settings['page'];
148
+
149
+ return $screen_ids;
150
+ }
151
+
152
+ /**
153
+ * Returns current active tab slug
154
+ *
155
+ * @return string
156
+ * @since 2.0.0
157
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
158
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
159
+ */
160
+ public function get_current_tab() {
161
+ global $pagenow;
162
+ $tabs = $this->get_available_tabs();
163
+
164
+ if ( $pagenow == 'admin.php' && isset( $_REQUEST['tab'] ) && in_array( $_REQUEST['tab'], $tabs ) ) {
165
+ return $_REQUEST['tab'];
166
+ }
167
+ else {
168
+ return $tabs[0];
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Return available tabs
174
+ *
175
+ * read all options and show sections and fields
176
+ *
177
+ * @param bool false for all tabs slug, true for current tab
178
+ *
179
+ * @return mixed Array tabs | String current tab
180
+ * @since 1.0
181
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
182
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
183
+ */
184
+ public function get_available_tabs( $default = false ) {
185
+ $tabs = array_keys( $this->settings['admin-tabs'] );
186
+ return $default ? $tabs[0] : $tabs;
187
+ }
188
+
189
+
190
+ /**
191
+ * Add sections and fields to setting panel
192
+ *
193
+ * read all options and show sections and fields
194
+ *
195
+ * @return void
196
+ * @since 1.0
197
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
198
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
199
+ */
200
+ public function add_fields() {
201
+ $yit_options = $this->get_main_array_options();
202
+ $current_tab = $this->get_current_tab();
203
+
204
+ if ( ! $current_tab ) {
205
+ return;
206
+ }
207
+
208
+ woocommerce_admin_fields( $yit_options[$current_tab] );
209
+ }
210
+
211
+ /**
212
+ * Print the panel content
213
+ *
214
+ * check if the tab is a wc options tab or custom tab and print the content
215
+ *
216
+ * @return void
217
+ * @since 1.0
218
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
219
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
220
+ */
221
+ public function print_panel_content() {
222
+ $yit_options = $this->get_main_array_options();
223
+ $current_tab = $this->get_current_tab();
224
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
225
+
226
+ if ( $custom_tab_action ) {
227
+ $this->print_custom_tab( $custom_tab_action );
228
+ return;
229
+ }
230
+ else {
231
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-form.php' );
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Update options
237
+ *
238
+ * @return void
239
+ * @since 1.0
240
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
241
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
242
+ * @see woocommerce_update_options function
243
+ * @internal fire two action (before and after update): yit_panel_wc_before_update and yit_panel_wc_after_update
244
+ */
245
+ public function woocommerce_update_options() {
246
+
247
+ if ( isset( $_POST['yit_panel_wc_options_nonce'] ) && wp_verify_nonce( $_POST['yit_panel_wc_options_nonce'], 'yit_panel_wc_options_'.$this->settings['page'] ) ) {
248
+
249
+ do_action( 'yit_panel_wc_before_update' );
250
+
251
+ $yit_options = $this->get_main_array_options();
252
+ $current_tab = $this->get_current_tab();
253
+
254
+ woocommerce_update_options( $yit_options[ $current_tab ] );
255
+
256
+ do_action( 'yit_panel_wc_after_update' );
257
+
258
+ } elseif( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'wc-options-reset' ){
259
+
260
+ $yit_options = $this->get_main_array_options();
261
+ $current_tab = $this->get_current_tab();
262
+
263
+ foreach( $yit_options[ $current_tab ] as $id => $option ){
264
+ if( isset( $option['default'] ) ){
265
+ update_option( $option['id'], $option['default'] );
266
+ }
267
+ }
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Add Admin WC Style and Scripts
273
+ *
274
+ * @return void
275
+ * @since 1.0
276
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
277
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
278
+ */
279
+ public function admin_enqueue_scripts() {
280
+ global $woocommerce;
281
+
282
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
283
+
284
+ wp_enqueue_media();
285
+ wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce->version );
286
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $woocommerce->version );
287
+ wp_enqueue_style ( 'wp-jquery-ui-dialog' );
288
+
289
+
290
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
291
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
292
+ wp_enqueue_script( 'woocommerce_settings', $woocommerce->plugin_url() . '/assets/js/admin/settings.min.js', array( 'jquery', 'jquery-ui-datepicker','jquery-ui-dialog', 'jquery-ui-sortable', 'iris', 'chosen' ), $woocommerce->version, true );
293
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.min.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
294
+ wp_localize_script( 'woocommerce_settings', 'woocommerce_settings_params', array(
295
+ 'i18n_nav_warning' => __( 'The changes you have made will be lost if you leave this page.', 'yith-plugin-fw' )
296
+ ) );
297
+ }
298
+
299
+ /**
300
+ * Default options
301
+ *
302
+ * Sets up the default options used on the settings page
303
+ *
304
+ * @access public
305
+ * @return void
306
+ * @since 1.0.0
307
+ */
308
+ public function set_default_options() {
309
+
310
+ $default_options = $this->get_main_array_options();
311
+
312
+ foreach ($default_options as $section) {
313
+ foreach ( $section as $value ) {
314
+ if ( ( isset( $value['std'] ) || isset( $value['default'] ) ) && isset( $value['id'] ) ) {
315
+ $default_value = ( isset( $value['default'] ) ) ? $value['default'] : $value['std'];
316
+
317
+ if ( $value['type'] == 'image_width' ) {
318
+ add_option($value['id'].'_width', $default_value);
319
+ add_option($value['id'].'_height', $default_value);
320
+ } else {
321
+ add_option($value['id'], $default_value);
322
+ }
323
+
324
+ }
325
+
326
+ }
327
+ }
328
+
329
+ }
330
+
331
+
332
+ }
333
+ }
plugin-fw/lib/yit-plugin-panel.php ADDED
@@ -0,0 +1,798 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+ /**
40
+ * @var array
41
+ */
42
+ protected $_tabs_path_files;
43
+
44
+ /**
45
+ * @var array
46
+ */
47
+ private $_main_array_options = array();
48
+
49
+ /**
50
+ * Constructor
51
+ *
52
+ * @since 1.0
53
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
54
+ *
55
+ * @param array $args
56
+ */
57
+ public function __construct( $args = array() ) {
58
+
59
+ if ( ! empty( $args ) ) {
60
+
61
+ $default_args = array(
62
+ 'parent_slug' => 'edit.php?',
63
+ 'page_title' => __( 'Plugin Settings', 'yith-plugin-fw' ),
64
+ 'menu_title' => __( 'Settings', 'yith-plugin-fw' ),
65
+ 'capability' => 'manage_options',
66
+ 'icon_url' => '',
67
+ 'position' => null
68
+ );
69
+
70
+ $this->settings = wp_parse_args( $args, $default_args );
71
+ $this->_tabs_path_files = $this->get_tabs_path_files();
72
+
73
+ if ( isset( $this->settings['create_menu_page'] ) && $this->settings['create_menu_page'] ) {
74
+ $this->add_menu_page();
75
+ }
76
+
77
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
78
+ add_action( 'admin_menu', array( $this, 'add_setting_page' ), 20 );
79
+ add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
80
+ add_action( 'admin_init', array( $this, 'add_fields' ) );
81
+
82
+ }
83
+
84
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
85
+ }
86
+
87
+ /**
88
+ * Add Menu page link
89
+ *
90
+ * @return void
91
+ * @since 1.0
92
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
93
+ */
94
+ public function add_menu_page() {
95
+ $position = apply_filters( 'yit_plugins_menu_item_position', '62.32' );
96
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yith-plugin-fw' ), 'manage_options', 'yit_plugin_panel', NULL, YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png', $position );
97
+ }
98
+
99
+ /**
100
+ * Remove duplicate submenu
101
+ *
102
+ * Submenu page hack: Remove the duplicate YIT Plugin link on subpages
103
+ *
104
+ * @return void
105
+ * @since 1.0
106
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
107
+ */
108
+ public function remove_duplicate_submenu_page() {
109
+ /* === Duplicate Items Hack === */
110
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
111
+ }
112
+
113
+ /**
114
+ * Enqueue script and styles in admin side
115
+ *
116
+ * Add style and scripts to administrator
117
+ *
118
+ * @return void
119
+ * @since 1.0
120
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
121
+ */
122
+ public function admin_enqueue_scripts() {
123
+
124
+ global $wp_scripts;
125
+
126
+ //scripts
127
+ wp_enqueue_media();
128
+ wp_enqueue_script( 'jquery-ui' );
129
+ wp_enqueue_script( 'jquery-ui-core' );
130
+ wp_enqueue_script( 'jquery-ui-slider' );
131
+ wp_enqueue_script( 'jquery-ui-dialog' );
132
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
133
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
134
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
135
+ wp_register_script( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/codemirror.js', array( 'jquery' ), $this->version, true );
136
+ wp_register_script( 'codemirror-javascript', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/javascript.js', array( 'jquery', 'codemirror' ), $this->version, true );
137
+
138
+
139
+ wp_register_style( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/css/codemirror/codemirror.css' );
140
+
141
+ //styles
142
+
143
+ $jquery_version = isset( $wp_scripts->registered['jquery-ui-core']->ver ) ? $wp_scripts->registered['jquery-ui-core']->ver : '1.9.2';
144
+
145
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
146
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $this->version );
147
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
148
+
149
+ wp_enqueue_style( 'jquery-ui-style', '//code.jquery.com/ui/' . $jquery_version . '/themes/smoothness/jquery-ui.css', array(), $jquery_version );
150
+ }
151
+
152
+ /**
153
+ * Register Settings
154
+ *
155
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
156
+ *
157
+ * @return void
158
+ * @since 1.0
159
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
160
+ */
161
+ public function register_settings() {
162
+ register_setting( 'yit_' . $this->settings['parent'] . '_options', 'yit_' . $this->settings['parent'] . '_options', array( $this, 'options_validate' ) );
163
+ }
164
+
165
+ /**
166
+ * Options Validate
167
+ *
168
+ * a callback function called by Register Settings function
169
+ *
170
+ * @param $input
171
+ *
172
+ * @return array validate input fields
173
+ * @since 1.0
174
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
175
+ */
176
+ public function options_validate( $input ) {
177
+
178
+ $current_tab = ! empty( $input['current_tab'] ) ? $input['current_tab'] : 'general';
179
+
180
+ $yit_options = $this->get_main_array_options();
181
+
182
+ // default
183
+ $valid_input = $this->get_options();
184
+
185
+ $submit = ( ! empty( $input['submit-general'] ) ? true : false );
186
+ $reset = ( ! empty( $input['reset-general'] ) ? true : false );
187
+
188
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
189
+ foreach ( $data as $option ) {
190
+ if ( isset( $option['sanitize_call'] ) && isset( $option['id'] ) ) { //yiw_debug($option, false);
191
+ if ( is_array( $option['sanitize_call'] ) ) :
192
+ foreach ( $option['sanitize_call'] as $callback ) {
193
+ if ( is_array( $input[$option['id']] ) ) {
194
+ $valid_input[$option['id']] = array_map( $callback, $input[$option['id']] );
195
+ }
196
+ else {
197
+ $valid_input[$option['id']] = call_user_func( $callback, $input[$option['id']] );
198
+ }
199
+ }
200
+ else :
201
+ if ( is_array( $input[$option['id']] ) ) {
202
+ $valid_input[$option['id']] = array_map( $option['sanitize_call'], $input[$option['id']] );
203
+ }
204
+ else {
205
+ $valid_input[$option['id']] = call_user_func( $option['sanitize_call'], $input[$option['id']] );
206
+ }
207
+ endif;
208
+ }
209
+ else {
210
+ if ( isset( $option['id'] ) ) {
211
+ if ( isset( $input[$option['id']] ) ) {
212
+ $valid_input[$option['id']] = $input[$option['id']];
213
+ }
214
+ else {
215
+ $valid_input[$option['id']] = 'no';
216
+ }
217
+
218
+ }
219
+ }
220
+
221
+ }
222
+ }
223
+
224
+ return $valid_input;
225
+ }
226
+
227
+ /**
228
+ * Add Setting SubPage
229
+ *
230
+ * add Setting SubPage to wordpress administrator
231
+ *
232
+ * @return array validate input fields
233
+ * @since 1.0
234
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
235
+ */
236
+ public function add_setting_page() {
237
+ $this->settings['icon_url'] = isset( $this->settings['icon_url'] ) ? $this->settings['icon_url'] : '';
238
+ $this->settings['position'] = isset( $this->settings['position'] ) ? $this->settings['position'] : null;
239
+ $parent = $this->settings['parent_slug'] . $this->settings['parent_page'];
240
+
241
+ if ( ! empty( $parent ) ) {
242
+ add_submenu_page( $parent, $this->settings['page_title'], $this->settings['menu_title'], $this->settings['capability'], $this->settings['page'], array( $this, 'yit_panel' ) );
243
+ } else {
244
+ add_menu_page( $this->settings['page_title'], $this->settings['menu_title'], $this->settings['capability'], $this->settings['page'], array( $this, 'yit_panel' ), $this->settings['icon_url'], $this->settings['position'] );
245
+ }
246
+ /* === Duplicate Items Hack === */
247
+ $this->remove_duplicate_submenu_page();
248
+ do_action( 'yit_after_add_settings_page' );
249
+ }
250
+
251
+ /**
252
+ * Show a tabbed panel to setting page
253
+ *
254
+ * a callback function called by add_setting_page => add_submenu_page
255
+ *
256
+ * @return void
257
+ * @since 1.0
258
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
259
+ */
260
+ public function yit_panel() {
261
+
262
+ $tabs = '';
263
+ $current_tab = $this->get_current_tab();
264
+ $yit_options = $this->get_main_array_options();
265
+
266
+ // tabs
267
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
268
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
269
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?' . $this->settings['parent_page'] . '&page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
270
+ }
271
+ ?>
272
+ <div id="icon-themes" class="icon32"><br /></div>
273
+ <h2 class="nav-tab-wrapper">
274
+ <?php echo $tabs ?>
275
+ </h2>
276
+ <?php
277
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
278
+ if ( $custom_tab_action ) {
279
+ $this->print_custom_tab( $custom_tab_action );
280
+ return;
281
+ }
282
+ ?>
283
+ <?php $this->print_video_box(); ?>
284
+ <div id="wrap" class="plugin-option">
285
+ <?php $this->message(); ?>
286
+ <h2><?php echo $this->get_tab_title() ?></h2>
287
+ <?php if ( $this->is_show_form() ) : ?>
288
+ <form method="post" action="options.php">
289
+ <?php do_settings_sections( 'yit' ); ?>
290
+ <p>&nbsp;</p>
291
+ <?php settings_fields( 'yit_' . $this->settings['parent'] . '_options' ); ?>
292
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
293
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yith-plugin-fw' ) ?>" style="float:left;margin-right:10px;" />
294
+ </form>
295
+ <form method="post">
296
+ <?php $warning = __( 'If you continue with this action, you will reset all options in this page.', 'yith-plugin-fw' ) ?>
297
+ <input type="hidden" name="yit-action" value="reset" />
298
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset to default', 'yith-plugin-fw' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure?', 'yith-plugin-fw' ) ?>');" />
299
+ </form>
300
+ <p>&nbsp;</p>
301
+ <?php endif ?>
302
+ </div>
303
+ <?php
304
+ }
305
+
306
+ public function is_custom_tab( $options, $current_tab ) {
307
+ foreach ( $options[$current_tab] as $section => $option ) {
308
+ if ( isset( $option['type'] ) && isset( $option['action'] ) && 'custom_tab' == $option['type'] && ! empty( $option['action'] ) ) {
309
+ return $option['action'];
310
+ }
311
+ else {
312
+ return false;
313
+ }
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Fire the action to print the custom tab
319
+ *
320
+ *
321
+ * @param $action Action to fire
322
+ *
323
+ * @return void
324
+ * @since 1.0
325
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
326
+ */
327
+ public function print_custom_tab( $action ) {
328
+ do_action( $action );
329
+ }
330
+
331
+ /**
332
+ * Add sections and fields to setting panel
333
+ *
334
+ * read all options and show sections and fields
335
+ *
336
+ * @return void
337
+ * @since 1.0
338
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
339
+ */
340
+ public function add_fields() {
341
+ $yit_options = $this->get_main_array_options();
342
+ $current_tab = $this->get_current_tab();
343
+
344
+ if ( ! $current_tab ) {
345
+ return;
346
+ }
347
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
348
+ add_settings_section( "yit_settings_{$current_tab}_{$section}", $this->get_section_title( $section ), $this->get_section_description( $section ), 'yit' );
349
+ foreach ( $data as $option ) {
350
+ if ( isset( $option['id'] ) && isset( $option['type'] ) && isset( $option['name'] ) ) {
351
+ add_settings_field( "yit_setting_" . $option['id'], $option['name'], array( $this, 'render_field' ), 'yit', "yit_settings_{$current_tab}_{$section}", array( 'option' => $option, 'label_for' => $this->get_id_field( $option['id'] ) ) );
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+
358
+ /**
359
+ * Add the tabs to admin bar menu
360
+ *
361
+ * set all tabs of settings page on wp admin bar
362
+ *
363
+ * @return void|array return void when capability is false
364
+ * @since 1.0
365
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
366
+ */
367
+ public function add_admin_bar_menu() {
368
+
369
+ global $wp_admin_bar;
370
+
371
+ if ( ! current_user_can( 'manage_options' ) ) {
372
+ return;
373
+ }
374
+
375
+ if ( ! empty( $this->settings['admin_tabs'] ) ) {
376
+ foreach ( $this->settings['admin-tabs'] as $item => $title ) {
377
+
378
+ $wp_admin_bar->add_menu( array(
379
+ 'parent' => $this->settings['parent'],
380
+ 'title' => $title,
381
+ 'id' => $this->settings['parent'] . '-' . $item,
382
+ 'href' => admin_url( 'themes.php' ) . '?page=' . $this->settings['parent_page'] . '&tab=' . $item
383
+ ) );
384
+ }
385
+ }
386
+ }
387
+
388
+
389
+ /**
390
+ * Get current tab
391
+ *
392
+ * get the id of tab showed, return general is the current tab is not defined
393
+ *
394
+ * @return string
395
+ * @since 1.0
396
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
397
+ */
398
+ function get_current_tab() {
399
+ $admin_tabs = array_keys( $this->settings['admin-tabs'] );
400
+
401
+ if ( ! isset( $_GET['page'] ) || $_GET['page'] != $this->settings['page'] ) {
402
+ return false;
403
+ }
404
+ if ( isset( $_REQUEST['yit_tab_options'] ) ) {
405
+ return $_REQUEST['yit_tab_options'];
406
+ }
407
+ elseif ( isset( $_GET['tab'] ) && isset( $this->_tabs_path_files[$_GET['tab']] ) ) {
408
+ return $_GET['tab'];
409
+ }
410
+ elseif ( isset( $admin_tabs[0] ) ) {
411
+ return $admin_tabs[0];
412
+ }
413
+ else {
414
+ return 'general';
415
+ }
416
+ }
417
+
418
+
419
+ /**
420
+ * Message
421
+ *
422
+ * define an array of message and show the content od message if
423
+ * is find in the query string
424
+ *
425
+ * @return void
426
+ * @since 1.0
427
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
428
+ */
429
+ public function message() {
430
+
431
+ $message = array(
432
+ 'element_exists' => $this->get_message( '<strong>' . __( 'The element you have entered already exists. Please, enter another name.', 'yith-plugin-fw' ) . '</strong>', 'error', false ),
433
+ 'saved' => $this->get_message( '<strong>' . __( 'Settings saved', 'yith-plugin-fw' ) . '.</strong>', 'updated', false ),
434
+ 'reset' => $this->get_message( '<strong>' . __( 'Settings reset', 'yith-plugin-fw' ) . '.</strong>', 'updated', false ),
435
+ 'delete' => $this->get_message( '<strong>' . __( 'Element deleted correctly.', 'yith-plugin-fw' ) . '</strong>', 'updated', false ),
436
+ 'updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yith-plugin-fw' ) . '</strong>', 'updated', false ),
437
+ 'settings-updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yith-plugin-fw' ) . '</strong>', 'updated', false ),
438
+ 'imported' => $this->get_message( '<strong>' . __( 'Database imported correctly.', 'yith-plugin-fw' ) . '</strong>', 'updated', false ),
439
+ 'no-imported' => $this->get_message( '<strong>' . __( 'An error has occurred during import. Please try again.', 'yith-plugin-fw' ) . '</strong>', 'error', false ),
440
+ 'file-not-valid' => $this->get_message( '<strong>' . __( 'The added file is not valid.', 'yith-plugin-fw' ) . '</strong>', 'error', false ),
441
+ 'cant-import' => $this->get_message( '<strong>' . __( 'Sorry, import is disabled.', 'yith-plugin-fw' ) . '</strong>', 'error', false ),
442
+ 'ord' => $this->get_message( '<strong>' . __( 'Sorting successful.', 'yith-plugin-fw' ) . '</strong>', 'updated', false )
443
+ );
444
+
445
+ foreach ( $message as $key => $value ) {
446
+ if ( isset( $_GET[$key] ) ) {
447
+ echo $message[$key];
448
+ }
449
+ }
450
+
451
+ }
452
+
453
+ /**
454
+ * Get Message
455
+ *
456
+ * return html code of message
457
+ *
458
+ * @param $message
459
+ * @param string $type can be 'error' or 'updated'
460
+ * @param bool $echo
461
+ *
462
+ * @return void|string
463
+ * @since 1.0
464
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
465
+ */
466
+ public function get_message( $message, $type = 'error', $echo = true ) {
467
+ $message = '<div id="message" class="' . $type . ' fade"><p>' . $message . '</p></div>';
468
+ if ( $echo ) {
469
+ echo $message;
470
+ }
471
+ return $message;
472
+ }
473
+
474
+
475
+ /**
476
+ * Get Tab Path Files
477
+ *
478
+ * return an array with filenames of tabs
479
+ *
480
+ * @return array
481
+ * @since 1.0
482
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
483
+ */
484
+ function get_tabs_path_files() {
485
+
486
+ $option_files_path = $this->settings['options-path'] . '/';
487
+
488
+ $tabs = array();
489
+
490
+ foreach ( ( array ) glob( $option_files_path . '*.php' ) as $filename ) {
491
+ preg_match( '/(.*)-options\.(.*)/', basename( $filename ), $filename_parts );
492
+
493
+ if ( ! isset( $filename_parts[1] ) ) {
494
+ continue;
495
+ }
496
+
497
+ $tab = $filename_parts[1];
498
+
499
+ $tabs[$tab] = $filename;
500
+ }
501
+
502
+ return $tabs;
503
+ }
504
+
505
+ /**
506
+ * Get main array options
507
+ *
508
+ * return an array with all options defined on options-files
509
+ *
510
+ * @return array
511
+ * @since 1.0
512
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
513
+ */
514
+ function get_main_array_options() {
515
+ if ( ! empty( $this->_main_array_options ) ) {
516
+ return $this->_main_array_options;
517
+ }
518
+
519
+ foreach ( $this->settings['admin-tabs'] as $item => $v ) {
520
+ $path = $this->settings['options-path'] . '/' . $item . '-options.php';
521
+ if ( file_exists( $path ) ) {
522
+ $this->_main_array_options = array_merge( $this->_main_array_options, include $path );
523
+ }
524
+ }
525
+
526
+ return $this->_main_array_options;
527
+ }
528
+
529
+
530
+ /**
531
+ * Set an array with all default options
532
+ *
533
+ * put default options in an array
534
+ *
535
+ * @return array
536
+ * @since 1.0
537
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
538
+ */
539
+ public function get_default_options() {
540
+ $yit_options = $this->get_main_array_options();
541
+ $default_options = array();
542
+
543
+ foreach ( $yit_options as $tab => $sections ) {
544
+ foreach ( $sections as $section ) {
545
+ foreach ( $section as $id => $value ) {
546
+ if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
547
+ $default_options[$value['id']] = $value['std'];
548
+ }
549
+ }
550
+ }
551
+ }
552
+
553
+ unset( $yit_options );
554
+ return $default_options;
555
+ }
556
+
557
+
558
+ /**
559
+ * Get the title of the tab
560
+ *
561
+ * return the title of tab
562
+ *
563
+ * @return string
564
+ * @since 1.0
565
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
566
+ */
567
+ function get_tab_title() {
568
+ $yit_options = $this->get_main_array_options();
569
+ $current_tab = $this->get_current_tab();
570
+
571
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
572
+ foreach ( $data as $option ) {
573
+ if ( isset( $option['type'] ) && $option['type'] == 'title' ) {
574
+ return $option['name'];
575
+ }
576
+ }
577
+ }
578
+ }
579
+
580
+ /**
581
+ * Get the title of the section
582
+ *
583
+ * return the title of section
584
+ *
585
+ * @param $section
586
+ *
587
+ * @return string
588
+ * @since 1.0
589
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
590
+ */
591
+ function get_section_title( $section ) {
592
+ $yit_options = $this->get_main_array_options();
593
+ $current_tab = $this->get_current_tab();
594
+
595
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
596
+ if ( isset( $option['type'] ) && $option['type'] == 'section' ) {
597
+ return $option['name'];
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Get the description of the section
604
+ *
605
+ * return the description of section if is set
606
+ *
607
+ * @param $section
608
+ *
609
+ * @return string
610
+ * @since 1.0
611
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
612
+ */
613
+ function get_section_description( $section ) {
614
+ $yit_options = $this->get_main_array_options();
615
+ $current_tab = $this->get_current_tab();
616
+
617
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
618
+ if ( isset( $option['type'] ) && $option['type'] == 'section' && isset( $option['desc'] ) ) {
619
+ return '<p>' . $option['desc'] . '</p>';
620
+ }
621
+ }
622
+ }
623
+
624
+
625
+ /**
626
+ * Show form when necessary
627
+ *
628
+ * return true if 'showform' is not defined
629
+ *
630
+ * @return bool
631
+ * @since 1.0
632
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
633
+ */
634
+ function is_show_form() {
635
+ $yit_options = $this->get_main_array_options();
636
+ $current_tab = $this->get_current_tab();
637
+
638
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
639
+ foreach ( $data as $option ) {
640
+ if ( ! isset( $option['type'] ) || $option['type'] != 'title' ) {
641
+ continue;
642
+ }
643
+ if ( isset( $option['showform'] ) ) {
644
+ return $option['showform'];
645
+ }
646
+ else {
647
+ return true;
648
+ }
649
+ }
650
+ }
651
+ }
652
+
653
+ /**
654
+ * Get name field
655
+ *
656
+ * return a string with the name of the input field
657
+ *
658
+ * @param string $name
659
+ *
660
+ * @return string
661
+ * @since 1.0
662
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
663
+ */
664
+ function get_name_field( $name = '' ) {
665
+ return 'yit_' . $this->settings['parent'] . '_options[' . $name . ']';
666
+ }
667
+
668
+ /**
669
+ * Get id field
670
+ *
671
+ * return a string with the id of the input field
672
+ *
673
+ * @param string $id
674
+ *
675
+ * @return string
676
+ * @since 1.0
677
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
678
+ */
679
+ function get_id_field( $id ) {
680
+ return 'yit_' . $this->settings['parent'] . '_options_' . $id;
681
+ }
682
+
683
+
684
+ /**
685
+ * Render the field showed in the setting page
686
+ *
687
+ * include the file of the option type, if file do not exists
688
+ * return a text area
689
+ *
690
+ * @param array $param
691
+ *
692
+ * @return void
693
+ * @since 1.0
694
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
695
+ */
696
+ function render_field( $param ) {
697
+
698
+ if ( ! empty( $param ) && isset( $param ['option'] ) ) {
699
+ $option = $param ['option'];
700
+ $db_options = $this->get_options();
701
+
702
+ $custom_attributes = array();
703
+
704
+ if ( ! empty( $option['custom_attributes'] ) && is_array( $option['custom_attributes'] ) ) {
705
+ foreach ( $option['custom_attributes'] as $attribute => $attribute_value ) {
706
+ $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';
707
+ }
708
+ }
709
+
710
+ $custom_attributes = implode( ' ', $custom_attributes );
711
+
712
+ $db_value = ( isset( $db_options[$option['id']] ) ) ? $db_options[$option['id']] : '';
713
+ if ( isset( $option['deps'] ) ) {
714
+ $deps = $option['deps'];
715
+ }
716
+ $type = YIT_CORE_PLUGIN_PATH . '/templates/panel/types/' . $option['type'] . '.php';
717
+ if ( file_exists( $type ) ) {
718
+ include $type;
719
+ }
720
+ else {
721
+ do_action( "yit_panel_{$option['type']}", $option, $db_value, $custom_attributes );
722
+ }
723
+ }
724
+ }
725
+
726
+ /**
727
+ * Get options from db
728
+ *
729
+ * return the options from db, if the options aren't defined in the db,
730
+ * get the default options ad add the options in the db
731
+ *
732
+ * @return array
733
+ * @since 1.0
734
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
735
+ */
736
+ public function get_options() {
737
+ $options = get_option( 'yit_' . $this->settings['parent'] . '_options' );
738
+ if ( $options === false || ( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'reset' ) ) {
739
+ $options = $this->get_default_options();
740
+ }
741
+ return $options;
742
+ }
743
+
744
+ /**
745
+ * Show a box panel with specific content in two columns as a new woocommerce type
746
+ *
747
+ *
748
+ * @param array $args
749
+ *
750
+ * @return void
751
+ * @since 1.0
752
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
753
+ */
754
+ public function add_infobox( $args = array() ) {
755
+ if ( ! empty( $args ) ) {
756
+ extract( $args );
757
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/boxinfo.php' );
758
+ }
759
+ }
760
+
761
+ /**
762
+ * Show a box panel with specific content in two columns as a new woocommerce type
763
+ *
764
+ * @param array $args
765
+ *
766
+ * @return void
767
+ * @since 1.0
768
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
769
+ */
770
+ public function add_videobox( $args = array() ) {
771
+ if ( ! empty( $args ) ) {
772
+ extract( $args );
773
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/videobox.php' );
774
+ }
775
+ }
776
+
777
+ /**
778
+ * Fire the action to print the custom tab
779
+ *
780
+ * @return void
781
+ * @since 1.0
782
+ * @author Antonino Scarfì <antonino.scarfi@yithemes.com>
783
+ */
784
+ public function print_video_box() {
785
+ $file = $this->settings['options-path'] . '/video-box.php';
786
+
787
+ if ( ! file_exists( $file ) ) {
788
+ return;
789
+ }
790
+
791
+ $args = include_once( $file );
792
+
793
+ $this->add_videobox( $args );
794
+ }
795
+
796
+ }
797
+
798
+ }
plugin-fw/lib/yit-plugin-subpanel.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_SubPanel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_SubPanel extends YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ private $_main_array_options = array();
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
50
+ */
51
+
52
+ public function __construct( $args = array() ) {
53
+ if ( ! empty( $args ) ) {
54
+ $this->settings = $args;
55
+ $this->settings['parent'] = $this->settings['page'];
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
59
+ add_action( 'admin_menu', array( &$this, 'add_setting_page' ) );
60
+ add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), 100 );
61
+ add_action( 'admin_init', array( &$this, 'add_fields' ) );
62
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
63
+ }
64
+ }
65
+
66
+
67
+ /**
68
+ * Register Settings
69
+ *
70
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
71
+ *
72
+ * @return void
73
+ * @since 1.0
74
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
75
+ */
76
+ public function register_settings() {
77
+ register_setting( 'yit_' . $this->settings['page'] . '_options', 'yit_' . $this->settings['page'] . '_options', array( &$this, 'options_validate' ) );
78
+ }
79
+
80
+
81
+
82
+ /**
83
+ * Add Setting SubPage
84
+ *
85
+ * add Setting SubPage to wordpress administrator
86
+ *
87
+ * @return array validate input fields
88
+ * @since 1.0
89
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
90
+ */
91
+ public function add_setting_page() {
92
+
93
+ $logo = YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png';
94
+
95
+ $admin_logo = function_exists( 'yit_get_option' ) ? yit_get_option( 'admin-logo-menu' ) : '';
96
+
97
+ if ( isset( $admin_logo ) && ! empty( $admin_logo ) && $admin_logo != '' && $admin_logo) {
98
+ $logo = $admin_logo;
99
+ }
100
+ $position = apply_filters( 'yit_plugins_menu_item_position', '62.32' );
101
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yith-plugin-fw' ), 'nosuchcapability', 'yit_plugin_panel', NULL, $logo, $position );
102
+
103
+ add_submenu_page( 'yit_plugin_panel', $this->settings['label'], $this->settings['label'], 'manage_options', $this->settings['page'], array( $this, 'yit_panel' ) );
104
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
105
+
106
+ }
107
+
108
+ /**
109
+ * Show a tabbed panel to setting page
110
+ *
111
+ * a callback function called by add_setting_page => add_submenu_page
112
+ *
113
+ * @return void
114
+ * @since 1.0
115
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
116
+ */
117
+ public function yit_panel() {
118
+
119
+ $tabs = '';
120
+ $current_tab = $this->get_current_tab();
121
+
122
+ // tabs
123
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
124
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
125
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
126
+ }
127
+ ?>
128
+ <div id="icon-themes" class="icon32"><br /></div>
129
+ <h2 class="nav-tab-wrapper">
130
+ <?php echo $tabs ?>
131
+ </h2>
132
+
133
+ <div id="wrap" class="plugin-option">
134
+ <?php $this->message(); ?>
135
+ <h2><?php echo $this->get_tab_title() ?></h2>
136
+
137
+ <?php if ( $this->is_show_form() ) : ?>
138
+ <form method="post" action="options.php">
139
+ <?php do_settings_sections( 'yit' ); ?>
140
+ <p>&nbsp;</p>
141
+ <?php settings_fields( 'yit_' . $this->settings['page'] . '_options' ); ?>
142
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
143
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yith-plugin-fw' ) ?>" style="float:left;margin-right:10px;" />
144
+ </form>
145
+ <form method="post">
146
+ <?php $warning = __( 'If you continue with this action, you will reset all the options in this page.', 'yith-plugin-fw' ) ?>
147
+ <input type="hidden" name="yit-action" value="reset" />
148
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset to default', 'yith-plugin-fw' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure?', 'yith-plugin-fw' ) ?>');" />
149
+ </form>
150
+ <p>&nbsp;</p>
151
+ <?php endif ?>
152
+ </div>
153
+ <?php
154
+ }
155
+
156
+
157
+
158
+ }
159
+
160
+ }
161
+
plugin-fw/lib/yit-pointers.php ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ /**
15
+ *
16
+ *
17
+ * @class yit-pointers
18
+ * @package Yithemes
19
+ * @since Version 2.0.0
20
+ * @author Your Inspiration Themes
21
+ *
22
+ */
23
+ if ( ! class_exists( 'YIT_Pointers' ) ) {
24
+ /**
25
+ * YIT Pointers
26
+ *
27
+ * Initializes the new feature pointers.
28
+ *
29
+ * @class YIT_Pointers
30
+ * @package Yithemes
31
+ * @since 1.0
32
+ * @author Your Inspiration Themes
33
+ * @see WP_Internal_Pointers
34
+ */
35
+ class YIT_Pointers {
36
+
37
+ /**
38
+ * @var YIT_Upgrade The main instance
39
+ */
40
+ protected static $_instance;
41
+
42
+ /**
43
+ * @var screen id where to show pointer
44
+ */
45
+ public $screen_ids = array();
46
+
47
+ public $pointers = array();
48
+
49
+ public $special_screen = array();
50
+
51
+ protected $_plugins_registered = array();
52
+
53
+ protected $_default_pointer = array();
54
+
55
+ protected $_default_position = array( 'edge' => 'left', 'align' => 'center' );
56
+
57
+ /**
58
+ * Construct
59
+ *
60
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
61
+ * @since 1.0
62
+ */
63
+ public function __construct() {
64
+
65
+ $this->_default_pointer['plugins'] = array(
66
+ 'screen_id' => 'plugins',
67
+ 'options' => array(
68
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
69
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
70
+ __( 'Plugins Activated', 'yith-plugin-fw' ),
71
+ __( 'From now on, you can find all plugin options in YIT Plugin menu.
72
+ For each plugin installed, customization settings will be available as a new entry in YIT Plugin menu.', 'yith-plugin-fw' ),
73
+ __( 'Discover all our plugins available on:', 'yith-plugin-fw' ),
74
+ __( 'and', 'yith-plugin-fw' )
75
+ ),
76
+ ),
77
+ );
78
+
79
+ $this->_default_pointer['update'] = array(
80
+ 'screen_id' => 'update',
81
+ 'options' => array(
82
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
83
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
84
+ __( 'Plugins Upgraded', 'yith-plugin-fw' ),
85
+ __( 'From now on, you can find all options of your plugins in YIT Plugin menu.
86
+ Any time one of our plugins is updated, a new entry will be added to this menu.
87
+ For example, after the update, plugin options (such as for YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search, etc.)
88
+ will be moved from previous location to YIT Plugin tab.', 'yith-plugin-fw' ),
89
+ __( 'Discover all our plugins available on:', 'yith-plugin-fw' ),
90
+ __( 'and', 'yith-plugin-fw' )
91
+ ),
92
+ ),
93
+ );
94
+
95
+ $this->_default_pointer = $this->parse_args( $this->_default_pointer );
96
+
97
+ /**
98
+ * Screens that require a particular action
99
+ */
100
+ $this->special_screen = apply_filters( 'yit-pointer-special-screen', array( 'plugins', 'update' ) );
101
+
102
+ add_action( 'admin_enqueue_scripts', array( $this, 'pointer_load' ) );
103
+ add_action( 'admin_init', array( $this, 'add_pointers' ), 100 );
104
+ }
105
+
106
+ public function parse_args( $args ) {
107
+ $default = array(
108
+ 'pointer_id' => 'yith_default_pointer',
109
+ 'target' => '#toplevel_page_yit_plugin_panel',
110
+ 'init' => null
111
+ );
112
+
113
+ foreach ( $args as $id => $pointer ) {
114
+ $args[ $id ] = wp_parse_args( $pointer, $default );
115
+ $args[ $id ]['options']['position'] = $this->_default_position;
116
+ }
117
+
118
+ return $args;
119
+ }
120
+
121
+ public function add_pointers(){
122
+ if( ! empty( $this->screen_ids ) ){
123
+ foreach( $this->screen_ids as $screen_id ){
124
+ add_filter( "yit_pointers-{$screen_id}", array( $this, 'pointers' ) );
125
+ }
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Main plugin Instance
131
+ *
132
+ * @static
133
+ * @return object Main instance
134
+ *
135
+ * @since 1.0
136
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
137
+ */
138
+ public static function instance() {
139
+ if ( is_null( self::$_instance ) ) {
140
+ self::$_instance = new self();
141
+ }
142
+
143
+ return self::$_instance;
144
+ }
145
+
146
+ public function register( $args ) {
147
+
148
+ foreach ( $args as $id => $pointer ) {
149
+
150
+ extract( $pointer );
151
+
152
+ if ( ! isset( $screen_id ) && ! empty( $screen_id ) && ! isset( $init ) && ! empty( $init ) ) {
153
+ return;
154
+ }
155
+
156
+ if ( ! in_array( $screen_id, $this->screen_ids ) ) {
157
+ $this->screen_ids[] = $screen_id;
158
+ }
159
+
160
+ $this->pointers[$screen_id][$pointer_id] = array(
161
+ 'target' => $target,
162
+ 'options' => array(
163
+ 'content' => $content,
164
+ 'position' => $position,
165
+ ),
166
+ 'init' => isset( $init ) ? $init : false
167
+ );
168
+ }
169
+ }
170
+
171
+ public function get_plugins_init( $screen_id ) {
172
+
173
+ $registered = array();
174
+
175
+ foreach( $this->pointers[ $screen_id ] as $pointer_id => $pointer ){
176
+ $registered[ $pointer['init'] ] = $pointer_id;
177
+ }
178
+
179
+ return $registered;
180
+ }
181
+
182
+ public function pointer_load( $hook_suffix ) {
183
+
184
+ /**
185
+ * Get pointers for this screen
186
+ */
187
+ $screen = get_current_screen();
188
+ $pointers = apply_filters( "yit_pointers-{$screen->id}", array() );
189
+
190
+ if ( ! $pointers || ! is_array( $pointers ) ) {
191
+ return;
192
+ }
193
+
194
+ /**
195
+ * Get dismissed pointers
196
+ */
197
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
198
+ $valid_pointers = array();
199
+ //$point_id = null;
200
+
201
+ /**
202
+ * show pointers only on plugin activate action
203
+ */
204
+ if( in_array( $screen->id, $this->special_screen ) ){
205
+
206
+ $show = false;
207
+ $registered = $this->get_plugins_init( $screen->id );
208
+ $recently_activate = get_option( 'yit_recently_activated', array() );
209
+
210
+ /**
211
+ * For "plugins" screen
212
+ */
213
+ $is_single_activate = ( isset( $_GET['activate'] ) && 'true' == $_GET['activate'] ) ? true : false;
214
+ $is_multi_activate = ( isset( $_GET['activate-multi'] ) && 'true' == $_GET['activate-multi'] ) ? true : false;
215
+
216
+ /**
217
+ * For "update" screen
218
+ *
219
+ * Single plugin update use GET method
220
+ *
221
+ * Multi update plugins with bulk action send two post args called "action" and "action2"
222
+ * action refer to first bulk action button (at the top of plugins table)
223
+ * action2 refer to last bulk action button (at the bottom of plugins table)
224
+ *
225
+ */
226
+ $is_single_upgrade = ( isset( $_GET['action'] ) && 'upgrade-plugin' == $_GET['action'] ) ? true : false;
227
+ $is_multi_upgrade = ( isset( $_POST['action'] ) && 'update-selected' == $_POST['action'] ) || ( isset( $_POST['action2'] ) && 'update-selected' == $_POST['action2'] ) ? true: false;
228
+
229
+ if( $is_single_activate || $is_single_upgrade ){
230
+
231
+ $point_id = '';
232
+
233
+ /**
234
+ * Single activation plugin
235
+ * Single update plugin
236
+ */
237
+ foreach( $registered as $init => $p_id ){
238
+ if ( in_array( $init, $recently_activate ) ) {
239
+ $point_id = $p_id;
240
+ $pointer = $pointers[ $point_id ];
241
+
242
+ /**
243
+ * Sanity check
244
+ */
245
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
246
+ /**
247
+ * Add the pointer to $valid_pointers array
248
+ */
249
+ $pointer['pointer_id'] = $point_id;
250
+ $valid_pointers['pointers'][] = $pointer;
251
+ $show = true;
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ } else if( $is_multi_activate || $is_multi_upgrade ){
257
+
258
+ /**
259
+ * Bulk Action: multi plugins activation
260
+ * Bulk Action: multi plugins update
261
+ */
262
+ $point_id = array();
263
+ $screen_id = $screen->id;
264
+
265
+ if( $is_multi_upgrade && isset( $_POST['checked'] ) && ( count( $_POST['checked'] ) > 0 ) ){
266
+ $recently_activate = $_POST['checked'];
267
+ $screen_id = 'update';
268
+ $pointers = apply_filters( "yit_pointers-{$screen_id}", array() );
269
+ }
270
+
271
+ foreach ( $registered as $init => $p_id ) {
272
+ if ( in_array( $init, $recently_activate ) ) {
273
+ $point_id[] = $p_id;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Bulk Action: Activate Plugins
279
+ *
280
+ * count( $point_id ) is the number of YITH plugins that have registered specific pointers
281
+ * case 0 -> No pointers -> Exit
282
+ * case 1 -> Only one pointers to show -> Use the specific plugin pointer
283
+ * defautl -> Two or more plugins need to show a pointer -> use a generic pointers
284
+ *
285
+ */
286
+ switch ( count( $point_id ) ) {
287
+ case 0:
288
+ $show = false;
289
+ break;
290
+
291
+ case 1:
292
+ $point_id = array_pop( $point_id );
293
+ $pointer = $pointers[$point_id];
294
+ /**
295
+ * Sanity check
296
+ */
297
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
298
+ /**
299
+ * Add the pointer to $valid_pointers array
300
+ */
301
+ $pointer['pointer_id'] = $point_id;
302
+ $valid_pointers['pointers'][] = $pointer;
303
+ $show = true;
304
+ }
305
+ break;
306
+
307
+ default:
308
+ $valid_pointers['pointers'][] = $this->_default_pointer[ $screen_id ];
309
+ $show = true;
310
+ break;
311
+ }
312
+ }
313
+
314
+ update_option( 'yit_recently_activated', array() );
315
+
316
+ if( ! $show ){
317
+ return;
318
+ }
319
+
320
+ } else {
321
+ /**
322
+ * Check pointers and remove dismissed ones.
323
+ */
324
+ foreach ( $pointers as $pointer_id => $pointer ) {
325
+
326
+ /**
327
+ * Sanity check
328
+ */
329
+ if ( in_array( $pointer_id, $dismissed ) || empty( $pointer ) || empty( $pointer_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) {
330
+ continue;
331
+ }
332
+
333
+ $pointer['pointer_id'] = $pointer_id;
334
+
335
+ /**
336
+ * Add the pointer to $valid_pointers array
337
+ */
338
+ $valid_pointers['pointers'][] = $pointer;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * No valid pointers? Stop here.
344
+ */
345
+ if ( empty( $valid_pointers ) ) {
346
+ return;
347
+ }
348
+
349
+ $script_file = function_exists( 'yit_load_js_file' ) ? yit_load_js_file( 'yit-wp-pointer.js' ) : 'yit-wp-pointer.min.js';
350
+
351
+ /**
352
+ * Enqueue wp-pointer script and style
353
+ */
354
+ wp_enqueue_style( 'wp-pointer' );
355
+ wp_enqueue_script( 'wp-pointer' );
356
+
357
+ wp_enqueue_script( 'yit-wp-pointer', YIT_CORE_PLUGIN_URL . '/assets/js/' . $script_file, array( 'wp-pointer' ), false, true );
358
+ wp_localize_script( 'yit-wp-pointer', 'custom_pointer', $valid_pointers );
359
+ }
360
+
361
+ public function pointers( $pointers ){
362
+ $screen_id = str_replace( 'yit_pointers-', '', current_filter() );
363
+ $pointers_to_add = $this->get_pointers( $screen_id );
364
+
365
+ return ! empty( $pointers_to_add ) ? array_merge( $pointers, $pointers_to_add ) : $pointers;
366
+ }
367
+
368
+ public function get_pointers( $screen_id ){
369
+ return isset( $this->pointers[ $screen_id ] ) ? $this->pointers[ $screen_id ] : array();
370
+ }
371
+ }
372
+ }
373
+
374
+ if ( ! function_exists( 'YIT_Pointers' ) ) {
375
+ /**
376
+ * Main instance of plugin
377
+ *
378
+ * @return object YIT_Pointers
379
+ * @since 1.0
380
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
381
+ */
382
+ function YIT_Pointers() {
383
+ return YIT_Pointers::instance();
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Instance a YIT_Pointers object
389
+ */
390
+ YIT_Pointers();
plugin-fw/lib/yit-upgrade.php ADDED
@@ -0,0 +1,543 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ if ( ! class_exists( 'YIT_Upgrade' ) ) {
15
+ /**
16
+ * YIT Upgrade
17
+ *
18
+ * Notify and Update plugin
19
+ *
20
+ * @class YIT_Upgrade
21
+ * @package Yithemes
22
+ * @since 1.0
23
+ * @author Your Inspiration Themes
24
+ * @see WP_Updater Class
25
+ */
26
+
27
+ class YIT_Upgrade {
28
+
29
+ /**
30
+ * @var string XML notifier update
31
+ */
32
+ protected $_xml = 'http://update.yithemes.com/plugins/%plugin_slug%.xml';
33
+
34
+ /**
35
+ * @var string api server url
36
+ */
37
+ protected $_package_url = 'http://www.yithemes.com';
38
+
39
+ /**
40
+ * @var array The registered plugins
41
+ */
42
+ protected $_plugins = array();
43
+
44
+ /**
45
+ * @var YIT_Upgrade The main instance
46
+ */
47
+ protected static $_instance;
48
+
49
+ /**
50
+ * Construct
51
+ *
52
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
53
+ * @since 1.0
54
+ */
55
+ public function __construct() {
56
+ add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download') , 10, 3 );
57
+ add_action( 'update-custom_upgrade-plugin-multisite', array( $this, 'upgrade_plugin_multisite' ) );
58
+
59
+ if( is_network_admin() ){
60
+ add_action( 'admin_enqueue_scripts', array( $this, 'network_admin_enqueue_scripts' ) );
61
+ }
62
+
63
+ if( defined( 'YIT_LICENCE_DEBUG' ) && YIT_LICENCE_DEBUG ){
64
+ $this->_package_url = 'http://dev.yithemes.com';
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Main plugin Instance
70
+ *
71
+ * @param $plugin_slug | string The plugin slug
72
+ * @param $plugin_init | string The plugin init file
73
+ *
74
+ * @return void
75
+ *
76
+ * @since 1.0
77
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
78
+ */
79
+ public function register( $plugin_slug, $plugin_init ) {
80
+
81
+ if( ! function_exists( 'get_plugins' ) ){
82
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
83
+ }
84
+
85
+ $plugins = get_plugins();
86
+ $plugin_info = $plugins[ $plugin_init ];
87
+
88
+ $this->_plugins[ $plugin_init ] = array(
89
+ 'info' => $plugin_info,
90
+ 'slug' => $plugin_slug,
91
+ );
92
+
93
+ /* === HOOKS === */
94
+ if( ! is_multisite() || is_plugin_active_for_network( $plugin_init ) ){
95
+ add_action( 'admin_init', array( $this, 'remove_wp_plugin_update_row' ), 15 );
96
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
97
+ } else if( is_multisite() && current_user_can( 'update_plugins' ) ) {
98
+ $xml = str_replace( '%plugin_slug%', $plugin_slug, $this->_xml );
99
+ $remote_xml = wp_remote_get( $xml );
100
+
101
+ if( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) {
102
+ $plugin_remote_info = new SimpleXmlElement( $remote_xml['body'] );
103
+ $this->_plugins[ $plugin_init ]['info']['Latest'] = (string) $plugin_remote_info->latest;
104
+ $this->_plugins[ $plugin_init ]['info']['changelog'] = (string) $plugin_remote_info->changelog;
105
+ add_action( 'admin_enqueue_scripts', array( $this, 'multisite_updater_script' ) );
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Add the multisite updater scripts
112
+ *
113
+ * @return void
114
+ *
115
+ * @since 1.0
116
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
117
+ */
118
+ public function multisite_updater_script(){
119
+
120
+ $update_url = array();
121
+ $changelogs = array();
122
+ $strings = array(
123
+ 'new_version' => __( 'There is a new version of %plugin_name% available.', 'yith-plugin-fw' ),
124
+ 'latest' => __( 'View version %latest% details.', 'yith-plugin-fw' ),
125
+ 'unavailable' => __( 'Automatic update is unavailable for this plugin,', 'yith-plugin-fw' ),
126
+ 'activate' => __( 'please <a href="%activate_link%">activate</a> your copy of %plugin_name%.', 'yith-plugin-fw' ),
127
+ 'update_now' => __( 'Update now.', 'yith-plugin-fw' )
128
+
129
+ );
130
+
131
+ foreach( $this->_plugins as $init => $info ){
132
+ YIT_Plugin_Licence()->check( $init );
133
+
134
+ $update_url[ $init ] = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin-multisite&plugin=') . $init, 'upgrade-plugin-multisite_' . $init );
135
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
136
+ $details_url[ $init ] = '#TB_inline' . esc_url( add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' ) );
137
+ $changelogs[ $init ] = $this->in_theme_update_message( $this->_plugins[ $init ], $this->_plugins[ $init ]['info']['changelog'], $changelog_id, false );
138
+ }
139
+
140
+ $localize_script_args = array(
141
+ 'registered' => $this->_plugins,
142
+ 'activated' => YIT_Plugin_Licence()->get_activated_products(),
143
+ 'licence_activation_url' => YIT_Plugin_Licence()->get_licence_activation_page_url(),
144
+ 'update_url' => $update_url,
145
+ 'details_url' => $details_url,
146
+ 'strings' => $strings,
147
+ 'changelogs' => $changelogs
148
+ );
149
+
150
+ yit_enqueue_script( 'yit-multisite-updater', YIT_CORE_PLUGIN_URL . '/assets/js/multisite-updater.min.js', array( 'jquery' ), false, true );
151
+
152
+ wp_localize_script( 'yit-multisite-updater', 'plugins', $localize_script_args );
153
+ }
154
+
155
+ public function network_admin_enqueue_scripts(){
156
+ yit_enqueue_style( 'yit-upgrader', YIT_CORE_PLUGIN_URL . '/assets/css/yit-upgrader.css' );
157
+ }
158
+
159
+ /**
160
+ * Call the protected method _upgrader_pre_download to retrive the zip package file
161
+ *
162
+ * @param bool $reply Whether to bail without returning the package. Default false.
163
+ * @param string $package The package file name.
164
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
165
+ *
166
+ * @return string | The download file
167
+ *
168
+ * @since 1.0
169
+ * @see wp-admin/includes/class-wp-upgrader.php
170
+ * @access public
171
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
172
+ */
173
+ public function upgrader_pre_download( $reply, $package, $upgrader ){
174
+ return $this->_upgrader_pre_download( $reply, $package, $upgrader );
175
+ }
176
+
177
+ /**
178
+ * Retrive the zip package file
179
+ *
180
+ * @param bool $reply Whether to bail without returning the package. Default false.
181
+ * @param string $package The package file name.
182
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
183
+ *
184
+ * @return string | The download file
185
+ *
186
+ * @since 1.0
187
+ * @see wp-admin/includes/class-wp-upgrader.php
188
+ * @access protected
189
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
190
+ */
191
+ protected function _upgrader_pre_download( $reply, $package, $upgrader ) {
192
+
193
+ /**
194
+ * It isn't YITH Premium plugins, please wordpress update it for me!
195
+ */
196
+ if( ! isset( $upgrader->skin->plugin ) ) {
197
+ return $reply;
198
+ }
199
+
200
+ $plugin_info = YIT_Plugin_Licence()->get_product( $upgrader->skin->plugin );
201
+
202
+ /**
203
+ * False ? It isn't YITH Premium plugins, please wordpress update it for me!
204
+ */
205
+ if( false === $plugin_info ) {
206
+ return $reply;
207
+ }
208
+
209
+ $licence = YIT_Plugin_Licence()->get_licence();
210
+ $product_id = $plugin_info['product_id'];
211
+ $args = array(
212
+ 'email' => $licence[ $product_id ]['email'],
213
+ 'licence_key' => $licence[$product_id]['licence_key'],
214
+ 'product_id' => $plugin_info['product_id'],
215
+ 'secret_key' => $plugin_info['secret_key'],
216
+ 'instance' => YIT_Plugin_Licence()->get_home_url(),
217
+ 'wc-api' => 'download-api',
218
+ 'request' => 'download'
219
+ );
220
+
221
+ if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) {
222
+ //Local file or remote?
223
+ return $package;
224
+ }
225
+
226
+ if ( empty( $package ) ) {
227
+ return new WP_Error( 'no_package', $upgrader->strings['no_package'] );
228
+ }
229
+
230
+ $upgrader->skin->feedback( 'downloading_package', __( 'Yithemes Repository', 'yith-plugin-fw' ) );
231
+
232
+ $download_file = $this->_download_url( $package, $args );
233
+
234
+ /**
235
+ * Regenerate update_plugins transient
236
+ */
237
+ $this->force_regenerate_update_transient();
238
+
239
+ if ( is_wp_error( $download_file ) ) {
240
+ return new WP_Error( 'download_failed', $upgrader->strings['download_failed'], $download_file->get_error_message() );
241
+ }
242
+
243
+ return $download_file;
244
+ }
245
+
246
+ /**
247
+ * Retrive the temp filename
248
+ *
249
+ * @param string $url The package url
250
+ * @param string $body The post data fields
251
+ * @param int $timeout Execution timeout (default: 300)
252
+ *
253
+ * @return string | The temp filename
254
+ *
255
+ * @since 1.0
256
+ * @see wp-admin/includes/class-wp-upgrader.php
257
+ * @access protected
258
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
259
+ */
260
+ protected function _download_url( $url, $body, $timeout = 300 ) {
261
+
262
+ //WARNING: The file is not automatically deleted, The script must unlink() the file.
263
+ if ( ! $url ) {
264
+ return new WP_Error( 'http_no_url', __( 'Invalid URL Provided.' ) );
265
+ }
266
+
267
+ $tmpfname = wp_tempnam( $url );
268
+
269
+ $args = array(
270
+ 'timeout' => $timeout,
271
+ 'stream' => true,
272
+ 'filename' => $tmpfname,
273
+ 'body' => $body
274
+ );
275
+
276
+ if ( ! $tmpfname ) {
277
+ return new WP_Error( 'http_no_file', __( 'Could not create Temporary file.' ) );
278
+ }
279
+
280
+ $response = wp_safe_remote_post( $url, $args );
281
+
282
+ if ( is_wp_error( $response ) ) {
283
+ unlink( $tmpfname );
284
+ return $response;
285
+ }
286
+
287
+ if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
288
+ unlink( $tmpfname );
289
+ return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
290
+ }
291
+
292
+ $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' );
293
+
294
+ if ( $content_md5 ) {
295
+ $md5_check = verify_file_md5( $tmpfname, $content_md5 );
296
+ if ( is_wp_error( $md5_check ) ) {
297
+ unlink( $tmpfname );
298
+ return $md5_check;
299
+ }
300
+ }
301
+
302
+ return $tmpfname;
303
+ }
304
+
305
+ /**
306
+ * Main plugin Instance
307
+ *
308
+ * @static
309
+ * @return object Main instance
310
+ *
311
+ * @since 1.0
312
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
313
+ */
314
+ public static function instance() {
315
+ if ( is_null( self::$_instance ) ) {
316
+ self::$_instance = new self();
317
+ }
318
+
319
+ return self::$_instance;
320
+ }
321
+
322
+ /**
323
+ * Delete the update plugins transient
324
+ *
325
+ * @return void
326
+ *
327
+ * @since 1.0
328
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
329
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
330
+ */
331
+ public function force_regenerate_update_transient(){
332
+ delete_site_transient( 'update_plugins' );
333
+ }
334
+
335
+ /**
336
+ * Check for plugins update
337
+ *
338
+ * If a new plugin version is available set it in the pre_set_site_transient_update_plugins hooks
339
+ *
340
+ * @param mixed $transient | update_plugins transient value
341
+ * @param bool $save | Default: false. Set true to regenerate the update_transient plugins
342
+ *
343
+ * @return mixed $transient | The new update_plugins transient value
344
+ *
345
+ * @since 1.0
346
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
347
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
348
+ */
349
+ public function check_update( $transient, $save = false ) {
350
+
351
+ foreach ($this->_plugins as $init => $plugin) {
352
+ $xml = str_replace('%plugin_slug%', $this->_plugins[$init]['slug'], $this->_xml);
353
+ $remote_xml = wp_remote_get($xml);
354
+
355
+ if (!is_wp_error($remote_xml) && isset($remote_xml['response']['code']) && '200' == $remote_xml['response']['code']) {
356
+
357
+
358
+ $plugin_remote_info = new SimpleXmlElement($remote_xml['body']);
359
+
360
+ if (version_compare($plugin_remote_info->latest, $plugin['info']['Version'], '>') && !isset($transient->response[$init])) {
361
+
362
+ $package = YIT_Plugin_Licence()->check($init) ? $this->_package_url : null;
363
+
364
+ $obj = new stdClass();
365
+ $obj->slug = (string)$init;
366
+ $obj->new_version = (string)$plugin_remote_info->latest;
367
+ $obj->changelog = (string)$plugin_remote_info->changelog;
368
+ $obj->package = $package;
369
+ $obj->plugin = $init;
370
+ $transient->response[$init] = $obj;
371
+ }
372
+
373
+ }
374
+ }
375
+
376
+ if( $save ) {
377
+ set_site_transient( 'update_plugins', $transient );
378
+ }
379
+
380
+ return $transient;
381
+ }
382
+
383
+ /**
384
+ * Add the plugin update row in plugin page
385
+ *
386
+ * @return void
387
+ * @fire "in_theme_update_message-{$init}" action
388
+ *
389
+ * @since 1.0
390
+ * @see after_plugin_row_{$init} action
391
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
392
+ */
393
+ public function plugin_update_row() {
394
+
395
+ $current = get_site_transient( 'update_plugins' );
396
+ $init = str_replace( 'after_plugin_row_', '', current_filter() );
397
+
398
+ if ( ! isset( $current->response[ $init ] ) ) {
399
+ return false;
400
+ }
401
+
402
+ /**
403
+ * stdClass Object
404
+ */
405
+ $r = $current->response[ $init ];
406
+
407
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
408
+ $details_url = '#TB_inline' . esc_url( add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' ) );
409
+
410
+ /**
411
+ * @see wp_plugin_update_rows() in wp-single\wp-admin\includes\update.php
412
+ */
413
+ $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' );
414
+
415
+ if( is_network_admin() || ! is_multisite() || true ) {
416
+ echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
417
+
418
+ if( ! current_user_can( 'update_plugins' ) ){
419
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>.', 'yith-plugin-fw'), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
420
+ }elseif( is_plugin_active_for_network( $init ) ){
421
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>You have to activate the plugin on a single site of the network to benefit from automatic updates.</em>', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
422
+ }elseif ( empty( $r->package ) ) {
423
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>Automatic update is unavailable for this plugin, please <a href="%5$s" title="Licence activation">activate</a> your copy of %6s.</em>', 'yith-plugin-fw' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, YIT_Plugin_Licence()->get_licence_activation_page_url(), $this->_plugins[ $init ]['info']['Name'] );
424
+ } else {
425
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a> or <a href="%5$s">update now</a>.', 'yith-plugin-fw'), $this->_plugins[ $init ]['info']['Name'], esc_url($details_url), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=') . $init, 'upgrade-plugin_' . $init ) );
426
+ }
427
+
428
+ /**
429
+ * Fires at the end of the update message container in each
430
+ * row of the themes list table.
431
+ *
432
+ * The dynamic portion of the hook name, `$theme_key`, refers to
433
+ * the theme slug as found in the WordPress.org themes repository.
434
+ *
435
+ * @since Wordpress 3.1.0
436
+ * }
437
+ */
438
+ do_action( "in_theme_update_message-{$init}", $this->_plugins[ $init ], $r->changelog, $changelog_id );
439
+
440
+ echo '</div></td></tr>';
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Remove the standard plugin_update_row
446
+ *
447
+ * Remove the standard plugin_update_row and Add a custom plugin update row in plugin page.
448
+ *
449
+ * @return void
450
+ * @fire "in_theme_update_message-{$init}" action
451
+ *
452
+ * @since 1.0
453
+ * @see after_plugin_row_{$init} action
454
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
455
+ */
456
+ public function remove_wp_plugin_update_row() {
457
+ foreach( $this->_plugins as $init => $plugin ){
458
+ remove_action( "after_plugin_row_{$init}", 'wp_plugin_update_row', 10, 2 );
459
+ add_action( "after_plugin_row_{$init}", array( $this, 'plugin_update_row' ) );
460
+ add_action( "in_theme_update_message-{$init}", array( $this, 'in_theme_update_message' ), 10, 3 );
461
+ }
462
+ }
463
+
464
+ public function in_theme_update_message( $plugin, $changelog, $changelog_id, $echo = true ){
465
+
466
+ $res = "<div id='{$changelog_id}' class='yit-plugin-changelog-wrapper'>
467
+ <div class='yit-plugin-changelog'>
468
+ <h2 class='yit-plugin-changelog-title'>{$plugin['info']['Name']} - Changelog</h2>
469
+ <p>{$changelog}</p>
470
+ </div>
471
+ </div>";
472
+
473
+ if( $echo ){
474
+ echo $res;
475
+ }
476
+ else{
477
+ return $res;
478
+ }
479
+ }
480
+
481
+ /**
482
+ * Auto-Update Plugin in multisite
483
+ *
484
+ * Manage the non standard upgrade-plugin-multisite action
485
+ *
486
+ * @return void
487
+ *
488
+ * @since 1.0
489
+ * @see upgrade-plugin action
490
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
491
+ */
492
+ public function upgrade_plugin_multisite(){
493
+
494
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
495
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
496
+
497
+ if( 'upgrade-plugin-multisite' != $action ){
498
+ wp_die( __( 'You can\'t update the plugins for this site.', 'yith-plugin-fw' ) );
499
+ }
500
+
501
+ if ( ! current_user_can( 'update_plugins' ) ) {
502
+ wp_die( __( 'You do not have sufficient permissions to update the plugins for this site.', 'yith-plugin-fw' ) );
503
+ }
504
+
505
+ $this->check_update( get_site_transient( 'update_plugins'