Event Tickets - Version 4.11.1.1

Version Description

Download this release

Release Info

Developer borkweb
Plugin Icon 128x128 Event Tickets
Version 4.11.1.1
Comparing to
See all releases

Code changes from version 4.12.1.1 to 4.11.1.1

Files changed (322) hide show
  1. common/lang/readme.txt +0 -3
  2. common/lang/tribe-common-af.mo +0 -0
  3. common/lang/tribe-common-ar.mo +0 -0
  4. common/lang/tribe-common-bg_BG.mo +0 -0
  5. common/lang/tribe-common-ca.mo +0 -0
  6. common/lang/tribe-common-cs_CZ.mo +0 -0
  7. common/lang/tribe-common-da_DK.mo +0 -0
  8. common/lang/tribe-common-de_DE.mo +0 -0
  9. common/lang/tribe-common-el.mo +0 -0
  10. common/lang/tribe-common-en_GB.mo +0 -0
  11. common/lang/tribe-common-es_ES.mo +0 -0
  12. common/lang/tribe-common-et.mo +0 -0
  13. common/lang/tribe-common-fi.mo +0 -0
  14. common/lang/tribe-common-fr_CA.mo +0 -0
  15. common/lang/tribe-common-fr_FR.mo +0 -0
  16. common/lang/tribe-common-hu_HU.mo +0 -0
  17. common/lang/tribe-common-id_ID.mo +0 -0
  18. common/lang/tribe-common-is_IS.mo +0 -0
  19. common/lang/tribe-common-it_IT.mo +0 -0
  20. common/lang/tribe-common-ja.mo +0 -0
  21. common/lang/tribe-common-lt_LT.mo +0 -0
  22. common/lang/tribe-common-lv.mo +0 -0
  23. common/lang/tribe-common-nb_NO.mo +0 -0
  24. common/lang/tribe-common-nl_NL.mo +0 -0
  25. common/lang/tribe-common-pl_PL.mo +0 -0
  26. common/lang/tribe-common-pt_BR.mo +0 -0
  27. common/lang/tribe-common-pt_PT.mo +0 -0
  28. common/lang/tribe-common-ro_RO.mo +0 -0
  29. common/lang/tribe-common-ru_RU.mo +0 -0
  30. common/lang/tribe-common-sk_SK.mo +0 -0
  31. common/lang/tribe-common-sl_SI.mo +0 -0
  32. common/lang/tribe-common-sr_RS.mo +0 -0
  33. common/lang/tribe-common-sv_SE.mo +0 -0
  34. common/lang/tribe-common-tr_TR.mo +0 -0
  35. common/lang/tribe-common-zh_CN.mo +0 -0
  36. common/lang/tribe-common-zh_TW.mo +0 -0
  37. common/lang/tribe-common.pot +89 -110
  38. common/src/Tribe/Admin/Notice/Plugin_Download.php +2 -2
  39. common/src/Tribe/Admin/Notices.php +11 -91
  40. common/src/Tribe/Assets.php +49 -97
  41. common/src/Tribe/Autoloader.php +1 -18
  42. common/src/Tribe/Cache.php +85 -229
  43. common/src/Tribe/Cache_Listener.php +7 -42
  44. common/src/Tribe/Container.php +0 -46
  45. common/src/Tribe/Context.php +1 -9
  46. common/src/Tribe/Context/locations.php +2 -47
  47. common/src/Tribe/Customizer.php +137 -23
  48. common/src/Tribe/Data.php +9 -9
  49. common/src/Tribe/Date_Utils.php +23 -198
  50. common/src/Tribe/Debug_Bar/Panels/Json_Ld.php +0 -84
  51. common/src/Tribe/Dependency.php +26 -25
  52. common/src/Tribe/Dialog/View.php +2 -2
  53. common/src/Tribe/Editor.php +1 -43
  54. common/src/Tribe/Editor/Blocks/Abstract.php +3 -37
  55. common/src/Tribe/Editor/Configuration.php +0 -1
  56. common/src/Tribe/Extension.php +9 -57
  57. common/src/Tribe/Field.php +0 -5
  58. common/src/Tribe/Freemius.php +2 -3
  59. common/src/Tribe/Image/Uploader.php +70 -148
  60. common/src/Tribe/Languages/Locations.php +2 -2
  61. common/src/Tribe/Log/File_Logger.php +1 -1
  62. common/src/Tribe/Main.php +90 -155
  63. common/src/Tribe/PUE/Checker.php +1 -9
  64. common/src/Tribe/PUE/Update_Prevention.php +1 -1
  65. common/src/Tribe/Plugins.php +0 -32
  66. common/src/Tribe/Post_Transient.php +10 -11
  67. common/src/Tribe/Process/Post_Thumbnail_Setter.php +15 -13
  68. common/src/Tribe/Promoter/Connector.php +1 -1
  69. common/src/Tribe/Repository.php +11 -31
  70. common/src/Tribe/Repository/Query_Filters.php +3 -3
  71. common/src/Tribe/Rewrite.php +25 -128
  72. common/src/Tribe/Service_Providers/Debug_Bar.php +0 -2
  73. common/src/Tribe/Service_Providers/Shortcodes.php +0 -80
  74. common/src/Tribe/Settings_Manager.php +13 -45
  75. common/src/Tribe/Shortcode/Manager.php +0 -107
  76. common/src/Tribe/Shortcode/Shortcode_Abstract.php +0 -247
  77. common/src/Tribe/Shortcode/Shortcode_Interface.php +0 -125
  78. common/src/Tribe/Support.php +1 -14
  79. common/src/Tribe/Template.php +99 -625
  80. common/src/Tribe/Traits/Cache_User.php +0 -17
  81. common/src/Tribe/Utils/Array.php +0 -79
  82. common/src/Tribe/Utils/Collection_Trait.php +2 -15
  83. common/src/Tribe/Utils/Date_I18n.php +0 -48
  84. common/src/Tribe/Utils/Date_I18n_Immutable.php +0 -48
  85. common/src/Tribe/Utils/Post_Thumbnail.php +32 -53
  86. common/src/Tribe/Utils/Strings.php +0 -65
  87. common/src/Tribe/Validate.php +1 -4
  88. common/src/Tribe/Validator/Base.php +1 -3
  89. common/src/Tribe/View_Helpers.php +5 -13
  90. common/src/admin-views/tribe-options-display.php +7 -7
  91. common/src/functions/template-tags/date.php +18 -38
  92. common/src/functions/template-tags/general.php +2 -23
  93. common/src/functions/template-tags/html.php +1 -1
  94. common/src/functions/template-tags/post.php +11 -43
  95. common/src/functions/utils.php +1 -1
  96. common/src/modules/components/form/index.js +1 -0
  97. common/src/modules/components/form/select/component.js +116 -0
  98. common/src/modules/components/form/select/index.js +1 -0
  99. common/src/modules/components/form/select/style.pcss +56 -0
  100. common/src/modules/components/index.js +5 -0
  101. common/src/modules/components/plugin-block-hooks/__tests__/__snapshots__/plugin-block-hooks.spec.js.snap +131 -0
  102. common/src/modules/components/plugin-block-hooks/__tests__/plugin-block-hooks.spec.js +92 -0
  103. common/src/modules/components/plugin-block-hooks/component.js +138 -0
  104. common/src/modules/components/plugin-block-hooks/container.js +21 -0
  105. common/src/modules/components/plugin-block-hooks/index.js +1 -0
  106. common/src/modules/components/plugin-block-hooks/style.pcss +37 -0
  107. common/src/modules/components/prevent-block-close/__tests__/component.spec.js +15 -0
  108. common/src/modules/components/prevent-block-close/component.js +38 -0
  109. common/src/modules/components/prevent-block-close/index.js +1 -0
  110. common/src/modules/data/__tests__/utils.test.js +10 -0
  111. common/src/modules/data/editor/post-types.js +3 -0
  112. common/src/modules/data/forms/__tests__/__snapshots__/actions.test.js.snap +147 -0
  113. common/src/modules/data/forms/__tests__/actions.test.js +96 -0
  114. common/src/modules/data/forms/__tests__/reducer.test.js +88 -0
  115. common/src/modules/data/forms/__tests__/selectors.test.js +89 -0
  116. common/src/modules/data/forms/__tests__/types.js +19 -0
  117. common/src/modules/data/forms/actions.js +153 -0
  118. common/src/modules/data/forms/index.js +12 -0
  119. common/src/modules/data/forms/reducer.js +33 -0
  120. common/src/modules/data/forms/reducers/__tests__/__snapshots__/form.test.js.snap +84 -0
  121. common/src/modules/data/forms/reducers/__tests__/form.test.js +49 -0
  122. common/src/modules/data/forms/reducers/__tests__/volatile.test.js +23 -0
  123. common/src/modules/data/forms/reducers/form.js +58 -0
  124. common/src/modules/data/forms/reducers/index.js +2 -0
  125. common/src/modules/data/forms/reducers/volatile.js +15 -0
  126. common/src/modules/data/forms/selectors.js +39 -0
  127. common/src/modules/data/forms/types.js +15 -0
  128. common/src/modules/data/index.js +9 -0
  129. common/src/modules/data/plugins/__tests__/__snapshots__/actions.test.js.snap +19 -0
  130. common/src/modules/data/plugins/__tests__/actions.test.js +14 -0
  131. common/src/modules/data/plugins/__tests__/reducer.test.js +25 -0
  132. common/src/modules/data/plugins/__tests__/selectors.test.js +23 -0
  133. common/src/modules/data/plugins/__tests__/types.test.js +12 -0
  134. common/src/modules/data/plugins/actions.js +18 -0
  135. common/src/modules/data/plugins/constants.js +4 -0
  136. common/src/modules/data/plugins/index.js +12 -0
  137. common/src/modules/data/plugins/proptypes.js +15 -0
  138. common/src/modules/data/plugins/reducer.js +20 -0
  139. common/src/modules/data/plugins/selectors.js +9 -0
  140. common/src/modules/data/plugins/types.js +7 -0
  141. common/src/modules/data/reducers.js +15 -0
  142. common/src/modules/data/utils.js +1 -0
  143. common/src/modules/elements/accordion/__tests__/__snapshots__/element.test.js.snap +71 -0
  144. common/src/modules/elements/accordion/__tests__/element.test.js +45 -0
  145. common/src/modules/elements/accordion/element.js +58 -0
  146. common/src/modules/elements/accordion/row/__tests__/__snapshots__/template.test.js.snap +31 -0
  147. common/src/modules/elements/accordion/row/__tests__/template.test.js +56 -0
  148. common/src/modules/elements/accordion/row/template.js +129 -0
  149. common/src/modules/elements/accordion/style.pcss +8 -0
  150. common/src/modules/elements/block-icon/index.js +16 -0
  151. common/src/modules/elements/block-icon/style.pcss +24 -0
  152. common/src/modules/elements/button/__tests__/__snapshots__/element.test.js.snap +62 -0
  153. common/src/modules/elements/button/__tests__/element.test.js +60 -0
  154. common/src/modules/elements/button/element.js +56 -0
  155. common/src/modules/elements/button/style.pcss +58 -0
  156. common/src/modules/elements/checkbox-input/__tests__/__snapshots__/element.test.js.snap +47 -0
  157. common/src/modules/elements/checkbox-input/__tests__/element.test.js +39 -0
  158. common/src/modules/elements/checkbox-input/element.js +35 -0
  159. common/src/modules/elements/checkbox-input/style.pcss +25 -0
  160. common/src/modules/elements/checkbox/__tests__/__snapshots__/element.test.js.snap +168 -0
  161. common/src/modules/elements/checkbox/__tests__/element.test.js +70 -0
  162. common/src/modules/elements/checkbox/element.js +61 -0
  163. common/src/modules/elements/counter/__tests__/__snapshots__/element.test.js.snap +57 -0
  164. common/src/modules/elements/counter/__tests__/element.test.js +32 -0
  165. common/src/modules/elements/counter/element.js +37 -0
  166. common/src/modules/elements/counter/style.pcss +22 -0
  167. common/src/modules/elements/creatable-select/__tests__/__snapshots__/element.test.js.snap +241 -0
  168. common/src/modules/elements/creatable-select/__tests__/element.test.js +31 -0
  169. common/src/modules/elements/creatable-select/element.js +50 -0
  170. common/src/modules/elements/creatable-select/style.pcss +75 -0
  171. common/src/modules/elements/day-picker-input/element.js +34 -0
  172. common/src/modules/elements/day-picker-input/style.pcss +109 -0
  173. common/src/modules/elements/heading/__tests__/__snapshots__/element.test.js.snap +49 -0
  174. common/src/modules/elements/heading/__tests__/element.test.js +47 -0
  175. common/src/modules/elements/heading/element.js +32 -0
  176. common/src/modules/elements/heading/style.pcss +16 -0
  177. common/src/modules/elements/image-upload/__tests__/__snapshots__/element.test.js.snap +191 -0
  178. common/src/modules/elements/image-upload/__tests__/element.test.js +168 -0
  179. common/src/modules/elements/image-upload/element.js +114 -0
  180. common/src/modules/elements/image-upload/style.pcss +109 -0
  181. common/src/modules/elements/image/__tests__/__snapshots__/element.test.js.snap +27 -0
  182. common/src/modules/elements/image/__tests__/element.test.js +38 -0
  183. common/src/modules/elements/image/element.js +28 -0
  184. common/src/modules/elements/index.js +36 -0
  185. common/src/modules/elements/input/__tests__/__snapshots__/element.test.js.snap +23 -0
  186. common/src/modules/elements/input/__tests__/element.test.js +28 -0
  187. common/src/modules/elements/input/element.js +30 -0
  188. common/src/modules/elements/input/style.pcss +25 -0
  189. common/src/modules/elements/label-with-link/__tests__/__snapshots__/element.test.js.snap +51 -0
  190. common/src/modules/elements/label-with-link/__tests__/element.test.js +32 -0
  191. common/src/modules/elements/label-with-link/element.js +66 -0
  192. common/src/modules/elements/label-with-link/style.pcss +54 -0
  193. common/src/modules/elements/label-with-modal/__tests__/__snapshots__/element.test.js.snap +60 -0
  194. common/src/modules/elements/label-with-modal/__tests__/element.test.js +26 -0
  195. common/src/modules/elements/label-with-modal/element.js +71 -0
  196. common/src/modules/elements/label-with-modal/style.pcss +53 -0
  197. common/src/modules/elements/labeled-item/__tests__/__snapshots__/element.test.js.snap +50 -0
  198. common/src/modules/elements/labeled-item/__tests__/element.test.js +39 -0
  199. common/src/modules/elements/labeled-item/element.js +52 -0
  200. common/src/modules/elements/link/__tests__/__snapshots__/element.test.js.snap +40 -0
  201. common/src/modules/elements/link/__tests__/element.test.js +39 -0
  202. common/src/modules/elements/link/element.js +44 -0
  203. common/src/modules/elements/modal-button/__tests__/__snapshots__/element.test.js.snap +51 -0
  204. common/src/modules/elements/modal-button/__tests__/element.test.js +46 -0
  205. common/src/modules/elements/modal-button/element.js +107 -0
  206. common/src/modules/elements/number-input/__tests__/__snapshots__/element.test.js.snap +55 -0
  207. common/src/modules/elements/number-input/__tests__/element.test.js +47 -0
  208. common/src/modules/elements/number-input/element.js +40 -0
  209. common/src/modules/elements/paragraph/__tests__/__snapshots__/element.test.js.snap +17 -0
  210. common/src/modules/elements/paragraph/__tests__/element.test.js +19 -0
  211. common/src/modules/elements/paragraph/element.js +41 -0
  212. common/src/modules/elements/paragraph/style.pcss +24 -0
  213. common/src/modules/elements/placeholder/__tests__/__snapshots__/element.test.js.snap +17 -0
  214. common/src/modules/elements/placeholder/__tests__/element.test.js +18 -0
  215. common/src/modules/elements/placeholder/element.js +23 -0
  216. common/src/modules/elements/placeholder/style.pcss +12 -0
  217. common/src/modules/elements/radio-input/element.js +29 -0
  218. common/src/modules/elements/radio/element.js +50 -0
  219. common/src/modules/elements/select/__tests__/__snapshots__/element.test.js.snap +241 -0
  220. common/src/modules/elements/select/__tests__/element.test.js +31 -0
  221. common/src/modules/elements/select/element.js +41 -0
  222. common/src/modules/elements/select/style.pcss +78 -0
  223. common/src/modules/elements/style.pcss +3 -0
  224. common/src/modules/elements/textarea/element.js +20 -0
  225. common/src/modules/elements/time-picker/element.js +204 -0
  226. common/src/modules/elements/time-picker/style.pcss +86 -0
  227. common/src/modules/elements/tooltip/__tests__/__snapshots__/element.test.js.snap +22 -0
  228. common/src/modules/elements/tooltip/__tests__/element.test.js +33 -0
  229. common/src/modules/elements/tooltip/element.js +56 -0
  230. common/src/modules/elements/tooltip/style.pcss +14 -0
  231. common/src/modules/elements/url-input/element.js +27 -0
  232. common/src/modules/hoc/__tests__/__snapshots__/with-form.test.js.snap +19 -0
  233. common/src/modules/hoc/__tests__/__snapshots__/with-save-data.test.js.snap +62 -0
  234. common/src/modules/hoc/__tests__/__snapshots__/with-store.test.js.snap +18 -0
  235. common/src/modules/hoc/__tests__/with-form.test.js +89 -0
  236. common/src/modules/hoc/__tests__/with-save-data.test.js +191 -0
  237. common/src/modules/hoc/__tests__/with-selected.test.js +97 -0
  238. common/src/modules/hoc/__tests__/with-store.test.js +28 -0
  239. common/src/modules/hoc/index.js +5 -0
  240. common/src/modules/hoc/with-block-closer.js +129 -0
  241. common/src/modules/hoc/with-form.js +71 -0
  242. {src/modules/blocks → common/src/modules}/hoc/with-save-data.js +1 -6
  243. common/src/modules/hoc/with-selected.js +64 -0
  244. common/src/modules/hoc/with-store.js +26 -0
  245. common/src/modules/package.json +17 -0
  246. common/src/modules/store/configure-store.js +37 -0
  247. common/src/modules/store/index.js +13 -0
  248. common/src/modules/store/middlewares/index.js +3 -0
  249. common/src/modules/store/middlewares/request/__tests__/__snapshots__/actions.test.js.snap +11 -0
  250. common/src/modules/store/middlewares/request/__tests__/actions.test.js +14 -0
  251. common/src/modules/store/middlewares/request/__tests__/types.test.js +11 -0
  252. common/src/modules/store/middlewares/request/__tests__/utils.test.js +61 -0
  253. common/src/modules/store/middlewares/request/__tests__/wp-request.test.js +169 -0
  254. common/src/modules/store/middlewares/request/actions.js +9 -0
  255. common/src/modules/store/middlewares/request/index.js +9 -0
  256. common/src/modules/store/middlewares/request/types.js +6 -0
  257. common/src/modules/store/middlewares/request/utils.js +32 -0
  258. common/src/modules/store/middlewares/request/wp-request.js +76 -0
  259. common/src/modules/utils/__tests__/__snapshots__/globals.test.js.snap +93 -0
  260. common/src/modules/utils/__tests__/__snapshots__/time.test.js.snap +33 -0
  261. common/src/modules/utils/__tests__/date.test.js +189 -0
  262. common/src/modules/utils/__tests__/dom.test.js +73 -0
  263. common/src/modules/utils/__tests__/globals.test.js +84 -0
  264. common/src/modules/utils/__tests__/input.test.js +20 -0
  265. common/src/modules/utils/__tests__/moment.test.js +332 -0
  266. common/src/modules/utils/__tests__/number.test.js +36 -0
  267. common/src/modules/utils/__tests__/proptypes.test.js +145 -0
  268. common/src/modules/utils/__tests__/range.test.js +65 -0
  269. common/src/modules/utils/__tests__/slide.test.js +12 -0
  270. common/src/modules/utils/__tests__/string.test.js +135 -0
  271. common/src/modules/utils/__tests__/time.test.js +222 -0
  272. common/src/modules/utils/api.js +57 -0
  273. common/src/modules/utils/date.js +151 -0
  274. common/src/modules/utils/dom.js +50 -0
  275. common/src/modules/utils/get-hidden-height.js +28 -0
  276. common/src/modules/utils/globals.js +37 -0
  277. common/src/modules/utils/index.js +27 -0
  278. common/src/modules/utils/input.js +12 -0
  279. common/src/modules/utils/moment.js +332 -0
  280. common/src/modules/utils/number.js +22 -0
  281. common/src/modules/utils/proptypes.js +73 -0
  282. common/src/modules/utils/range.js +89 -0
  283. common/src/modules/utils/slide.js +119 -0
  284. common/src/modules/utils/string.js +109 -0
  285. common/src/modules/utils/time.js +207 -0
  286. common/src/modules/utils/timezone.js +72 -0
  287. common/src/resources/css/accessibility.css +34 -0
  288. common/src/resources/css/app-shop.css +102 -0
  289. common/src/resources/css/app/components.css +2 -0
  290. common/src/resources/css/app/components.min.css +1 -1
  291. common/src/resources/css/app/elements.css +20 -0
  292. common/src/resources/css/app/elements.min.css +1 -1
  293. common/src/resources/css/bumpdown.css +69 -0
  294. common/src/resources/css/buttonset.css +39 -0
  295. common/src/resources/css/common-full.css +2300 -0
  296. common/src/resources/css/common-full.min.css +1 -1
  297. common/src/resources/css/common-skeleton.css +1740 -0
  298. common/src/resources/css/common-skeleton.min.css +1 -1
  299. common/src/resources/css/datatables.css +396 -0
  300. common/src/resources/css/datepicker.css +566 -0
  301. common/src/resources/css/dependency.css +30 -0
  302. common/src/resources/css/dialog.css +204 -0
  303. common/src/resources/css/dialog.min.css +1 -1
  304. common/src/resources/css/promoter.css +33 -0
  305. common/src/resources/css/tooltip.css +121 -0
  306. common/src/resources/css/tooltip.min.css +1 -1
  307. common/src/resources/css/tribe-common-admin.css +1387 -0
  308. common/src/resources/css/tribe-common-admin.min.css +1 -1
  309. common/src/resources/css/tribe-ui.css +36 -0
  310. common/src/resources/css/tribe-ui.min.css +1 -1
  311. common/src/resources/css/validation.css +18 -0
  312. common/src/resources/images/app-shop-community.jpg +0 -0
  313. common/src/resources/images/app-shop-eventbrite.jpg +0 -0
  314. common/src/resources/images/app-shop-ical.jpg +0 -0
  315. common/src/resources/images/app-shop-pro.jpg +0 -0
  316. common/src/resources/images/app-shop-promoter.jpg +0 -0
  317. common/src/resources/images/app-shop-tickets-plus.jpg +0 -0
  318. common/src/resources/images/donate-link-screenshot.png +0 -0
  319. common/src/resources/images/gutenberg-admin-notice-TEC.png +0 -0
  320. common/src/resources/images/gutenberg-admin-notice-tickets.png +0 -0
  321. common/src/resources/images/mascot.png +0 -0
  322. common/src/resources/js/app/components.js +1407 -0
common/lang/readme.txt DELETED
@@ -1,3 +0,0 @@
1
- If you are interested in contributing to translations, you can get started at https://translations.theeventscalendar.com/projects/tribe-common/
2
-
3
- On that site you can also find the .po translation files for doing local translations. We do not include these in the plugin itself to save space.
 
 
 
common/lang/tribe-common-af.mo CHANGED
Binary file
common/lang/tribe-common-ar.mo CHANGED
Binary file
common/lang/tribe-common-bg_BG.mo CHANGED
Binary file
common/lang/tribe-common-ca.mo CHANGED
Binary file
common/lang/tribe-common-cs_CZ.mo CHANGED
Binary file
common/lang/tribe-common-da_DK.mo CHANGED
Binary file
common/lang/tribe-common-de_DE.mo CHANGED
Binary file
common/lang/tribe-common-el.mo CHANGED
Binary file
common/lang/tribe-common-en_GB.mo CHANGED
Binary file
common/lang/tribe-common-es_ES.mo CHANGED
Binary file
common/lang/tribe-common-et.mo CHANGED
Binary file
common/lang/tribe-common-fi.mo CHANGED
Binary file
common/lang/tribe-common-fr_CA.mo CHANGED
Binary file
common/lang/tribe-common-fr_FR.mo CHANGED
Binary file
common/lang/tribe-common-hu_HU.mo CHANGED
Binary file
common/lang/tribe-common-id_ID.mo CHANGED
Binary file
common/lang/tribe-common-is_IS.mo CHANGED
Binary file
common/lang/tribe-common-it_IT.mo CHANGED
Binary file
common/lang/tribe-common-ja.mo CHANGED
Binary file
common/lang/tribe-common-lt_LT.mo CHANGED
Binary file
common/lang/tribe-common-lv.mo CHANGED
Binary file
common/lang/tribe-common-nb_NO.mo CHANGED
Binary file
common/lang/tribe-common-nl_NL.mo CHANGED
Binary file
common/lang/tribe-common-pl_PL.mo ADDED
Binary file
common/lang/tribe-common-pt_BR.mo CHANGED
Binary file
common/lang/tribe-common-pt_PT.mo CHANGED
Binary file
common/lang/tribe-common-ro_RO.mo CHANGED
Binary file
common/lang/tribe-common-ru_RU.mo CHANGED
Binary file
common/lang/tribe-common-sk_SK.mo CHANGED
Binary file
common/lang/tribe-common-sl_SI.mo CHANGED
Binary file
common/lang/tribe-common-sr_RS.mo CHANGED
Binary file
common/lang/tribe-common-sv_SE.mo CHANGED
Binary file
common/lang/tribe-common-tr_TR.mo CHANGED
Binary file
common/lang/tribe-common-zh_CN.mo CHANGED
Binary file
common/lang/tribe-common-zh_TW.mo CHANGED
Binary file
common/lang/tribe-common.pot CHANGED
@@ -1,14 +1,16 @@
1
- # Copyright (C) 2020 Modern Tribe
2
  # This file is distributed under the same license as the Tribe Common package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Tribe Common 4.12.2\n"
 
6
  "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
7
- "POT-Creation-Date: 2020-05-19 04:07:31+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2020-05-19 04:07\n"
 
12
  "Last-Translator: \n"
13
  "Language-Team: \n"
14
 
@@ -40,7 +42,7 @@ msgstr ""
40
  msgid "Press \"Cmd + C\" to copy"
41
  msgstr ""
42
 
43
- #: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:563
44
  #: src/Tribe/Plugins_API.php:25
45
  msgid "The Events Calendar"
46
  msgstr ""
@@ -203,8 +205,7 @@ msgid "To begin using %2$s, please install and activate %3$s."
203
  msgstr ""
204
 
205
  #: src/Tribe/Admin/Notice/Plugin_Download.php:124
206
- #: src/Tribe/PUE/Update_Prevention.php:181
207
- msgid "Read more"
208
  msgstr ""
209
 
210
  #: src/Tribe/Admin/Notice/Plugin_Download.php:125
@@ -252,7 +253,7 @@ msgstr ""
252
  msgid "Rate %1$sEvent Tickets%2$s %3$s"
253
  msgstr ""
254
 
255
- #: src/Tribe/Customizer.php:564
256
  msgid ""
257
  "Use the following panel of your customizer to change the styling of your "
258
  "Calendar and Event pages."
@@ -291,11 +292,6 @@ msgstr ""
291
  msgid "State"
292
  msgstr ""
293
 
294
- #: src/Tribe/Debug_Bar/Panels/Json_Ld.php:21
295
- #: src/Tribe/Debug_Bar/Panels/Json_Ld.php:40
296
- msgid "Modern Tribe JSON-LD Data"
297
- msgstr ""
298
-
299
  #: src/Tribe/Dialog/View.php:153
300
  msgid "Open the modal window"
301
  msgstr ""
@@ -441,24 +437,24 @@ msgid "Problem loading the block, please remove this block to restart."
441
  msgstr ""
442
 
443
  #. translators: %s: duration
444
- #: src/Tribe/Editor/Configuration.php:89
445
  msgid "%s from now"
446
  msgstr ""
447
 
448
  #. translators: %s: duration
449
- #: src/Tribe/Editor/Configuration.php:91
450
  msgid "%s ago"
451
  msgstr ""
452
 
453
- #: src/Tribe/Editor/Configuration.php:95 src/Tribe/Editor/Configuration.php:98
454
  msgid "g:i a"
455
  msgstr ""
456
 
457
- #: src/Tribe/Editor/Configuration.php:96 src/Tribe/Editor/Configuration.php:98
458
  msgid "F j, Y"
459
  msgstr ""
460
 
461
- #: src/Tribe/Editor/Configuration.php:97
462
  msgid "F j"
463
  msgstr ""
464
 
@@ -478,7 +474,7 @@ msgstr ""
478
  msgid "Tutorial"
479
  msgstr ""
480
 
481
- #: src/Tribe/Extension.php:406
482
  msgid ""
483
  "Unable to run Tribe Extensions. Your website host is running PHP 5.2 or "
484
  "older, and has likely disabled or misconfigured debug_backtrace(). You, or "
@@ -486,28 +482,19 @@ msgid ""
486
  "debug_backtrace() for Tribe Extensions to work."
487
  msgstr ""
488
 
489
- #: src/Tribe/Extension.php:421
490
- msgctxt "extension disallowed"
491
- msgid ""
492
- "This extension has been programmatically disallowed. The most common reason "
493
- "is due to another Modern Tribe plugin having absorbed or replaced this "
494
- "extension's functionality. This extension plugin has been deactivated, and "
495
- "you should likely delete it."
496
- msgstr ""
497
-
498
- #: src/Tribe/Field.php:233
499
  msgid "Invalid field type specified"
500
  msgstr ""
501
 
502
- #: src/Tribe/Field.php:541
503
  msgid "No radio options specified"
504
  msgstr ""
505
 
506
- #: src/Tribe/Field.php:577
507
  msgid "No checkbox options specified"
508
  msgstr ""
509
 
510
- #: src/Tribe/Field.php:638
511
  msgid "No select options specified"
512
  msgstr ""
513
 
@@ -843,8 +830,7 @@ msgstr ""
843
  msgid "Gambia"
844
  msgstr ""
845
 
846
- #: src/Tribe/Languages/Locations.php:138
847
- msgctxt "The country"
848
  msgid "Georgia"
849
  msgstr ""
850
 
@@ -1524,11 +1510,6 @@ msgstr ""
1524
  msgid "Florida"
1525
  msgstr ""
1526
 
1527
- #: src/Tribe/Languages/Locations.php:334
1528
- msgctxt "The US state Georgia"
1529
- msgid "Georgia"
1530
- msgstr ""
1531
-
1532
  #: src/Tribe/Languages/Locations.php:335
1533
  msgid "Hawaii"
1534
  msgstr ""
@@ -1731,87 +1712,87 @@ msgstr ""
1731
  msgid "Full debug (all events)"
1732
  msgstr ""
1733
 
1734
- #: src/Tribe/Main.php:313
1735
  msgid ": activate to sort column ascending"
1736
  msgstr ""
1737
 
1738
- #: src/Tribe/Main.php:314
1739
  msgid ": activate to sort column descending"
1740
  msgstr ""
1741
 
1742
- #: src/Tribe/Main.php:316
1743
  msgid "Show _MENU_ entries"
1744
  msgstr ""
1745
 
1746
- #: src/Tribe/Main.php:317
1747
  msgid "No data available in table"
1748
  msgstr ""
1749
 
1750
- #: src/Tribe/Main.php:318
1751
  msgid "Showing _START_ to _END_ of _TOTAL_ entries"
1752
  msgstr ""
1753
 
1754
- #: src/Tribe/Main.php:319
1755
  msgid "Showing 0 to 0 of 0 entries"
1756
  msgstr ""
1757
 
1758
- #: src/Tribe/Main.php:320
1759
  msgid "(filtered from _MAX_ total entries)"
1760
  msgstr ""
1761
 
1762
- #: src/Tribe/Main.php:321
1763
  msgid "No matching records found"
1764
  msgstr ""
1765
 
1766
- #: src/Tribe/Main.php:322
1767
  msgid "Search:"
1768
  msgstr ""
1769
 
1770
- #: src/Tribe/Main.php:323
1771
  msgid "All items on this page were selected. "
1772
  msgstr ""
1773
 
1774
- #: src/Tribe/Main.php:324
1775
  msgid "Select all pages"
1776
  msgstr ""
1777
 
1778
- #: src/Tribe/Main.php:325
1779
  msgid "Clear Selection."
1780
  msgstr ""
1781
 
1782
- #: src/Tribe/Main.php:327
1783
  msgid "All"
1784
  msgstr ""
1785
 
1786
- #: src/Tribe/Main.php:328 src/Tribe/Main.php:345
1787
  msgid "Next"
1788
  msgstr ""
1789
 
1790
- #: src/Tribe/Main.php:329
1791
  msgid "Previous"
1792
  msgstr ""
1793
 
1794
- #: src/Tribe/Main.php:334
1795
  msgid ": Selected %d rows"
1796
  msgstr ""
1797
 
1798
- #: src/Tribe/Main.php:335
1799
  msgid ": Selected 1 row"
1800
  msgstr ""
1801
 
1802
- #: src/Tribe/Main.php:346
1803
  msgid "Prev"
1804
  msgstr ""
1805
 
1806
- #: src/Tribe/Main.php:347 src/Tribe/Main.php:349
1807
  msgid "Today"
1808
  msgstr ""
1809
 
1810
- #: src/Tribe/Main.php:348
1811
  msgid "Done"
1812
  msgstr ""
1813
 
1814
- #: src/Tribe/Main.php:350
1815
  msgid "Clear"
1816
  msgstr ""
1817
 
@@ -1850,68 +1831,68 @@ msgstr ""
1850
  msgid "License key(s) updated."
1851
  msgstr ""
1852
 
1853
- #: src/Tribe/PUE/Checker.php:907
1854
  msgid ""
1855
  "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
1856
  msgstr ""
1857
 
1858
- #: src/Tribe/PUE/Checker.php:920
1859
  msgid "unknown date"
1860
  msgstr ""
1861
 
1862
- #: src/Tribe/PUE/Checker.php:926
1863
  msgid "Sorry, key validation server is not available."
1864
  msgstr ""
1865
 
1866
- #: src/Tribe/PUE/Checker.php:946
1867
  msgid "Valid Key! Expires on %s"
1868
  msgstr ""
1869
 
1870
- #: src/Tribe/PUE/Checker.php:951
1871
  msgid "Thanks for setting up a valid key. It will expire on %s"
1872
  msgstr ""
1873
 
1874
- #: src/Tribe/PUE/Checker.php:978 src/Tribe/PUE/Notices.php:342
1875
  msgid "Renew Your License Now"
1876
  msgstr ""
1877
 
1878
- #: src/Tribe/PUE/Checker.php:980 src/Tribe/PUE/Notices.php:344
1879
  msgid " (opens in a new window)"
1880
  msgstr ""
1881
 
1882
- #: src/Tribe/PUE/Checker.php:997
1883
  msgid "Please refresh the page and try your request again."
1884
  msgstr ""
1885
 
1886
- #: src/Tribe/PUE/Checker.php:1017
1887
  msgid ""
1888
  "There is an update for %s. You'll need to %scheck your license%s to have "
1889
  "access to updates, downloads, and support."
1890
  msgstr ""
1891
 
1892
- #: src/Tribe/PUE/Checker.php:1074
1893
  msgid ""
1894
  "There is an update for %s. %sRenew your license%s to get access to bug "
1895
  "fixes, security updates, and new features."
1896
  msgstr ""
1897
 
1898
- #: src/Tribe/PUE/Checker.php:1104
1899
  msgid "Update now to version %s."
1900
  msgstr ""
1901
 
1902
- #: src/Tribe/PUE/Checker.php:1115
1903
  msgid "There is a new version of %1$s available. %2$s"
1904
  msgstr ""
1905
 
1906
- #: src/Tribe/PUE/Checker.php:1696
1907
  msgid "A valid license has been entered by your network administrator."
1908
  msgstr ""
1909
 
1910
- #: src/Tribe/PUE/Checker.php:1697
1911
  msgid "No license entered. Consult your network administrator."
1912
  msgstr ""
1913
 
1914
- #: src/Tribe/PUE/Checker.php:1698
1915
  msgid "Expired license. Consult your network administrator."
1916
  msgstr ""
1917
 
@@ -1958,6 +1939,10 @@ msgctxt "formatted plugin list"
1958
  msgid "%1$s and %2$s"
1959
  msgstr ""
1960
 
 
 
 
 
1961
  #: src/Tribe/PUE/Update_Prevention.php:184
1962
  msgid ""
1963
  "Your update failed due to an incompatibility between the version (%1$s) of "
@@ -1965,12 +1950,6 @@ msgid ""
1965
  "%4$s"
1966
  msgstr ""
1967
 
1968
- #: src/Tribe/Plugins.php:147
1969
- msgid ""
1970
- "Using this function before \"plugins_loaded\" action has fired can return "
1971
- "unreliable results."
1972
- msgstr ""
1973
-
1974
  #: src/Tribe/Plugins_API.php:28
1975
  msgid ""
1976
  "Create an events calendar and manage it with ease. The Events Calendar "
@@ -2146,24 +2125,24 @@ msgstr[1] ""
2146
  msgid "Settings saved."
2147
  msgstr ""
2148
 
2149
- #: src/Tribe/Settings_Manager.php:80
2150
  msgid "General"
2151
  msgstr ""
2152
 
2153
- #: src/Tribe/Settings_Manager.php:81
2154
  msgid "Display"
2155
  msgstr ""
2156
 
2157
- #: src/Tribe/Settings_Manager.php:254
2158
  msgid "Network"
2159
  msgstr ""
2160
 
2161
- #: src/Tribe/Settings_Manager.php:288
2162
  #: src/admin-views/tribe-options-licenses.php:57
2163
  msgid "Licenses"
2164
  msgstr ""
2165
 
2166
- #: src/Tribe/Settings_Manager.php:318
2167
  msgid "Help"
2168
  msgstr ""
2169
 
@@ -2201,42 +2180,42 @@ msgid ""
2201
  "overrides is provided below."
2202
  msgstr ""
2203
 
2204
- #: src/Tribe/Support.php:182
2205
  msgid "English"
2206
  msgstr ""
2207
 
2208
- #: src/Tribe/Support.php:201 src/Tribe/Support.php:202
2209
  msgid "Unknown or not set"
2210
  msgstr ""
2211
 
2212
- #: src/Tribe/Support.php:212
2213
  msgid ""
2214
  "Rewrite rules were purged on load of this help page. Chances are there is a "
2215
  "rewrite rule flush occurring in a plugin or theme!"
2216
  msgstr ""
2217
 
2218
- #: src/Tribe/Support.php:318
2219
  msgid ""
2220
  "Yes, automatically share my system information with the Modern Tribe support "
2221
  "team"
2222
  msgstr ""
2223
 
2224
- #: src/Tribe/Support.php:319
2225
  msgid ""
2226
  "Your system information will only be used by the Modern Tribe support team. "
2227
  "All information is stored securely. We do not share this information with "
2228
  "any third parties."
2229
  msgstr ""
2230
 
2231
- #: src/Tribe/Support.php:338 src/Tribe/Support.php:343
2232
  msgid "Invalid Key"
2233
  msgstr ""
2234
 
2235
- #: src/Tribe/Support.php:371 src/Tribe/Support.php:397
2236
  msgid "Permission Error"
2237
  msgstr ""
2238
 
2239
- #: src/Tribe/Support.php:385
2240
  msgid "Unique System Info Key Generated"
2241
  msgstr ""
2242
 
@@ -2286,69 +2265,69 @@ msgstr ""
2286
  msgid "%s must be a whole number."
2287
  msgstr ""
2288
 
2289
- #: src/Tribe/Validate.php:250
2290
  msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
2291
  msgstr ""
2292
 
2293
- #: src/Tribe/Validate.php:263
2294
  msgid "%s must be a valid URL."
2295
  msgstr ""
2296
 
2297
- #: src/Tribe/Validate.php:277 src/Tribe/Validate.php:289
2298
- #: src/Tribe/Validate.php:302 src/Tribe/Validate.php:322
2299
  msgid "%s must have a value that's part of its options."
2300
  msgstr ""
2301
 
2302
- #: src/Tribe/Validate.php:334
2303
  msgid ""
2304
  "Comparison validation failed because no comparison value was provided, for "
2305
  "field %s"
2306
  msgstr ""
2307
 
2308
- #: src/Tribe/Validate.php:341
2309
  msgid "%s cannot be the same as %s."
2310
  msgstr ""
2311
 
2312
- #: src/Tribe/Validate.php:343
2313
  msgid "%s cannot be a duplicate"
2314
  msgstr ""
2315
 
2316
- #: src/Tribe/Validate.php:357
2317
  msgid "%s must be a number or percentage."
2318
  msgstr ""
2319
 
2320
- #: src/Tribe/Validate.php:401
2321
  msgid "%s must be a number between 0 and 21."
2322
  msgstr ""
2323
 
2324
- #: src/Tribe/Validate.php:415
2325
  msgid ""
2326
  "%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
2327
  msgstr ""
2328
 
2329
- #: src/Tribe/Validate.php:429
2330
  msgid "%s must consist of letters, spaces, apostrophes, and dashes."
2331
  msgstr ""
2332
 
2333
- #: src/Tribe/Validate.php:441
2334
  msgid "%s must consist of 5 numbers."
2335
  msgstr ""
2336
 
2337
- #: src/Tribe/Validate.php:453
2338
  msgid "%s must be a phone number."
2339
  msgstr ""
2340
 
2341
- #: src/Tribe/Validate.php:467
2342
  msgid ""
2343
  "Country List must be formatted as one country per line in the following "
2344
  "format: <br>US, United States <br> UK, United Kingdom."
2345
  msgstr ""
2346
 
2347
- #: src/Tribe/Validate.php:496
2348
  msgid "%s must be an email address."
2349
  msgstr ""
2350
 
2351
- #: src/Tribe/View_Helpers.php:59
2352
  msgid "Select a Country:"
2353
  msgstr ""
2354
 
1
+ # Copyright (C) 2019 Modern Tribe
2
  # This file is distributed under the same license as the Tribe Common package.
3
  msgid ""
4
  msgstr ""
5
+
6
+ "Project-Id-Version: Tribe Common 4.10.2\n"
7
  "Report-Msgid-Bugs-To: http://m.tri.be/191x\n"
8
+ "POT-Creation-Date: 2019-12-10 00:34:42+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2019-12-10 00:34\n"
13
+
14
  "Last-Translator: \n"
15
  "Language-Team: \n"
16
 
42
  msgid "Press \"Cmd + C\" to copy"
43
  msgstr ""
44
 
45
+ #: src/Tribe/Admin/Help_Page.php:79 src/Tribe/Customizer.php:642
46
  #: src/Tribe/Plugins_API.php:25
47
  msgid "The Events Calendar"
48
  msgstr ""
205
  msgstr ""
206
 
207
  #: src/Tribe/Admin/Notice/Plugin_Download.php:124
208
+ msgid "Read more."
 
209
  msgstr ""
210
 
211
  #: src/Tribe/Admin/Notice/Plugin_Download.php:125
253
  msgid "Rate %1$sEvent Tickets%2$s %3$s"
254
  msgstr ""
255
 
256
+ #: src/Tribe/Customizer.php:643
257
  msgid ""
258
  "Use the following panel of your customizer to change the styling of your "
259
  "Calendar and Event pages."
292
  msgid "State"
293
  msgstr ""
294
 
 
 
 
 
 
295
  #: src/Tribe/Dialog/View.php:153
296
  msgid "Open the modal window"
297
  msgstr ""
437
  msgstr ""
438
 
439
  #. translators: %s: duration
440
+ #: src/Tribe/Editor/Configuration.php:88
441
  msgid "%s from now"
442
  msgstr ""
443
 
444
  #. translators: %s: duration
445
+ #: src/Tribe/Editor/Configuration.php:90
446
  msgid "%s ago"
447
  msgstr ""
448
 
449
+ #: src/Tribe/Editor/Configuration.php:94 src/Tribe/Editor/Configuration.php:97
450
  msgid "g:i a"
451
  msgstr ""
452
 
453
+ #: src/Tribe/Editor/Configuration.php:95 src/Tribe/Editor/Configuration.php:97
454
  msgid "F j, Y"
455
  msgstr ""
456
 
457
+ #: src/Tribe/Editor/Configuration.php:96
458
  msgid "F j"
459
  msgstr ""
460
 
474
  msgid "Tutorial"
475
  msgstr ""
476
 
477
+ #: src/Tribe/Extension.php:377
478
  msgid ""
479
  "Unable to run Tribe Extensions. Your website host is running PHP 5.2 or "
480
  "older, and has likely disabled or misconfigured debug_backtrace(). You, or "
482
  "debug_backtrace() for Tribe Extensions to work."
483
  msgstr ""
484
 
485
+ #: src/Tribe/Field.php:231
 
 
 
 
 
 
 
 
 
486
  msgid "Invalid field type specified"
487
  msgstr ""
488
 
489
+ #: src/Tribe/Field.php:539
490
  msgid "No radio options specified"
491
  msgstr ""
492
 
493
+ #: src/Tribe/Field.php:575
494
  msgid "No checkbox options specified"
495
  msgstr ""
496
 
497
+ #: src/Tribe/Field.php:633
498
  msgid "No select options specified"
499
  msgstr ""
500
 
830
  msgid "Gambia"
831
  msgstr ""
832
 
833
+ #: src/Tribe/Languages/Locations.php:138 src/Tribe/Languages/Locations.php:334
 
834
  msgid "Georgia"
835
  msgstr ""
836
 
1510
  msgid "Florida"
1511
  msgstr ""
1512
 
 
 
 
 
 
1513
  #: src/Tribe/Languages/Locations.php:335
1514
  msgid "Hawaii"
1515
  msgstr ""
1712
  msgid "Full debug (all events)"
1713
  msgstr ""
1714
 
1715
+ #: src/Tribe/Main.php:284
1716
  msgid ": activate to sort column ascending"
1717
  msgstr ""
1718
 
1719
+ #: src/Tribe/Main.php:285
1720
  msgid ": activate to sort column descending"
1721
  msgstr ""
1722
 
1723
+ #: src/Tribe/Main.php:287
1724
  msgid "Show _MENU_ entries"
1725
  msgstr ""
1726
 
1727
+ #: src/Tribe/Main.php:288
1728
  msgid "No data available in table"
1729
  msgstr ""
1730
 
1731
+ #: src/Tribe/Main.php:289
1732
  msgid "Showing _START_ to _END_ of _TOTAL_ entries"
1733
  msgstr ""
1734
 
1735
+ #: src/Tribe/Main.php:290
1736
  msgid "Showing 0 to 0 of 0 entries"
1737
  msgstr ""
1738
 
1739
+ #: src/Tribe/Main.php:291
1740
  msgid "(filtered from _MAX_ total entries)"
1741
  msgstr ""
1742
 
1743
+ #: src/Tribe/Main.php:292
1744
  msgid "No matching records found"
1745
  msgstr ""
1746
 
1747
+ #: src/Tribe/Main.php:293
1748
  msgid "Search:"
1749
  msgstr ""
1750
 
1751
+ #: src/Tribe/Main.php:294
1752
  msgid "All items on this page were selected. "
1753
  msgstr ""
1754
 
1755
+ #: src/Tribe/Main.php:295
1756
  msgid "Select all pages"
1757
  msgstr ""
1758
 
1759
+ #: src/Tribe/Main.php:296
1760
  msgid "Clear Selection."
1761
  msgstr ""
1762
 
1763
+ #: src/Tribe/Main.php:298
1764
  msgid "All"
1765
  msgstr ""
1766
 
1767
+ #: src/Tribe/Main.php:299 src/Tribe/Main.php:316
1768
  msgid "Next"
1769
  msgstr ""
1770
 
1771
+ #: src/Tribe/Main.php:300
1772
  msgid "Previous"
1773
  msgstr ""
1774
 
1775
+ #: src/Tribe/Main.php:305
1776
  msgid ": Selected %d rows"
1777
  msgstr ""
1778
 
1779
+ #: src/Tribe/Main.php:306
1780
  msgid ": Selected 1 row"
1781
  msgstr ""
1782
 
1783
+ #: src/Tribe/Main.php:317
1784
  msgid "Prev"
1785
  msgstr ""
1786
 
1787
+ #: src/Tribe/Main.php:318 src/Tribe/Main.php:320
1788
  msgid "Today"
1789
  msgstr ""
1790
 
1791
+ #: src/Tribe/Main.php:319
1792
  msgid "Done"
1793
  msgstr ""
1794
 
1795
+ #: src/Tribe/Main.php:321
1796
  msgid "Clear"
1797
  msgstr ""
1798
 
1831
  msgid "License key(s) updated."
1832
  msgstr ""
1833
 
1834
+ #: src/Tribe/PUE/Checker.php:899
1835
  msgid ""
1836
  "Hmmm... something's wrong with this validator. Please contact %ssupport%s."
1837
  msgstr ""
1838
 
1839
+ #: src/Tribe/PUE/Checker.php:912
1840
  msgid "unknown date"
1841
  msgstr ""
1842
 
1843
+ #: src/Tribe/PUE/Checker.php:918
1844
  msgid "Sorry, key validation server is not available."
1845
  msgstr ""
1846
 
1847
+ #: src/Tribe/PUE/Checker.php:938
1848
  msgid "Valid Key! Expires on %s"
1849
  msgstr ""
1850
 
1851
+ #: src/Tribe/PUE/Checker.php:943
1852
  msgid "Thanks for setting up a valid key. It will expire on %s"
1853
  msgstr ""
1854
 
1855
+ #: src/Tribe/PUE/Checker.php:970 src/Tribe/PUE/Notices.php:342
1856
  msgid "Renew Your License Now"
1857
  msgstr ""
1858
 
1859
+ #: src/Tribe/PUE/Checker.php:972 src/Tribe/PUE/Notices.php:344
1860
  msgid " (opens in a new window)"
1861
  msgstr ""
1862
 
1863
+ #: src/Tribe/PUE/Checker.php:989
1864
  msgid "Please refresh the page and try your request again."
1865
  msgstr ""
1866
 
1867
+ #: src/Tribe/PUE/Checker.php:1009
1868
  msgid ""
1869
  "There is an update for %s. You'll need to %scheck your license%s to have "
1870
  "access to updates, downloads, and support."
1871
  msgstr ""
1872
 
1873
+ #: src/Tribe/PUE/Checker.php:1066
1874
  msgid ""
1875
  "There is an update for %s. %sRenew your license%s to get access to bug "
1876
  "fixes, security updates, and new features."
1877
  msgstr ""
1878
 
1879
+ #: src/Tribe/PUE/Checker.php:1096
1880
  msgid "Update now to version %s."
1881
  msgstr ""
1882
 
1883
+ #: src/Tribe/PUE/Checker.php:1107
1884
  msgid "There is a new version of %1$s available. %2$s"
1885
  msgstr ""
1886
 
1887
+ #: src/Tribe/PUE/Checker.php:1688
1888
  msgid "A valid license has been entered by your network administrator."
1889
  msgstr ""
1890
 
1891
+ #: src/Tribe/PUE/Checker.php:1689
1892
  msgid "No license entered. Consult your network administrator."
1893
  msgstr ""
1894
 
1895
+ #: src/Tribe/PUE/Checker.php:1690
1896
  msgid "Expired license. Consult your network administrator."
1897
  msgstr ""
1898
 
1939
  msgid "%1$s and %2$s"
1940
  msgstr ""
1941
 
1942
+ #: src/Tribe/PUE/Update_Prevention.php:181
1943
+ msgid "Read More."
1944
+ msgstr ""
1945
+
1946
  #: src/Tribe/PUE/Update_Prevention.php:184
1947
  msgid ""
1948
  "Your update failed due to an incompatibility between the version (%1$s) of "
1950
  "%4$s"
1951
  msgstr ""
1952
 
 
 
 
 
 
 
1953
  #: src/Tribe/Plugins_API.php:28
1954
  msgid ""
1955
  "Create an events calendar and manage it with ease. The Events Calendar "
2125
  msgid "Settings saved."
2126
  msgstr ""
2127
 
2128
+ #: src/Tribe/Settings_Manager.php:57
2129
  msgid "General"
2130
  msgstr ""
2131
 
2132
+ #: src/Tribe/Settings_Manager.php:58
2133
  msgid "Display"
2134
  msgstr ""
2135
 
2136
+ #: src/Tribe/Settings_Manager.php:222
2137
  msgid "Network"
2138
  msgstr ""
2139
 
2140
+ #: src/Tribe/Settings_Manager.php:256
2141
  #: src/admin-views/tribe-options-licenses.php:57
2142
  msgid "Licenses"
2143
  msgstr ""
2144
 
2145
+ #: src/Tribe/Settings_Manager.php:286
2146
  msgid "Help"
2147
  msgstr ""
2148
 
2180
  "overrides is provided below."
2181
  msgstr ""
2182
 
2183
+ #: src/Tribe/Support.php:171
2184
  msgid "English"
2185
  msgstr ""
2186
 
2187
+ #: src/Tribe/Support.php:188 src/Tribe/Support.php:189
2188
  msgid "Unknown or not set"
2189
  msgstr ""
2190
 
2191
+ #: src/Tribe/Support.php:199
2192
  msgid ""
2193
  "Rewrite rules were purged on load of this help page. Chances are there is a "
2194
  "rewrite rule flush occurring in a plugin or theme!"
2195
  msgstr ""
2196
 
2197
+ #: src/Tribe/Support.php:305
2198
  msgid ""
2199
  "Yes, automatically share my system information with the Modern Tribe support "
2200
  "team"
2201
  msgstr ""
2202
 
2203
+ #: src/Tribe/Support.php:306
2204
  msgid ""
2205
  "Your system information will only be used by the Modern Tribe support team. "
2206
  "All information is stored securely. We do not share this information with "
2207
  "any third parties."
2208
  msgstr ""
2209
 
2210
+ #: src/Tribe/Support.php:325 src/Tribe/Support.php:330
2211
  msgid "Invalid Key"
2212
  msgstr ""
2213
 
2214
+ #: src/Tribe/Support.php:358 src/Tribe/Support.php:384
2215
  msgid "Permission Error"
2216
  msgstr ""
2217
 
2218
+ #: src/Tribe/Support.php:372
2219
  msgid "Unique System Info Key Generated"
2220
  msgstr ""
2221
 
2265
  msgid "%s must be a whole number."
2266
  msgstr ""
2267
 
2268
+ #: src/Tribe/Validate.php:247
2269
  msgid "%s must be a valid slug (numbers, letters, dashes, and underscores)."
2270
  msgstr ""
2271
 
2272
+ #: src/Tribe/Validate.php:260
2273
  msgid "%s must be a valid URL."
2274
  msgstr ""
2275
 
2276
+ #: src/Tribe/Validate.php:274 src/Tribe/Validate.php:286
2277
+ #: src/Tribe/Validate.php:299 src/Tribe/Validate.php:319
2278
  msgid "%s must have a value that's part of its options."
2279
  msgstr ""
2280
 
2281
+ #: src/Tribe/Validate.php:331
2282
  msgid ""
2283
  "Comparison validation failed because no comparison value was provided, for "
2284
  "field %s"
2285
  msgstr ""
2286
 
2287
+ #: src/Tribe/Validate.php:338
2288
  msgid "%s cannot be the same as %s."
2289
  msgstr ""
2290
 
2291
+ #: src/Tribe/Validate.php:340
2292
  msgid "%s cannot be a duplicate"
2293
  msgstr ""
2294
 
2295
+ #: src/Tribe/Validate.php:354
2296
  msgid "%s must be a number or percentage."
2297
  msgstr ""
2298
 
2299
+ #: src/Tribe/Validate.php:398
2300
  msgid "%s must be a number between 0 and 21."
2301
  msgstr ""
2302
 
2303
+ #: src/Tribe/Validate.php:412
2304
  msgid ""
2305
  "%s must consist of letters, numbers, dashes, apostrophes, and spaces only."
2306
  msgstr ""
2307
 
2308
+ #: src/Tribe/Validate.php:426
2309
  msgid "%s must consist of letters, spaces, apostrophes, and dashes."
2310
  msgstr ""
2311
 
2312
+ #: src/Tribe/Validate.php:438
2313
  msgid "%s must consist of 5 numbers."
2314
  msgstr ""
2315
 
2316
+ #: src/Tribe/Validate.php:450
2317
  msgid "%s must be a phone number."
2318
  msgstr ""
2319
 
2320
+ #: src/Tribe/Validate.php:464
2321
  msgid ""
2322
  "Country List must be formatted as one country per line in the following "
2323
  "format: <br>US, United States <br> UK, United Kingdom."
2324
  msgstr ""
2325
 
2326
+ #: src/Tribe/Validate.php:493
2327
  msgid "%s must be an email address."
2328
  msgstr ""
2329
 
2330
+ #: src/Tribe/View_Helpers.php:51
2331
  msgid "Select a Country:"
2332
  msgstr ""
2333
 
common/src/Tribe/Admin/Notice/Plugin_Download.php CHANGED
@@ -121,7 +121,7 @@ class Tribe__Admin__Notice__Plugin_Download {
121
 
122
  $notice_html_content = '<p>' . esc_html__( 'To begin using %2$s, please install and activate %3$s.', 'tribe-common' ) . '</p>';
123
 
124
- $read_more_link = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read more', 'tribe-common' ) . '.</a>';
125
  $pue_notice_text = esc_html__( 'There’s a new version of %1$s available, but your license is expired. You’ll need to renew your license to get access to the latest version. If you plan to continue using your current version of the plugin(s), be sure to use a compatible version of The Events Calendar. %2$s', 'tribe-common' );
126
  $pue_notice_html = '<p>' . sprintf( $pue_notice_text, $plugin_names_clean_text, $read_more_link ) . '</p>';
127
 
@@ -163,4 +163,4 @@ class Tribe__Admin__Notice__Plugin_Download {
163
  return $output;
164
  }
165
 
166
- }
121
 
122
  $notice_html_content = '<p>' . esc_html__( 'To begin using %2$s, please install and activate %3$s.', 'tribe-common' ) . '</p>';
123
 
124
+ $read_more_link = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read more.', 'tribe-common' ) . '</a>';
125
  $pue_notice_text = esc_html__( 'There’s a new version of %1$s available, but your license is expired. You’ll need to renew your license to get access to the latest version. If you plan to continue using your current version of the plugin(s), be sure to use a compatible version of The Events Calendar. %2$s', 'tribe-common' );
126
  $pue_notice_html = '<p>' . sprintf( $pue_notice_text, $plugin_names_clean_text, $read_more_link ) . '</p>';
127
 
163
  return $output;
164
  }
165
 
166
+ }
common/src/Tribe/Admin/Notices.php CHANGED
@@ -111,15 +111,23 @@ class Tribe__Admin__Notices {
111
  $transients = $this->get_transients();
112
 
113
  foreach ( $transients as $slug => $transient ) {
114
- if ( $this->transient_notice_expired( $slug ) ) {
 
115
  continue;
116
  }
117
- list( $html, $args, $expire ) = $transients[ $slug ];
118
  $this->register( $slug, $html, $args );
119
  }
120
 
121
  foreach ( $this->notices as $notice ) {
122
- if ( ! $this->showing_notice( $notice->slug ) ) {
 
 
 
 
 
 
 
 
123
  continue;
124
  }
125
 
@@ -549,12 +557,6 @@ class Tribe__Admin__Notices {
549
  * @return array An associative array in the shape [ <slug> => [ <html>, <args>, <expire timestamp> ] ]
550
  */
551
  protected function get_transients() {
552
- $cached = tribe( 'cache' )['transient_admin_notices'];
553
-
554
- if ( false !== $cached ) {
555
- return $cached;
556
- }
557
-
558
  $transient = self::$transient_notices_name;
559
  $notices = get_transient( $transient );
560
  $notices = is_array( $notices ) ? $notices : array();
@@ -570,8 +572,6 @@ class Tribe__Admin__Notices {
570
  }
571
  }
572
 
573
- tribe( 'cache' )['transient_admin_notices'] = $notices;
574
-
575
  return $notices;
576
  }
577
 
@@ -586,84 +586,4 @@ class Tribe__Admin__Notices {
586
  $transient = self::$transient_notices_name;
587
  set_transient( $transient, $notices, MONTH_IN_SECONDS );
588
  }
589
-
590
- /**
591
- * Checks whether a specific transient admin notices is being shown or not, depending on its expiration and
592
- * dismissible status.
593
- *
594
- *
595
- * @since 4.11.1
596
- *
597
- * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
598
- * to register the transient notice in the `tribe_transient_notice` function or the
599
- * `Tribe__Admin__Notices::register_transient()` method.
600
- *
601
- * @return bool Whether the transient notice is showing or not.
602
- */
603
- public function showing_transient_notice( $slug ) {
604
- $transient_notices = (array) $this->get_transients();
605
-
606
- return isset( $transient_notices[ $slug ] )
607
- && ! $this->has_user_dimissed( $slug )
608
- && ! $this->transient_notice_expired( $slug );
609
- }
610
-
611
- /**
612
- * Checks whether a transient notice expired or not.
613
- *
614
- * @since 4.11.1
615
- *
616
- * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
617
- * to register the transient notice in the `tribe_transient_notice` function or the
618
- * `Tribe__Admin__Notices::register_transient()` method.
619
- *
620
- * @return bool Whether the transient notice is expired or not.
621
- */
622
- protected function transient_notice_expired( $slug ) {
623
- $transients = (array) $this->get_transients();
624
-
625
- if ( ! isset( $transients[ $slug ] ) ) {
626
- return true;
627
- }
628
-
629
- list( $html, $args, $expire ) = $transients[ $slug ];
630
- if ( $expire < time() ) {
631
- return true;
632
- }
633
-
634
- return false;
635
- }
636
-
637
- /**
638
- * Checks whether a notice is being shown or not; the result takes the notice callback and dismissible status into
639
- * account.
640
- *
641
- * @since 4.11.1
642
- *
643
- * @param string|array $slug The slug, or slugs, of the transient notices to check. This is the same slug used
644
- * to register the transient notice in the `tribe_transient_notice` function or the
645
- * `Tribe__Admin__Notices::register_transient()` method.
646
- *
647
- * @return bool Whether the notice is showing or not.
648
- */
649
- public function showing_notice( $slug ) {
650
- if ( ! isset( $this->notices[ $slug ] ) ) {
651
- return false;
652
- }
653
-
654
- $notice = $this->notices[ $slug ];
655
- if ( $notice->dismiss && $this->has_user_dimissed( $notice->slug ) ) {
656
- return false;
657
- }
658
-
659
- if (
660
- ! empty( $notice->active_callback )
661
- && is_callable( $notice->active_callback )
662
- && false == call_user_func( $notice->active_callback )
663
- ) {
664
- return false;
665
- }
666
-
667
- return true;
668
- }
669
  }
111
  $transients = $this->get_transients();
112
 
113
  foreach ( $transients as $slug => $transient ) {
114
+ list( $html, $args, $expire ) = $transient;
115
+ if ( $expire < time() ) {
116
  continue;
117
  }
 
118
  $this->register( $slug, $html, $args );
119
  }
120
 
121
  foreach ( $this->notices as $notice ) {
122
+ if ( $notice->dismiss && $this->has_user_dimissed( $notice->slug ) ) {
123
+ continue;
124
+ }
125
+
126
+ if (
127
+ ! empty( $notice->active_callback )
128
+ && is_callable( $notice->active_callback )
129
+ && false == call_user_func( $notice->active_callback )
130
+ ) {
131
  continue;
132
  }
133
 
557
  * @return array An associative array in the shape [ <slug> => [ <html>, <args>, <expire timestamp> ] ]
558
  */
559
  protected function get_transients() {
 
 
 
 
 
 
560
  $transient = self::$transient_notices_name;
561
  $notices = get_transient( $transient );
562
  $notices = is_array( $notices ) ? $notices : array();
572
  }
573
  }
574
 
 
 
575
  return $notices;
576
  }
577
 
586
  $transient = self::$transient_notices_name;
587
  set_transient( $transient, $notices, MONTH_IN_SECONDS );
588
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  }
common/src/Tribe/Assets.php CHANGED
@@ -49,13 +49,15 @@ class Tribe__Assets {
49
  */
50
  public function register_in_wp( $assets = null ) {
51
  if ( is_null( $assets ) ) {
52
- $assets = $this->get();
53
  }
54
 
55
  if ( ! is_array( $assets ) ) {
56
  $assets = [ $assets ];
57
  }
58
 
 
 
59
  foreach ( $assets as $asset ) {
60
  // Asset is already registered.
61
  if ( $asset->is_registered ) {
@@ -95,7 +97,7 @@ class Tribe__Assets {
95
  if ( did_action( $action ) > 0 ) {
96
  $this->enqueue();
97
  } else {
98
- add_action( $action, [ $this, 'enqueue' ], $asset->priority, 0 );
99
  }
100
  }
101
  }
@@ -111,7 +113,7 @@ class Tribe__Assets {
111
  * @param string|array $groups Which groups will be enqueued.
112
  */
113
  public function enqueue_group( $groups ) {
114
- $assets = $this->get( null, false );
115
  $enqueue = [];
116
 
117
  foreach ( $assets as $asset ) {
@@ -124,6 +126,7 @@ class Tribe__Assets {
124
  if ( empty( $intersect ) ) {
125
  continue;
126
  }
 
127
  $enqueue[] = $asset->slug;
128
  }
129
 
@@ -145,11 +148,7 @@ class Tribe__Assets {
145
  */
146
  public function enqueue( $forcibly_enqueue = null ) {
147
  $forcibly_enqueue = array_filter( (array) $forcibly_enqueue );
148
- if ( ! empty( $forcibly_enqueue ) ) {
149
- $assets = (array) $this->get( $forcibly_enqueue );
150
- } else {
151
- $assets = $this->get();
152
- }
153
 
154
  foreach ( $assets as $asset ) {
155
  // Should this asset be enqueued regardless of the current filter/any conditional requirements?
@@ -275,81 +274,53 @@ class Tribe__Assets {
275
  * @return string|false The url to the minified version or false, if file not found.
276
  */
277
  public static function maybe_get_min_file( $url ) {
278
- static $wpmu_plugin_url;
279
- static $wp_plugin_url;
280
- static $wp_content_url;
281
- static $plugins_url;
282
- static $base_dirs;
283
-
284
- $urls = [];
285
- if ( ! isset( $wpmu_plugin_url ) ) {
286
- $wpmu_plugin_url = set_url_scheme( WPMU_PLUGIN_URL );
287
- }
288
-
289
- if ( ! isset( $wp_plugin_url ) ) {
290
- $wp_plugin_url = set_url_scheme( WP_PLUGIN_URL );
291
- }
292
-
293
- if ( ! isset( $wp_content_url ) ) {
294
- $wp_content_url = set_url_scheme( WP_CONTENT_URL );
295
- }
296
-
297
- if ( ! isset( $plugins_url ) ) {
298
- $plugins_url = plugins_url();
299
- }
300
-
301
- if ( ! isset( $base_dirs ) ) {
302
- $base_dirs[ WPMU_PLUGIN_DIR ] = wp_normalize_path( WPMU_PLUGIN_DIR );
303
- $base_dirs[ WP_PLUGIN_DIR ] = wp_normalize_path( WP_PLUGIN_DIR );
304
- $base_dirs[ WP_CONTENT_DIR ] = wp_normalize_path( WP_CONTENT_DIR );
305
- }
306
 
307
  if ( 0 === strpos( $url, $wpmu_plugin_url ) ) {
308
  // URL inside WPMU plugin dir.
309
- $base_dir = $base_dirs[ WPMU_PLUGIN_DIR ];
310
  $base_url = $wpmu_plugin_url;
311
  } elseif ( 0 === strpos( $url, $wp_plugin_url ) ) {
312
  // URL inside WP plugin dir.
313
- $base_dir = $base_dirs[ WP_PLUGIN_DIR ];
314
  $base_url = $wp_plugin_url;
315
  } elseif ( 0 === strpos( $url, $wp_content_url ) ) {
316
  // URL inside WP content dir.
317
- $base_dir = $base_dirs[ WP_CONTENT_DIR ];
318
  $base_url = $wp_content_url;
319
  } elseif ( 0 === strpos( $url, $plugins_url ) ) {
320
- $base_dir = $base_dirs[ WP_PLUGIN_DIR ];
321
  $base_url = $plugins_url;
322
  } else {
323
  // Resource needs to be inside wp-content or a plugins dir.
324
  return false;
325
  }
326
 
327
- $script_debug = defined( 'SCRIPT_DEBUG' ) && tribe_is_truthy( SCRIPT_DEBUG );
328
-
329
  // Strip the plugin URL and make this relative.
330
  $relative_location = str_replace( $base_url, '', $url );
331
 
332
- if ( $script_debug ) {
333
- // Add the actual url after having the min file added.
334
- $urls[] = $relative_location;
335
- }
336
-
337
  // If needed add the Min Files.
338
- if ( substr( $relative_location, -3, 3 ) === '.js' ) {
339
- $urls[] = substr_replace( $relative_location, '.min', - 3, 0 );
340
- } elseif ( substr( $relative_location, -4, 4 ) === '.css' ) {
341
- $urls[] = substr_replace( $relative_location, '.min', - 4, 0 );
342
- }
343
 
344
- if ( ! $script_debug ) {
345
- // Add the actual url after having the min file added.
346
- $urls[] = $relative_location;
347
  }
348
 
 
 
 
349
  // Check for all Urls added to the array.
350
  foreach ( $urls as $partial_path ) {
351
  $file_path = wp_normalize_path( $base_dir . $partial_path );
352
- $file_url = $base_url . $partial_path;
353
 
354
  if ( file_exists( $file_path ) ) {
355
  return $file_url;
@@ -543,6 +514,9 @@ class Tribe__Assets {
543
  // Set the Asset on the array of notices.
544
  $this->assets[ $slug ] = $asset;
545
 
 
 
 
546
  // Return the Slug because it might be modified.
547
  return $asset;
548
  }
@@ -604,55 +578,19 @@ class Tribe__Assets {
604
  * Get the Asset Object configuration.
605
  *
606
  * @since 4.3
607
- * @since 4.11.0 Added $sort param.
608
  *
609
- * @param string|array $slug Slug of the Asset.
610
- * @param boolean $sort If we should do any sorting before returning.
611
  *
612
  * @return array|object|null Array of asset objects, single asset object, or null if looking for a single asset but
613
  * it was not in the array of objects.
614
  */
615
- public function get( $slug = null, $sort = true ) {
 
 
616
  if ( is_null( $slug ) ) {
617
- if ( $sort ) {
618
- $cache_key_count = __METHOD__ . ':count';
619
- // Sorts by priority.
620
- $cache_count = tribe_get_var( $cache_key_count, 0 );
621
- $count = count( $this->assets );
622
-
623
- if ( $count !== $cache_count ) {
624
- uasort( $this->assets, 'tribe_sort_by_priority' );
625
- tribe_set_var( $cache_key_count, $count );
626
- }
627
- }
628
  return $this->assets;
629
  }
630
 
631
- // If slug is an array we return all of those.
632
- if ( is_array( $slug ) ) {
633
- $assets = [];
634
- foreach ( $slug as $asset_slug ) {
635
- $asset_slug = sanitize_title_with_dashes( $asset_slug );
636
- // Skip empty assets.
637
- if ( empty( $this->assets[ $asset_slug ] ) ) {
638
- continue;
639
- }
640
-
641
- $assets[ $asset_slug ] = $this->assets[ $asset_slug ];
642
- }
643
-
644
- if ( empty( $assets ) ) {
645
- return null;
646
- }
647
-
648
- if ( $sort ) {
649
- // Sorts by priority.
650
- uasort( $assets, 'tribe_sort_by_priority' );
651
- }
652
-
653
- return $assets;
654
- }
655
-
656
  // Prevent weird stuff here.
657
  $slug = sanitize_title_with_dashes( $slug );
658
 
@@ -663,10 +601,24 @@ class Tribe__Assets {
663
  return null;
664
  }
665
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
  /**
667
  * Checks if an Asset exists.
668
  *
669
- * @param string|array $slug Slug of the Asset.
670
  *
671
  * @return bool
672
  */
49
  */
50
  public function register_in_wp( $assets = null ) {
51
  if ( is_null( $assets ) ) {
52
+ $assets = $this->assets;
53
  }
54
 
55
  if ( ! is_array( $assets ) ) {
56
  $assets = [ $assets ];
57
  }
58
 
59
+ uasort( $assets, [ $this, 'order_by_priority' ] );
60
+
61
  foreach ( $assets as $asset ) {
62
  // Asset is already registered.
63
  if ( $asset->is_registered ) {
97
  if ( did_action( $action ) > 0 ) {
98
  $this->enqueue();
99
  } else {
100
+ add_action( $action, [ $this, 'enqueue' ], $asset->priority );
101
  }
102
  }
103
  }
113
  * @param string|array $groups Which groups will be enqueued.
114
  */
115
  public function enqueue_group( $groups ) {
116
+ $assets = $this->get();
117
  $enqueue = [];
118
 
119
  foreach ( $assets as $asset ) {
126
  if ( empty( $intersect ) ) {
127
  continue;
128
  }
129
+
130
  $enqueue[] = $asset->slug;
131
  }
132
 
148
  */
149
  public function enqueue( $forcibly_enqueue = null ) {
150
  $forcibly_enqueue = array_filter( (array) $forcibly_enqueue );
151
+ $assets = $this->get();
 
 
 
 
152
 
153
  foreach ( $assets as $asset ) {
154
  // Should this asset be enqueued regardless of the current filter/any conditional requirements?
274
  * @return string|false The url to the minified version or false, if file not found.
275
  */
276
  public static function maybe_get_min_file( $url ) {
277
+ $urls = [];
278
+ $wpmu_plugin_url = set_url_scheme( WPMU_PLUGIN_URL );
279
+ $wp_plugin_url = set_url_scheme( WP_PLUGIN_URL );
280
+ $wp_content_url = set_url_scheme( WP_CONTENT_URL );
281
+ $plugins_url = plugins_url();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  if ( 0 === strpos( $url, $wpmu_plugin_url ) ) {
284
  // URL inside WPMU plugin dir.
285
+ $base_dir = wp_normalize_path( WPMU_PLUGIN_DIR );
286
  $base_url = $wpmu_plugin_url;
287
  } elseif ( 0 === strpos( $url, $wp_plugin_url ) ) {
288
  // URL inside WP plugin dir.
289
+ $base_dir = wp_normalize_path( WP_PLUGIN_DIR );
290
  $base_url = $wp_plugin_url;
291
  } elseif ( 0 === strpos( $url, $wp_content_url ) ) {
292
  // URL inside WP content dir.
293
+ $base_dir = wp_normalize_path( WP_CONTENT_DIR );
294
  $base_url = $wp_content_url;
295
  } elseif ( 0 === strpos( $url, $plugins_url ) ) {
296
+ $base_dir = wp_normalize_path( WP_PLUGIN_DIR );
297
  $base_url = $plugins_url;
298
  } else {
299
  // Resource needs to be inside wp-content or a plugins dir.
300
  return false;
301
  }
302
 
 
 
303
  // Strip the plugin URL and make this relative.
304
  $relative_location = str_replace( $base_url, '', $url );
305
 
 
 
 
 
 
306
  // If needed add the Min Files.
307
+ if ( ! defined( 'SCRIPT_DEBUG' ) || SCRIPT_DEBUG === false ) {
308
+ if ( substr( $relative_location, - 3, 3 ) === '.js' ) {
309
+ $urls[] = substr_replace( $relative_location, '.min', - 3, 0 );
310
+ }
 
311
 
312
+ if ( substr( $relative_location, - 4, 4 ) === '.css' ) {
313
+ $urls[] = substr_replace( $relative_location, '.min', - 4, 0 );
314
+ }
315
  }
316
 
317
+ // Add the actual url after having the min file added.
318
+ $urls[] = $relative_location;
319
+
320
  // Check for all Urls added to the array.
321
  foreach ( $urls as $partial_path ) {
322
  $file_path = wp_normalize_path( $base_dir . $partial_path );
323
+ $file_url = plugins_url( basename( $file_path ), $file_path );
324
 
325
  if ( file_exists( $file_path ) ) {
326
  return $file_url;
514
  // Set the Asset on the array of notices.
515
  $this->assets[ $slug ] = $asset;
516
 
517
+ // Sorts by priority.
518
+ uasort( $this->assets, [ $this, 'order_by_priority' ] );
519
+
520
  // Return the Slug because it might be modified.
521
  return $asset;
522
  }
578
  * Get the Asset Object configuration.
579
  *
580
  * @since 4.3
 
581
  *
582
+ * @param string $slug Slug of the Asset.
 
583
  *
584
  * @return array|object|null Array of asset objects, single asset object, or null if looking for a single asset but
585
  * it was not in the array of objects.
586
  */
587
+ public function get( $slug = null ) {
588
+ uasort( $this->assets, [ $this, 'order_by_priority' ] );
589
+
590
  if ( is_null( $slug ) ) {
 
 
 
 
 
 
 
 
 
 
 
591
  return $this->assets;
592
  }
593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594
  // Prevent weird stuff here.
595
  $slug = sanitize_title_with_dashes( $slug );
596
 
601
  return null;
602
  }
603
 
604
+ /**
605
+ * Add the Priority ordering, which was causing an issue of not respecting which order stuff was registered.
606
+ *
607
+ * @since 4.7
608
+ *
609
+ * @param object $a First Subject to compare.
610
+ * @param object $b Second subject to compare.
611
+ *
612
+ * @return boolean
613
+ */
614
+ public function order_by_priority( $a, $b ) {
615
+ return (int) $a->priority === (int) $b->priority ? 0 : (int) $a->priority > (int) $b->priority;
616
+ }
617
+
618
  /**
619
  * Checks if an Asset exists.
620
  *
621
+ * @param string $slug Slug of the Asset.
622
  *
623
  * @return bool
624
  */
common/src/Tribe/Autoloader.php CHANGED
@@ -121,14 +121,6 @@
121
  public function register_prefix( $prefix, $root_dir, $slug = '' ) {
122
  $root_dir = $this->normalize_root_dir( $root_dir );
123
 
124
- // Determine if we need to normalize the $prefix.
125
- $is_namespaced = false !== strpos( $prefix, '\\' );
126
-
127
- if ( $is_namespaced ) {
128
- // If the prefix is a namespace, then normalize it.
129
- $prefix = trim( $prefix, '\\' ) . '\\';
130
- }
131
-
132
  if ( ! isset( $this->prefixes[ $prefix ] ) ) {
133
  $this->prefixes[ $prefix ] = array();
134
  }
@@ -171,20 +163,11 @@
171
 
172
  protected function get_prefixed_path( $class ) {
173
  foreach ( $this->prefixes as $prefix => $dirs ) {
174
- $is_namespaced = false !== strpos( $prefix, '\\' );
175
-
176
  if ( strpos( $class, $prefix ) !== 0 ) {
177
  continue;
178
  }
179
-
180
  $class_name = str_replace( $prefix, '', $class );
181
-
182
- if ( ! $is_namespaced ) {
183
- $class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
184
- } else {
185
- $class_path_frag = implode( '/', explode( '\\', $class_name ) ) . '.php';
186
- }
187
-
188
  foreach ( $dirs as $dir ) {
189
  $path = $dir . '/' . $class_path_frag;
190
  if ( ! file_exists( $path ) ) {
121
  public function register_prefix( $prefix, $root_dir, $slug = '' ) {
122
  $root_dir = $this->normalize_root_dir( $root_dir );
123
 
 
 
 
 
 
 
 
 
124
  if ( ! isset( $this->prefixes[ $prefix ] ) ) {
125
  $this->prefixes[ $prefix ] = array();
126
  }
163
 
164
  protected function get_prefixed_path( $class ) {
165
  foreach ( $this->prefixes as $prefix => $dirs ) {
 
 
166
  if ( strpos( $class, $prefix ) !== 0 ) {
167
  continue;
168
  }
 
169
  $class_name = str_replace( $prefix, '', $class );
170
+ $class_path_frag = implode( '/', explode( $this->dir_separator, $class_name ) ) . '.php';
 
 
 
 
 
 
171
  foreach ( $dirs as $dir ) {
172
  $path = $dir . '/' . $class_path_frag;
173
  if ( ! file_exists( $path ) ) {
common/src/Tribe/Cache.php CHANGED
@@ -10,41 +10,23 @@
10
  * When used in its ArrayAccess API the cache will provide non persistent storage.
11
  */
12
  class Tribe__Cache implements ArrayAccess {
13
- const SCHEDULED_EVENT_DELETE_TRANSIENT = 'tribe_schedule_transient_purge';
14
-
15
- const NO_EXPIRATION = 0;
16
-
17
- const NON_PERSISTENT = -1;
18
 
19
  /**
20
  * @var array
21
  */
22
- protected $non_persistent_keys = [];
23
-
24
- /**
25
- * Bootstrap hook
26
- *
27
- * @since 4.11.0
28
- */
29
- public function hook() {
30
- if ( ! wp_next_scheduled( self::SCHEDULED_EVENT_DELETE_TRANSIENT ) ) {
31
- wp_schedule_event( time(), 'twicedaily', self::SCHEDULED_EVENT_DELETE_TRANSIENT );
32
- }
33
-
34
- add_action( self::SCHEDULED_EVENT_DELETE_TRANSIENT, [ $this, 'delete_expired_transients' ] );
35
-
36
- add_action( 'shutdown', [ $this, 'maybe_delete_expired_transients' ] );
37
- }
38
 
39
  public static function setup() {
40
- wp_cache_add_non_persistent_groups( [ 'tribe-events-non-persistent' ] );
41
  }
42
 
43
  /**
44
- * @param string $id
45
- * @param mixed $value
46
- * @param int $expiration
47
- * @param string|array $expiration_trigger
48
  *
49
  * @return bool
50
  */
@@ -55,13 +37,13 @@ class Tribe__Cache implements ArrayAccess {
55
  * Filters the expiration for cache objects to provide the ability
56
  * to make non-persistent objects be treated as persistent.
57
  *
58
- * @since 4.8
 
 
 
 
59
  *
60
- * @param int $expiration Cache expiration time.
61
- * @param string $id Cache ID.
62
- * @param mixed $value Cache value.
63
- * @param string|array $expiration_trigger Action that triggers automatic expiration.
64
- * @param string $key Unique cache key based on Cache ID and expiration trigger last run time.
65
  */
66
  $expiration = apply_filters( 'tribe_cache_expiration', $expiration, $id, $value, $expiration_trigger, $key );
67
 
@@ -79,10 +61,10 @@ class Tribe__Cache implements ArrayAccess {
79
  }
80
 
81
  /**
82
- * @param $id
83
- * @param $value
84
- * @param int $expiration
85
- * @param string|array $expiration_trigger
86
  *
87
  * @return bool
88
  */
@@ -95,18 +77,17 @@ class Tribe__Cache implements ArrayAccess {
95
  *
96
  * Note: When a default value or callback is specified, this value gets set in the cache.
97
  *
98
- * @param string $id The key for the cached value.
99
- * @param string|array $expiration_trigger Optional. Hook to trigger cache invalidation.
100
- * @param mixed $default Optional. A default value or callback that returns a default value.
101
- * @param int $expiration Optional. When the default value expires, if it gets set.
102
- * @param mixed $args Optional. Args passed to callback.
103
  *
104
  * @return mixed
105
  */
106
- public function get( $id, $expiration_trigger = '', $default = false, $expiration = 0, $args = [] ) {
107
- $flipped = array_flip( $this->non_persistent_keys );
108
- $group = isset( $flipped[ $id ] ) ? 'tribe-events-non-persistent' : 'tribe-events';
109
- $value = wp_cache_get( $this->get_id( $id, $expiration_trigger ), $group );
110
 
111
  // Value found.
112
  if ( false !== $value ) {
@@ -130,8 +111,8 @@ class Tribe__Cache implements ArrayAccess {
130
  }
131
 
132
  /**
133
- * @param string $id
134
- * @param string|array $expiration_trigger
135
  *
136
  * @return mixed
137
  */
@@ -140,8 +121,8 @@ class Tribe__Cache implements ArrayAccess {
140
  }
141
 
142
  /**
143
- * @param string $id
144
- * @param string|array $expiration_trigger
145
  *
146
  * @return bool
147
  */
@@ -150,8 +131,8 @@ class Tribe__Cache implements ArrayAccess {
150
  }
151
 
152
  /**
153
- * @param string $id
154
- * @param string|array $expiration_trigger
155
  *
156
  * @return bool
157
  */
@@ -160,116 +141,16 @@ class Tribe__Cache implements ArrayAccess {
160
  }
161
 
162
  /**
163
- * Purge all expired tribe_ transients.
164
- *
165
- * This uses a modification of the the query from https://core.trac.wordpress.org/ticket/20316
166
- *
167
- * @since 4.11.0
168
- *
169
- * @return void Just execute the database SQL no return required.
170
- */
171
- public function delete_expired_transients() {
172
- if ( tribe_get_var( 'has_deleted_expired_transients', false ) ) {
173
- return;
174
- }
175
-
176
- global $wpdb;
177
-
178
- $time = time();
179
-
180
- $sql = "
181
- DELETE
182
- a,
183
- b
184
- FROM
185
- {$wpdb->options} a
186
- INNER JOIN {$wpdb->options} b
187
- ON b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )
188
- AND b.option_value < {$time}
189
- WHERE
190
- a.option_name LIKE '\_transient\_tribe\_%'
191
- AND a.option_name NOT LIKE '\_transient\_timeout\_tribe\_%'
192
- ";
193
-
194
- /**
195
- * Allow third party filtering of the SQL used for deleting expired transients.
196
- *
197
- * @since 4.11.5
198
- *
199
- * @param string $sql The SQL we execute to delete all the expired transients.
200
- * @param int $time Time we are using to determine what is expired.
201
- */
202
- $sql = apply_filters( 'tribe_cache_delete_expired_transients_sql', $sql, $time );
203
-
204
- if ( empty( $sql ) ) {
205
- return;
206
- }
207
-
208
- $wpdb->query( $sql );
209
-
210
- // Set the variable to prevent this call from running twice.
211
- tribe_set_var( 'has_deleted_expired_transients', true );
212
- }
213
-
214
- /**
215
- * Flag if we should delete
216
- *
217
- * @since 4.11.5
218
- *
219
- * @param boolean $value If we should delete transients or not on shutdown.
220
- *
221
- * @return void No return for setting the flag.
222
- */
223
- public function flag_required_delete_transients( $value = true ) {
224
- tribe_set_var( 'should_delete_expired_transients', $value );
225
- }
226
-
227
- /**
228
- * Runs on hook `shutdown` and will delete transients on the end of the request.
229
- *
230
- * @since 4.11.5
231
- *
232
- * @return void No return for action hook method.
233
- */
234
- public function maybe_delete_expired_transients() {
235
- if ( ! tribe_get_var( 'should_delete_expired_transients', false ) ) {
236
- return;
237
- }
238
-
239
- $this->delete_expired_transients();
240
- }
241
-
242
- /**
243
- * @param string $key
244
- * @param string|array $expiration_trigger
245
  *
246
  * @return string
247
  */
248
  public function get_id( $key, $expiration_trigger = '' ) {
249
- if ( is_array( $expiration_trigger ) ) {
250
- $triggers = $expiration_trigger;
251
- } else {
252
- $triggers = array_filter( explode( '|', $expiration_trigger ) );
253
- }
254
-
255
- $last = 0;
256
- foreach ( $triggers as $trigger ) {
257
- // Bail on empty trigger otherwise it creates a `tribe_last_` opt on the DB.
258
- if ( empty( $trigger ) ) {
259
- continue;
260
- }
261
-
262
- $occurrence = $this->get_last_occurrence( $trigger );
263
-
264
- if ( $occurrence > $last ) {
265
- $last = $occurrence;
266
- }
267
- }
268
-
269
- $last = empty( $last ) ? '' : $last;
270
  $id = $key . $last;
271
- if ( strlen( $id ) > 80 ) {
272
- $id = 'tribe_' . md5( $id );
273
  }
274
 
275
  return $id;
@@ -278,33 +159,14 @@ class Tribe__Cache implements ArrayAccess {
278
  /**
279
  * Returns the time of an action last occurrence.
280
  *
281
- * @since 4.9.14 Changed the return value type from `int` to `float`.
282
- *
283
  * @param string $action The action to return the time for.
284
  *
 
 
285
  * @return float The time (microtime) an action last occurred, or the current microtime if it never occurred.
286
  */
287
  public function get_last_occurrence( $action ) {
288
- static $cache_var_name = __METHOD__;
289
-
290
- $cache_last_actions = tribe_get_var( $cache_var_name, [] );
291
-
292
- if ( isset( $cache_last_actions[ $action ] ) ) {
293
- return $cache_last_actions[ $action ];
294
- }
295
-
296
- $last_action = (float) get_option( 'tribe_last_' . $action, null );
297
-
298
- if ( ! $last_action ) {
299
- $last_action = microtime( true );
300
- $this->set_last_occurrence( $action, $last_action );
301
- }
302
-
303
- $cache_last_actions[ $action ] = (float) $last_action;
304
-
305
- tribe_set_var( $cache_var_name, $cache_last_actions );
306
-
307
- return $cache_last_actions[ $action ];
308
  }
309
 
310
  /**
@@ -312,23 +174,14 @@ class Tribe__Cache implements ArrayAccess {
312
  *
313
  * @since 4.9.14 Changed the type of the time stored from an `int` to a `float`.
314
  *
315
- * @param string $action The action to record the last occurrence of.
316
- * @param int|float $timestamp The timestamp to assign to the action last occurrence or the current time (microtime).
317
- *
318
- * @return boolean IF we were able to set the last occurrence or not.
319
  */
320
  public function set_last_occurrence( $action, $timestamp = 0 ) {
321
  if ( empty( $timestamp ) ) {
322
  $timestamp = microtime( true );
323
  }
324
- $updated = update_option( 'tribe_last_' . $action, (float) $timestamp );
325
-
326
- // For performance reasons we will only expire cache once per request, when needed.
327
- if ( $updated ) {
328
- $this->flag_required_delete_transients( true );
329
- }
330
-
331
- return $updated;
332
  }
333
 
334
  /**
@@ -336,14 +189,13 @@ class Tribe__Cache implements ArrayAccess {
336
  *
337
  * @param mixed $components Either a single component of the key or an array of key components.
338
  * @param string $prefix
339
- * @param bool $sort Whether component arrays should be sorted or not to generate the key; defaults to
340
- * `true`.
341
  *
342
  * @return string The resulting key.
343
  */
344
  public function make_key( $components, $prefix = '', $sort = true ) {
345
- $key = '';
346
- $components = is_array( $components ) ? $components : [ $components ];
347
  foreach ( $components as $component ) {
348
  if ( $sort && is_array( $component ) ) {
349
  $is_associative = count( array_filter( array_keys( $component ), 'is_numeric' ) ) < count( array_keys( $component ) );
@@ -360,63 +212,62 @@ class Tribe__Cache implements ArrayAccess {
360
  }
361
 
362
  /**
363
- * Whether a offset exists.
364
- *
365
- * @since 4.11.0
366
  *
367
  * @link http://php.net/manual/en/arrayaccess.offsetexists.php
368
- *
369
- * @param mixed $offset An offset to check for.
370
- *
371
- * @return boolean Whether the offset exists in the cache.
 
 
 
 
372
  */
373
  public function offsetExists( $offset ) {
374
- $flipped = array_flip( $this->non_persistent_keys );
375
-
376
- return isset( $flipped[ $offset ] );
377
  }
378
 
379
  /**
380
- * Offset to retrieve.
381
  *
382
  * @link http://php.net/manual/en/arrayaccess.offsetget.php
383
- *
384
- * @since 4.11.0
385
- *
386
- * @param mixed $offset The offset to retrieve.
387
- *
388
  * @return mixed Can return all value types.
 
389
  */
390
  public function offsetGet( $offset ) {
391
  return $this->get( $offset );
392
  }
393
 
394
  /**
395
- * Offset to set.
396
- *
397
- * @since 4.11.0
398
  *
399
  * @link http://php.net/manual/en/arrayaccess.offsetset.php
400
- *
401
- * @param mixed $offset The offset to assign the value to.
402
- * @param mixed $value The value to set.
403
- *
 
 
404
  * @return void
 
405
  */
406
  public function offsetSet( $offset, $value ) {
407
  $this->set( $offset, $value, self::NON_PERSISTENT );
408
  }
409
 
410
  /**
411
- * Offset to unset.
412
- *
413
- * @since 4.11.0
414
  *
415
  * @link http://php.net/manual/en/arrayaccess.offsetunset.php
416
- *
417
- * @param mixed $offset The offset to unset.
418
- *
419
  * @return void
 
420
  */
421
  public function offsetUnset( $offset ) {
422
  $this->delete( $offset );
@@ -453,8 +304,8 @@ class Tribe__Cache implements ArrayAccess {
453
  }
454
 
455
  /** @var Tribe__Feature_Detection $feature_detection */
456
- $feature_detection = tribe( 'feature-detection' );
457
- $limit = $feature_detection->mysql_limit_for_example( 'post_result' );
458
 
459
  /**
460
  * Filters the LIMIT that should be used to warm-up post caches and postmeta caches (if the
@@ -479,7 +330,7 @@ class Tribe__Cache implements ArrayAccess {
479
 
480
  do {
481
  $limit_clause = $limit < 0 ? sprintf( 'LIMIT %d,%d', $limit * $page, $limit ) : '';
482
- $page++;
483
  $these_ids = array_splice( $buffer, 0, $limit );
484
  $interval = implode( ',', array_map( 'absint', $these_ids ) );
485
  $posts_query = "SELECT * FROM {$wpdb->posts} WHERE ID IN ({$interval}) {$limit_clause}";
@@ -494,6 +345,11 @@ class Tribe__Cache implements ArrayAccess {
494
  update_meta_cache( 'post', $these_ids );
495
  }
496
  }
497
- } while ( ! empty( $post_objects ) && is_array( $post_objects ) && count( $post_objects ) < count( $post_ids ) );
498
- }
499
- }
 
 
 
 
 
10
  * When used in its ArrayAccess API the cache will provide non persistent storage.
11
  */
12
  class Tribe__Cache implements ArrayAccess {
13
+ const NO_EXPIRATION = 0;
14
+ const NON_PERSISTENT = - 1;
 
 
 
15
 
16
  /**
17
  * @var array
18
  */
19
+ protected $non_persistent_keys = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  public static function setup() {
22
+ wp_cache_add_non_persistent_groups( array( 'tribe-events-non-persistent' ) );
23
  }
24
 
25
  /**
26
+ * @param string $id
27
+ * @param mixed $value
28
+ * @param int $expiration
29
+ * @param string $expiration_trigger
30
  *
31
  * @return bool
32
  */
37
  * Filters the expiration for cache objects to provide the ability
38
  * to make non-persistent objects be treated as persistent.
39
  *
40
+ * @param int $expiration Cache expiration time.
41
+ * @param string $id Cache ID.
42
+ * @param mixed $value Cache value.
43
+ * @param string $expiration_trigger Action that triggers automatic expiration.
44
+ * @param string $key Unique cache key based on Cache ID and expiration trigger last run time.
45
  *
46
+ * @since 4.8
 
 
 
 
47
  */
48
  $expiration = apply_filters( 'tribe_cache_expiration', $expiration, $id, $value, $expiration_trigger, $key );
49
 
61
  }
62
 
63
  /**
64
+ * @param $id
65
+ * @param $value
66
+ * @param int $expiration
67
+ * @param string $expiration_trigger
68
  *
69
  * @return bool
70
  */
77
  *
78
  * Note: When a default value or callback is specified, this value gets set in the cache.
79
  *
80
+ * @param string $id The key for the cached value.
81
+ * @param string $expiration_trigger Optional. Hook to trigger cache invalidation.
82
+ * @param mixed $default Optional. A default value or callback that returns a default value.
83
+ * @param int $expiration Optional. When the default value expires, if it gets set.
84
+ * @param mixed $args Optional. Args passed to callback.
85
  *
86
  * @return mixed
87
  */
88
+ public function get( $id, $expiration_trigger = '', $default = false, $expiration = 0, $args = array() ) {
89
+ $group = in_array( $id, $this->non_persistent_keys ) ? 'tribe-events-non-persistent' : 'tribe-events';
90
+ $value = wp_cache_get( $this->get_id( $id, $expiration_trigger ), $group );
 
91
 
92
  // Value found.
93
  if ( false !== $value ) {
111
  }
112
 
113
  /**
114
+ * @param string $id
115
+ * @param string $expiration_trigger
116
  *
117
  * @return mixed
118
  */
121
  }
122
 
123
  /**
124
+ * @param string $id
125
+ * @param string $expiration_trigger
126
  *
127
  * @return bool
128
  */
131
  }
132
 
133
  /**
134
+ * @param string $id
135
+ * @param string $expiration_trigger
136
  *
137
  * @return bool
138
  */
141
  }
142
 
143
  /**
144
+ * @param string $key
145
+ * @param string $expiration_trigger
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  *
147
  * @return string
148
  */
149
  public function get_id( $key, $expiration_trigger = '' ) {
150
+ $last = empty( $expiration_trigger ) ? '' : $this->get_last_occurrence( $expiration_trigger );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  $id = $key . $last;
152
+ if ( strlen( $id ) > 40 ) {
153
+ $id = md5( $id );
154
  }
155
 
156
  return $id;
159
  /**
160
  * Returns the time of an action last occurrence.
161
  *
 
 
162
  * @param string $action The action to return the time for.
163
  *
164
+ * @since 4.9.14 Changed the return value type from `int` to `float`.
165
+ *
166
  * @return float The time (microtime) an action last occurred, or the current microtime if it never occurred.
167
  */
168
  public function get_last_occurrence( $action ) {
169
+ return (float) get_option( 'tribe_last_' . $action, microtime( true ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  }
171
 
172
  /**
174
  *
175
  * @since 4.9.14 Changed the type of the time stored from an `int` to a `float`.
176
  *
177
+ * @param string $action The action to record the last occurrence of.
178
+ * @param int $timestamp The timestamp to assign to the action last occurrence or the current time (microtime).
 
 
179
  */
180
  public function set_last_occurrence( $action, $timestamp = 0 ) {
181
  if ( empty( $timestamp ) ) {
182
  $timestamp = microtime( true );
183
  }
184
+ update_option( 'tribe_last_' . $action, (float) $timestamp );
 
 
 
 
 
 
 
185
  }
186
 
187
  /**
189
  *
190
  * @param mixed $components Either a single component of the key or an array of key components.
191
  * @param string $prefix
192
+ * @param bool $sort Whether component arrays should be sorted or not to generate the key; defaults to `true`.
 
193
  *
194
  * @return string The resulting key.
195
  */
196
  public function make_key( $components, $prefix = '', $sort = true ) {
197
+ $key = '';
198
+ $components = is_array( $components ) ? $components : array( $components );
199
  foreach ( $components as $component ) {
200
  if ( $sort && is_array( $component ) ) {
201
  $is_associative = count( array_filter( array_keys( $component ), 'is_numeric' ) ) < count( array_keys( $component ) );
212
  }
213
 
214
  /**
215
+ * Whether a offset exists
 
 
216
  *
217
  * @link http://php.net/manual/en/arrayaccess.offsetexists.php
218
+ * @param mixed $offset <p>
219
+ * An offset to check for.
220
+ * </p>
221
+ * @return boolean true on success or false on failure.
222
+ * </p>
223
+ * <p>
224
+ * The return value will be casted to boolean if non-boolean was returned.
225
+ * @since 5.0.0
226
  */
227
  public function offsetExists( $offset ) {
228
+ return in_array( $offset, $this->non_persistent_keys );
 
 
229
  }
230
 
231
  /**
232
+ * Offset to retrieve
233
  *
234
  * @link http://php.net/manual/en/arrayaccess.offsetget.php
235
+ * @param mixed $offset <p>
236
+ * The offset to retrieve.
237
+ * </p>
 
 
238
  * @return mixed Can return all value types.
239
+ * @since 5.0.0
240
  */
241
  public function offsetGet( $offset ) {
242
  return $this->get( $offset );
243
  }
244
 
245
  /**
246
+ * Offset to set
 
 
247
  *
248
  * @link http://php.net/manual/en/arrayaccess.offsetset.php
249
+ * @param mixed $offset <p>
250
+ * The offset to assign the value to.
251
+ * </p>
252
+ * @param mixed $value <p>
253
+ * The value to set.
254
+ * </p>
255
  * @return void
256
+ * @since 5.0.0
257
  */
258
  public function offsetSet( $offset, $value ) {
259
  $this->set( $offset, $value, self::NON_PERSISTENT );
260
  }
261
 
262
  /**
263
+ * Offset to unset
 
 
264
  *
265
  * @link http://php.net/manual/en/arrayaccess.offsetunset.php
266
+ * @param mixed $offset <p>
267
+ * The offset to unset.
268
+ * </p>
269
  * @return void
270
+ * @since 5.0.0
271
  */
272
  public function offsetUnset( $offset ) {
273
  $this->delete( $offset );
304
  }
305
 
306
  /** @var Tribe__Feature_Detection $feature_detection */
307
+ $feature_detection = tribe('feature-detection');
308
+ $limit = $feature_detection->mysql_limit_for_example( 'post_result' );
309
 
310
  /**
311
  * Filters the LIMIT that should be used to warm-up post caches and postmeta caches (if the
330
 
331
  do {
332
  $limit_clause = $limit < 0 ? sprintf( 'LIMIT %d,%d', $limit * $page, $limit ) : '';
333
+ $page ++;
334
  $these_ids = array_splice( $buffer, 0, $limit );
335
  $interval = implode( ',', array_map( 'absint', $these_ids ) );
336
  $posts_query = "SELECT * FROM {$wpdb->posts} WHERE ID IN ({$interval}) {$limit_clause}";
345
  update_meta_cache( 'post', $these_ids );
346
  }
347
  }
348
+ } while (
349
+ ! empty( $post_objects )
350
+ && is_array( $post_objects )
351
+ && count( $post_objects ) < count( $post_ids )
352
+ );
353
+
354
+ }
355
+ }
common/src/Tribe/Cache_Listener.php CHANGED
@@ -14,11 +14,6 @@
14
  */
15
  const TRIGGER_SAVE_POST = 'save_post';
16
 
17
- /**
18
- * The name of the trigger that will be fired when an option is updated
19
- */
20
- const TRIGGER_UPDATED_OPTION = 'updated_option';
21
-
22
  /**
23
  * The singleton instance of the class.
24
  *
@@ -58,7 +53,6 @@
58
  */
59
  private function add_hooks() {
60
  add_action( 'save_post', [ $this, 'save_post' ], 0, 2 );
61
- add_action( 'updated_option', [ $this, 'update_last_updated_option' ], 10, 3 );
62
  add_action( 'updated_option', [ $this, 'update_last_save_post' ], 10, 3 );
63
  add_action( 'generate_rewrite_rules', [ $this, 'generate_rewrite_rules' ] );
64
  }
@@ -85,46 +79,17 @@
85
  * @param mixed $value The new option value.
86
  */
87
  public function update_last_save_post( $option_name, $old_value, $value ) {
88
- $triggers = [
89
- 'tribe_events_calendar_options' => true,
90
- 'permalink_structure' => true,
91
- 'rewrite_rules' => true,
92
- 'start_of_week' => true,
93
- ];
94
- if ( ! empty( $triggers[ $option_name ] ) ) {
95
  $this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST );
96
  }
97
  }
98
 
99
- /**
100
- * Run the caching functionality that is executed on saving tribe calendar options.
101
- *
102
- * @see 'updated_option'
103
- *
104
- * @since 4.11.0
105
- *
106
- * @param string $option_name Name of the updated option.
107
- * @param mixed $old_value The old option value.
108
- * @param mixed $value The new option value.
109
- */
110
- public function update_last_updated_option( $option_name, $old_value, $value ) {
111
- $triggers = [
112
- 'active_plugins' => true,
113
- 'tribe_events_calendar_options' => true,
114
- 'permalink_structure' => true,
115
- 'rewrite_rules' => true,
116
- 'start_of_week' => true,
117
- 'sidebars_widgets' => true,
118
- 'stylesheet' => true,
119
- 'template' => true,
120
- 'WPLANG' => true,
121
- ];
122
-
123
- if ( ! empty( $triggers[ $option_name ] ) ) {
124
- $this->cache->set_last_occurrence( self::TRIGGER_UPDATED_OPTION );
125
- }
126
- }
127
-
128
  /**
129
  * For any hook that doesn't need any additional filtering
130
  *
14
  */
15
  const TRIGGER_SAVE_POST = 'save_post';
16
 
 
 
 
 
 
17
  /**
18
  * The singleton instance of the class.
19
  *
53
  */
54
  private function add_hooks() {
55
  add_action( 'save_post', [ $this, 'save_post' ], 0, 2 );
 
56
  add_action( 'updated_option', [ $this, 'update_last_save_post' ], 10, 3 );
57
  add_action( 'generate_rewrite_rules', [ $this, 'generate_rewrite_rules' ] );
58
  }
79
  * @param mixed $value The new option value.
80
  */
81
  public function update_last_save_post( $option_name, $old_value, $value ) {
82
+ $triggers = array(
83
+ 'tribe_events_calendar_options',
84
+ 'permalink_structure',
85
+ 'rewrite_rules',
86
+ 'start_of_week',
87
+ );
88
+ if ( in_array( $option_name, $triggers, true ) ) {
89
  $this->cache->set_last_occurrence( self::TRIGGER_SAVE_POST );
90
  }
91
  }
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  /**
94
  * For any hook that doesn't need any additional filtering
95
  *
common/src/Tribe/Container.php CHANGED
@@ -224,52 +224,6 @@ if ( ! function_exists( 'tribe_get_var' ) ) {
224
  }
225
  }
226
 
227
- if ( ! function_exists( 'tribe_unset_var' ) ) {
228
- /**
229
- * Returns the value of a registered variable.
230
- *
231
- * Example use:
232
- *
233
- * tribe_set_var( 'tec.url', 'http://example.com' );
234
- *
235
- * tribe_unset_var( 'tec.url' );
236
- *
237
- * @since 4.11.0
238
- *
239
- * @param string $slug The slug of the variable registered using `tribe_unset_var`.
240
- *
241
- * @return void
242
- */
243
- function tribe_unset_var( $slug ) {
244
- $container = Tribe__Container::init();
245
- try {
246
- $container->offsetUnset( $slug );
247
- } catch ( Exception $e ) {}
248
- }
249
- }
250
-
251
- if ( ! function_exists( 'tribe_isset_var' ) ) {
252
- /**
253
- * Returns the value of a registered variable.
254
- *
255
- * Example use:
256
- *
257
- * tribe_set_var( 'tec.url', 'http://example.com' );
258
- *
259
- * tribe_isset_var( 'tec.url' );
260
- *
261
- * @since 4.11.0
262
- *
263
- * @param string $slug The slug of the variable checked using `tribe_isset_var`.
264
- *
265
- * @return boolean Either a the given slug exists.
266
- */
267
- function tribe_isset_var( $slug ) {
268
- $container = Tribe__Container::init();
269
- return $container->offsetExists( $slug );
270
- }
271
- }
272
-
273
  if ( ! function_exists( 'tribe_register_provider' ) ) {
274
  /**
275
  * Registers a service provider in the container.
224
  }
225
  }
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  if ( ! function_exists( 'tribe_register_provider' ) ) {
228
  /**
229
  * Registers a service provider in the container.
common/src/Tribe/Context.php CHANGED
@@ -376,7 +376,6 @@ class Tribe__Context {
376
 
377
  $value = $default;
378
  $locations = $this->get_locations();
379
- $found = false;
380
 
381
  if ( ! $force && isset( $this->request_cache[ $key ] ) ) {
382
  $value = $this->request_cache[ $key ];
@@ -385,7 +384,6 @@ class Tribe__Context {
385
  $the_value = $this->$location( (array) $keys, $default );
386
 
387
  if ( $default !== $the_value && static::NOT_FOUND !== $the_value ) {
388
- $found = true;
389
  $value = $the_value;
390
  break;
391
  }
@@ -403,8 +401,7 @@ class Tribe__Context {
403
  */
404
  $value = apply_filters( "tribe_context_{$key}", $value );
405
 
406
- // Only cache if the value was found.
407
- if ( $found ) {
408
  $this->request_cache[ $key ] = $value;
409
  }
410
 
@@ -517,11 +514,6 @@ class Tribe__Context {
517
  $value = $default;
518
 
519
  global $wp_query;
520
-
521
- if ( ! $wp_query instanceof \WP_Query ) {
522
- return $value;
523
- }
524
-
525
  foreach ( $query_vars as $query_var ) {
526
  $the_value = $wp_query->get( $query_var, self::NOT_FOUND );
527
  if ( $the_value !== self::NOT_FOUND ) {
376
 
377
  $value = $default;
378
  $locations = $this->get_locations();
 
379
 
380
  if ( ! $force && isset( $this->request_cache[ $key ] ) ) {
381
  $value = $this->request_cache[ $key ];
384
  $the_value = $this->$location( (array) $keys, $default );
385
 
386
  if ( $default !== $the_value && static::NOT_FOUND !== $the_value ) {
 
387
  $value = $the_value;
388
  break;
389
  }
401
  */
402
  $value = apply_filters( "tribe_context_{$key}", $value );
403
 
404
+ if ( $value !== static::NOT_FOUND ) {
 
405
  $this->request_cache[ $key ] = $value;
406
  }
407
 
514
  $value = $default;
515
 
516
  global $wp_query;
 
 
 
 
 
517
  foreach ( $query_vars as $query_var ) {
518
  $the_value = $wp_query->get( $query_var, self::NOT_FOUND );
519
  if ( $the_value !== self::NOT_FOUND ) {
common/src/Tribe/Context/locations.php CHANGED
@@ -9,6 +9,7 @@
9
  *
10
  * @since 4.9.11
11
  */
 
12
  return [
13
  'post_id' => [
14
  'read' => [
@@ -17,21 +18,6 @@ return [
17
  }
18
  ],
19
  ],
20
- 'permalink_structure' => [
21
- 'read' => [
22
- Tribe__Context::OPTION => [ 'permalink_structure' ],
23
- ],
24
- ],
25
- 'plain_permalink' => [
26
- 'read' => [
27
- Tribe__Context::LOCATION_FUNC => [
28
- 'permalink_structure',
29
- static function( $struct ){
30
- return empty( $struct );
31
- },
32
- ],
33
- ],
34
- ],
35
  'posts_per_page' => [
36
  'read' => [
37
  Tribe__Context::REQUEST_VAR => 'posts_per_page',
@@ -90,30 +76,6 @@ return [
90
  ],
91
  'post_type' => [
92
  'read' => [
93
- Tribe__Context::FUNC => static function() {
94
- $post_type_objs = get_post_types(
95
- [
96
- 'public' => true,
97
- '_builtin' => false,
98
- ],
99
- 'objects'
100
- );
101
-
102
- foreach( $post_type_objs as $post_type ) {
103
- if ( empty( $post_type->query_var ) ) {
104
- continue;
105
- }
106
-
107
- $url_value = tribe_get_request_var( $post_type->query_var, false );
108
- if ( empty( $url_value ) ) {
109
- continue;
110
- }
111
-
112
- return $post_type->name;
113
- }
114
-
115
- return Tribe__Context::NOT_FOUND;
116
- },
117
  Tribe__Context::QUERY_PROP => 'post_type',
118
  Tribe__Context::QUERY_VAR => 'post_type',
119
  Tribe__Context::REQUEST_VAR => 'post_type',
@@ -128,12 +90,5 @@ return [
128
  Tribe__Context::QUERY_VAR => [ 'taxonomy' ],
129
  Tribe__Context::REQUEST_VAR => [ 'taxonomy' ],
130
  ],
131
- ],
132
- 'post_tag' => [
133
- 'read' => [
134
- Tribe__Context::QUERY_PROP => [ 'post_tag', 'tag' ],
135
- Tribe__Context::QUERY_VAR => [ 'post_tag', 'tag' ],
136
- Tribe__Context::REQUEST_VAR => [ 'post_tag', 'tag' ],
137
- ],
138
- ],
139
  ];
9
  *
10
  * @since 4.9.11
11
  */
12
+
13
  return [
14
  'post_id' => [
15
  'read' => [
18
  }
19
  ],
20
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  'posts_per_page' => [
22
  'read' => [
23
  Tribe__Context::REQUEST_VAR => 'posts_per_page',
76
  ],
77
  'post_type' => [
78
  'read' => [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  Tribe__Context::QUERY_PROP => 'post_type',
80
  Tribe__Context::QUERY_VAR => 'post_type',
81
  Tribe__Context::REQUEST_VAR => 'post_type',
90
  Tribe__Context::QUERY_VAR => [ 'taxonomy' ],
91
  Tribe__Context::REQUEST_VAR => [ 'taxonomy' ],
92
  ],
93
+ ]
 
 
 
 
 
 
 
94
  ];
common/src/Tribe/Customizer.php CHANGED
@@ -104,6 +104,17 @@ final class Tribe__Customizer {
104
  return;
105
  }
106
 
 
 
 
 
 
 
 
 
 
 
 
107
  /**
108
  * Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
109
  *
@@ -316,6 +327,18 @@ final class Tribe__Customizer {
316
  $option = $sections;
317
  }
318
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  /**
320
  * Apply Filters After finding the variable
321
  *
@@ -370,6 +393,18 @@ final class Tribe__Customizer {
370
  return false;
371
  }
372
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  /**
374
  * Use this filter to add more CSS, using Underscore Template style
375
  *
@@ -379,7 +414,7 @@ final class Tribe__Customizer {
379
  *
380
  * @param string $template
381
  */
382
- $css_template = trim( apply_filters( 'tribe_customizer_css_template', '' ) );
383
 
384
  // If we don't have anything on the customizer don't print empty styles
385
  // On Customize Page, we don't care we need this
@@ -404,7 +439,8 @@ final class Tribe__Customizer {
404
  * @return void
405
  */
406
  public function inline_style() {
407
- // Only load once on front-end.
 
408
  if ( is_customize_preview() || is_admin() || $this->inline_style ) {
409
  return false;
410
  }
@@ -425,30 +461,29 @@ final class Tribe__Customizer {
425
  return false;
426
  }
427
 
428
- $sheets = [];
 
429
 
430
- /**
431
- * Allow plugins to add themselves to this list.
432
- *
433
- * @since 4.12.1
434
- *
435
- * @param array<string> $sheets An array of sheets to search for.
436
- * @param string $css_template String containing the inline css to add.
437
- */
438
- $sheets = apply_filters( 'tribe_customizer_inline_stylesheets', $sheets, $css_template );
439
 
440
- if ( empty( $sheets ) ) {
441
- return false;
442
  }
443
 
444
- // add customizer styles inline with whichever stylesheet is enqueued.
445
- foreach ( $sheets as $sheet ) {
446
- if ( wp_style_is( $sheet ) ) {
447
- wp_add_inline_style( $sheet, wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
448
- $this->inline_style = true;
449
 
450
- break;
451
- }
 
 
 
 
 
 
 
 
 
 
452
  }
453
  }
454
 
@@ -496,6 +531,17 @@ final class Tribe__Customizer {
496
  // Set the Cutomizer on a class variable
497
  $this->manager = $customizer;
498
 
 
 
 
 
 
 
 
 
 
 
 
499
  /**
500
  * Allow users to filter the Panel
501
  *
@@ -504,7 +550,18 @@ final class Tribe__Customizer {
504
  * @param WP_Customize_Panel $panel
505
  * @param Tribe__Customizer $customizer
506
  */
507
- $this->panel = apply_filters( 'tribe_customizer_panel', $this->register_panel(), $this );
 
 
 
 
 
 
 
 
 
 
 
508
 
509
  /**
510
  * Filter the Sections within our Panel before they are added to the Cutomize Manager
@@ -519,6 +576,17 @@ final class Tribe__Customizer {
519
  foreach ( $this->sections as $id => $section ) {
520
  $this->sections[ $id ] = $this->register_section( $id, $section );
521
 
 
 
 
 
 
 
 
 
 
 
 
522
  /**
523
  * Allows people to Register and de-register the method to register more Fields
524
  *
@@ -530,6 +598,17 @@ final class Tribe__Customizer {
530
  do_action( "tribe_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
531
  }
532
 
 
 
 
 
 
 
 
 
 
 
 
533
  /**
534
  * Filter the Sections within our Panel, now using the actual WP_Customize_Section
535
  *
@@ -567,6 +646,18 @@ final class Tribe__Customizer {
567
  'priority' => 125,
568
  );
569
 
 
 
 
 
 
 
 
 
 
 
 
 
570
  /**
571
  * Filter the Panel Arguments for WP Customize
572
  *
@@ -598,6 +689,17 @@ final class Tribe__Customizer {
598
  * @return WP_Customize_Section
599
  */
600
  public function register_section( $id, $args ) {
 
 
 
 
 
 
 
 
 
 
 
601
  /**
602
  * Filter the Section ID
603
  *
@@ -606,7 +708,7 @@ final class Tribe__Customizer {
606
  * @param string $section_id
607
  * @param Tribe__Customizer $customizer
608
  */
609
- $section_id = apply_filters( 'tribe_customizer_section_id', $id, $this );
610
 
611
  // Tries to fetch the section
612
  $section = $this->manager->get_section( $section_id );
@@ -616,6 +718,18 @@ final class Tribe__Customizer {
616
  return $section;
617
  }
618
 
 
 
 
 
 
 
 
 
 
 
 
 
619
  /**
620
  * Filter the Section arguments, so that developers can filter arguments based on $section_id
621
  *
104
  return;
105
  }
106
 
107
+ /**
108
+ * Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
109
+ *
110
+ * @deprecated
111
+ * @since 4.0
112
+ *
113
+ * @param string $ID
114
+ * @param self $customizer
115
+ */
116
+ $this->ID = apply_filters( 'tribe_events_pro_customizer_panel_id', 'tribe_customizer', $this );
117
+
118
  /**
119
  * Filters the Panel ID, which is also the `wp_option` name for the Customizer settings
120
  *
327
  $option = $sections;
328
  }
329
 
330
+ /**
331
+ * Apply Filters After finding the variable
332
+ *
333
+ * @deprecated
334
+ * @since 4.0
335
+ *
336
+ * @param mixed $option
337
+ * @param array $search
338
+ * @param array $sections
339
+ */
340
+ $option = apply_filters( 'tribe_events_pro_customizer_get_option', $option, $search, $sections );
341
+
342
  /**
343
  * Apply Filters After finding the variable
344
  *
393
  return false;
394
  }
395
 
396
+ /**
397
+ * Use this filter to add more CSS, using Underscore Template style
398
+ *
399
+ * @deprecated
400
+ * @since 4.0
401
+ *
402
+ * @link http://underscorejs.org/#template
403
+ *
404
+ * @param string $template
405
+ */
406
+ $css_template = trim( apply_filters( 'tribe_events_pro_customizer_css_template', '' ) );
407
+
408
  /**
409
  * Use this filter to add more CSS, using Underscore Template style
410
  *
414
  *
415
  * @param string $template
416
  */
417
+ $css_template = trim( apply_filters( 'tribe_customizer_css_template', $css_template ) );
418
 
419
  // If we don't have anything on the customizer don't print empty styles
420
  // On Customize Page, we don't care we need this
439
  * @return void
440
  */
441
  public function inline_style() {
442
+
443
+ //Only load on front end
444
  if ( is_customize_preview() || is_admin() || $this->inline_style ) {
445
  return false;
446
  }
461
  return false;
462
  }
463
 
464
+ // add customizer styles inline with either main stylesheet is enqueued or widgets
465
+ if ( wp_style_is( 'tribe-events-calendar-style' ) ) {
466
 
467
+ wp_add_inline_style( 'tribe-events-calendar-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
468
+ $this->inline_style = true;
 
 
 
 
 
 
 
469
 
470
+ return;
 
471
  }
472
 
473
+ if ( wp_style_is( 'tribe-events-calendar-pro-style' ) ) {
 
 
 
 
474
 
475
+ wp_add_inline_style( 'tribe-events-calendar-pro-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
476
+ $this->inline_style = true;
477
+
478
+ return;
479
+ }
480
+
481
+ if ( wp_style_is( 'widget-calendar-pro-style' ) ) {
482
+
483
+ wp_add_inline_style( 'widget-calendar-pro-style', wp_strip_all_tags( $this->parse_css_template( $css_template ) ) );
484
+ $this->inline_style = true;
485
+
486
+ return;
487
  }
488
  }
489
 
531
  // Set the Cutomizer on a class variable
532
  $this->manager = $customizer;
533
 
534
+ /**
535
+ * Allow users to filter the Panel
536
+ *
537
+ * @deprecated
538
+ * @since 4.0
539
+ *
540
+ * @param WP_Customize_Panel $panel
541
+ * @param Tribe__Customizer $customizer
542
+ */
543
+ $this->panel = apply_filters( 'tribe_events_pro_customizer_panel', $this->register_panel(), $this );
544
+
545
  /**
546
  * Allow users to filter the Panel
547
  *
550
  * @param WP_Customize_Panel $panel
551
  * @param Tribe__Customizer $customizer
552
  */
553
+ $this->panel = apply_filters( 'tribe_customizer_panel', $this->panel, $this );
554
+
555
+ /**
556
+ * Filter the Sections within our Panel before they are added to the Cutomize Manager
557
+ *
558
+ * @deprecated
559
+ * @since 4.0
560
+ *
561
+ * @param array $sections
562
+ * @param Tribe__Customizer $customizer
563
+ */
564
+ $this->sections = apply_filters( 'tribe_events_pro_customizer_pre_sections', $this->sections, $this );
565
 
566
  /**
567
  * Filter the Sections within our Panel before they are added to the Cutomize Manager
576
  foreach ( $this->sections as $id => $section ) {
577
  $this->sections[ $id ] = $this->register_section( $id, $section );
578
 
579
+ /**
580
+ * Allows people to Register and de-register the method to register more Fields
581
+ *
582
+ * @deprecated
583
+ * @since 4.0
584
+ *
585
+ * @param array $section
586
+ * @param WP_Customize_Manager $manager
587
+ */
588
+ do_action( "tribe_events_pro_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
589
+
590
  /**
591
  * Allows people to Register and de-register the method to register more Fields
592
  *
598
  do_action( "tribe_customizer_register_{$id}_settings", $this->sections[ $id ], $this->manager );
599
  }
600
 
601
+ /**
602
+ * Filter the Sections within our Panel, now using the actual WP_Customize_Section
603
+ *
604
+ * @deprecated
605
+ * @since 4.0
606
+ *
607
+ * @param array $sections
608
+ * @param Tribe__Customizer $customizer
609
+ */
610
+ $this->sections = apply_filters( 'tribe_events_pro_customizer_sections', $this->sections, $this );
611
+
612
  /**
613
  * Filter the Sections within our Panel, now using the actual WP_Customize_Section
614
  *
646
  'priority' => 125,
647
  );
648
 
649
+ /**
650
+ * Filter the Panel Arguments for WP Customize
651
+ *
652
+ * @deprecated
653
+ * @since 4.0
654
+ *
655
+ * @param array $args
656
+ * @param string $ID
657
+ * @param Tribe__Customizer $customizer
658
+ */
659
+ $panel_args = apply_filters( 'tribe_events_pro_customizer_panel_args', $panel_args, $this->ID, $this );
660
+
661
  /**
662
  * Filter the Panel Arguments for WP Customize
663
  *
689
  * @return WP_Customize_Section
690
  */
691
  public function register_section( $id, $args ) {
692
+ /**
693
+ * Filter the Section ID
694
+ *
695
+ * @deprecated
696
+ * @since 4.0
697
+ *
698
+ * @param string $section_id
699
+ * @param Tribe__Customizer $customizer
700
+ */
701
+ $section_id = apply_filters( 'tribe_events_pro_customizer_section_id', $id, $this );
702
+
703
  /**
704
  * Filter the Section ID
705
  *
708
  * @param string $section_id
709
  * @param Tribe__Customizer $customizer
710
  */
711
+ $section_id = apply_filters( 'tribe_customizer_section_id', $section_id, $this );
712
 
713
  // Tries to fetch the section
714
  $section = $this->manager->get_section( $section_id );
718
  return $section;
719
  }
720
 
721
+ /**
722
+ * Filter the Section arguments, so that developers can filter arguments based on $section_id
723
+ *
724
+ * @deprecated
725
+ * @since 4.0
726
+ *
727
+ * @param array $args
728
+ * @param string $section_id
729
+ * @param Tribe__Customizer $customizer
730
+ */
731
+ $section_args = apply_filters( 'tribe_events_pro_customizer_section_args', $args, $section_id, $this );
732
+
733
  /**
734
  * Filter the Section arguments, so that developers can filter arguments based on $section_id
735
  *
common/src/Tribe/Data.php CHANGED
@@ -65,7 +65,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
65
  * </p>
66
  * <p>
67
  * The return value will be casted to boolean if non-boolean was returned.
68
- * @since 4.11.0
69
  */
70
  public function offsetExists( $offset ) {
71
  return isset( $this->data[ $offset ] );
@@ -79,7 +79,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
79
  * The offset to retrieve.
80
  * </p>
81
  * @return mixed Can return all value types.
82
- * @since 4.11.0
83
  */
84
  public function offsetGet( $offset ) {
85
  return isset( $this->data[ $offset ] )
@@ -98,7 +98,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
98
  * The value to set.
99
  * </p>
100
  * @return void
101
- * @since 4.11.0
102
  */
103
  public function offsetSet( $offset, $value ) {
104
  $this->data[ $offset ] = $value;
@@ -112,7 +112,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
112
  * The offset to unset.
113
  * </p>
114
  * @return void
115
- * @since 4.11.0
116
  */
117
  public function offsetUnset( $offset ) {
118
  unset( $this->data[ $offset ] );
@@ -159,7 +159,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
159
  *
160
  * @link http://php.net/manual/en/iterator.current.php
161
  * @return mixed Can return any type.
162
- * @since 4.11.0
163
  */
164
  public function current() {
165
  $keys = array_keys( $this->data );
@@ -172,7 +172,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
172
  *
173
  * @link http://php.net/manual/en/iterator.next.php
174
  * @return void Any returned value is ignored.
175
- * @since 4.11.0
176
  */
177
  public function next() {
178
  $keys = array_keys( $this->data );
@@ -189,7 +189,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
189
  *
190
  * @link http://php.net/manual/en/iterator.key.php
191
  * @return mixed scalar on success, or null on failure.
192
- * @since 4.11.0
193
  */
194
  public function key() {
195
  $keys = array_keys( $this->data );
@@ -203,7 +203,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
203
  * @link http://php.net/manual/en/iterator.valid.php
204
  * @return boolean The return value will be casted to boolean and then evaluated.
205
  * Returns true on success or false on failure.
206
- * @since 4.11.0
207
  */
208
  public function valid() {
209
  $keys = array_keys( $this->data );
@@ -216,7 +216,7 @@ class Tribe__Data implements ArrayAccess, Iterator {
216
  *
217
  * @link http://php.net/manual/en/iterator.rewind.php
218
  * @return void Any returned value is ignored.
219
- * @since 4.11.0
220
  */
221
  public function rewind() {
222
  $this->index = 0;
65
  * </p>
66
  * <p>
67
  * The return value will be casted to boolean if non-boolean was returned.
68
+ * @since 5.0.0
69
  */
70
  public function offsetExists( $offset ) {
71
  return isset( $this->data[ $offset ] );
79
  * The offset to retrieve.
80
  * </p>
81
  * @return mixed Can return all value types.
82
+ * @since 5.0.0
83
  */
84
  public function offsetGet( $offset ) {
85
  return isset( $this->data[ $offset ] )
98
  * The value to set.
99
  * </p>
100
  * @return void
101
+ * @since 5.0.0
102
  */
103
  public function offsetSet( $offset, $value ) {
104
  $this->data[ $offset ] = $value;
112
  * The offset to unset.
113
  * </p>
114
  * @return void
115
+ * @since 5.0.0
116
  */
117
  public function offsetUnset( $offset ) {
118
  unset( $this->data[ $offset ] );
159
  *
160
  * @link http://php.net/manual/en/iterator.current.php
161
  * @return mixed Can return any type.
162
+ * @since 5.0.0
163
  */
164
  public function current() {
165
  $keys = array_keys( $this->data );
172
  *
173
  * @link http://php.net/manual/en/iterator.next.php
174
  * @return void Any returned value is ignored.
175
+ * @since 5.0.0
176
  */
177
  public function next() {
178
  $keys = array_keys( $this->data );
189
  *
190
  * @link http://php.net/manual/en/iterator.key.php
191
  * @return mixed scalar on success, or null on failure.
192
+ * @since 5.0.0
193
  */
194
  public function key() {
195
  $keys = array_keys( $this->data );
203
  * @link http://php.net/manual/en/iterator.valid.php
204
  * @return boolean The return value will be casted to boolean and then evaluated.
205
  * Returns true on success or false on failure.
206
+ * @since 5.0.0
207
  */
208
  public function valid() {
209
  $keys = array_keys( $this->data );
216
  *
217
  * @link http://php.net/manual/en/iterator.rewind.php
218
  * @return void Any returned value is ignored.
219
+ * @since 5.0.0
220
  */
221
  public function rewind() {
222
  $this->index = 0;
common/src/Tribe/Date_Utils.php CHANGED
@@ -3,9 +3,6 @@
3
  * Date utility functions used throughout TEC + Addons
4
  */
5
 
6
- use Tribe\Utils\Date_I18n;
7
- use Tribe\Utils\Date_I18n_Immutable;
8
-
9
  // Don't load directly
10
 
11
  if ( ! defined( 'ABSPATH' ) ) {
@@ -26,38 +23,11 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
26
  const DBTIMEFORMAT = 'H:i:s';
27
  const DBYEARMONTHTIMEFORMAT = 'Y-m';
28
 
29
- /**
30
- * Default datepicker format index.
31
- *
32
- * @since 4.11.0.1
33
- *
34
- * @var int
35
- */
36
- private static $default_datepicker_format_index = 1;
37
-
38
  private static $localized_months_full = array();
39
  private static $localized_months_short = array();
40
  private static $localized_weekdays = array();
41
  private static $localized_months = array();
42
 
43
- /**
44
- * Get the datepickerFormat index.
45
- *
46
- * @since 4.11.0.1
47
- *
48
- * @return int
49
- */
50
- public static function get_datepicker_format_index() {
51
- /**
52
- * Filter the datepickerFormat index.
53
- *
54
- * @since 4.11.0.1
55
- *
56
- * @param int $format_index Index of datepickerFormat.
57
- */
58
- return apply_filters( 'tribe_datepicker_format_index', tribe_get_option( 'datepickerFormat', static::$default_datepicker_format_index ) );
59
- }
60
-
61
  /**
62
  * Try to format a Date to the Default Datepicker format
63
  *
@@ -69,14 +39,14 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
69
  */
70
  public static function maybe_format_from_datepicker( $date, $datepicker = null ) {
71
  if ( ! is_numeric( $datepicker ) ) {
72
- $datepicker = self::get_datepicker_format_index();
73
  }
74
 
75
  if ( is_numeric( $datepicker ) ) {
76
  $datepicker = self::datepicker_formats( $datepicker );
77
  }
78
 
79
- $default_datepicker = self::datepicker_formats( 1 );
80
 
81
  // If the current datepicker is the default we don't care
82
  if ( $datepicker === $default_datepicker ) {
@@ -126,7 +96,7 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
126
  return $formats;
127
  }
128
 
129
- return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[ static::get_datepicker_format_index() ];
130
  }
131
 
132
  /**
@@ -1249,13 +1219,13 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1249
  return clone $datetime;
1250
  }
1251
 
1252
- if ( class_exists( 'DateTimeImmutable' ) && $datetime instanceof DateTimeImmutable ) {
1253
  // Return the mutable version of the date.
1254
- return Date_I18n::createFromImmutable( $datetime );
1255
  }
1256
 
1257
  $timezone_object = null;
1258
- $datetime = empty( $datetime ) ? 'now' : $datetime;
1259
 
1260
  try {
1261
  // PHP 5.2 will not throw an exception but will generate an error.
@@ -1263,24 +1233,23 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1263
  $timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
1264
 
1265
  if ( self::is_timestamp( $datetime ) ) {
1266
- $timestamp_timezone = $timezone ? $timezone_object : $utc;
 
1267
 
1268
- return new Date_I18n( '@' . $datetime, $timestamp_timezone );
 
1269
  }
1270
 
1271
  set_error_handler( 'tribe_catch_and_throw' );
1272
- $date = new Date_I18n( $datetime, $timezone_object );
1273
  restore_error_handler();
1274
  } catch ( Exception $e ) {
1275
- // If we encounter an error, we need to restore after catching.
1276
- restore_error_handler();
1277
-
1278
  if ( $timezone_object === null ) {
1279
  $timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
1280
  }
1281
 
1282
  return $with_fallback
1283
- ? new Date_I18n( 'now', $timezone_object )
1284
  : false;
1285
  }
1286
 
@@ -1298,19 +1267,7 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1298
  * like `strtotime`, or not.
1299
  */
1300
  public static function is_valid_date( $date ) {
1301
- static $cache_var_name = __FUNCTION__;
1302
-
1303
- $cache_date_check = tribe_get_var( $cache_var_name, [] );
1304
-
1305
- if ( isset( $cache_date_check[ $date ] ) ) {
1306
- return $cache_date_check[ $date ];
1307
- }
1308
-
1309
- $cache_date_check[ $date ] = self::build_date_object( $date, null, false ) instanceof DateTimeInterface;
1310
-
1311
- tribe_set_var( $cache_var_name, $cache_date_check );
1312
-
1313
- return $cache_date_check[ $date ];
1314
  }
1315
 
1316
  /**
@@ -1318,8 +1275,6 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1318
  *
1319
  * @since 4.9.21
1320
  *
1321
- * @throws Exception
1322
- *
1323
  * @param string|int|\DateTime $date The date string, timestamp or object.
1324
  * @param int|null $start_of_week The number representing the start of week day as handled by
1325
  * WordPress: `0` (for Sunday) through `6` (for Saturday).
@@ -1330,28 +1285,15 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1330
  * `23:59:59`.
1331
  */
1332
  public static function get_week_start_end( $date, $start_of_week = null ) {
1333
- static $cache_var_name = __FUNCTION__;
1334
-
1335
- $cache_week_start_end = tribe_get_var( $cache_var_name, [] );
1336
-
1337
- $date_obj = static::build_date_object( $date );
1338
- $date_obj->setTime( 0, 0, 0 );
1339
-
1340
- $date_string = $date_obj->format( static::DBDATEFORMAT );
1341
-
1342
  // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
1343
  $week_start_day = null !== $start_of_week
1344
  ? (int) $start_of_week
1345
  : (int) get_option( 'start_of_week', 0 );
1346
 
1347
- $memory_cache_key = "{$date_string}:{$week_start_day}";
1348
-
1349
- if ( isset( $cache_week_start_end[ $memory_cache_key ] ) ) {
1350
- return $cache_week_start_end[ $memory_cache_key ];
1351
- }
1352
-
1353
  $cache_key = md5(
1354
- __METHOD__ . serialize( [ $date_obj->format( static::DBDATEFORMAT ), $week_start_day ] )
1355
  );
1356
  $cache = tribe( 'cache' );
1357
 
@@ -1360,20 +1302,10 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1360
  }
1361
 
1362
  // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
1363
- $date_day = (int) $date_obj->format( 'w' );
1364
-
1365
- $week_offset = 0;
1366
- if ( 0 === $date_day && 0 !== $week_start_day ) {
1367
- $week_offset = 0;
1368
- } elseif ( $date_day < $week_start_day ) {
1369
- // If the current date of the week is before the start of the week, move back a week.
1370
- $week_offset = -1;
1371
- } elseif ( 0 === $date_day ) {
1372
- // When start of the week is on a sunday we add a week.
1373
- $week_offset = 1;
1374
- }
1375
 
1376
- $week_start = clone $date_obj;
 
1377
 
1378
  /*
1379
  * From the PHP docs, the `W` format stands for:
@@ -1393,118 +1325,11 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1393
  $week_start = static::immutable( $week_start );
1394
  $week_end = static::immutable( $week_end );
1395
 
1396
- $cache[ $cache_key ] = [ $week_start, $week_end ];
1397
- $cache_week_start_end[ $memory_cache_key ] = [ $week_start, $week_end ];
1398
-
1399
- tribe_set_var( $cache_var_name, $cache_week_start_end );
1400
 
1401
  return [ $week_start, $week_end ];
1402
  }
1403
 
1404
- /**
1405
- * Given a specific DateTime we determine the end of that day based on our Internal End of Day Cut-off.
1406
- *
1407
- * @since 4.11.2
1408
- *
1409
- * @param string|DateTimeInterface $date Date that we are getting the end of day from.
1410
- * @param null|string $cutoff Which cutoff to use.
1411
- *
1412
- * @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false.
1413
- */
1414
- public static function get_shifted_end_of_day( $date, $cutoff = null ) {
1415
- $date_obj = static::build_date_object( $date );
1416
-
1417
- if ( ! $date_obj ) {
1418
- return false;
1419
- }
1420
-
1421
- $start_of_day = clone $date_obj;
1422
- $end_of_day = clone $date_obj;
1423
-
1424
- if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) {
1425
- $cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
1426
- }
1427
-
1428
- list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) );
1429
-
1430
- $seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS );
1431
- if ( 0 !== $seconds_to_add ) {
1432
- $interval = static::interval( "PT{$seconds_to_add}S" );
1433
- }
1434
-
1435
- $start_of_day->setTime( '0', '0', '0' );
1436
- $end_of_day->setTime( '23', '59', '59' );
1437
-
1438
- if ( 0 !== $seconds_to_add ) {
1439
- $start_of_day->add( $interval );
1440
- $end_of_day->add( $interval );
1441
- }
1442
-
1443
- if ( $end_of_day >= $date_obj && $date_obj >= $start_of_day ) {
1444
- return $end_of_day;
1445
- }
1446
-
1447
- $start_of_day->sub( static::interval( 'P1D' ) );
1448
-
1449
- if ( $start_of_day < $date_obj ) {
1450
- $end_of_day->sub( static::interval( 'P1D' ) );
1451
- }
1452
-
1453
- return $end_of_day;
1454
- }
1455
-
1456
- /**
1457
- * Given a specific DateTime we determine the start of that day based on our Internal End of Day Cut-off.
1458
- *
1459
- * @since 4.11.2
1460
- *
1461
- * @param string|DateTimeInterface $date Date that we are getting the start of day from.
1462
- * @param null|string $cutoff Which cutoff to use.
1463
- *
1464
- * @return DateTimeInterface|false Returns a DateTimeInterface when a valid date is given or false.
1465
- */
1466
- public static function get_shifted_start_of_day( $date, $cutoff = null ) {
1467
- $date_obj = static::build_date_object( $date );
1468
-
1469
- if ( ! $date_obj ) {
1470
- return false;
1471
- }
1472
-
1473
- $start_of_day = clone $date_obj;
1474
- $end_of_day = clone $date_obj;
1475
-
1476
- if ( empty( $cutoff ) || ! is_string( $cutoff ) || false === strpos( $cutoff, ':' ) ) {
1477
- $cutoff = tribe_get_option( 'multiDayCutoff', '00:00' );
1478
- }
1479
-
1480
- list( $hours_to_add, $minutes_to_add ) = array_map( 'absint', explode( ':', $cutoff ) );
1481
-
1482
- $seconds_to_add = ( $hours_to_add * HOUR_IN_SECONDS ) + ( $minutes_to_add * MINUTE_IN_SECONDS );
1483
- if ( 0 !== $seconds_to_add ) {
1484
- $interval = static::interval( "PT{$seconds_to_add}S" );
1485
- }
1486
-
1487
- $start_of_day->setTime( '0', '0', '0' );
1488
- $end_of_day->setTime( '23', '59', '59' );
1489
-
1490
- if ( 0 !== $seconds_to_add ) {
1491
- $start_of_day->add( $interval );
1492
- $end_of_day->add( $interval );
1493
- }
1494
-
1495
- if ( $end_of_day <= $date_obj && $date_obj >= $start_of_day ) {
1496
- return $start_of_day;
1497
- }
1498
-
1499
- $end_of_day->sub( static::interval( 'P1D' ) );
1500
-
1501
- if ( $end_of_day > $date_obj ) {
1502
- $start_of_day->sub( static::interval( 'P1D' ) );
1503
- }
1504
-
1505
- return $start_of_day;
1506
- }
1507
-
1508
  /**
1509
  * Builds and returns a `DateInterval` object from the interval specification.
1510
  *
@@ -1550,7 +1375,7 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1550
  }
1551
 
1552
  if ( $datetime instanceof DateTime ) {
1553
- return Date_I18n_Immutable::createFromMutable( $datetime );
1554
  }
1555
 
1556
  $mutable = static::build_date_object( $datetime, $timezone, $with_fallback );
@@ -1559,14 +1384,14 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
1559
  return false;
1560
  }
1561
 
1562
- $cache_key = md5( ( __METHOD__ . $mutable->getTimezone()->getName() . $mutable->getTimestamp() ) );
1563
  $cache = tribe( 'cache' );
1564
 
1565
  if ( false !== $cached = $cache[ $cache_key ] ) {
1566
  return $cached;
1567
  }
1568
 
1569
- $immutable = Date_I18n_Immutable::createFromMutable( $mutable );
1570
 
1571
  $cache[ $cache_key ] = $immutable;
1572
 
3
  * Date utility functions used throughout TEC + Addons
4
  */
5
 
 
 
 
6
  // Don't load directly
7
 
8
  if ( ! defined( 'ABSPATH' ) ) {
23
  const DBTIMEFORMAT = 'H:i:s';
24
  const DBYEARMONTHTIMEFORMAT = 'Y-m';
25
 
 
 
 
 
 
 
 
 
 
26
  private static $localized_months_full = array();
27
  private static $localized_months_short = array();
28
  private static $localized_weekdays = array();
29
  private static $localized_months = array();
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  /**
32
  * Try to format a Date to the Default Datepicker format
33
  *
39
  */
40
  public static function maybe_format_from_datepicker( $date, $datepicker = null ) {
41
  if ( ! is_numeric( $datepicker ) ) {
42
+ $datepicker = tribe_get_option( 'datepickerFormat' );
43
  }
44
 
45
  if ( is_numeric( $datepicker ) ) {
46
  $datepicker = self::datepicker_formats( $datepicker );
47
  }
48
 
49
+ $default_datepicker = self::datepicker_formats( 0 );
50
 
51
  // If the current datepicker is the default we don't care
52
  if ( $datepicker === $default_datepicker ) {
96
  return $formats;
97
  }
98
 
99
+ return isset( $formats[ $translate ] ) ? $formats[ $translate ] : $formats[0];
100
  }
101
 
102
  /**
1219
  return clone $datetime;
1220
  }
1221
 
1222
+ if ( class_exists('DateTimeImmutable') && $datetime instanceof DateTimeImmutable ) {
1223
  // Return the mutable version of the date.
1224
+ return new DateTime( $datetime->format( 'Y-m-d H:i:s' ), $datetime->getTimezone() );
1225
  }
1226
 
1227
  $timezone_object = null;
1228
+ $datetime = empty($datetime) ? 'now' : $datetime;
1229
 
1230
  try {
1231
  // PHP 5.2 will not throw an exception but will generate an error.
1233
  $timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
1234
 
1235
  if ( self::is_timestamp( $datetime ) ) {
1236
+ // Timestamps timezone is always UTC.
1237
+ $date = new DateTime( '@' . $datetime, $utc );
1238
 
1239
+ // If we have a timezone, then set it.
1240
+ return $timezone ? $date->setTimezone( $timezone_object ) : $date;
1241
  }
1242
 
1243
  set_error_handler( 'tribe_catch_and_throw' );
1244
+ $date = new DateTime( $datetime, $timezone_object );
1245
  restore_error_handler();
1246
  } catch ( Exception $e ) {
 
 
 
1247
  if ( $timezone_object === null ) {
1248
  $timezone_object = Tribe__Timezones::build_timezone_object( $timezone );
1249
  }
1250
 
1251
  return $with_fallback
1252
+ ? new DateTime( 'now', $timezone_object )
1253
  : false;
1254
  }
1255
 
1267
  * like `strtotime`, or not.
1268
  */
1269
  public static function is_valid_date( $date ) {
1270
+ return self::build_date_object( $date, null, false ) instanceof DateTime;
 
 
 
 
 
 
 
 
 
 
 
 
1271
  }
1272
 
1273
  /**
1275
  *
1276
  * @since 4.9.21
1277
  *
 
 
1278
  * @param string|int|\DateTime $date The date string, timestamp or object.
1279
  * @param int|null $start_of_week The number representing the start of week day as handled by
1280
  * WordPress: `0` (for Sunday) through `6` (for Saturday).
1285
  * `23:59:59`.
1286
  */
1287
  public static function get_week_start_end( $date, $start_of_week = null ) {
1288
+ $week_start = static::build_date_object( $date );
1289
+ $week_start->setTime( 0, 0, 0 );
 
 
 
 
 
 
 
1290
  // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
1291
  $week_start_day = null !== $start_of_week
1292
  ? (int) $start_of_week
1293
  : (int) get_option( 'start_of_week', 0 );
1294
 
 
 
 
 
 
 
1295
  $cache_key = md5(
1296
+ __METHOD__ . serialize( [ $week_start->format( static::DBDATEFORMAT ), $week_start_day ] )
1297
  );
1298
  $cache = tribe( 'cache' );
1299
 
1302
  }
1303
 
1304
  // `0` (for Sunday) through `6` (for Saturday), the way WP handles the `start_of_week` option.
1305
+ $date_day = (int) $week_start->format( 'w' );
 
 
 
 
 
 
 
 
 
 
 
1306
 
1307
+ // If the current date is before the start of the week, move back a week.
1308
+ $week_offset = $date_day < $week_start_day ? - 1 : 0;
1309
 
1310
  /*
1311
  * From the PHP docs, the `W` format stands for:
1325
  $week_start = static::immutable( $week_start );
1326
  $week_end = static::immutable( $week_end );
1327
 
1328
+ $cache[ $cache_key ] = [ $week_start, $week_end ];
 
 
 
1329
 
1330
  return [ $week_start, $week_end ];
1331
  }
1332
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1333
  /**
1334
  * Builds and returns a `DateInterval` object from the interval specification.
1335
  *
1375
  }
1376
 
1377
  if ( $datetime instanceof DateTime ) {
1378
+ return DateTimeImmutable::createFromMutable( $datetime );
1379
  }
1380
 
1381
  $mutable = static::build_date_object( $datetime, $timezone, $with_fallback );
1384
  return false;
1385
  }
1386
 
1387
+ $cache_key = md5( ( __METHOD__ . $mutable->getTimestamp() ) );
1388
  $cache = tribe( 'cache' );
1389
 
1390
  if ( false !== $cached = $cache[ $cache_key ] ) {
1391
  return $cached;
1392
  }
1393
 
1394
+ $immutable = DateTimeImmutable::createFromMutable( $mutable );
1395
 
1396
  $cache[ $cache_key ] = $immutable;
1397
 
common/src/Tribe/Debug_Bar/Panels/Json_Ld.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
- /**
3
- * JSON-LD information Debug Bar panel.
4
- *
5
- * @since 4.11.2
6
- *
7
- * @package Tribe\Debug_Bar\Panels
8
- */
9
-
10
- class Tribe__Debug_Bar__Panels__Json_Ld extends Debug_Bar_Panel {
11
- /**
12
- * Returns the Panel name.
13
- *
14
- * @since 4.11.2
15
- *
16
- * @param null $title The panel input title.
17
- *
18
- * @return string The panel title
19
- */
20
- public function title( $title = null ) {
21
- return __( 'Modern Tribe JSON-LD Data', 'tribe-common' );
22
- }
23
-
24
- /**
25
- * Renders the panel contents.
26
- *
27
- * @since 4.9.5
28
- */
29
- public function render() {
30
- $html = '<style>
31
- #mt-debug-bar .mt-debug-bar-title {
32
- margin-bottom: 1em;
33
- }
34
- #mt-debug-bar .mt-debug-bar-section {
35
- padding: .5em .5em .5em 1em;
36
- }
37
- </style>';
38
- $html .= '<div id="mt-debug-bar" class="mt-debug-bar-json-ld">';
39
-
40
- $html .= '<header class="mt-debug-bar-title"><h2>' . esc_html__( 'Modern Tribe JSON-LD Data',
41
- 'tribe-common' ) . '</h2></header>';
42
-
43
-
44
- $json_ld_data = array_filter( (array) tribe_cache()['json-ld-data'] );
45
-
46
- if ( ! empty( $json_ld_data ) ) {
47
- $html .= '<div class="mt-debug-bar-section">';
48
- $html .= sprintf(
49
- '<header>The request produced %d JSON-LD data %s.</header><br>',
50
- count( $json_ld_data ),
51
- count( $json_ld_data ) > 1 ? 'scripts' : 'script'
52
- );
53
-
54
- $html .= '<p>Copy the code below and paste it into ' .
55
- '<a href="https://search.google.com/structured-data/testing-tool/u/0/" target="_blank">' .
56
- 'Google\'s Structured Data Testing Tool' .
57
- '</a>' .
58
- ' to test it using the Code Snippet option.</p><br>';
59
-
60
- foreach ( $json_ld_data as $full_entry ) {
61
- preg_match(
62
- '/(?<open>^\\s*<script[^>]*?>\\s*)(?<json>.*)(?<close>\\s<\\/script>)$/uism',
63
- $full_entry,
64
- $frags
65
- );
66
-
67
- if ( isset( $frags['open'], $frags['json'], $frags['close'] ) ) {
68
- // Let's try and format it if we've got all the pieces.
69
- $full_entry = $frags['open']
70
- . json_encode( json_decode( $frags['json'], true ), JSON_PRETTY_PRINT )
71
- . $frags['close'];
72
- }
73
-
74
- $html .= sprintf( '<pre><code>%s</code></pre>', esc_html( $full_entry ) );
75
- }
76
-
77
- $html .= '</div>';
78
- }
79
-
80
- $html .= '</div>';
81
-
82
- echo $html;
83
- }
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Dependency.php CHANGED
@@ -301,11 +301,11 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
301
  *
302
  * @since 4.9
303
  *
304
- * @param array $plugin An array of data for given registered plugin.,
305
- * @param array $dependencies An array of dependencies for a plugin.
306
- * @param bool $addon Indicates if the plugin is an add-on for The Events Calendar or Event Tickets.
307
  *
308
- * @return true|int The number of failed dependency checks; `true` or `0` to indicate no checks failed.
309
  */
310
  public function has_valid_dependencies( $plugin, $dependencies = array(), $addon = false ) {
311
  if ( empty( $dependencies ) ) {
@@ -409,11 +409,11 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
409
  *
410
  * @since 4.9
411
  *
412
- * @param string $file_path Full file path to the base plugin file.
413
- * @param string $main_class The Main/base class for this plugin.
414
- * @param string $version The plugin version.
415
- * @param array $classes_req Any Main class files/tribe plugins required for this to run.
416
- * @param array $dependencies an array of dependencies to check.
417
  */
418
  public function register_plugin( $file_path, $main_class, $version, $classes_req = array(), $dependencies = array() ) {
419
  /**
@@ -475,7 +475,11 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
475
  *
476
  * @since 4.9
477
  *
 
478
  * @param string $main_class The Main/base class for this plugin
 
 
 
479
  *
480
  * @return bool Indicates if plugin should continue initialization
481
  */
@@ -483,25 +487,25 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
483
 
484
  $parent_dependencies = $co_dependencies = $addon_dependencies = 0;
485
 
486
- // Check if plugin is registered, if not return false.
487
  $plugin = $this->get_registered_plugin( $main_class );
488
  if ( empty( $plugin ) ) {
489
  return false;
490
  }
491
 
492
- // Check parent dependencies in add-on.
493
  if ( ! empty( $plugin['dependencies']['parent-dependencies'] ) ) {
494
  $parent_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['parent-dependencies'] );
495
  }
496
- // Check co-dependencies in add-on.
497
  if ( ! empty( $plugin['dependencies']['co-dependencies'] ) ) {
498
  $co_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['co-dependencies'] );
499
  }
500
 
501
- // Check add-on dependencies from parent.
502
  $addon_dependencies = $this->check_addon_dependencies( $main_class );
503
 
504
- // If good then we set as active plugin and continue to load.
505
  if ( ! $parent_dependencies && ! $co_dependencies && ! $addon_dependencies ) {
506
  $this->add_active_plugin( $main_class, $plugin['version'], $plugin['path'] );
507
 
@@ -516,26 +520,23 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
516
  *
517
  * @since 4.9
518
  *
519
- * @param string $main_class A string of the main class for the plugin being checked.
520
  *
521
- * @return bool Returns false if any dependency is invalid.
522
  */
523
  protected function check_addon_dependencies( $main_class ) {
 
 
 
524
  foreach ( $this->registered_plugins as $registered ) {
525
  if ( empty( $registered['dependencies']['addon-dependencies'][ $main_class ] ) ) {
526
  continue;
527
  }
528
 
529
- $dependencies = [ $main_class => $registered['dependencies']['addon-dependencies'][ $main_class ] ];
530
- $check = $this->has_valid_dependencies( $registered, $dependencies, true );
531
-
532
- // A value of `true` or `0` indicates there are no failing checks. So here we check for ints gt 0.
533
- if ( is_int( $check ) && $check > 0 ) {
534
- return true;
535
- }
536
  }
537
 
538
- return false;
539
  }
540
 
541
  /**
@@ -550,4 +551,4 @@ if ( ! class_exists( 'Tribe__Dependency' ) ) {
550
  }
551
  }
552
 
553
- }
301
  *
302
  * @since 4.9
303
  *
304
+ * @param array $plugin An array of data for given registered plugin
305
+ * @param array $dependencies An array of dependencies for a plugin
306
+ * @param bool $addon Indicates if the plugin is an add-on for The Events Calendar or Event Tickets
307
  *
308
+ * @return bool returns false if any dependency is invalid
309
  */
310
  public function has_valid_dependencies( $plugin, $dependencies = array(), $addon = false ) {
311
  if ( empty( $dependencies ) ) {
409
  *
410
  * @since 4.9
411
  *
412
+ * @param $file_path
413
+ * @param $main_class
414
+ * @param $version
415
+ * @param array $classes_req
416
+ * @param array $dependencies
417
  */
418
  public function register_plugin( $file_path, $main_class, $version, $classes_req = array(), $dependencies = array() ) {
419
  /**
475
  *
476
  * @since 4.9
477
  *
478
+ * @param string $file_path Full file path to the base plugin file
479
  * @param string $main_class The Main/base class for this plugin
480
+ * @param string $version The version
481
+ * @param array $classes_req Any Main class files/tribe plugins required for this to run
482
+ * @param array $dependencies an array of dependencies to check
483
  *
484
  * @return bool Indicates if plugin should continue initialization
485
  */
487
 
488
  $parent_dependencies = $co_dependencies = $addon_dependencies = 0;
489
 
490
+ //check if plugin is registered, if not return false
491
  $plugin = $this->get_registered_plugin( $main_class );
492
  if ( empty( $plugin ) ) {
493
  return false;
494
  }
495
 
496
+ // check parent dependencies in add-on
497
  if ( ! empty( $plugin['dependencies']['parent-dependencies'] ) ) {
498
  $parent_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['parent-dependencies'] );
499
  }
500
+ //check co-dependencies in add-on
501
  if ( ! empty( $plugin['dependencies']['co-dependencies'] ) ) {
502
  $co_dependencies = $this->has_valid_dependencies( $plugin, $plugin['dependencies']['co-dependencies'] );
503
  }
504
 
505
+ //check add-on dependencies from parent
506
  $addon_dependencies = $this->check_addon_dependencies( $main_class );
507
 
508
+ //if good then we set as active plugin and continue to load
509
  if ( ! $parent_dependencies && ! $co_dependencies && ! $addon_dependencies ) {
510
  $this->add_active_plugin( $main_class, $plugin['version'], $plugin['path'] );
511
 
520
  *
521
  * @since 4.9
522
  *
523
+ * @param string $main_class a string of the main class for the plugin being checked
524
  *
525
+ * @return bool returns false if any dependency is invalid
526
  */
527
  protected function check_addon_dependencies( $main_class ) {
528
+
529
+ $addon_dependencies = 0;
530
+
531
  foreach ( $this->registered_plugins as $registered ) {
532
  if ( empty( $registered['dependencies']['addon-dependencies'][ $main_class ] ) ) {
533
  continue;
534
  }
535
 
536
+ $addon_dependencies = $this->has_valid_dependencies( $registered, $registered['dependencies']['addon-dependencies'], true );
 
 
 
 
 
 
537
  }
538
 
539
+ return $addon_dependencies;
540
  }
541
 
542
  /**
551
  }
552
  }
553
 
554
+ }
common/src/Tribe/Dialog/View.php CHANGED
@@ -47,7 +47,7 @@ class View extends \Tribe__Template {
47
  * @type array $button_classes Any desired classes for the trigger button (optional).
48
  * @type boolean $button_disabled Should the button be disabled (optional).
49
  * @type string $button_text The text for the dialog trigger button ("Open the dialog window").
50
- * @type string $button_type The type for the trigger button (optional).
51
  * @type string $button_value The value for the trigger button (optional).
52
  * @type string $close_event The dialog close event hook name (`tribe_dialog_close_dialog`).
53
  * @type string $content_classes The dialog content classes ("tribe-dialog__content").
@@ -349,7 +349,7 @@ class View extends \Tribe__Template {
349
  private function build_dialog( $content, $id, $args ) {
350
  $default_args = [
351
  'button_classes' => '',
352
- 'button_disabled' => false,
353
  'button_id' => '',
354
  'button_name' => '',
355
  'button_text' => __( 'Open the dialog window', 'tribe-common' ),
47
  * @type array $button_classes Any desired classes for the trigger button (optional).
48
  * @type boolean $button_disabled Should the button be disabled (optional).
49
  * @type string $button_text The text for the dialog trigger button ("Open the dialog window").
50
+ * @type string $button_type The type for the trigger button (optinoal).
51
  * @type string $button_value The value for the trigger button (optional).
52
  * @type string $close_event The dialog close event hook name (`tribe_dialog_close_dialog`).
53
  * @type string $content_classes The dialog content classes ("tribe-dialog__content").
349
  private function build_dialog( $content, $id, $args ) {
350
  $default_args = [
351
  'button_classes' => '',
352
+ 'button_diabled' => false,
353
  'button_id' => '',
354
  'button_name' => '',
355
  'button_text' => __( 'Open the dialog window', 'tribe-common' ),
common/src/Tribe/Editor.php CHANGED
@@ -31,18 +31,7 @@ class Tribe__Editor {
31
  $blocks = $this->is_blocks_editor_active();
32
  $classic = $this->is_classic_plugin_active() || $this->is_classic_option_active();
33
 
34
- $should_load_blocks = $gutenberg && $blocks && ! $classic;
35
-
36
- /**
37
- * Filters whether the Blocks Editor should be activated or not.
38
- *
39
- * @since 4.12.0
40
- *
41
- * @param bool $should_load_blocks Whether the blocks editor should be activated or not.
42
- */
43
- $should_load_blocks = (bool) apply_filters( 'tribe_editor_should_load_blocks', $should_load_blocks );
44
-
45
- return $should_load_blocks;
46
  }
47
 
48
  /**
@@ -222,35 +211,4 @@ class Tribe__Editor {
222
 
223
  return $is_classic_editor_request || $disabled_by_plugin || $disabled_by_filter;
224
  }
225
-
226
- /**
227
- * Whether the events are being served using Blocks or the Classical Editor.
228
- *
229
- * @since 4.12.0
230
- *
231
- * @return bool True if using Blocks. False if using the Classical Editor.
232
- */
233
- public function is_events_using_blocks() {
234
- /**
235
- * Whether the event is being served through blocks
236
- * or the classical editor.
237
- *
238
- * @since 4.12.0
239
- *
240
- * @param bool $is_using_blocks True if using blocks. False if using the classical editor.
241
- */
242
- $is_using_blocks = apply_filters( 'tribe_is_using_blocks', null );
243
-
244
- // Early bail: The filter was overridden to return either true or false.
245
- if ( null !== $is_using_blocks ) {
246
- return $is_using_blocks;
247
- }
248
-
249
- // Early bail: The site itself is not using blocks.
250
- if ( ! $this->should_load_blocks() ) {
251
- return false;
252
- }
253
-
254
- return tribe_is_truthy( tribe_get_option( 'toggle_blocks_editor' ) );
255
- }
256
  }
31
  $blocks = $this->is_blocks_editor_active();
32
  $classic = $this->is_classic_plugin_active() || $this->is_classic_option_active();
33
 
34
+ return $gutenberg && $blocks && ! $classic;
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
  /**
211
 
212
  return $is_classic_editor_request || $disabled_by_plugin || $disabled_by_filter;
213
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  }
common/src/Tribe/Editor/Blocks/Abstract.php CHANGED
@@ -38,7 +38,7 @@ implements Tribe__Editor__Blocks__Interface {
38
  return $this->namespace;
39
  }
40
 
41
- /**
42
  * Return the block attributes
43
  *
44
  * @since 4.8
@@ -69,7 +69,7 @@ implements Tribe__Editor__Blocks__Interface {
69
  return $attributes;
70
  }
71
 
72
- /**
73
  * Return the block default attributes
74
  *
75
  * @since 4.8
@@ -203,39 +203,5 @@ implements Tribe__Editor__Blocks__Interface {
203
  */
204
  public function hook() {
205
  }
206
-
207
- /**
208
- * Returns the block data for the block editor.
209
- *
210
- * @since 4.12.0
211
- *
212
- * @return array<string,mixed> The block editor data.
213
- */
214
- public function block_data() {
215
- $block_data = [
216
- 'id' => $this->slug(),
217
- ];
218
-
219
- /**
220
- * Filters the block data.
221
- *
222
- * @since 4.12.0
223
- *
224
- * @param array $block_data The block data.
225
- * @param object $this The current object.
226
- */
227
- $block_data = apply_filters( 'tribe_block_block_data', $block_data, $this );
228
-
229
- /**
230
- * Filters the block data for the block.
231
- *
232
- * @since 4.12.0
233
- *
234
- * @param array $block_data The block data.
235
- * @param object $this The current object.
236
- */
237
- $block_data = apply_filters( 'tribe_block_block_data_' . $this->slug(), $block_data, $this );
238
-
239
- return $block_data;
240
- }
241
  }
 
38
  return $this->namespace;
39
  }
40
 
41
+ /*
42
  * Return the block attributes
43
  *
44
  * @since 4.8
69
  return $attributes;
70
  }
71
 
72
+ /*
73
  * Return the block default attributes
74
  *
75
  * @since 4.8
203
  */
204
  public function hook() {
205
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
+
common/src/Tribe/Editor/Configuration.php CHANGED
@@ -39,7 +39,6 @@ class Tribe__Editor__Configuration implements Tribe__Editor__Configuration_Inter
39
  'countries' => tribe( 'languages.locations' )->get_countries(),
40
  'usStates' => Tribe__View_Helpers::loadStates(),
41
  ),
42
- 'blocks' => [],
43
  );
44
 
45
  /**
39
  'countries' => tribe( 'languages.locations' )->get_countries(),
40
  'usStates' => Tribe__View_Helpers::loadStates(),
41
  ),
 
42
  );
43
 
44
  /**
common/src/Tribe/Extension.php CHANGED
@@ -160,54 +160,25 @@ abstract class Tribe__Extension {
160
  * Checks if the extension has permission to run, if so runs init() in child class
161
  */
162
  final public function register() {
163
- $extension_file = $this->get_plugin_file();
164
- $extension_class_name = $this->get( 'class' );
165
- $extension_version = $this->get_version();
166
- $plugins_required = $this->get( 'requires', [] );
167
-
168
  tribe_register_plugin(
169
- $extension_file,
170
- $extension_class_name,
171
- $extension_version,
172
- $plugins_required
173
  );
174
 
175
  $dependency = Tribe__Dependency::instance();
176
 
177
  // check requisite plugins are active for this extension
178
- $is_plugin_authorized = $dependency->has_requisite_plugins( $plugins_required );
179
-
180
- /**
181
- * Explicitly disallow an extension, such as a core plugin having absorbed/replaced its functionality.
182
- *
183
- * @since 4.12.2
184
- *
185
- * @param bool $is_disallowed    False by default.
186
- * @param string $extension_class_name This extension's class name string
187
- * (without initial forward slash for namespaced classes).
188
- * @param Tribe__Extension $this_instance This extension class' instance.
189
- */
190
- $is_disallowed = (bool) apply_filters( 'tribe_extension_is_disallowed', false, $extension_class_name, $this );
191
-
192
- if ( $is_disallowed ) {
193
- if (
194
- is_admin()
195
- && current_user_can( 'activate_plugins' )
196
- ) {
197
- tribe_notice( 'tribe_extension_is_disallowed', [ $this, 'notice_disallowed' ], [ 'type' => 'error' ] );
198
- }
199
-
200
- deactivate_plugins( $extension_file, true );
201
-
202
- return;
203
- }
204
 
205
  if ( $is_plugin_authorized ) {
206
  $this->init();
207
 
208
- // Add extension as active to dependency checker.
209
- $dependency->add_active_plugin( $extension_class_name, $extension_version, $extension_file );
210
  }
 
211
  }
212
 
213
  /**
@@ -258,7 +229,7 @@ abstract class Tribe__Extension {
258
  }
259
 
260
  /**
261
- * Gets the action/hook for the extensions' init().
262
  *
263
  * @return string Action/hook
264
  */
@@ -407,25 +378,6 @@ abstract class Tribe__Extension {
407
  );
408
  }
409
 
410
- /**
411
- * Gets the error message about being explicitly disallowed.
412
- *
413
- * @since 4.12.2
414
- *
415
- * @return string Notice text.
416
- */
417
- public function notice_disallowed() {
418
- return sprintf(
419
- '<p><strong>%1$s:</strong> %2$s</p>',
420
- $this->get_name(),
421
- esc_html_x(
422
- "This extension has been programmatically disallowed. The most common reason is due to another Modern Tribe plugin having absorbed or replaced this extension's functionality. This extension plugin has been deactivated, and you should likely delete it.",
423
- 'extension disallowed',
424
- 'tribe-common'
425
- )
426
- );
427
- }
428
-
429
  /**
430
  * Prevent cloning the singleton with 'clone' operator
431
  *
160
  * Checks if the extension has permission to run, if so runs init() in child class
161
  */
162
  final public function register() {
 
 
 
 
 
163
  tribe_register_plugin(
164
+ $this->get_plugin_file(),
165
+ $this->get( 'class' ),
166
+ $this->get_version(),
167
+ $this->get( 'requires', array() )
168
  );
169
 
170
  $dependency = Tribe__Dependency::instance();
171
 
172
  // check requisite plugins are active for this extension
173
+ $is_plugin_authorized = $dependency->has_requisite_plugins( $this->get( 'requires', array() ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  if ( $is_plugin_authorized ) {
176
  $this->init();
177
 
178
+ //add extension as active to dependency checker
179
+ $dependency->add_active_plugin( $this->get( 'class' ), $this->get_version(), $this->get_plugin_file() );
180
  }
181
+
182
  }
183
 
184
  /**
229
  }
230
 
231
  /**
232
+ * Get's the action/hook for the extensions init()
233
  *
234
  * @return string Action/hook
235
  */
378
  );
379
  }
380
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  /**
382
  * Prevent cloning the singleton with 'clone' operator
383
  *
common/src/Tribe/Field.php CHANGED
@@ -89,7 +89,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
89
  'can_be_empty' => false,
90
  'clear_after' => true,
91
  'tooltip_first' => false,
92
- 'allow_clear' => false,
93
  );
94
 
95
  // a list of valid field types, to prevent screwy behavior
@@ -188,7 +187,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
188
  $can_be_empty = (bool) $args['can_be_empty'];
189
  $clear_after = (bool) $args['clear_after'];
190
  $tooltip_first = (bool) $args['tooltip_first'];
191
- $allow_clear = (bool) $args['allow_clear'];
192
 
193
  // set the ID
194
  $this->id = apply_filters( 'tribe_field_id', $id );
@@ -617,9 +615,6 @@ if ( ! class_exists( 'Tribe__Field' ) ) {
617
  $field .= $this->do_field_name();
618
  $field .= " id='{$this->id}-select'";
619
  $field .= " class='tribe-dropdown'";
620
- if ( empty( $this->allow_clear ) ) {
621
- $field .= " data-prevent-clear='true'";
622
- }
623
  $field .= '>';
624
  foreach ( $this->options as $option_id => $title ) {
625
  $field .= '<option value="' . esc_attr( $option_id ) . '"';
89
  'can_be_empty' => false,
90
  'clear_after' => true,
91
  'tooltip_first' => false,
 
92
  );
93
 
94
  // a list of valid field types, to prevent screwy behavior
187
  $can_be_empty = (bool) $args['can_be_empty'];
188
  $clear_after = (bool) $args['clear_after'];
189
  $tooltip_first = (bool) $args['tooltip_first'];
 
190
 
191
  // set the ID
192
  $this->id = apply_filters( 'tribe_field_id', $id );
615
  $field .= $this->do_field_name();
616
  $field .= " id='{$this->id}-select'";
617
  $field .= " class='tribe-dropdown'";
 
 
 
618
  $field .= '>';
619
  foreach ( $this->options as $option_id => $title ) {
620
  $field .= '<option value="' . esc_attr( $option_id ) . '"';
common/src/Tribe/Freemius.php CHANGED
@@ -15,9 +15,8 @@ class Tribe__Freemius {
15
  private $instances = [];
16
 
17
  /**
18
- * Load the vendor files for Freemius vendor.
19
- *
20
- * Freemius class should only be loaded once since it will be registered as a Singleton.
21
  *
22
  * @since 4.9.5
23
  */
15
  private $instances = [];
16
 
17
  /**
18
+ * Loading of the vendor files for Freemius vendor
19
+ * Freemius class should only be loaded once since it will be registred as a Singleton
 
20
  *
21
  * @since 4.9.5
22
  */
common/src/Tribe/Image/Uploader.php CHANGED
@@ -29,14 +29,13 @@ class Tribe__Image__Uploader {
29
  */
30
  public static function reset_cache() {
31
  self::$attachment_guids_cache = false;
32
- self::$original_urls_cache = false;
33
  }
34
 
35
  /**
36
  * Uploads a file and creates the media attachment or simply returns the attachment ID if existing.
37
  *
38
- * @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an
39
- * attachment;
40
  * `false` otherwise.
41
  */
42
  public function upload_and_get_attachment_id() {
@@ -47,13 +46,8 @@ class Tribe__Image__Uploader {
47
  $existing = false;
48
 
49
  if ( is_string( $this->featured_image ) && ! is_numeric( $this->featured_image ) ) {
50
- // Assume image exists in the local file system.
51
- $id = $this->get_attachment_ID_from_url( $this->featured_image );
52
- if ( ! $id ) {
53
- $id = $this->upload_file( $this->featured_image );
54
- $id = $this->maybe_retry_upload( $id );
55
- }
56
- $existing = (bool) $id;
57
  } elseif ( $post = get_post( $this->featured_image ) ) {
58
  $id = $post && 'attachment' === $post->post_type ? $this->featured_image : false;
59
  } else {
@@ -66,7 +60,7 @@ class Tribe__Image__Uploader {
66
  __CLASS__,
67
  [
68
  'featured_image' => $this->featured_image,
69
- 'exists' => $existing,
70
  'id' => $id,
71
  ]
72
  );
@@ -74,36 +68,6 @@ class Tribe__Image__Uploader {
74
  return $id;
75
  }
76
 
77
- /**
78
- * Retry to upload an image after it failed as was provided, try to decode the URL as in some cases the
79
- * original URL might be encoded HTML components such as: "&" and some CDNs does not handle well different URLs
80
- * as they were provided so we try to recreate the original URL where it might be required.
81
- *
82
- * @since 4.11.5
83
- *
84
- * @param int|bool $id The id of the attachment if was uploaded correctly, false otherwise.
85
- *
86
- * @return int The ID of the attachment after the upload retry.
87
- */
88
- protected function maybe_retry_upload( $id ) {
89
- if ( $id ) {
90
- do_action( 'tribe_log', 'debug', __CLASS__, [ 'message' => "ID: {$id} is already a valid one." ] );
91
-
92
- return $id;
93
- }
94
-
95
- $decoded = esc_url_raw( html_entity_decode( $this->featured_image ) );
96
-
97
- do_action( 'tribe_log', 'debug', __CLASS__, [
98
- 'message' => 'Retry upload decoding the URL of the image',
99
- 'url' => $this->featured_image,
100
- 'decoded' => $decoded,
101
- ] );
102
-
103
- // Maybe the URL was encoded and we need to convert it to a valid URL.
104
- return $this->upload_file( $decoded );
105
- }
106
-
107
  /**
108
  * @param string $file_url
109
  *
@@ -113,147 +77,105 @@ class Tribe__Image__Uploader {
113
  /**
114
  * Allow plugins to enable local URL uploads, mainly used for testing.
115
  *
116
- * @since 4.9.5
117
- *
118
  * @param bool $allow_local_urls Whether to allow local URLs.
119
  * @param string $file_url File URL.
 
 
120
  */
121
  $allow_local_urls = apply_filters( 'tribe_image_uploader_local_urls', false, $file_url );
122
 
123
- if ( ! $allow_local_urls && ! filter_var( $file_url, FILTER_VALIDATE_URL ) ) {
124
  return false;
125
  }
126
 
127
- // These files need to be included as dependencies
128
- require_once( ABSPATH . 'wp-admin/includes/image.php' );
129
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
130
- require_once( ABSPATH . 'wp-admin/includes/media.php' );
131
-
132
- $is_local = false;
133
- // This is a local file no need to fetch it from the wire.
134
- if ( $allow_local_urls && file_exists( $file_url ) ) {
135
- $file = $file_url;
136
- $is_local = true;
137
- } else {
138
- /**
139
- * Some CDN services will append query arguments to the image URL; removing
140
- * them now has the potential of blocking the image fetching completely so we
141
- * let them be here.
142
- */
143
- $file = download_url( $file_url );
144
- if ( is_wp_error( $file ) ) {
145
- do_action( 'tribe_log', 'error', __CLASS__, [
146
- 'message' => $file->get_error_message(),
147
- 'url' => $file_url,
148
- 'error' => $file,
149
- ] );
150
-
151
- return false;
152
- }
153
- }
154
-
155
- // Upload file into WP and leave WP handle the resize and such.
156
- $attachment_id = media_handle_sideload( [
157
- 'name' => $this->create_file_name( $file ),
158
- 'tmp_name' => $file,
159
- 'post_mime_type' => 'image',
160
- ] );
161
 
162
- // Remove the temporary file as is no longer required at this point.
163
- if ( ! $is_local && file_exists( $file ) ) {
164
- @unlink( $file );
165
- }
 
 
 
 
 
 
166
 
167
- if ( is_wp_error( $attachment_id ) ) {
168
- do_action( 'tribe_log', 'error', __CLASS__, [
169
- 'message' => $attachment_id->get_error_message(),
170
- 'url' => $file_url,
171
- 'error' => $attachment_id,
172
- ] );
173
 
174
  return false;
175
  }
176
 
177
- update_post_meta( $attachment_id, '_tribe_importer_original_url', $file_url );
178
 
179
- $this->maybe_init_attachment_guids_cache();
180
- $this->maybe_init_attachment_original_urls_cache();
 
181
 
182
- $attachment_post = get_post( $attachment_id );
183
- // Only update the cache if is a valid attachment.
184
- if ( $attachment_post instanceof WP_Post ) {
185
- self::$attachment_guids_cache[ $attachment_post->guid ] = $attachment_id;
186
- self::$original_urls_cache[ $file_url ] = $attachment_id;
187
  }
188
 
189
- return $attachment_id;
190
- }
191
-
192
- /**
193
- * WordPress requires to have an extension in all all files as uses `wp_check_filetype` which uses the extension
194
- * of the file to define if a file is valid or not, in this case the extension might not be present in some URLs of
195
- * attachments or media files, in those cases we try to guess the right extension using the mime of the file as
196
- * an alternative, if the $filename is a path we can verify the mime type using native WP functions.
197
- *
198
- * @since 4.11.5
199
- *
200
- * @param string $filename The name of the file or URL.
201
- *
202
- * @return string Returned a file name with an extension if is not already part of the file name.
203
- */
204
- protected function create_file_name( $filename ) {
205
- /**
206
  * We use the path basename only here to provided WordPress with a good filename
207
  * that will allow it to correctly detect and validate the extension.
208
  */
209
- $path = wp_parse_url( $filename, PHP_URL_PATH );
 
210
 
211
- $name = basename( $path );
212
- $properties = wp_check_filetype( $name );
 
213
 
214
- // Type can be defined from the name use that one instead.
215
- if ( ! empty( $properties['type'] ) ) {
216
- return $name;
217
  }
218
 
219
- // This is not a file that exists on the system, use the name instead.
220
- if ( ! file_exists( $filename ) ) {
221
- return $name;
 
 
 
 
 
222
  }
223
 
224
- $mime = wp_get_image_mime( $filename );
 
 
 
 
 
 
225
 
226
- // There's no mime defined for the file use the plain name instead.
227
- if ( $mime === '' ) {
228
- return $name;
229
- }
230
 
231
- // create an array with the mimes as the keys and extensions as values.
232
- $mime_to_extensions = array_flip( wp_get_mime_types() );
233
 
234
- // No mime was found for the file on the array of allowed mime types, fallback to the name.
235
- if ( ! isset( $mime_to_extensions[ $mime ] ) ) {
236
- return $name;
237
- }
238
 
239
- // If there are more than one extension just ose one.
240
- $parts = explode( '|', $mime_to_extensions[ $mime ] );
 
 
 
241
 
242
- // Create a new name with extension.
243
- return implode( '.', [ $name, reset( $parts ) ] );
244
  }
245
 
246
  protected function get_attachment_ID_from_url( $featured_image ) {
247
  $this->maybe_init_attachment_guids_cache();
248
  $this->maybe_init_attachment_original_urls_cache();
249
 
250
- $guids_cache = self::$attachment_guids_cache;
251
  $original_urls_cache = self::$original_urls_cache;
252
  if ( isset( $guids_cache[ $featured_image ] ) ) {
253
  return $guids_cache[ $featured_image ];
254
- }
255
-
256
- if ( isset( $original_urls_cache[ $featured_image ] ) ) {
257
  return $original_urls_cache[ $featured_image ];
258
  }
259
 
@@ -267,11 +189,11 @@ class Tribe__Image__Uploader {
267
  $guids = $wpdb->get_results( "SELECT ID, guid FROM $wpdb->posts where post_type = 'attachment'" );
268
 
269
  if ( $guids ) {
270
- $keys = wp_list_pluck( $guids, 'guid' );
271
- $values = wp_list_pluck( $guids, 'ID' );
272
  self::$attachment_guids_cache = array_combine( $keys, $values );
273
  } else {
274
- self::$attachment_guids_cache = [];
275
  }
276
  }
277
  }
@@ -289,11 +211,11 @@ class Tribe__Image__Uploader {
289
  " );
290
 
291
  if ( $original_urls ) {
292
- $keys = wp_list_pluck( $original_urls, 'meta_value' );
293
- $values = wp_list_pluck( $original_urls, 'ID' );
294
  self::$original_urls_cache = array_combine( $keys, $values );
295
  } else {
296
- self::$original_urls_cache = [];
297
  }
298
  }
299
  }
@@ -305,7 +227,7 @@ class Tribe__Image__Uploader {
305
  * @since 4.7.22
306
  *
307
  * @param string $unused_error_code The error numeric code.
308
- * @param string $message The error message.
309
  *
310
  * @throws RuntimeException To pass the error as an exception to
311
  * the handler.
29
  */
30
  public static function reset_cache() {
31
  self::$attachment_guids_cache = false;
32
+ self::$original_urls_cache = false;
33
  }
34
 
35
  /**
36
  * Uploads a file and creates the media attachment or simply returns the attachment ID if existing.
37
  *
38
+ * @return int|bool The attachment post ID if the uploading and attachment is successful or the ID refers to an attachment;
 
39
  * `false` otherwise.
40
  */
41
  public function upload_and_get_attachment_id() {
46
  $existing = false;
47
 
48
  if ( is_string( $this->featured_image ) && ! is_numeric( $this->featured_image ) ) {
49
+ $existing = $this->get_attachment_ID_from_url( $this->featured_image );
50
+ $id = $existing ? $existing : $this->upload_file( $this->featured_image );
 
 
 
 
 
51
  } elseif ( $post = get_post( $this->featured_image ) ) {
52
  $id = $post && 'attachment' === $post->post_type ? $this->featured_image : false;
53
  } else {
60
  __CLASS__,
61
  [
62
  'featured_image' => $this->featured_image,
63
+ 'exists' => (bool) $existing,
64
  'id' => $id,
65
  ]
66
  );
68
  return $id;
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  /**
72
  * @param string $file_url
73
  *
77
  /**
78
  * Allow plugins to enable local URL uploads, mainly used for testing.
79
  *
 
 
80
  * @param bool $allow_local_urls Whether to allow local URLs.
81
  * @param string $file_url File URL.
82
+ *
83
+ * @since 4.9.5
84
  */
85
  $allow_local_urls = apply_filters( 'tribe_image_uploader_local_urls', false, $file_url );
86
 
87
+ if ( ! filter_var( $file_url, FILTER_VALIDATE_URL ) && ! $allow_local_urls ) {
88
  return false;
89
  }
90
 
91
+ /*
92
+ * Since `file_get_contents` would fail silently we set an explicit
93
+ * error handler to catch the content of error.s.
94
+ */
95
+ set_error_handler( array( $this, 'handle_error' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ /*
98
+ * Some CDN services will append query arguments to the image URL; removing
99
+ * them now has the potential of blocking the image fetching completely so we
100
+ * let them be here.
101
+ */
102
+ try {
103
+ $contents = file_get_contents( $file_url );
104
+ } catch ( Exception $e ) {
105
+ $message = sprintf( 'Could not upload image file "%s": with message "%s"', $file_url, $e->getMessage() );
106
+ tribe( 'logger' )->log_error( $message, 'Image Uploader' );
107
 
108
+ restore_error_handler();
 
 
 
 
 
109
 
110
  return false;
111
  }
112
 
113
+ restore_error_handler();
114
 
115
+ if ( false === $contents ) {
116
+ $message = sprintf( 'Could not upload image file "%s": failed getting the contents.', $file_url );
117
+ tribe( 'logger' )->log_error( $message, 'Image Uploader' );
118
 
119
+ return false;
 
 
 
 
120
  }
121
 
122
+ /*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  * We use the path basename only here to provided WordPress with a good filename
124
  * that will allow it to correctly detect and validate the extension.
125
  */
126
+ $path = parse_url( $file_url, PHP_URL_PATH );
127
+ $upload = wp_upload_bits( basename( $path ), null, $contents );
128
 
129
+ if ( isset( $upload['error'] ) && $upload['error'] ) {
130
+ $message = sprintf( 'Could not upload image file "%s" with message "%s"', $file_url, $upload['error'] );
131
+ tribe( 'logger' )->log_error( $message, 'Image Uploader' );
132
 
133
+ return false;
 
 
134
  }
135
 
136
+ $type = '';
137
+ if ( ! empty( $upload['type'] ) ) {
138
+ $type = $upload['type'];
139
+ } else {
140
+ $mime = wp_check_filetype( $upload['file'] );
141
+ if ( $mime ) {
142
+ $type = $mime['type'];
143
+ }
144
  }
145
 
146
+ $attachment = array(
147
+ 'post_title' => basename( $upload['file'] ),
148
+ 'post_content' => '',
149
+ 'post_type' => 'attachment',
150
+ 'post_mime_type' => $type,
151
+ 'guid' => $upload['url'],
152
+ );
153
 
154
+ $id = wp_insert_attachment( $attachment, $upload['file'] );
 
 
 
155
 
156
+ require_once( ABSPATH . 'wp-admin/includes/image.php' );
 
157
 
158
+ wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $upload['file'] ) );
159
+ update_post_meta( $id, '_tribe_importer_original_url', $file_url );
 
 
160
 
161
+ $this->maybe_init_attachment_guids_cache();
162
+ $this->maybe_init_attachment_original_urls_cache();
163
+
164
+ self::$attachment_guids_cache[ get_post( $id )->guid ] = $id;
165
+ self::$original_urls_cache[ $file_url ] = $id;
166
 
167
+ return $id;
 
168
  }
169
 
170
  protected function get_attachment_ID_from_url( $featured_image ) {
171
  $this->maybe_init_attachment_guids_cache();
172
  $this->maybe_init_attachment_original_urls_cache();
173
 
174
+ $guids_cache = self::$attachment_guids_cache;
175
  $original_urls_cache = self::$original_urls_cache;
176
  if ( isset( $guids_cache[ $featured_image ] ) ) {
177
  return $guids_cache[ $featured_image ];
178
+ } elseif ( isset( $original_urls_cache[ $featured_image ] ) ) {
 
 
179
  return $original_urls_cache[ $featured_image ];
180
  }
181
 
189
  $guids = $wpdb->get_results( "SELECT ID, guid FROM $wpdb->posts where post_type = 'attachment'" );
190
 
191
  if ( $guids ) {
192
+ $keys = wp_list_pluck( $guids, 'guid' );
193
+ $values = wp_list_pluck( $guids, 'ID' );
194
  self::$attachment_guids_cache = array_combine( $keys, $values );
195
  } else {
196
+ self::$attachment_guids_cache = array();
197
  }
198
  }
199
  }
211
  " );
212
 
213
  if ( $original_urls ) {
214
+ $keys = wp_list_pluck( $original_urls, 'meta_value' );
215
+ $values = wp_list_pluck( $original_urls, 'ID' );
216
  self::$original_urls_cache = array_combine( $keys, $values );
217
  } else {
218
+ self::$original_urls_cache = array();
219
  }
220
  }
221
  }
227
  * @since 4.7.22
228
  *
229
  * @param string $unused_error_code The error numeric code.
230
+ * @param string $message The error message.
231
  *
232
  * @throws RuntimeException To pass the error as an exception to
233
  * the handler.
common/src/Tribe/Languages/Locations.php CHANGED
@@ -135,7 +135,7 @@ class Tribe__Languages__Locations {
135
  'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
136
  'GA' => esc_html__( 'Gabon', 'tribe-common' ),
137
  'GM' => esc_html__( 'Gambia', 'tribe-common' ),
138
- 'GE' => esc_html_x( 'Georgia', 'The country', 'tribe-common' ),
139
  'DE' => esc_html__( 'Germany', 'tribe-common' ),
140
  'GH' => esc_html__( 'Ghana', 'tribe-common' ),
141
  'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
@@ -331,7 +331,7 @@ class Tribe__Languages__Locations {
331
  'DE' => esc_html__( 'Delaware', 'tribe-common' ),
332
  'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
333
  'FL' => esc_html__( 'Florida', 'tribe-common' ),
334
- 'GA' => esc_html_x( 'Georgia', 'The US state Georgia','tribe-common' ),
335
  'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
336
  'ID' => esc_html__( 'Idaho', 'tribe-common' ),
337
  'IL' => esc_html__( 'Illinois', 'tribe-common' ),
135
  'TF' => esc_html__( 'French Southern Territories', 'tribe-common' ),
136
  'GA' => esc_html__( 'Gabon', 'tribe-common' ),
137
  'GM' => esc_html__( 'Gambia', 'tribe-common' ),
138
+ 'GE' => esc_html__( 'Georgia', 'tribe-common' ),
139
  'DE' => esc_html__( 'Germany', 'tribe-common' ),
140
  'GH' => esc_html__( 'Ghana', 'tribe-common' ),
141
  'GI' => esc_html__( 'Gibraltar', 'tribe-common' ),
331
  'DE' => esc_html__( 'Delaware', 'tribe-common' ),
332
  'DC' => esc_html__( 'District of Columbia', 'tribe-common' ),
333
  'FL' => esc_html__( 'Florida', 'tribe-common' ),
334
+ 'GA' => esc_html__( 'Georgia', 'tribe-common' ),
335
  'HI' => esc_html__( 'Hawaii', 'tribe-common' ),
336
  'ID' => esc_html__( 'Idaho', 'tribe-common' ),
337
  'IL' => esc_html__( 'Illinois', 'tribe-common' ),
common/src/Tribe/Log/File_Logger.php CHANGED
@@ -27,7 +27,7 @@ class Tribe__Log__File_Logger implements Tribe__Log__Logger {
27
  *
28
  * @var string $log_dir
29
  */
30
- $this->log_dir = apply_filters( 'tribe_file_logger_directory', get_temp_dir() );
31
  }
32
 
33
  /**
27
  *
28
  * @var string $log_dir
29
  */
30
+ $this->log_dir = apply_filters( 'tribe_file_logger_directory', sys_get_temp_dir() );
31
  }
32
 
33
  /**
common/src/Tribe/Main.php CHANGED
@@ -17,7 +17,7 @@ class Tribe__Main {
17
  const OPTIONNAME = 'tribe_events_calendar_options';
18
  const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
 
20
- const VERSION = '4.12.2';
21
 
22
  const FEED_URL = 'https://theeventscalendar.com/feed/';
23
 
@@ -55,6 +55,7 @@ class Tribe__Main {
55
  /**
56
  * Constructor for Common Class
57
  *
 
58
  * We are using a `public` constructor here for backwards compatibility.
59
  *
60
  * The way our code used to work we would have `new Tribe__Main()` called directly
@@ -87,8 +88,8 @@ class Tribe__Main {
87
 
88
  $this->promoter_connector();
89
 
90
- add_action( 'plugins_loaded', [ $this, 'plugins_loaded' ], 1 );
91
- add_action( 'tribe_common_loaded', [ $this, 'tribe_common_app_store' ], 10 );
92
  }
93
 
94
  /**
@@ -96,6 +97,8 @@ class Tribe__Main {
96
  */
97
  public function plugins_loaded() {
98
 
 
 
99
  $this->init_autoloading();
100
 
101
  $this->bind_implementations();
@@ -127,7 +130,7 @@ class Tribe__Main {
127
 
128
  $autoloader = Tribe__Autoloader::instance();
129
 
130
- $prefixes = [ 'Tribe__' => dirname( __FILE__ ) ];
131
  $autoloader->register_prefixes( $prefixes );
132
 
133
  foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) {
@@ -192,8 +195,8 @@ class Tribe__Main {
192
  [ 'tribe-query-string', 'utils/query-string.js' ],
193
  [ 'tribe-clipboard', 'vendor/clipboard/clipboard.js' ],
194
  [ 'datatables', 'vendor/datatables/datatables.js', [ 'jquery' ] ],
195
- [ 'tribe-select2', 'vendor/tribe-selectWoo/dist/js/selectWoo.full.js', [ 'jquery' ] ],
196
- [ 'tribe-select2-css', 'vendor/tribe-selectWoo/dist/css/selectWoo.css' ],
197
  [ 'tribe-utils-camelcase', 'utils-camelcase.js', [ 'underscore' ] ],
198
  [ 'tribe-moment', 'vendor/momentjs/moment.js' ],
199
  [ 'tribe-tooltipster', 'vendor/tooltipster/tooltipster.bundle.js', [ 'jquery' ] ],
@@ -223,22 +226,21 @@ class Tribe__Main {
223
  // These ones will be enqueued on `admin_enqueue_scripts` if the conditional method on filter is met
224
  tribe_assets(
225
  $this,
226
- [
227
- [ 'tribe-ui', 'tribe-ui.css' ],
228
- [ 'tribe-buttonset', 'buttonset.js', [ 'jquery', 'underscore' ] ],
229
- [ 'tribe-common-admin', 'tribe-common-admin.css', [ 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ] ],
230
- [ 'tribe-validation', 'validation.js', [ 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ] ],
231
- [ 'tribe-validation-style', 'validation.css', [ 'tribe-tooltipster-css' ] ],
232
- [ 'tribe-dependency', 'dependency.js', [ 'jquery', 'underscore', 'tribe-common' ] ],
233
- [ 'tribe-dependency-style', 'dependency.css', [ 'tribe-select2-css' ] ],
234
- [ 'tribe-pue-notices', 'pue-notices.js', [ 'jquery' ] ],
235
- [ 'tribe-datepicker', 'datepicker.css' ],
236
- ],
237
  'admin_enqueue_scripts',
238
- [
239
- 'conditionals' => [ $this, 'should_load_common_admin_css' ],
240
  'priority' => 5,
241
- ]
242
  );
243
 
244
  tribe_asset(
@@ -260,44 +262,13 @@ class Tribe__Main {
260
  'admin_enqueue_scripts',
261
  [
262
  'conditionals' => [ $this, 'should_load_common_admin_css' ],
263
- 'priority' => 5,
264
  ]
265
  );
266
 
267
  tribe( Tribe__Admin__Help_Page::class )->register_assets();
268
  }
269
 
270
- /**
271
- * Load Common's text domain, then fire the hook for other plugins to do the same.
272
- *
273
- * Make sure this fires on 'init', per WordPress best practices.
274
- *
275
- * @since 4.12.0
276
- *
277
- * @return bool
278
- */
279
- public function hook_load_text_domain() {
280
- $loaded = $this->load_text_domain(
281
- 'tribe-common',
282
- basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/'
283
- );
284
-
285
- /**
286
- * After attempting (hopefully successfully) to load Common's text domain.
287
- *
288
- * Load other plugin text domains on this hook, but make sure they're setup on this hook prior to 'init'.
289
- *
290
- * @since 4.12.0
291
- *
292
- * @param bool $loaded Whether or not Common's text domain was loaded.
293
- *
294
- * @return bool
295
- */
296
- do_action( 'tribe_load_text_domains', $loaded );
297
-
298
- return $loaded;
299
- }
300
-
301
  /**
302
  * Load All localization data create by `asset.data`
303
  *
@@ -308,11 +279,11 @@ class Tribe__Main {
308
  public function load_localize_data() {
309
  $datepicker_months = array_values( Tribe__Date_Utils::get_localized_months_full() );
310
 
311
- tribe( 'asset.data' )->add( 'tribe_l10n_datatables', [
312
- 'aria' => [
313
  'sort_ascending' => __( ': activate to sort column ascending', 'tribe-common' ),
314
  'sort_descending' => __( ': activate to sort column descending', 'tribe-common' ),
315
- ],
316
  'length_menu' => __( 'Show _MENU_ entries', 'tribe-common' ),
317
  'empty_table' => __( 'No data available in table', 'tribe-common' ),
318
  'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'tribe-common' ),
@@ -323,19 +294,19 @@ class Tribe__Main {
323
  'all_selected_text' => __( 'All items on this page were selected. ', 'tribe-common' ),
324
  'select_all_link' => __( 'Select all pages', 'tribe-common' ),
325
  'clear_selection' => __( 'Clear Selection.', 'tribe-common' ),
326
- 'pagination' => [
327
  'all' => __( 'All', 'tribe-common' ),
328
  'next' => __( 'Next', 'tribe-common' ),
329
  'previous' => __( 'Previous', 'tribe-common' ),
330
- ],
331
- 'select' => [
332
- 'rows' => [
333
  0 => '',
334
  '_' => __( ': Selected %d rows', 'tribe-common' ),
335
  1 => __( ': Selected 1 row', 'tribe-common' ),
336
- ],
337
- ],
338
- 'datepicker' => [
339
  'dayNames' => Tribe__Date_Utils::get_localized_weekdays_full(),
340
  'dayNamesShort' => Tribe__Date_Utils::get_localized_weekdays_short(),
341
  'dayNamesMin' => Tribe__Date_Utils::get_localized_weekdays_initial(),
@@ -348,38 +319,28 @@ class Tribe__Main {
348
  'closeText' => esc_html__( 'Done', 'the-events-calendar' ),
349
  'today' => esc_html__( 'Today', 'the-events-calendar' ),
350
  'clear' => esc_html__( 'Clear', 'the-events-calendar' ),
351
- ],
352
- ] );
353
  }
354
 
355
  /**
356
  * Adds core hooks
357
  */
358
  public function add_hooks() {
359
- add_action( 'plugins_loaded', [ 'Tribe__App_Shop', 'instance' ] );
360
- add_action( 'plugins_loaded', [ $this, 'tribe_plugins_loaded' ], PHP_INT_MAX );
361
 
362
  // Register for the assets to be available everywhere
363
- add_action( 'tribe_common_loaded', [ $this, 'load_assets' ], 1 );
364
- add_action( 'init', [ $this, 'hook_load_text_domain' ] );
365
- add_action( 'init', [ $this, 'load_localize_data' ] );
366
- add_action( 'plugins_loaded', [ 'Tribe__Admin__Notices', 'instance' ], 1 );
367
- add_action( 'admin_enqueue_scripts', [ $this, 'store_admin_notices' ] );
368
-
369
- add_filter( 'body_class', [ $this, 'add_js_class' ] );
370
- add_action( 'wp_footer', [ $this, 'toggle_js_class' ] );
371
  }
372
 
373
- /**
374
- * Adds `tribe-no-js` class to all pages when common is active.
375
- *
376
- * @since 4.3.4
377
- *
378
- * @param array|string $classes Previous classes on body.
379
- *
380
- * @return array All classes that will be printed on `<body>`.
381
- */
382
- public function add_js_class( $classes = [] ) {
383
  if ( ! is_array( $classes ) ) {
384
  $classes = explode( ' ', $classes );
385
  }
@@ -389,13 +350,6 @@ class Tribe__Main {
389
  return array_filter( array_unique( $classes ) );
390
  }
391
 
392
- /**
393
- * Removes `tribe-no-js` and replaces with `tribe-js` when the Javascript of the page is enabled.
394
- *
395
- * @since 4.3.4
396
- *
397
- * @return void This method only prints HTML to the screen no return.
398
- */
399
  public function toggle_js_class() {
400
  ?>
401
  <script>
@@ -415,7 +369,7 @@ class Tribe__Main {
415
  *
416
  * @since 4.5.7
417
  *
418
- * @return bool Whether we should load Common Admin CSS or not.
419
  */
420
  public function should_load_common_admin_css() {
421
  $helper = Tribe__Admin__Helpers::instance();
@@ -435,15 +389,13 @@ class Tribe__Main {
435
 
436
  /**
437
  * A Helper method to load text domain
438
- * First it tries to load the wp-content/languages translation then if falls to the try to load $dir language files.
 
439
  *
440
- * @since 4.0.1 Introduced.
441
- * @since 4.2 Included $domain and $dir params.
442
  *
443
- * @param string $domain The text domain that will be loaded.
444
- * @param string|false $dir What directory should be used to try to load if the default doesn't work.
445
- *
446
- * @return bool If it was able to load the text domain.
447
  */
448
  public function load_text_domain( $domain, $dir = false ) {
449
  // Added safety just in case this runs twice...
@@ -455,13 +407,13 @@ class Tribe__Main {
455
  $plugin_rel_path = WP_LANG_DIR . '/plugins/';
456
 
457
  /**
458
- * Allows users to filter the file location for a given text domain..
459
  * Be careful when using this filter, it will apply across the whole plugin suite.
460
  *
461
- * @param string $plugin_rel_path The relative path for the language files.
462
- * @param string $domain Which plugin domain we are trying to load.
463
- * @param string $locale Which Language we will load.
464
- * @param string|bool $dir If there was a custom directory passed on the method call.
465
  */
466
  $plugin_rel_path = apply_filters( 'tribe_load_text_domain', $plugin_rel_path, $domain, $locale, $dir );
467
 
@@ -475,21 +427,11 @@ class Tribe__Main {
475
  }
476
 
477
  /**
478
- * Returns the post types registered by Tribe plugins.
479
- *
480
- * @since 4.0.1 Introduced the method.
481
- *
482
- * @return array Slugs for all Post Types registered.
483
  */
484
  public static function get_post_types() {
485
- /**
486
- * We default the post type array to empty in tribe-common. Plugins like TEC add to it.
487
- *
488
- * @since 4.0.1
489
- *
490
- * @param array Slugs for all Post Types registered.
491
- */
492
- return apply_filters( 'tribe_post_types', [] );
493
  }
494
 
495
  /**
@@ -500,6 +442,7 @@ class Tribe__Main {
500
  * @param $insert_array
501
  *
502
  * @return array
 
503
  */
504
  public static function array_insert_after_key( $key, $source_array, $insert_array ) {
505
  if ( array_key_exists( $key, $source_array ) ) {
@@ -551,6 +494,26 @@ class Tribe__Main {
551
  return $candidate_post instanceof WP_Post ? $candidate_post->ID : false;
552
  }
553
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  /**
555
  * Adds a hook
556
  *
@@ -568,7 +531,6 @@ class Tribe__Main {
568
  */
569
  public function tribe_plugins_loaded() {
570
  tribe( 'admin.notice.php.version' );
571
- tribe( 'cache' );
572
  tribe_singleton( 'feature-detection', 'Tribe__Feature_Detection' );
573
  tribe_register_provider( 'Tribe__Service_Providers__Processes' );
574
 
@@ -586,26 +548,22 @@ class Tribe__Main {
586
 
587
  /**
588
  * Registers the slug bound to the implementations in the container.
589
- *
590
- * @since 4.4
591
- *
592
- * @return void Implementation of components loader doesnt return anything.
593
  */
594
  public function bind_implementations() {
595
  tribe_singleton( 'settings.manager', 'Tribe__Settings_Manager' );
596
- tribe_singleton( 'settings', 'Tribe__Settings', [ 'hook' ] );
597
- tribe_singleton( 'ajax.dropdown', 'Tribe__Ajax__Dropdown', [ 'hook' ] );
598
  tribe_singleton( 'assets', 'Tribe__Assets' );
599
- tribe_singleton( 'assets.pipeline', 'Tribe__Assets_Pipeline', [ 'hook' ] );
600
- tribe_singleton( 'asset.data', 'Tribe__Asset__Data', [ 'hook' ] );
601
  tribe_singleton( 'admin.helpers', 'Tribe__Admin__Helpers' );
602
- tribe_singleton( 'tracker', 'Tribe__Tracker', [ 'hook' ] );
603
- tribe_singleton( 'chunker', 'Tribe__Meta__Chunker', [ 'set_post_types', 'hook' ] );
604
- tribe_singleton( 'cache', 'Tribe__Cache', [ 'hook' ] );
605
  tribe_singleton( 'languages.locations', 'Tribe__Languages__Locations' );
606
  tribe_singleton( 'plugins.api', new Tribe__Plugins_API );
607
  tribe_singleton( 'logger', 'Tribe__Log' );
608
- tribe_singleton( 'cost-utils', [ 'Tribe__Cost_Utils', 'instance' ] );
609
  tribe_singleton( 'post-duplicate.strategy-factory', 'Tribe__Duplicate__Strategy_Factory' );
610
  tribe_singleton( 'post-duplicate', 'Tribe__Duplicate__Post' );
611
  tribe_singleton( 'context', 'Tribe__Context' );
@@ -620,8 +578,8 @@ class Tribe__Main {
620
 
621
  tribe_singleton( Tribe__Admin__Help_Page::class, Tribe__Admin__Help_Page::class );
622
 
623
- tribe_singleton( 'admin.notice.php.version', 'Tribe__Admin__Notice__Php_Version', [ 'hook' ] );
624
- tribe_singleton( 'admin.notice.marketing', 'Tribe__Admin__Notice__Marketing', [ 'hook' ] );
625
 
626
  tribe_register_provider( Tribe__Editor__Provider::class );
627
  tribe_register_provider( Tribe__Service_Providers__Debug_Bar::class );
@@ -629,7 +587,6 @@ class Tribe__Main {
629
  tribe_register_provider( Tribe\Service_Providers\Tooltip::class );
630
  tribe_register_provider( Tribe\Service_Providers\Dialog::class );
631
  tribe_register_provider( Tribe\Service_Providers\PUE::class );
632
- tribe_register_provider( Tribe\Service_Providers\Shortcodes::class );
633
  tribe_register_provider( Tribe\Log\Service_Provider::class );
634
  }
635
 
@@ -639,8 +596,6 @@ class Tribe__Main {
639
  * Add a filter to determine_current_user during the setup of common library.
640
  *
641
  * @since 4.9.20
642
- *
643
- * @return void Internal method without any return.
644
  */
645
  public function promoter_connector() {
646
  tribe_singleton( 'promoter.connector', 'Tribe__Promoter__Connector' );
@@ -659,26 +614,6 @@ class Tribe__Main {
659
  ************************/
660
  // @codingStandardsIgnoreStart
661
 
662
- /**
663
- * Helper function to indicate whether the current execution context is AJAX
664
- *
665
- * This method exists to allow us test code that behaves differently depending on the execution
666
- * context.
667
- *
668
- * @since 4.0
669
- *
670
- * @todo Add warning with '_deprecated_function'
671
- *
672
- * @param bool $doing_ajax An injectable status to override the `DOING_AJAX` check.
673
- *
674
- * @deprecated 4.7.12
675
- *
676
- * @return boolean
677
- */
678
- public function doing_ajax( $doing_ajax = null ) {
679
- return tribe( 'context' )->doing_ajax( $doing_ajax );
680
- }
681
-
682
  /**
683
  * Manages PUE license key notifications.
684
  *
17
  const OPTIONNAME = 'tribe_events_calendar_options';
18
  const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
 
20
+ const VERSION = '4.10.3';
21
 
22
  const FEED_URL = 'https://theeventscalendar.com/feed/';
23
 
55
  /**
56
  * Constructor for Common Class
57
  *
58
+ * @access public
59
  * We are using a `public` constructor here for backwards compatibility.
60
  *
61
  * The way our code used to work we would have `new Tribe__Main()` called directly
88
 
89
  $this->promoter_connector();
90
 
91
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 1 );
92
+ add_action( 'tribe_common_loaded', array( $this, 'tribe_common_app_store' ), 10 );
93
  }
94
 
95
  /**
97
  */
98
  public function plugins_loaded() {
99
 
100
+ $this->load_text_domain( 'tribe-common', basename( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) ) . '/common/lang/' );
101
+
102
  $this->init_autoloading();
103
 
104
  $this->bind_implementations();
130
 
131
  $autoloader = Tribe__Autoloader::instance();
132
 
133
+ $prefixes = array( 'Tribe__' => dirname( __FILE__ ) );
134
  $autoloader->register_prefixes( $prefixes );
135
 
136
  foreach ( glob( $this->plugin_path . 'src/deprecated/*.php' ) as $file ) {
195
  [ 'tribe-query-string', 'utils/query-string.js' ],
196
  [ 'tribe-clipboard', 'vendor/clipboard/clipboard.js' ],
197
  [ 'datatables', 'vendor/datatables/datatables.js', [ 'jquery' ] ],
198
+ [ 'tribe-select2', 'vendor/tribe-select2/select2.js', [ 'jquery' ] ],
199
+ [ 'tribe-select2-css', 'vendor/tribe-select2/select2.css' ],
200
  [ 'tribe-utils-camelcase', 'utils-camelcase.js', [ 'underscore' ] ],
201
  [ 'tribe-moment', 'vendor/momentjs/moment.js' ],
202
  [ 'tribe-tooltipster', 'vendor/tooltipster/tooltipster.bundle.js', [ 'jquery' ] ],
226
  // These ones will be enqueued on `admin_enqueue_scripts` if the conditional method on filter is met
227
  tribe_assets(
228
  $this,
229
+ array(
230
+ array( 'tribe-buttonset', 'buttonset.js', array( 'jquery', 'underscore' ) ),
231
+ array( 'tribe-common-admin', 'tribe-common-admin.css', array( 'tribe-dependency-style', 'tribe-bumpdown-css', 'tribe-buttonset-style', 'tribe-select2-css' ) ),
232
+ array( 'tribe-validation', 'validation.js', array( 'jquery', 'underscore', 'tribe-common', 'tribe-utils-camelcase', 'tribe-tooltipster' ) ),
233
+ array( 'tribe-validation-style', 'validation.css', array( 'tribe-tooltipster-css' ) ),
234
+ array( 'tribe-dependency', 'dependency.js', array( 'jquery', 'underscore', 'tribe-common' ) ),
235
+ array( 'tribe-dependency-style', 'dependency.css', array( 'tribe-select2-css' ) ),
236
+ array( 'tribe-pue-notices', 'pue-notices.js', array( 'jquery' ) ),
237
+ array( 'tribe-datepicker', 'datepicker.css' ),
238
+ ),
 
239
  'admin_enqueue_scripts',
240
+ array(
241
+ 'conditionals' => array( $this, 'should_load_common_admin_css' ),
242
  'priority' => 5,
243
+ )
244
  );
245
 
246
  tribe_asset(
262
  'admin_enqueue_scripts',
263
  [
264
  'conditionals' => [ $this, 'should_load_common_admin_css' ],
265
+ 'priority' => 5,
266
  ]
267
  );
268
 
269
  tribe( Tribe__Admin__Help_Page::class )->register_assets();
270
  }
271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  /**
273
  * Load All localization data create by `asset.data`
274
  *
279
  public function load_localize_data() {
280
  $datepicker_months = array_values( Tribe__Date_Utils::get_localized_months_full() );
281
 
282
+ tribe( 'asset.data' )->add( 'tribe_l10n_datatables', array(
283
+ 'aria' => array(
284
  'sort_ascending' => __( ': activate to sort column ascending', 'tribe-common' ),
285
  'sort_descending' => __( ': activate to sort column descending', 'tribe-common' ),
286
+ ),
287
  'length_menu' => __( 'Show _MENU_ entries', 'tribe-common' ),
288
  'empty_table' => __( 'No data available in table', 'tribe-common' ),
289
  'info' => __( 'Showing _START_ to _END_ of _TOTAL_ entries', 'tribe-common' ),
294
  'all_selected_text' => __( 'All items on this page were selected. ', 'tribe-common' ),
295
  'select_all_link' => __( 'Select all pages', 'tribe-common' ),
296
  'clear_selection' => __( 'Clear Selection.', 'tribe-common' ),
297
+ 'pagination' => array(
298
  'all' => __( 'All', 'tribe-common' ),
299
  'next' => __( 'Next', 'tribe-common' ),
300
  'previous' => __( 'Previous', 'tribe-common' ),
301
+ ),
302
+ 'select' => array(
303
+ 'rows' => array(
304
  0 => '',
305
  '_' => __( ': Selected %d rows', 'tribe-common' ),
306
  1 => __( ': Selected 1 row', 'tribe-common' ),
307
+ ),
308
+ ),
309
+ 'datepicker' => array(
310
  'dayNames' => Tribe__Date_Utils::get_localized_weekdays_full(),
311
  'dayNamesShort' => Tribe__Date_Utils::get_localized_weekdays_short(),
312
  'dayNamesMin' => Tribe__Date_Utils::get_localized_weekdays_initial(),
319
  'closeText' => esc_html__( 'Done', 'the-events-calendar' ),
320
  'today' => esc_html__( 'Today', 'the-events-calendar' ),
321
  'clear' => esc_html__( 'Clear', 'the-events-calendar' ),
322
+ ),
323
+ ) );
324
  }
325
 
326
  /**
327
  * Adds core hooks
328
  */
329
  public function add_hooks() {
330
+ add_action( 'plugins_loaded', array( 'Tribe__App_Shop', 'instance' ) );
331
+ add_action( 'plugins_loaded', array( $this, 'tribe_plugins_loaded' ), PHP_INT_MAX );
332
 
333
  // Register for the assets to be available everywhere
334
+ add_action( 'tribe_common_loaded', array( $this, 'load_assets' ), 1 );
335
+ add_action( 'init', array( $this, 'load_localize_data' ) );
336
+ add_action( 'plugins_loaded', array( 'Tribe__Admin__Notices', 'instance' ), 1 );
337
+ add_action( 'admin_enqueue_scripts', array( $this, 'store_admin_notices' ) );
338
+
339
+ add_filter( 'body_class', array( $this, 'add_js_class' ) );
340
+ add_action( 'wp_footer', array( $this, 'toggle_js_class' ) );
 
341
  }
342
 
343
+ public function add_js_class( $classes = array() ) {
 
 
 
 
 
 
 
 
 
344
  if ( ! is_array( $classes ) ) {
345
  $classes = explode( ' ', $classes );
346
  }
350
  return array_filter( array_unique( $classes ) );
351
  }
352
 
 
 
 
 
 
 
 
353
  public function toggle_js_class() {
354
  ?>
355
  <script>
369
  *
370
  * @since 4.5.7
371
  *
372
+ * @return bool
373
  */
374
  public function should_load_common_admin_css() {
375
  $helper = Tribe__Admin__Helpers::instance();
389
 
390
  /**
391
  * A Helper method to load text domain
392
+ * First it tries to load the wp-content/languages translation then if falls to the
393
+ * try to load $dir language files
394
  *
395
+ * @param string $domain The text domain that will be loaded
396
+ * @param string $dir What directory should be used to try to load if the default doenst work
397
  *
398
+ * @return bool If it was able to load the text domain
 
 
 
399
  */
400
  public function load_text_domain( $domain, $dir = false ) {
401
  // Added safety just in case this runs twice...
407
  $plugin_rel_path = WP_LANG_DIR . '/plugins/';
408
 
409
  /**
410
+ * Allows users to filter the file location for a given text domain
411
  * Be careful when using this filter, it will apply across the whole plugin suite.
412
  *
413
+ * @param string $plugin_rel_path The relative path for the language files
414
+ * @param string $domain Which plugin domain we are trying to load
415
+ * @param string $locale Which Language we will load
416
+ * @param string|bool $dir If there was a custom directory passed on the method call
417
  */
418
  $plugin_rel_path = apply_filters( 'tribe_load_text_domain', $plugin_rel_path, $domain, $locale, $dir );
419
 
427
  }
428
 
429
  /**
430
+ * Returns the post types registered by Tribe plugins
 
 
 
 
431
  */
432
  public static function get_post_types() {
433
+ // we default the post type array to empty in tribe-common. Plugins like TEC add to it
434
+ return apply_filters( 'tribe_post_types', array() );
 
 
 
 
 
 
435
  }
436
 
437
  /**
442
  * @param $insert_array
443
  *
444
  * @return array
445
+ *
446
  */
447
  public static function array_insert_after_key( $key, $source_array, $insert_array ) {
448
  if ( array_key_exists( $key, $source_array ) ) {
494
  return $candidate_post instanceof WP_Post ? $candidate_post->ID : false;
495
  }
496
 
497
+ /**
498
+ * Helper function to indicate whether the current execution context is AJAX
499
+ *
500
+ * This method exists to allow us test code that behaves differently depending on the execution
501
+ * context.
502
+ *
503
+ * @since 4.0
504
+ *
505
+ * @todo Add warning with '_deprecated_function'
506
+ *
507
+ * @param bool $doing_ajax An injectable status to override the `DOING_AJAX` check.
508
+ *
509
+ * @deprecated 4.7.12
510
+ *
511
+ * @return boolean
512
+ */
513
+ public function doing_ajax( $doing_ajax = null ) {
514
+ return tribe( 'context' )->doing_ajax( $doing_ajax );
515
+ }
516
+
517
  /**
518
  * Adds a hook
519
  *
531
  */
532
  public function tribe_plugins_loaded() {
533
  tribe( 'admin.notice.php.version' );
 
534
  tribe_singleton( 'feature-detection', 'Tribe__Feature_Detection' );
535
  tribe_register_provider( 'Tribe__Service_Providers__Processes' );
536
 
548
 
549
  /**
550
  * Registers the slug bound to the implementations in the container.
 
 
 
 
551
  */
552
  public function bind_implementations() {
553
  tribe_singleton( 'settings.manager', 'Tribe__Settings_Manager' );
554
+ tribe_singleton( 'settings', 'Tribe__Settings', array( 'hook' ) );
555
+ tribe_singleton( 'ajax.dropdown', 'Tribe__Ajax__Dropdown', array( 'hook' ) );
556
  tribe_singleton( 'assets', 'Tribe__Assets' );
557
+ tribe_singleton( 'assets.pipeline', 'Tribe__Assets_Pipeline', array( 'hook' ) );
558
+ tribe_singleton( 'asset.data', 'Tribe__Asset__Data', array( 'hook' ) );
559
  tribe_singleton( 'admin.helpers', 'Tribe__Admin__Helpers' );
560
+ tribe_singleton( 'tracker', 'Tribe__Tracker', array( 'hook' ) );
561
+ tribe_singleton( 'chunker', 'Tribe__Meta__Chunker', array( 'set_post_types', 'hook' ) );
562
+ tribe_singleton( 'cache', 'Tribe__Cache' );
563
  tribe_singleton( 'languages.locations', 'Tribe__Languages__Locations' );
564
  tribe_singleton( 'plugins.api', new Tribe__Plugins_API );
565
  tribe_singleton( 'logger', 'Tribe__Log' );
566
+ tribe_singleton( 'cost-utils', array( 'Tribe__Cost_Utils', 'instance' ) );
567
  tribe_singleton( 'post-duplicate.strategy-factory', 'Tribe__Duplicate__Strategy_Factory' );
568
  tribe_singleton( 'post-duplicate', 'Tribe__Duplicate__Post' );
569
  tribe_singleton( 'context', 'Tribe__Context' );
578
 
579
  tribe_singleton( Tribe__Admin__Help_Page::class, Tribe__Admin__Help_Page::class );
580
 
581
+ tribe_singleton( 'admin.notice.php.version', 'Tribe__Admin__Notice__Php_Version', array( 'hook' ) );
582
+ tribe_singleton( 'admin.notice.marketing', 'Tribe__Admin__Notice__Marketing', array( 'hook' ) );
583
 
584
  tribe_register_provider( Tribe__Editor__Provider::class );
585
  tribe_register_provider( Tribe__Service_Providers__Debug_Bar::class );
587
  tribe_register_provider( Tribe\Service_Providers\Tooltip::class );
588
  tribe_register_provider( Tribe\Service_Providers\Dialog::class );
589
  tribe_register_provider( Tribe\Service_Providers\PUE::class );
 
590
  tribe_register_provider( Tribe\Log\Service_Provider::class );
591
  }
592
 
596
  * Add a filter to determine_current_user during the setup of common library.
597
  *
598
  * @since 4.9.20
 
 
599
  */
600
  public function promoter_connector() {
601
  tribe_singleton( 'promoter.connector', 'Tribe__Promoter__Connector' );
614
  ************************/
615
  // @codingStandardsIgnoreStart
616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617
  /**
618
  * Manages PUE license key notifications.
619
  *
common/src/Tribe/PUE/Checker.php CHANGED
@@ -841,15 +841,7 @@ if ( ! class_exists( 'Tribe__PUE__Checker' ) ) {
841
  $class_name = $autoloader->get_prefix_by_slug( $this->get_slug() );
842
 
843
  if ( $class_name ) {
844
- $is_namespaced = false !== strpos( $class_name, '\\' );
845
-
846
- if ( $is_namespaced ) {
847
- // Handle class prefixes like Tribe\Plugin\.
848
- $class_name .= 'PUE\Helper';
849
- } else {
850
- // Handle class prefixes like Tribe__Plugin__.
851
- $class_name .= 'PUE__Helper';
852
- }
853
 
854
  if ( constant( $class_name . '::DATA' ) ) {
855
  $license_key = constant( $class_name . '::DATA' );
841
  $class_name = $autoloader->get_prefix_by_slug( $this->get_slug() );
842
 
843
  if ( $class_name ) {
844
+ $class_name .= 'PUE__Helper';
 
 
 
 
 
 
 
 
845
 
846
  if ( constant( $class_name . '::DATA' ) ) {
847
  $license_key = constant( $class_name . '::DATA' );
common/src/Tribe/PUE/Update_Prevention.php CHANGED
@@ -178,7 +178,7 @@ class Update_Prevention {
178
  $plugins_classes = array_keys( $incompatible_plugins );
179
  $plugins_list_html = tribe( 'pue.notices' )->get_formatted_plugin_names_from_classes( $plugins_classes );
180
 
181
- $link_read_more = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read more', 'tribe-common' ) . '.</a>';
182
 
183
  $message = sprintf(
184
  esc_html__( 'Your update failed due to an incompatibility between the version (%1$s) of the %2$s you tried to update to and the version of %3$s that you are using. %4$s', 'tribe-common' ),
178
  $plugins_classes = array_keys( $incompatible_plugins );
179
  $plugins_list_html = tribe( 'pue.notices' )->get_formatted_plugin_names_from_classes( $plugins_classes );
180
 
181
+ $link_read_more = '<a href="http://m.tri.be/1aev" target="_blank">' . esc_html__( 'Read More.', 'tribe-common' ) . '</a>';
182
 
183
  $message = sprintf(
184
  esc_html__( 'Your update failed due to an incompatibility between the version (%1$s) of the %2$s you tried to update to and the version of %3$s that you are using. %4$s', 'tribe-common' ),
common/src/Tribe/Plugins.php CHANGED
@@ -131,37 +131,5 @@ if ( ! class_exists( 'Tribe__Plugins' ) ) {
131
  return apply_filters( 'tribe_plugins_get_list', $this->tribe_plugins );
132
  }
133
 
134
- /**
135
- * Checks if given plugin is active. Usually a Modern Tribe plugin.
136
- *
137
- * @param string $plugin_name The name of the plugin. Each plugin defines their name upon hooking on the filter.
138
- *
139
- * @since 4.12.1
140
- *
141
- * @return bool True if plugin is active. False if plugin is not active.
142
- */
143
- public static function is_active( $plugin_name ) {
144
- if ( ! did_action( "plugins_loaded" ) ) {
145
- _doing_it_wrong(
146
- __METHOD__,
147
- __( 'Using this function before "plugins_loaded" action has fired can return unreliable results.', 'tribe-common' ),
148
- 'TBD'
149
- );
150
- }
151
-
152
- /**
153
- * Filters the array that each Tribe plugin overrides to
154
- * set itself as active when this function is called.
155
- *
156
- * @example [ 'the-events-calendar' => true, 'event-tickets' => true ]
157
- *
158
- * @since 4.12.1
159
- *
160
- * @return array Plugin slugs as keys and bool as value for whether it's active or not.
161
- */
162
- $plugins = apply_filters( 'tribe_active_plugins', [] );
163
-
164
- return isset( $plugins[ $plugin_name ] ) && tribe_is_truthy( $plugins[ $plugin_name ] );
165
- }
166
  }
167
  }
131
  return apply_filters( 'tribe_plugins_get_list', $this->tribe_plugins );
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  }
135
  }
common/src/Tribe/Post_Transient.php CHANGED
@@ -29,7 +29,6 @@ class Tribe__Post_Transient {
29
  * @param int $post_id The Post ID, can also be a WP_Post
30
  * @param string $transient Post Meta to Fetch
31
  *
32
- * @return mixed Value stored on the Post Transient.
33
  */
34
  public function get( $post_id, $transient ) {
35
  global $_wp_using_ext_object_cache;
@@ -98,11 +97,10 @@ class Tribe__Post_Transient {
98
  *
99
  * @since 4.1
100
  *
101
- * @param int $post_id The Post ID, can also be a WP_Post.
102
- * @param string $transient Post Meta to Delete.
103
- * @param string $value Only delete if the value Matches.
104
  *
105
- * @return boolean If we were able to delete the transient.
106
  */
107
  public function delete( $post_id, $transient, $value = null ) {
108
  global $_wp_using_ext_object_cache;
@@ -151,16 +149,15 @@ class Tribe__Post_Transient {
151
  }
152
 
153
  /**
154
- * Sets a new value for the Transient.
155
  *
156
  * @since 4.1
157
  *
158
- * @param int $post_id The Post ID, can also be a WP_Post.
159
- * @param string $transient Post Meta to set.
160
- * @param string $value Only delete if the value Matches.
161
- * @param int $expiration How long this transient will be valid, in seconds.
162
  *
163
- * @return int|false Meta ID on success, false on failure.
164
  */
165
  public function set( $post_id, $transient, $value, $expiration = 0 ) {
166
  global $_wp_using_ext_object_cache;
@@ -211,4 +208,6 @@ class Tribe__Post_Transient {
211
 
212
  return $result;
213
  }
 
 
214
  }
29
  * @param int $post_id The Post ID, can also be a WP_Post
30
  * @param string $transient Post Meta to Fetch
31
  *
 
32
  */
33
  public function get( $post_id, $transient ) {
34
  global $_wp_using_ext_object_cache;
97
  *
98
  * @since 4.1
99
  *
100
+ * @param int $post_id The Post ID, can also be a WP_Post
101
+ * @param string $transient Post Meta to Delete
102
+ * @param string $value Only delete if the value Matches
103
  *
 
104
  */
105
  public function delete( $post_id, $transient, $value = null ) {
106
  global $_wp_using_ext_object_cache;
149
  }
150
 
151
  /**
152
+ * Sets a new value for the Transient
153
  *
154
  * @since 4.1
155
  *
156
+ * @param int $post_id The Post ID, can also be a WP_Post
157
+ * @param string $transient Post Meta to set
158
+ * @param string $value Only delete if the value Matches
159
+ * @param int $expiration How long this transient will be valid, in seconds
160
  *
 
161
  */
162
  public function set( $post_id, $transient, $value, $expiration = 0 ) {
163
  global $_wp_using_ext_object_cache;
208
 
209
  return $result;
210
  }
211
+
212
+
213
  }
common/src/Tribe/Process/Post_Thumbnail_Setter.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  /**
4
  * Class Tribe__Process__Post_Thumbnail_Setter
 
5
  *
6
  * Handles upload and setting of a post thumbnail in an async process.
7
  * Example usage:
@@ -48,7 +49,7 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
48
 
49
  $this->data( $data );
50
 
51
- do_action( 'tribe_log', 'debug', $this->identifier, $data );
52
 
53
  return parent::dispatch();
54
  }
@@ -85,11 +86,10 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
85
  *
86
  * @since 4.7.12
87
  *
88
- * @param array|null $data_source An optional source of data.
89
- *
90
  * @see Tribe__Process__Post_Thumbnail_Setter::sync_handle()
91
  *
92
- * @see tribe_upload_image()
93
  */
94
  protected function handle( array $data_source = null ) {
95
  $this->sync_handle( $data_source );
@@ -99,7 +99,11 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
99
  * {@inheritdoc}
100
  */
101
  public function sync_handle( array $data_source = null ) {
102
- do_action( 'tribe_log', 'debug', $this->identifier, [ 'status' => 'handling request' ] );
 
 
 
 
103
 
104
  $data_source = isset( $data_source ) ? $data_source : $_POST;
105
 
@@ -112,11 +116,7 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
112
  $id = filter_var( $data_source['post_id'], FILTER_SANITIZE_NUMBER_INT );
113
  $post_thumbnail = filter_var( $data_source['post_thumbnail'], FILTER_SANITIZE_STRING );
114
 
115
- do_action( 'tribe_log', 'debug', $this->identifier, [
116
- 'status' => 'fetching thumbnail',
117
- 'post_thumbnail' => $post_thumbnail,
118
- 'post_id' => $id,
119
- ] );
120
 
121
  $thumbnail_id = tribe_upload_image( $post_thumbnail );
122
 
@@ -129,9 +129,9 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
129
  'action' => 'fetch',
130
  'post_thumbnail' => $post_thumbnail,
131
  'post_id' => $id,
132
- 'status' => 'could not fetch',
133
  ]
134
  );
 
135
 
136
  return 0;
137
  }
@@ -151,10 +151,11 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
151
  'post_thumbnail' => $post_thumbnail,
152
  'attachment_id' => $thumbnail_id,
153
  'post_id' => $id,
154
- 'status' => 'unable to set thumbnail',
155
  ]
156
  );
157
 
 
 
158
  return $thumbnail_id;
159
  }
160
 
@@ -167,10 +168,11 @@ class Tribe__Process__Post_Thumbnail_Setter extends Tribe__Process__Handler {
167
  'post_thumbnail' => $post_thumbnail,
168
  'attachment_id' => $thumbnail_id,
169
  'post_id' => $id,
170
- 'status' => 'completed - attachment created and linked to the post',
171
  ]
172
  );
173
 
 
 
174
  return $thumbnail_id;
175
  }
176
  }
2
 
3
  /**
4
  * Class Tribe__Process__Post_Thumbnail_Setter
5
+
6
  *
7
  * Handles upload and setting of a post thumbnail in an async process.
8
  * Example usage:
49
 
50
  $this->data( $data );
51
 
52
+ do_action( 'tribe_log', 'debug', __CLASS__, $data );
53
 
54
  return parent::dispatch();
55
  }
86
  *
87
  * @since 4.7.12
88
  *
89
+ * @see tribe_upload_image()
 
90
  * @see Tribe__Process__Post_Thumbnail_Setter::sync_handle()
91
  *
92
+ * @param array|null $data_source An optional source of data.
93
  */
94
  protected function handle( array $data_source = null ) {
95
  $this->sync_handle( $data_source );
99
  * {@inheritdoc}
100
  */
101
  public function sync_handle( array $data_source = null ) {
102
+ /** @var Tribe__Log $logger */
103
+ $logger = tribe( 'logger' );
104
+ $log_src = 'Featured image setter';
105
+
106
+ $logger->log_debug( "(ID: {$this->identifier}) - handling request.", $log_src );
107
 
108
  $data_source = isset( $data_source ) ? $data_source : $_POST;
109
 
116
  $id = filter_var( $data_source['post_id'], FILTER_SANITIZE_NUMBER_INT );
117
  $post_thumbnail = filter_var( $data_source['post_thumbnail'], FILTER_SANITIZE_STRING );
118
 
119
+ $logger->log_debug( "(ID: {$this->identifier}) - fetching {$post_thumbnail} for post {$id}", $log_src );
 
 
 
 
120
 
121
  $thumbnail_id = tribe_upload_image( $post_thumbnail );
122
 
129
  'action' => 'fetch',
130
  'post_thumbnail' => $post_thumbnail,
131
  'post_id' => $id,
 
132
  ]
133
  );
134
+ $logger->log_debug( "(ID: {$this->identifier}) - could not fetch {$post_thumbnail} for post {$id}, done.", $log_src );
135
 
136
  return 0;
137
  }
151
  'post_thumbnail' => $post_thumbnail,
152
  'attachment_id' => $thumbnail_id,
153
  'post_id' => $id,
 
154
  ]
155
  );
156
 
157
+ $logger->log_debug( "(ID: {$this->identifier}) - fetched {$post_thumbnail}, created attachment with ID {$thumbnail_id}, unable to set thumbnail for post {$id}, done.", $log_src );
158
+
159
  return $thumbnail_id;
160
  }
161
 
168
  'post_thumbnail' => $post_thumbnail,
169
  'attachment_id' => $thumbnail_id,
170
  'post_id' => $id,
 
171
  ]
172
  );
173
 
174
+ $logger->log_debug( "(ID: {$this->identifier}) - fetched {$post_thumbnail}, created attachment with ID {$thumbnail_id}, set thumbnail for post {$id}, done.", $log_src );
175
+
176
  return $thumbnail_id;
177
  }
178
  }
common/src/Tribe/Promoter/Connector.php CHANGED
@@ -192,7 +192,7 @@ class Tribe__Promoter__Connector {
192
 
193
  $payload = [
194
  'licenseKey' => $license_key,
195
- 'sourceId' => $post_id instanceof WP_Post ? $post_id->ID : $post_id,
196
  ];
197
 
198
  $token = \Firebase\JWT\JWT::encode( $payload, $secret_key );
192
 
193
  $payload = [
194
  'licenseKey' => $license_key,
195
+ 'sourceId' => $post_id,
196
  ];
197
 
198
  $token = \Firebase\JWT\JWT::encode( $payload, $secret_key );
common/src/Tribe/Repository.php CHANGED
@@ -5,8 +5,6 @@ use Tribe__Utils__Array as Arr;
5
  abstract class Tribe__Repository
6
  implements Tribe__Repository__Interface {
7
 
8
- const MAX_NUMBER_OF_POSTS_PER_PAGE = 99999999999;
9
-
10
  /**
11
  * @var array An array of keys that cannot be updated on this repository.
12
  */
@@ -3169,38 +3167,20 @@ abstract class Tribe__Repository
3169
  */
3170
  $query_args = apply_filters( "tribe_repository_{$this->filter_name}_query_args", $query_args, $query, $this );
3171
 
3172
- /**
3173
- * Provides a last-ditch effort to override the filtered offset.
3174
- *
3175
- * This should only be used if doing creating pagination for performance purposes.
3176
- *
3177
- * @since 4.11.0
3178
- *
3179
- * @param null|int $filtered_offset Offset parameter setting.
3180
- * @param array $query_args List of query arguments.
3181
- */
3182
- $filtered_offset = apply_filters( 'tribe_repository_query_arg_offset_override', null, $query_args );
3183
-
3184
- if ( $filtered_offset || isset( $query_args['offset'] ) ) {
3185
  $per_page = (int) Tribe__Utils__Array::get( $query_args, 'posts_per_page', get_option( 'posts_per_page' ) );
 
3186
 
3187
- if ( $filtered_offset ) {
3188
- $query_args['offset'] = $filtered_offset;
3189
- } elseif ( isset( $query_args['offset'] ) ) {
3190
- $offset = absint( $query_args['offset'] );
3191
- $page = (int) Tribe__Utils__Array::get( $query_args, 'paged', 1 );
3192
 
3193
- $real_offset = $per_page === -1 ? $offset : ( $per_page * ( $page - 1 ) ) + $offset;
3194
- $query_args['offset'] = $real_offset;
3195
-
3196
- /**
3197
- * Unset the `offset` query argument to avoid applying it multiple times when this method
3198
- * is used, on the same repository, more than once.
3199
- */
3200
- unset( $this->query_args['offset'] );
3201
- }
3202
-
3203
- $query_args['posts_per_page'] = $per_page === -1 ? self::MAX_NUMBER_OF_POSTS_PER_PAGE : $per_page;
3204
  }
3205
 
3206
  foreach ( $query_args as $key => $value ) {
5
  abstract class Tribe__Repository
6
  implements Tribe__Repository__Interface {
7
 
 
 
8
  /**
9
  * @var array An array of keys that cannot be updated on this repository.
10
  */
3167
  */
3168
  $query_args = apply_filters( "tribe_repository_{$this->filter_name}_query_args", $query_args, $query, $this );
3169
 
3170
+ if ( isset( $query_args['offset'] ) ) {
3171
+ $offset = absint( $query_args['offset'] );
 
 
 
 
 
 
 
 
 
 
 
3172
  $per_page = (int) Tribe__Utils__Array::get( $query_args, 'posts_per_page', get_option( 'posts_per_page' ) );
3173
+ $page = (int) Tribe__Utils__Array::get( $query_args, 'paged', 1 );
3174
 
3175
+ $real_offset = $per_page === - 1 ? $offset : ( $per_page * ( $page - 1 ) ) + $offset;
3176
+ $query_args['offset'] = $real_offset;
3177
+ $query_args['posts_per_page'] = $per_page === - 1 ? 99999999999 : $per_page;
 
 
3178
 
3179
+ /**
3180
+ * Unset the `offset` query argument to avoid applying it multiple times when this method
3181
+ * is used, on the same repository, more than once.
3182
+ */
3183
+ unset( $this->query_args['offset'] );
 
 
 
 
 
 
3184
  }
3185
 
3186
  foreach ( $query_args as $key => $value ) {
common/src/Tribe/Repository/Query_Filters.php CHANGED
@@ -973,10 +973,10 @@ class Tribe__Repository__Query_Filters {
973
  *
974
  * @since 4.9.5
975
  *
976
- * @param string $orderby The `ORDER BY` clause of the query being filtered.
977
- * @param WP_Query $query The query object currently being filtered.
978
  *
979
- * @return string The filtered `ORDER BY` clause.
980
  */
981
  public function filter_posts_orderby( $orderby, WP_Query $query ) {
982
  if ( $query !== $this->current_query ) {
973
  *
974
  * @since 4.9.5
975
  *
976
+ * @param string $orderby
977
+ * @param WP_Query $query
978
  *
979
+ * @return string
980
  */
981
  public function filter_posts_orderby( $orderby, WP_Query $query ) {
982
  if ( $query !== $this->current_query ) {
common/src/Tribe/Rewrite.php CHANGED
@@ -26,14 +26,6 @@ class Tribe__Rewrite {
26
  * @var static
27
  */
28
  public static $instance;
29
- /**
30
- * A delimiter used to separate a localized matcher from its base in the format `<loc_matcher><delim><base>`.
31
- *
32
- * @since 4.11.5
33
- *
34
- * @var string
35
- */
36
- protected static $localized_matcher_delimiter = '~';
37
 
38
  /**
39
  * WP_Rewrite Instance
@@ -197,17 +189,6 @@ class Tribe__Rewrite {
197
  remove_action( 'shutdown', [ $this, 'dump_cache' ] );
198
  }
199
 
200
- /**
201
- * Determines if we have plain permalink.
202
- *
203
- * @since 4.11.2
204
- *
205
- * @return bool If we use plain permalink or not.
206
- */
207
- public static function is_plain_permalink() {
208
- return tribe_context()->is( 'plain_permalink' );
209
- }
210
-
211
  /**
212
  * Get the base slugs for the rewrite rules.
213
  *
@@ -426,11 +407,8 @@ class Tribe__Rewrite {
426
  $query = (string) parse_url( $url, PHP_URL_QUERY );
427
  wp_parse_str( $query, $query_vars );
428
 
429
- // Drop any query var that is not a scalar; it should not be handled.
430
- $query_vars = array_filter( $query_vars, 'is_scalar' );
431
-
432
  if ( isset( $query_vars['paged'] ) && 1 === (int) $query_vars['paged'] ) {
433
- // Remove the `paged` query var if it's 1.
434
  unset( $query_vars['paged'] );
435
  }
436
 
@@ -438,16 +416,10 @@ class Tribe__Rewrite {
438
 
439
  $our_rules = $this->get_handled_rewrite_rules();
440
  $handled_query_vars = $this->get_rules_query_vars( $our_rules );
441
- $handled_post_types = $this->get_post_types();
442
 
443
  if (
444
- // The rules we handle should not be empty.
445
  empty( $our_rules )
446
- || ! (
447
- // Supported post types should be either keys or values, of the `post_type` argument, in the query vars.
448
- count( array_intersect_key( array_flip( $handled_post_types ), $query_vars ) )
449
- || in_array( Arr::get( $query_vars, 'post_type', 'post' ), $handled_post_types, true )
450
- )
451
  ) {
452
  $wp_canonical = redirect_canonical( $canonical_url, false );
453
  if ( empty( $wp_canonical ) ) {
@@ -513,38 +485,16 @@ class Tribe__Rewrite {
513
  return '';
514
  }
515
 
516
- if ( isset( $localized_matcher['localized_slug'] ) ) {
517
- // If available, then return the localized slug instead of inferring it as we do below.
518
- return $localized_matcher['localized_slug'];
519
- }
520
-
521
  /*
522
  * We use `end` as, by default, the localized version of the slug in the current language will be at the
523
  * end of the array.
 
524
  */
525
  return end( $localized_matcher['localized_slugs'] );
526
  }, $localized_matchers );
527
 
528
  // Include dynamic matchers now.
529
  $replace = array_merge( $dynamic_matchers, $replace );
530
-
531
- /*
532
- * Prune from the replacements the empty values. This will resolve conflicts (e.g. single and archive w/
533
- * same slug) as no two can be true at the same time.
534
- * Remove the `<delim><base>` prefix added to localized matchers, if any.
535
- */
536
- $replace = array_filter( $replace );
537
- $replace = array_combine(
538
- array_map( static function ( $key ) {
539
- return preg_replace(
540
- '/' . preg_quote( Tribe__Rewrite::$localized_matcher_delimiter ) . '\\w*$/',
541
- '',
542
- $key
543
- );
544
- }, array_keys( $replace ) ),
545
- $replace
546
- );
547
-
548
  $replaced = str_replace( array_keys( $replace ), $replace, $link_template );
549
 
550
  // Remove trailing chars.
@@ -600,29 +550,20 @@ class Tribe__Rewrite {
600
  * @return array An array of rewrite rules handled by the implementation in the shape `[ <regex> => <path> ]`.
601
  */
602
  protected function get_handled_rewrite_rules() {
603
- static $cache_var_name = __METHOD__;
604
-
605
- $our_rules = tribe_get_var( $cache_var_name, null );
606
-
607
  // We need to make sure we are have WP_Rewrite setup
608
  if ( ! $this->rewrite ) {
609
  $this->setup();
610
  }
611
 
612
- $all_rules = isset( $this->rewrite->rules ) ? (array) $this->rewrite->rules : [];
613
-
614
- if ( null === $our_rules ) {
615
- // While this is specific to The Events Calendar we're handling a small enough post type base to keep it here.
616
- $pattern = '/post_type=tribe_(events|venue|organizer)/';
617
- // Reverse the rules to try and match the most complex first.
618
- $our_rules = array_filter( $all_rules,
619
- static function ( $rule_query_string ) use ( $pattern ) {
620
- return preg_match( $pattern, $rule_query_string );
621
- }
622
- );
623
-
624
- tribe_set_var( $cache_var_name, $our_rules );
625
- }
626
 
627
  /**
628
  * Filters the list of rewrite rules handled by our code to add or remove some as required.
@@ -632,11 +573,8 @@ class Tribe__Rewrite {
632
  * @param array $our_rules An array of rewrite rules handled by our code, in the shape
633
  * `[ <rewrite_rule_regex_pattern> => <query_string> ]`.
634
  * E.g. `[ '(?:events)/(?:list)/?$' => 'index.php?post_type=tribe_events&eventDisplay=list' ]`.
635
- * @param array<string,string> All the current rewrite rules, before any filtering is applied; these have the
636
- * same `<pattern => rewrite >` format as the previous argument, which is the
637
- * format used by WordPress rewrite rules.
638
  */
639
- $our_rules = apply_filters( 'tribe_rewrite_handled_rewrite_rules', $our_rules, $all_rules );
640
 
641
  return $our_rules;
642
  }
@@ -649,25 +587,13 @@ class Tribe__Rewrite {
649
  * @return array A map of localized regex matchers in the shape `[ <localized_regex> => <query_var> ]`.
650
  */
651
  protected function get_localized_matchers() {
652
- static $cache_var_name = __METHOD__;
653
-
654
  $bases = (array) $this->get_bases();
655
-
656
  $query_var_map = $this->get_matcher_to_query_var_map();
657
 
658
- $localized_matchers = tribe_get_var( $cache_var_name, [] );
659
-
660
  foreach ( $bases as $base => $localized_matcher ) {
661
- // Use the base too to allow possible conflicts if the slugs are the same for single and archive.
662
- $localized_matcher_key = $localized_matcher . static::$localized_matcher_delimiter . $base;
663
-
664
- if ( isset( $localized_matchers[ $localized_matcher_key ] ) ) {
665
- continue;
666
- }
667
-
668
  if ( isset( $query_var_map[ $base ] ) ) {
669
- $localized_matchers[ $localized_matcher_key ] = [
670
- 'base' => $base,
671
  'query_var' => $query_var_map[ $base ],
672
  'en_slug' => $base,
673
  'localized_slugs' => [ $base ],
@@ -677,7 +603,7 @@ class Tribe__Rewrite {
677
  if ( ! empty( $buffer['slugs'] ) ) {
678
  $slugs = explode( '|', $buffer['slugs'] );
679
 
680
- $localized_matchers[ $localized_matcher_key ]['localized_slugs'] = array_map(
681
  static function ( $localized_slug ) {
682
  return str_replace( '\-', '-', $localized_slug );
683
  },
@@ -685,18 +611,16 @@ class Tribe__Rewrite {
685
  );
686
 
687
  // The English version is the first.
688
- $localized_matchers[ $localized_matcher_key ]['en_slug'] = reset( $slugs );
689
  }
690
  }
691
  }
692
 
693
- tribe_set_var( $cache_var_name, $localized_matchers );
694
-
695
  return $localized_matchers;
696
  }
697
 
698
  /**
699
- * Returns a map relating localized matcher slugs to the corresponding query var.
700
  *
701
  * @since 4.9.11
702
  *
@@ -718,33 +642,13 @@ class Tribe__Rewrite {
718
  * @return array A list of all the query vars handled in the rules.
719
  */
720
  protected function get_rules_query_vars( array $rules ) {
721
- static $cache_var_name = __METHOD__;
722
-
723
- $cached_rules = tribe_get_var( $cache_var_name, [] );
724
- $cache_key = md5( json_encode( $rules ) );
725
-
726
- if ( ! isset( $cached_rules[ $cache_key ] ) ) {
727
- $cached_rules[ $cache_key ] = array_unique(
728
- array_filter(
729
- array_merge(
730
- [],
731
- ...array_values(
732
- array_map(
733
- static function ( $rule_string ) {
734
- wp_parse_str( parse_url( $rule_string, PHP_URL_QUERY ), $vars );
735
- return array_keys( $vars );
736
- },
737
- $rules
738
- )
739
- )
740
- )
741
- )
742
- );
743
 
744
- tribe_set_var( $cache_var_name, $cached_rules );
745
- }
746
-
747
- return $cached_rules[ $cache_key ];
748
  }
749
 
750
  /**
@@ -809,8 +713,6 @@ class Tribe__Rewrite {
809
  * Returns a list of post types supported by the implementation.
810
  *
811
  * @since 4.9.11
812
- *
813
- * @return array<string> An array of post types supported and handled by the rewrite implementation.
814
  */
815
  protected function get_post_types() {
816
  throw new BadMethodCallException( 'Method get_post_types should be implemented by extending classes.' );
@@ -1018,11 +920,6 @@ class Tribe__Rewrite {
1018
  $query_vars = array_merge( $url_query_vars, $query_vars );
1019
  }
1020
 
1021
- // Prune the query vars to drop the empty `page` or `paged` ones.
1022
- $query_vars = array_filter( $query_vars, static function ( $value, $key ) {
1023
- return ! in_array( $key, [ 'paged', 'page' ] ) || (int) $value !== 0;
1024
- }, ARRAY_FILTER_USE_BOTH );
1025
-
1026
  /**
1027
  * Filters the array of parsed query variables after the class logic has been applied to it.
1028
  *
@@ -1078,7 +975,7 @@ class Tribe__Rewrite {
1078
  return home_url();
1079
  }
1080
 
1081
- $clean = $this->get_canonical_url( add_query_arg( $parsed_vars, home_url( '/' ) ), $force );
1082
 
1083
  $this->clean_url_cache[ $url ] = $clean;
1084
 
26
  * @var static
27
  */
28
  public static $instance;
 
 
 
 
 
 
 
 
29
 
30
  /**
31
  * WP_Rewrite Instance
189
  remove_action( 'shutdown', [ $this, 'dump_cache' ] );
190
  }
191
 
 
 
 
 
 
 
 
 
 
 
 
192
  /**
193
  * Get the base slugs for the rewrite rules.
194
  *
407
  $query = (string) parse_url( $url, PHP_URL_QUERY );
408
  wp_parse_str( $query, $query_vars );
409
 
410
+ // Remove the `paged` query var if it's 1.
 
 
411
  if ( isset( $query_vars['paged'] ) && 1 === (int) $query_vars['paged'] ) {
 
412
  unset( $query_vars['paged'] );
413
  }
414
 
416
 
417
  $our_rules = $this->get_handled_rewrite_rules();
418
  $handled_query_vars = $this->get_rules_query_vars( $our_rules );
 
419
 
420
  if (
 
421
  empty( $our_rules )
422
+ || ! in_array( Arr::get( $query_vars, 'post_type', 'post' ), $this->get_post_types(), true )
 
 
 
 
423
  ) {
424
  $wp_canonical = redirect_canonical( $canonical_url, false );
425
  if ( empty( $wp_canonical ) ) {
485
  return '';
486
  }
487
 
 
 
 
 
 
488
  /*
489
  * We use `end` as, by default, the localized version of the slug in the current language will be at the
490
  * end of the array.
491
+ * @todo here we should keep a map, that has to generated at permalink flush time, to map locales/slugs.
492
  */
493
  return end( $localized_matcher['localized_slugs'] );
494
  }, $localized_matchers );
495
 
496
  // Include dynamic matchers now.
497
  $replace = array_merge( $dynamic_matchers, $replace );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  $replaced = str_replace( array_keys( $replace ), $replace, $link_template );
499
 
500
  // Remove trailing chars.
550
  * @return array An array of rewrite rules handled by the implementation in the shape `[ <regex> => <path> ]`.
551
  */
552
  protected function get_handled_rewrite_rules() {
 
 
 
 
553
  // We need to make sure we are have WP_Rewrite setup
554
  if ( ! $this->rewrite ) {
555
  $this->setup();
556
  }
557
 
558
+ // While this is specific to The Events Calendar we're handling a small enough post type base to keep it here.
559
+ $pattern = '/post_type=tribe_(events|venue|organizer)/';
560
+ // Reverse the rules to try and match the most complex first.
561
+ $rules = isset( $this->rewrite->rules ) ? (array) $this->rewrite->rules : [];
562
+ $our_rules = array_filter( $rules,
563
+ static function ( $rule_query_string ) use ( $pattern ) {
564
+ return preg_match( $pattern, $rule_query_string );
565
+ }
566
+ );
 
 
 
 
 
567
 
568
  /**
569
  * Filters the list of rewrite rules handled by our code to add or remove some as required.
573
  * @param array $our_rules An array of rewrite rules handled by our code, in the shape
574
  * `[ <rewrite_rule_regex_pattern> => <query_string> ]`.
575
  * E.g. `[ '(?:events)/(?:list)/?$' => 'index.php?post_type=tribe_events&eventDisplay=list' ]`.
 
 
 
576
  */
577
+ $our_rules = apply_filters( 'tribe_rewrite_handled_rewrite_rules', $our_rules );
578
 
579
  return $our_rules;
580
  }
587
  * @return array A map of localized regex matchers in the shape `[ <localized_regex> => <query_var> ]`.
588
  */
589
  protected function get_localized_matchers() {
 
 
590
  $bases = (array) $this->get_bases();
 
591
  $query_var_map = $this->get_matcher_to_query_var_map();
592
 
593
+ $localized_matchers = [];
 
594
  foreach ( $bases as $base => $localized_matcher ) {
 
 
 
 
 
 
 
595
  if ( isset( $query_var_map[ $base ] ) ) {
596
+ $localized_matchers[ $localized_matcher ] = [
 
597
  'query_var' => $query_var_map[ $base ],
598
  'en_slug' => $base,
599
  'localized_slugs' => [ $base ],
603
  if ( ! empty( $buffer['slugs'] ) ) {
604
  $slugs = explode( '|', $buffer['slugs'] );
605
 
606
+ $localized_matchers[ $localized_matcher ]['localized_slugs'] = array_map(
607
  static function ( $localized_slug ) {
608
  return str_replace( '\-', '-', $localized_slug );
609
  },
611
  );
612
 
613
  // The English version is the first.
614
+ $localized_matchers[ $localized_matcher ]['en_slug'] = reset( $slugs );
615
  }
616
  }
617
  }
618
 
 
 
619
  return $localized_matchers;
620
  }
621
 
622
  /**
623
+ * Returns a map relating localize matcher slugs to the corresponding query var.
624
  *
625
  * @since 4.9.11
626
  *
642
  * @return array A list of all the query vars handled in the rules.
643
  */
644
  protected function get_rules_query_vars( array $rules ) {
645
+ return array_unique( array_filter( array_merge( [], ...
646
+ array_values( array_map( static function ( $rule_string ) {
647
+ wp_parse_str( parse_url( $rule_string, PHP_URL_QUERY ), $vars );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
 
649
+ return array_keys( $vars );
650
+ }, $rules ) ) ) )
651
+ );
 
652
  }
653
 
654
  /**
713
  * Returns a list of post types supported by the implementation.
714
  *
715
  * @since 4.9.11
 
 
716
  */
717
  protected function get_post_types() {
718
  throw new BadMethodCallException( 'Method get_post_types should be implemented by extending classes.' );
920
  $query_vars = array_merge( $url_query_vars, $query_vars );
921
  }
922
 
 
 
 
 
 
923
  /**
924
  * Filters the array of parsed query variables after the class logic has been applied to it.
925
  *
975
  return home_url();
976
  }
977
 
978
+ $clean = $this->get_canonical_url( add_query_arg( $parsed_vars, home_url() ), $force );
979
 
980
  $this->clean_url_cache[ $url ] = $clean;
981
 
common/src/Tribe/Service_Providers/Debug_Bar.php CHANGED
@@ -1,5 +1,4 @@
1
  <?php
2
-
3
  /**
4
  * Hooks and manages the plugins Debug Bar integrations.
5
  *
@@ -35,7 +34,6 @@ class Tribe__Service_Providers__Debug_Bar extends tad_DI52_ServiceProvider {
35
  */
36
  $tribe_panels = apply_filters( 'tribe_debug_bar_panels', array(
37
  new Tribe__Debug_Bar__Panels__Context(),
38
- new Tribe__Debug_Bar__Panels__Json_Ld(),
39
  ) );
40
 
41
  if ( count( $tribe_panels ) > 0 ) {
1
  <?php
 
2
  /**
3
  * Hooks and manages the plugins Debug Bar integrations.
4
  *
34
  */
35
  $tribe_panels = apply_filters( 'tribe_debug_bar_panels', array(
36
  new Tribe__Debug_Bar__Panels__Context(),
 
37
  ) );
38
 
39
  if ( count( $tribe_panels ) > 0 ) {
common/src/Tribe/Service_Providers/Shortcodes.php DELETED
@@ -1,80 +0,0 @@
1
- <?php
2
- namespace Tribe\Service_Providers;
3
-
4
- use Tribe\Shortcode\Manager;
5
-
6
- /**
7
- * Class Shortcode
8
- *
9
- * @since 4.12.0
10
- *
11
- * @package Tribe\Service_Providers
12
- */
13
- class Shortcodes extends \tad_DI52_ServiceProvider {
14
-
15
- /**
16
- * Binds and sets up implementations.
17
- *
18
- * @since 4.12.0
19
- */
20
- public function register() {
21
- if ( ! static::is_active() ) {
22
- return;
23
- }
24
-
25
- $this->container->singleton( Manager::class, Manager::class );
26
-
27
- $this->register_hooks();
28
- $this->register_assets();
29
-
30
- $this->container->singleton( static::class, $this );
31
- }
32
-
33
- /**
34
- * Static method wrapper around a filter to allow full deactivation of this provider
35
- *
36
- * @since 4.12.0
37
- *
38
- * @return boolean If this service provider is active.
39
- */
40
- public static function is_active() {
41
- /**
42
- * Allows filtering to deactivate all shortcodes loading.
43
- *
44
- * @since 4.12.0
45
- *
46
- * @param boolean $is_active If shortcodes should be loaded or not.
47
- */
48
- return apply_filters( 'tribe_shortcodes_is_active', true );
49
- }
50
-
51
- /**
52
- * Register all the assets associated with this service provider.
53
- *
54
- * @since 4.12.0
55
- */
56
- protected function register_assets() {
57
-
58
- }
59
-
60
- /**
61
- * Registers the provider handling all the 1st level filters and actions for this service provider.
62
- *
63
- * @since 4.12.0
64
- */
65
- protected function register_hooks() {
66
- add_action( 'init', [ $this, 'action_add_shortcodes' ], 20 );
67
- }
68
-
69
- /**
70
- * Adds the new shortcodes, this normally will trigger on `init@P20` due to how we the
71
- * v1 is added on `init@P10` and we remove them on `init@P15`.
72
- *
73
- * It's important to leave gaps on priority for better injection.
74
- *
75
- * @since 4.12.0
76
- */
77
- public function action_add_shortcodes() {
78
- $this->container->make( Manager::class )->add_shortcodes();
79
- }
80
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Settings_Manager.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
- class Tribe__Settings_Manager {
3
- const OPTION_CACHE_VAR_NAME = 'Tribe__Settings_Manager:option_cache';
4
 
 
5
  protected static $network_options;
6
  public static $tribe_events_mu_defaults;
7
 
@@ -30,28 +29,6 @@ class Tribe__Settings_Manager {
30
  add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
31
  add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
32
  add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
33
- add_action( 'updated_option', [ $this, 'update_options_cache' ], 10, 3 );
34
- }
35
-
36
- /**
37
- * For performance reasons our options are saved in memory, but we need to make sure we update it when WordPress
38
- * updates the variable directly.
39
- *
40
- * @since 4.11.0
41
- *
42
- * @param string $option Name of the updated option.
43
- * @param mixed $old_value The old option value.
44
- * @param mixed $value The new option value.
45
- *
46
- * @return void
47
- */
48
- public function update_options_cache( $option, $old_value, $value ) {
49
- // Bail when no our option.
50
- if ( Tribe__Main::OPTIONNAME !== $option ) {
51
- return;
52
- }
53
-
54
- tribe_set_var( self::OPTION_CACHE_VAR_NAME, $value );
55
  }
56
 
57
  /**
@@ -89,14 +66,11 @@ class Tribe__Settings_Manager {
89
  * @return array of options
90
  */
91
  public static function get_options() {
92
- $options = tribe_get_var( self::OPTION_CACHE_VAR_NAME, [] );
93
-
94
- if ( empty( $options ) ) {
95
- $options = (array) get_option( Tribe__Main::OPTIONNAME, [] );
96
-
97
- tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options );
98
- }
99
-
100
  return $options;
101
  }
102
 
@@ -112,7 +86,7 @@ class Tribe__Settings_Manager {
112
  if ( ! $option_name ) {
113
  return null;
114
  }
115
- $options = static::get_options();
116
 
117
  $option = $default;
118
  if ( array_key_exists( $option_name, $options ) ) {
@@ -136,16 +110,10 @@ class Tribe__Settings_Manager {
136
  if ( ! is_array( $options ) ) {
137
  return false;
138
  }
139
- if ( true === $apply_filters ) {
140
  $options = apply_filters( 'tribe-events-save-options', $options );
141
  }
142
- $updated = update_option( Tribe__Main::OPTIONNAME, $options );
143
-
144
- if ( $updated ) {
145
- tribe_set_var( self::OPTION_CACHE_VAR_NAME, $options );
146
- }
147
-
148
- return $updated;
149
  }
150
 
151
  /**
@@ -157,10 +125,10 @@ class Tribe__Settings_Manager {
157
  * @return bool
158
  */
159
  public static function set_option( $name, $value ) {
 
 
160
  $options = self::get_options();
161
- $options[ $name ] = $value;
162
-
163
- return self::set_options( $options );
164
  }
165
 
166
  /**
@@ -171,7 +139,7 @@ class Tribe__Settings_Manager {
171
  */
172
  public static function get_network_options() {
173
  if ( ! isset( self::$network_options ) ) {
174
- $options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, array() );
175
  self::$network_options = apply_filters( 'tribe_get_network_options', $options );
176
  }
177
 
1
  <?php
 
 
2
 
3
+ class Tribe__Settings_Manager {
4
  protected static $network_options;
5
  public static $tribe_events_mu_defaults;
6
 
29
  add_action( 'tribe_settings_do_tabs', array( $this, 'do_setting_tabs' ) );
30
  add_action( 'tribe_settings_do_tabs', array( $this, 'do_network_settings_tab' ), 400 );
31
  add_action( 'tribe_settings_validate_tab_network', array( $this, 'save_all_tabs_hidden' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
  /**
66
  * @return array of options
67
  */
68
  public static function get_options() {
69
+ $options = (array) get_option( Tribe__Main::OPTIONNAME, array() );
70
+ if ( has_filter( 'tribe_get_options' ) ) {
71
+ _deprecated_function( 'tribe_get_options', '3.10', 'option_' . Tribe__Main::OPTIONNAME );
72
+ $options = apply_filters( 'tribe_get_options', $options );
73
+ }
 
 
 
74
  return $options;
75
  }
76
 
86
  if ( ! $option_name ) {
87
  return null;
88
  }
89
+ $options = self::get_options();
90
 
91
  $option = $default;
92
  if ( array_key_exists( $option_name, $options ) ) {
110
  if ( ! is_array( $options ) ) {
111
  return false;
112
  }
113
+ if ( $apply_filters == true ) {
114
  $options = apply_filters( 'tribe-events-save-options', $options );
115
  }
116
+ return update_option( Tribe__Main::OPTIONNAME, $options );
 
 
 
 
 
 
117
  }
118
 
119
  /**
125
  * @return bool
126
  */
127
  public static function set_option( $name, $value ) {
128
+ $newOption = array();
129
+ $newOption[ $name ] = $value;
130
  $options = self::get_options();
131
+ return self::set_options( wp_parse_args( $newOption, $options ) );
 
 
132
  }
133
 
134
  /**
139
  */
140
  public static function get_network_options() {
141
  if ( ! isset( self::$network_options ) ) {
142
+ $options = get_site_option( Tribe__Main::OPTIONNAMENETWORK, array() );
143
  self::$network_options = apply_filters( 'tribe_get_network_options', $options );
144
  }
145
 
common/src/Tribe/Shortcode/Manager.php DELETED
@@ -1,107 +0,0 @@
1
- <?php
2
- /**
3
- * Shortcodes manager for Tribe plugins.
4
- *
5
- * @package Tribe\Shortcode
6
- * @since 4.12.0
7
- */
8
- namespace Tribe\Shortcode;
9
-
10
- /**
11
- * Class Shortcode Manager.
12
- *
13
- * @since 4.12.0
14
- *
15
- * @package Tribe\Shortcode
16
- */
17
- class Manager {
18
- /**
19
- * Get the list of shortcodes available for handling.
20
- *
21
- * @since 4.12.0
22
- *
23
- * @return array An associative array of shortcodes in the shape `[ <slug> => <class> ]`
24
- */
25
- public function get_registered_shortcodes() {
26
- $shortcodes = [];
27
-
28
- /**
29
- * Allow the registering of shortcodes into the our Tribe plugins.
30
- *
31
- * @since 4.12.0
32
- *
33
- * @var array An associative array of shortcodes in the shape `[ <slug> => <class> ]`.
34
- */
35
- $shortcodes = apply_filters( 'tribe_shortcodes', $shortcodes );
36
-
37
- return $shortcodes;
38
- }
39
-
40
- /**
41
- * Verifies if a given shortcode slug is registered for handling.
42
- *
43
- * @since 4.12.0
44
- *
45
- * @param string $slug Which slug we are checking if is registered.
46
- *
47
- * @return bool Whether a shortcode is registered or not.
48
- */
49
- public function is_shortcode_registered( $slug ) {
50
- $registered_shortcodes = $this->get_registered_shortcodes();
51
- return isset( $registered_shortcodes[ $slug ] );
52
- }
53
-
54
- /**
55
- * Verifies if a given shortcode class name is registered for handling.
56
- *
57
- * @since 4.12.0
58
- *
59
- * @param string $class_name Which class name we are checking if is registered.
60
- *
61
- * @return bool Whether a shortcode is registered, by class.
62
- */
63
- public function is_shortcode_registered_by_class( $class_name ) {
64
- $registered_shortcodes = $this->get_registered_shortcodes();
65
- return in_array( $class_name, $registered_shortcodes );
66
- }
67
-
68
- /**
69
- * Add new shortcodes handler to catch the correct strings.
70
- *
71
- * @since 4.12.0
72
- */
73
- public function add_shortcodes() {
74
- $registered_shortcodes = $this->get_registered_shortcodes();
75
-
76
- // Add to WordPress all of the registered Shortcodes
77
- foreach ( $registered_shortcodes as $shortcode => $class_name ) {
78
- add_shortcode( $shortcode, [ $this, 'render_shortcode' ] );
79
- }
80
- }
81
-
82
- /**
83
- * Makes sure we are correctly handling the Shortcodes we manage.
84
- *
85
- * @since 4.12.0
86
- *
87
- * @param array $arguments Set of arguments passed to the Shortcode at hand.
88
- * @param string $content Contents passed to the shortcode, inside of the open and close brackets.
89
- * @param string $shortcode Which shortcode tag are we handling here.
90
- *
91
- * @return string The rendered shortcode HTML.
92
- */
93
- public function render_shortcode( $arguments, $content, $shortcode ) {
94
- $registered_shortcodes = $this->get_registered_shortcodes();
95
-
96
- // Bail when we try to handle an unregistered shortcode (shouldn't happen)
97
- if ( ! $this->is_shortcode_registered( $shortcode ) ) {
98
- return false;
99
- }
100
-
101
- /** @var Shortcode_Interface $instance */
102
- $instance = new $registered_shortcodes[ $shortcode ];
103
- $instance->setup( $arguments, $content );
104
-
105
- return $instance->get_html();
106
- }
107
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Shortcode/Shortcode_Abstract.php DELETED
@@ -1,247 +0,0 @@
1
- <?php
2
-
3
- namespace Tribe\Shortcode;
4
-
5
- use Tribe__Utils__Array as Arr;
6
-
7
- /**
8
- * The abstract all shortcodes should implement.
9
- *
10
- * @package Tribe\Shortcode
11
- *
12
- * @since 4.12.0
13
- */
14
- abstract class Shortcode_Abstract implements Shortcode_Interface {
15
- /**
16
- * Slug of the current shortcode.
17
- *
18
- * @since 4.12.0
19
- *
20
- * @var string
21
- */
22
- protected $slug;
23
-
24
- /**
25
- * Default arguments to be merged into final arguments of the shortcode.
26
- *
27
- * @since 4.12.0
28
- *
29
- * @var array
30
- */
31
- protected $default_arguments = [];
32
-
33
- /**
34
- * Array map allowing aliased shortcode arguments.
35
- *
36
- * The array keys are aliases of the array values (i.e. the "real" shortcode attributes to parse).
37
- * Example array: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
38
- * Example shortcode usage: [some_tag alias=17 to='Fred'] will be parsed as [some_tag canonical=17 to='Fred']
39
- *
40
- * @since 4.12.2
41
- *
42
- * @var array<string,string>
43
- */
44
- protected $aliased_arguments = [];
45
-
46
- /**
47
- * Array of callbacks for arguments validation.
48
- *
49
- * @since 4.12.0
50
- *
51
- * @var array
52
- */
53
- protected $validate_arguments_map = [];
54
-
55
- /**
56
- * Arguments of the current shortcode.
57
- *
58
- * @since 4.12.0
59
- *
60
- * @var array
61
- */
62
- protected $arguments;
63
-
64
- /**
65
- * Content of the current shortcode.
66
- *
67
- * @since 4.12.0
68
- *
69
- * @var string
70
- */
71
- protected $content;
72
-
73
- /**
74
- * {@inheritDoc}
75
- */
76
- public function setup( $arguments, $content ) {
77
- $this->arguments = $this->parse_arguments( (array) $arguments );
78
- $this->content = $content;
79
- }
80
-
81
- /**
82
- * {@inheritDoc}
83
- */
84
- public function set_aliased_arguments( array $alias_map ) {
85
- $this->aliased_arguments = Arr::filter_to_flat_scalar_associative_array( (array) $alias_map );
86
- }
87
-
88
- /**
89
- * {@inheritDoc}
90
- */
91
- public function get_aliased_arguments() {
92
- return $this->aliased_arguments;
93
- }
94
-
95
- /**
96
- * {@inheritDoc}
97
- */
98
- public function parse_arguments( array $arguments ) {
99
- $arguments = Arr::parse_associative_array_alias( (array) $arguments, (array) $this->get_aliased_arguments() );
100
- $arguments = shortcode_atts( $this->get_default_arguments(), $arguments, $this->slug );
101
-
102
- return $this->validate_arguments( $arguments );
103
- }
104
-
105
- /**
106
- * {@inheritDoc}
107
- */
108
- public function validate_arguments( array $arguments ) {
109
- $validate_arguments_map = $this->get_validated_arguments_map();
110
- foreach ( $validate_arguments_map as $key => $callback ) {
111
- $arguments[ $key ] = $callback( isset( $arguments[ $key ] ) ? $arguments[ $key ] : null );
112
- }
113
-
114
- return $arguments;
115
- }
116
-
117
- /**
118
- * {@inheritDoc}
119
- */
120
- public function get_registration_slug() {
121
- return $this->slug;
122
- }
123
-
124
- /**
125
- * {@inheritDoc}
126
- */
127
- public function get_validated_arguments_map() {
128
- /**
129
- * Applies a filter to instance arguments validation callbacks.
130
- *
131
- * @since 4.12.0
132
- *
133
- * @param array $validate_arguments_map Current set of callbacks for arguments.
134
- * @param static $instance Which instance of shortcode we are dealing with.
135
- */
136
- $validate_arguments_map = apply_filters( 'tribe_shortcode_validate_arguments_map', $this->validate_arguments_map, $this );
137
-
138
- $registration_slug = $this->get_registration_slug();
139
-
140
- /**
141
- * Applies a filter to instance arguments validation callbacks based on the registration slug of the shortcode.
142
- *
143
- * @since 4.12.0
144
- *
145
- * @param array $validate_arguments_map Current set of callbacks for arguments.
146
- * @param static $instance Which instance of shortcode we are dealing with.
147
- */
148
- $validate_arguments_map = apply_filters( "tribe__shortcode_{$registration_slug}_validate_arguments_map", $validate_arguments_map, $this );
149
-
150
- return $validate_arguments_map;
151
- }
152
-
153
- /**
154
- * {@inheritDoc}
155
- */
156
- public function get_arguments() {
157
- /**
158
- * Applies a filter to instance arguments.
159
- *
160
- * @since 4.12.0
161
- *
162
- * @param array $arguments Current set of arguments.
163
- * @param static $instance Which instance of shortcode we are dealing with.
164
- */
165
- $arguments = apply_filters( 'tribe_shortcode_arguments', $this->arguments, $this );
166
-
167
- $registration_slug = $this->get_registration_slug();
168
-
169
- /**
170
- * Applies a filter to instance arguments based on the registration slug of the shortcode.
171
- *
172
- * @since 4.12.0
173
- *
174
- * @param array $arguments Current set of arguments.
175
- * @param static $instance Which instance of shortcode we are dealing with.
176
- */
177
- $arguments = apply_filters( "tribe_shortcode_{$registration_slug}_arguments", $arguments, $this );
178
-
179
- return $arguments;
180
- }
181
-
182
- /**
183
- * {@inheritDoc}
184
- */
185
- public function get_argument( $index, $default = null ) {
186
- $arguments = $this->get_arguments();
187
- $argument = Arr::get( $arguments, $index, $default );
188
-
189
- /**
190
- * Applies a filter to a specific shortcode argument, catch all for all shortcodes.
191
- *
192
- * @since 4.12.0
193
- *
194
- * @param mixed $argument The argument.
195
- * @param array $index Which index we indent to fetch from the arguments.
196
- * @param array $default Default value if it doesn't exist.
197
- * @param static $instance Which instance of shortcode we are dealing with.
198
- */
199
- $argument = apply_filters( 'tribe_shortcode_argument', $argument, $index, $default, $this );
200
-
201
- $registration_slug = $this->get_registration_slug();
202
-
203
- /**
204
- * Applies a filter to a specific shortcode argument, to a particular registration slug.
205
- *
206
- * @since 4.12.0
207
- *
208
- * @param mixed $argument The argument value.
209
- * @param array $index Which index we indent to fetch from the arguments.
210
- * @param array $default Default value if it doesn't exist.
211
- * @param static $instance Which instance of shortcode we are dealing with.
212
- */
213
- $argument = apply_filters( "tribe_shortcode_{$registration_slug}_argument", $argument, $index, $default, $this );
214
-
215
- return $argument;
216
- }
217
-
218
- /**
219
- * {@inheritDoc}
220
- */
221
- public function get_default_arguments() {
222
- /**
223
- * Applies a filter to instance default arguments.
224
- *
225
- * @since 4.12.0
226
- *
227
- * @param array $default_arguments Current set of default arguments.
228
- * @param static $instance Which instance of shortcode we are dealing with.
229
- */
230
- $default_arguments = apply_filters( 'tribe_shortcode_default_arguments', $this->default_arguments, $this );
231
-
232
- $registration_slug = $this->get_registration_slug();
233
-
234
- /**
235
- * Applies a filter to instance default arguments based on the registration slug of the shortcode.
236
- *
237
- * @since 4.12.0
238
- *
239
- * @param array $default_arguments Current set of default arguments.
240
- * @param static $instance Which instance of shortcode we are dealing with.
241
- */
242
- $default_arguments = apply_filters( "tribe_shortcode_{$registration_slug}_default_arguments", $default_arguments, $this );
243
-
244
- return $default_arguments;
245
- }
246
-
247
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Shortcode/Shortcode_Interface.php DELETED
@@ -1,125 +0,0 @@
1
- <?php
2
-
3
- namespace Tribe\Shortcode;
4
-
5
- /**
6
- * Interface Shortcode_Interface
7
- *
8
- * @package Tribe\Shortcode
9
- *
10
- * @since 4.12.0
11
- */
12
- interface Shortcode_Interface {
13
-
14
- /**
15
- * Returns the shortcode slug that allows the shortcode to be built via the shortcode class by slug.
16
- *
17
- * @since 4.12.0
18
- *
19
- * @return string The shortcode slug.
20
- */
21
- public function get_registration_slug();
22
-
23
- /**
24
- * Configures the base variables for an instance of shortcode.
25
- *
26
- * @since 4.12.0
27
- *
28
- * @param array|string $arguments Set of arguments passed to the Shortcode at hand. Empty string if no args.
29
- * @param string $content Contents passed to the shortcode, inside of the open and close brackets.
30
- */
31
- public function setup( $arguments, $content );
32
-
33
- /**
34
- * Sets the aliased arguments array.
35
- *
36
- * @see Tribe__Utils__Array::parse_associative_array_alias() The expected format.
37
- *
38
- * @since 4.12.2
39
- *
40
- * @param array $alias_map An associative array of aliases: key as alias, value as mapped canonical.
41
- * Example: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
42
- */
43
- public function set_aliased_arguments( array $alias_map );
44
-
45
- /**
46
- * Gets the aliased arguments array.
47
- *
48
- * @since 4.12.2
49
- *
50
- * @return array<string,string> The associative array map of aliases and their canonical arguments.
51
- */
52
- public function get_aliased_arguments();
53
-
54
- /**
55
- * Returns the arguments for the shortcode parsed correctly with defaults applied.
56
- *
57
- * @since 4.12.0
58
- *
59
- * @param array $arguments Set of arguments passed to the Shortcode at hand.
60
- *
61
- * @return array<string,mixed> The parsed shortcode arguments map.
62
- */
63
- public function parse_arguments( array $arguments );
64
-
65
- /**
66
- * Returns the array of arguments for this shortcode after applying the validation callbacks.
67
- *
68
- * @since 4.12.0
69
- *
70
- * @param array $arguments Set of arguments passed to the Shortcode at hand.
71
- *
72
- * @return array<string,mixed> The validated shortcode arguments map.
73
- */
74
- public function validate_arguments( array $arguments );
75
-
76
- /**
77
- * Returns the array of callbacks for this shortcode's arguments.
78
- *
79
- * @since 4.12.0
80
- *
81
- * @return array<string,mixed> A map of the shortcode arguments that have survived validation.
82
- */
83
- public function get_validated_arguments_map();
84
-
85
- /**
86
- * Returns a shortcode default arguments.
87
- *
88
- * @since 4.12.0
89
- *
90
- * @return array<string,mixed> The shortcode default arguments map.
91
- */
92
- public function get_default_arguments();
93
-
94
- /**
95
- * Returns a shortcode arguments after been parsed.
96
- *
97
- * @since 4.12.0
98
- *
99
- * @return array<string,mixed> The shortcode arguments, as set by the user in the shortcode string.
100
- */
101
- public function get_arguments();
102
-
103
- /**
104
- * Returns a shortcode argument after it has been parsed.
105
- *
106
- * @since 4.12.0
107
- *
108
- * @param array|string $index Which index we indent to fetch from the arguments.
109
- * @param array $default Default value if it doesn't exist.
110
- *
111
- * @uses Tribe__Utils__Array::get For index fetching and Default.
112
- *
113
- * @return mixed Value for the Index passed as the first argument.
114
- */
115
- public function get_argument( $index, $default = null );
116
-
117
- /**
118
- * Returns a shortcode's HTML.
119
- *
120
- * @since 4.12.0
121
- *
122
- * @return string The shortcode rendered HTML code.
123
- */
124
- public function get_html();
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Support.php CHANGED
@@ -164,17 +164,6 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
164
  $php_info[ $php_var ] = $val;
165
  }
166
 
167
- $homepage = get_option( 'show_on_front' );
168
- $homepage_page_id = get_option( 'page_on_front' );
169
-
170
- if ( 'page' === $homepage ) {
171
- if ( -10 === (int) $homepage_page_id ) {
172
- $homepage_page_id .= ' (Main Events Page)';
173
- } else {
174
- $homepage_page_id .= ' (' . esc_html( get_the_title( $homepage_page_id ) ) . ')';
175
- }
176
- }
177
-
178
  $site_url = get_site_url();
179
  $systeminfo = array(
180
  'Home URL' => get_home_url(),
@@ -186,8 +175,6 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
186
  'Install keys' => $keys,
187
  'WordPress version' => get_bloginfo( 'version' ),
188
  'Permalink Structure' => $site_url . get_option( 'permalink_structure' ),
189
- 'Your homepage displays' => $homepage,
190
- 'Homepage page ID' => $homepage_page_id,
191
  'PHP version' => phpversion(),
192
  'PHP' => $php_info,
193
  'Server' => $server[0],
@@ -287,7 +274,7 @@ if ( ! class_exists( 'Tribe__Support' ) ) {
287
  }
288
 
289
  /**
290
- * Logs the occurrence of rewrite rule purging
291
  */
292
  public function log_rewrite_rule_purge() {
293
  $this->rewrite_rules_purged = true;
164
  $php_info[ $php_var ] = $val;
165
  }
166
 
 
 
 
 
 
 
 
 
 
 
 
167
  $site_url = get_site_url();
168
  $systeminfo = array(
169
  'Home URL' => get_home_url(),
175
  'Install keys' => $keys,
176
  'WordPress version' => get_bloginfo( 'version' ),
177
  'Permalink Structure' => $site_url . get_option( 'permalink_structure' ),
 
 
178
  'PHP version' => phpversion(),
179
  'PHP' => $php_info,
180
  'Server' => $server[0],
274
  }
275
 
276
  /**
277
+ * Logs the occurence of rewrite rule purging
278
  */
279
  public function log_rewrite_rule_purge() {
280
  $this->rewrite_rules_purged = true;
common/src/Tribe/Template.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- use Tribe\Utils\Strings;
4
-
5
  class Tribe__Template {
6
  /**
7
  * The folders into which we will look for the template.
@@ -49,7 +47,7 @@ class Tribe__Template {
49
  protected $template_origin_base_folder = [ 'src', 'views' ];
50
 
51
  /**
52
- * Allow changing if class will extract data from the local context
53
  *
54
  * @since 4.6.2
55
  *
@@ -57,15 +55,6 @@ class Tribe__Template {
57
  */
58
  protected $template_context_extract = false;
59
 
60
- /**
61
- * Current template hook name.
62
- *
63
- * @since 4.12.1
64
- *
65
- * @var string|null
66
- */
67
- protected $template_current_hook_name;
68
-
69
  /**
70
  * Base template for where to look for template
71
  *
@@ -84,15 +73,6 @@ class Tribe__Template {
84
  */
85
  protected $template_folder_lookup = false;
86
 
87
- /**
88
- * Create a class variable for the include path, to avoid conflicting with extract.
89
- *
90
- * @since 4.11.0
91
- *
92
- * @var string
93
- */
94
- protected $template_current_file_path;
95
-
96
  /**
97
  * Configures the class origin plugin path
98
  *
@@ -110,33 +90,19 @@ class Tribe__Template {
110
  if ( is_string( $origin ) ) {
111
  // Origin needs to be a class with a `instance` method
112
  if ( class_exists( $origin ) && method_exists( $origin, 'instance' ) ) {
113
- $origin = call_user_func( [ $origin, 'instance' ] );
114
  }
115
  }
116
 
117
- if (
118
- empty( $origin->plugin_path )
119
- && empty( $origin->pluginPath )
120
- && ! is_dir( $origin )
121
- ) {
122
  throw new InvalidArgumentException( 'Invalid Origin Class for Template Instance' );
123
  }
124
 
125
- if ( is_string( $origin ) ) {
126
- $this->template_base_path = array_filter(
127
- (array) explode(
128
- '/',
129
- untrailingslashit( $origin )
130
- )
131
- );
132
- } else {
133
  $this->origin = $origin;
134
-
135
- $this->template_base_path = untrailingslashit(
136
- ! empty( $this->origin->plugin_path )
137
- ? $this->origin->plugin_path
138
- : $this->origin->pluginPath
139
- );
140
  }
141
 
142
  return $this;
@@ -168,23 +134,12 @@ class Tribe__Template {
168
  return $this;
169
  }
170
 
171
- /**
172
- * Returns the array for which folder this template instance is looking into.
173
- *
174
- * @since 4.11.0
175
- *
176
- * @return array Current folder we are looking for templates.
177
- */
178
- public function get_template_folder() {
179
- return $this->folder;
180
- }
181
-
182
  /**
183
  * Configures the class with the base folder in relation to the Origin
184
  *
185
  * @since 4.7.20
186
  *
187
- * @param mixed $value Should we look for template files in the list of folders.
188
  *
189
  * @return self
190
  */
@@ -194,17 +149,6 @@ class Tribe__Template {
194
  return $this;
195
  }
196
 
197
- /**
198
- * Gets in this instance of the template engine whether we are looking public folders like themes.
199
- *
200
- * @since 4.12.1
201
- *
202
- * @return bool Whether we are looking into theme folders.
203
- */
204
- public function get_template_folder_lookup() {
205
- return $this->template_folder_lookup;
206
- }
207
-
208
  /**
209
  * Configures the class global context
210
  *
@@ -237,32 +181,6 @@ class Tribe__Template {
237
  return $this;
238
  }
239
 
240
- /**
241
- * Set the current hook name for the template include.
242
- *
243
- * @since 4.12.1
244
- *
245
- * @param string $value Which value will be saved as the current hookname.
246
- *
247
- * @return self Allow daisy-chaining.
248
- */
249
- public function set_template_current_hook_name( $value ) {
250
- $this->template_current_hook_name = (string) $value;
251
-
252
- return $this;
253
- }
254
-
255
- /**
256
- * Gets the hook name for the current template setup.
257
- *
258
- * @since 4.12.1
259
- *
260
- * @return string Hook name currently set on the class.
261
- */
262
- public function get_template_current_hook_name() {
263
- return $this->template_current_hook_name;
264
- }
265
-
266
  /**
267
  * Sets a Index inside of the global or local context
268
  * Final to prevent extending the class when the `get` already exists on the child class
@@ -345,14 +263,14 @@ class Tribe__Template {
345
  *
346
  * @return array
347
  */
348
- public function merge_context( $context = [], $file = null, $name = null ) {
349
  // Allow for simple null usage as well as array() for nothing
350
  if ( is_null( $context ) ) {
351
- $context = [];
352
  }
353
 
354
- // Applies new local context on top of Global + Previous local.
355
- $context = wp_parse_args( (array) $context, $this->get_values() );
356
 
357
  /**
358
  * Allows filtering the Local context
@@ -399,20 +317,15 @@ class Tribe__Template {
399
  * in the theme's directory.
400
  *
401
  * @since 4.7.20
402
- * @since 4.11.0 Added param $plugin_namespace.
403
  *
404
- * @param string $plugin_namespace Overwrite the origin namespace with a given one.
405
- *
406
- * @return array Namespace where we to look for templates.
407
  */
408
- protected function get_template_public_namespace( $plugin_namespace ) {
409
- $namespace = [
410
  'tribe',
411
- ];
412
 
413
- if ( ! empty( $plugin_namespace ) ) {
414
- $namespace[] = $plugin_namespace;
415
- } elseif ( ! empty( $this->origin->template_namespace ) ) {
416
  $namespace[] = $this->origin->template_namespace;
417
  }
418
 
@@ -447,20 +360,18 @@ class Tribe__Template {
447
  }
448
 
449
  /**
450
- * Fetches the path for locating files given a base folder normally theme related.
451
  *
452
  * @since 4.7.20
453
- * @since 4.11.0 Added the param $namespace.
454
  *
455
- * @param mixed $base Base path to look into.
456
- * @param string $namespace Adds the plugin namespace to the path returned.
457
  *
458
- * @return string The public path for a given base.˙˙
459
  */
460
- protected function get_template_public_path( $base, $namespace ) {
461
 
462
  // Craft the plugin Path
463
- $path = array_merge( (array) $base, (array) $this->get_template_public_namespace( $namespace ) );
464
 
465
  // Pick up if the folder needs to be aded to the public template path.
466
  $folder = array_diff( $this->folder, $this->get_template_origin_base_folder() );
@@ -491,13 +402,27 @@ class Tribe__Template {
491
  * @return array
492
  */
493
  protected function get_template_path_list() {
494
- $folders = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
 
496
- $folders['plugin'] = [
497
- 'id' => 'plugin',
498
- 'priority' => 20,
499
- 'path' => $this->get_template_plugin_path(),
500
- ];
501
 
502
  /**
503
  * Allows filtering of the list of folders in which we will look for the
@@ -508,46 +433,7 @@ class Tribe__Template {
508
  * @param array $folders Complete path to include the base public folder
509
  * @param self $template Current instance of the Tribe__Template
510
  */
511
- $folders = (array) apply_filters( 'tribe_template_path_list', $folders, $this );
512
-
513
- uasort( $folders, 'tribe_sort_by_priority' );
514
-
515
- return $folders;
516
- }
517
-
518
- /**
519
- * Get the list of theme related folders we will look up for the template.
520
- *
521
- * @since 4.11.0
522
- *
523
- * @param string $namespace Which plugin namespace we are looking for.
524
- *
525
- * @return array
526
- */
527
- protected function get_template_theme_path_list( $namespace ) {
528
- $folders = [];
529
-
530
- $folders['child-theme'] = [
531
- 'id' => 'child-theme',
532
- 'priority' => 10,
533
- 'path' => $this->get_template_public_path( STYLESHEETPATH, $namespace ),
534
- ];
535
- $folders['parent-theme'] = [
536
- 'id' => 'parent-theme',
537
- 'priority' => 15,
538
- 'path' => $this->get_template_public_path( TEMPLATEPATH, $namespace ),
539
- ];
540
-
541
- /**
542
- * Allows filtering of the list of theme folders in which we will look for the template.
543
- *
544
- * @since 4.11.0
545
- *
546
- * @param array $folders Complete path to include the base public folder.
547
- * @param string $namespace Loads the files from a specified folder from the themes.
548
- * @param self $template Current instance of the Tribe__Template.
549
- */
550
- $folders = (array) apply_filters( 'tribe_template_theme_path_list', $folders, $namespace, $this );
551
 
552
  uasort( $folders, 'tribe_sort_by_priority' );
553
 
@@ -570,12 +456,11 @@ class Tribe__Template {
570
  $name = (array) explode( '/', $name );
571
  }
572
 
573
- $folders = $this->get_template_path_list();
574
- $found_file = false;
575
- $namespace = false;
576
 
577
  foreach ( $folders as $folder ) {
578
- if ( empty( $folder['path'] ) ) {
 
579
  continue;
580
  }
581
 
@@ -587,272 +472,64 @@ class Tribe__Template {
587
 
588
  // Skip non-existent files
589
  if ( file_exists( $file ) ) {
590
- $found_file = $file;
591
- $namespace = ! empty( $folder['namespace'] ) ? $folder['namespace'] : false;
592
- break;
593
- }
594
- }
595
-
596
- if ( $this->get_template_folder_lookup() ) {
597
- $theme_folders = $this->get_template_theme_path_list( $namespace );
598
-
599
- foreach ( $theme_folders as $folder ) {
600
- if ( empty( $folder['path'] ) ) {
601
- continue;
602
- }
603
-
604
- // Build the File Path
605
- $file = implode( DIRECTORY_SEPARATOR, array_merge( (array) $folder['path'], $name ) );
606
-
607
- // Append the Extension to the file path
608
- $file .= '.php';
609
-
610
- // Skip non-existent files
611
- if ( file_exists( $file ) ) {
612
- $found_file = $file;
613
- break;
614
- }
615
  }
616
  }
617
 
618
- if ( $found_file ) {
619
- /**
620
- * A more Specific Filter that will include the template name
621
- *
622
- * @since 4.6.2
623
- * @since 4.7.20 The $name param no longer contains the extension
624
- *
625
- * @param string $file Complete path to include the PHP File
626
- * @param array $name Template name
627
- * @param self $template Current instance of the Tribe__Template
628
- */
629
- return apply_filters( 'tribe_template_file', $found_file, $name, $this );
630
- }
631
-
632
  // Couldn't find a template on the Stack
633
  return false;
634
  }
635
 
636
- /**
637
- * Runs the entry point hooks and filters.
638
- *
639
- * @param string $entry_point_name The name of the entry point.
640
- * @param boolean $echo If we should also print the entry point content.
641
- *
642
- * @return null|string `null` if an entry point is disabled or the entry point HTML.
643
- */
644
- public function do_entry_point( $entry_point_name, $echo = true ) {
645
- $hook_name = $this->get_template_current_hook_name();
646
-
647
- /**
648
- * Filter if the entry points are enabled.
649
- *
650
- * @since 4.12.1
651
- *
652
- * @param boolean $is_enabled Is entry_point enabled.
653
- * @param string $hook_name For which template include this entry point belongs.
654
- * @param string $entry_point_name Which entry point specifically we are triggering.
655
- * @param self $template Current instance of the template class doing this entry point.
656
- */
657
- $is_entry_point_enabled = apply_filters( 'tribe_template_entry_point_is_enabled', true, $hook_name, $entry_point_name, $this );
658
-
659
- if ( ! $is_entry_point_enabled ) {
660
- return null;
661
- }
662
-
663
- ob_start();
664
-
665
- if ( has_action( "tribe_template_entry_point:$hook_name" ) ) {
666
- /**
667
- * Generic entry point action for the current template.
668
- *
669
- * @since 4.12.1
670
- *
671
- * @param string $hook_name For which template include this entry point belongs.
672
- * @param string $entry_point_name Which entry point specifically we are triggering.
673
- * @param self $template Current instance of the template class doing this entry point.
674
- */
675
- do_action( "tribe_template_entry_point:$hook_name", $hook_name, $entry_point_name, $this );
676
- }
677
-
678
- if ( has_action( "tribe_template_entry_point:$hook_name:$entry_point_name" ) ) {
679
- /**
680
- * Specific named entry point action called.
681
- *
682
- * @since 4.12.1
683
- *
684
- * @param string $hook_name For which template include this entry point belongs.
685
- * @param string $entry_point_name Which entry point specifically we are triggering.
686
- * @param self $template Current instance of the template class doing this entry point.
687
- */
688
- do_action( "tribe_template_entry_point:$hook_name:$entry_point_name", $hook_name, $entry_point_name, $this );
689
- }
690
-
691
- $html = ob_get_clean();
692
-
693
- if ( has_filter( "tribe_template_entry_point_html:$hook_name" ) ) {
694
- /**
695
- * Generic entry point action for the current template.
696
- *
697
- * @since 4.12.1
698
- *
699
- * @param string $html HTML returned and/or echoed for this for this entry point.
700
- * @param string $hook_name For which template include this entry point belongs.
701
- * @param string $entry_point_name Which entry point specifically we are triggering.
702
- * @param self $template Current instance of the template class doing this entry point.
703
- */
704
- $html = apply_filters( "tribe_template_entry_point_html:$hook_name", $html, $hook_name, $entry_point_name, $this );
705
- }
706
-
707
- if ( has_filter( "tribe_template_entry_point_html:$hook_name:$entry_point_name" ) ) {
708
- /**
709
- * Specific named entry point action called.
710
- *
711
- * @since 4.12.1
712
- *
713
- * @param string $html HTML returned and/or echoed for this for this entry point.
714
- * @param string $hook_name For which template include this entry point belongs.
715
- * @param string $entry_point_name Which entry point specifically we are triggering.
716
- * @param self $template Current instance of the template class doing this entry point.
717
- */
718
- $html = apply_filters( "tribe_template_entry_point_html:$hook_name:$entry_point_name", $html, $hook_name, $entry_point_name, $this );
719
- }
720
-
721
- if ( $echo ) {
722
- echo $html;
723
- }
724
-
725
- return $html;
726
- }
727
-
728
  /**
729
  * A very simple method to include a Template, allowing filtering and additions using hooks.
730
  *
731
  * @since 4.6.2
732
  *
733
- * @param string|array $name Which file we are talking about including.
734
- * If an array, each item will add a directory separator to get to the single template.
735
- * @param array $context Any context data you need to expose to this file
736
- * @param boolean $echo If we should also print the Template
737
  *
738
  * @return string|false Either the final content HTML or `false` if no template could be found.
739
  */
740
- public function template( $name, $context = [], $echo = true ) {
741
- static $file_exists = [];
742
- static $files = [];
743
- static $template_names = [];
744
-
745
- /**
746
- * Allow users to disable templates before rendering it by returning empty string.
747
- *
748
- * @since 4.12.0
749
- *
750
- * @param string null Whether to continue displaying the template or not.
751
- * @param array $name Template name.
752
- * @param array $context Any context data you need to expose to this file.
753
- * @param boolean $echo If we should also print the Template.
754
- */
755
- $done = apply_filters( 'tribe_template_done', null, $name, $context, $echo );
756
-
757
- if ( null !== $done ) {
758
- return false;
759
  }
760
 
761
- // Key we'll use for in-memory caching of expensive operations.
762
- $cache_name_key = is_array( $name ) ? implode( '/', $name ) : $name;
763
-
764
- // Cache template name massaging so we don't have to repeat these actions.
765
- if ( ! isset( $template_names[ $cache_name_key ] ) ) {
766
- // If name is String make it an Array
767
- if ( is_string( $name ) ) {
768
- $name = (array) explode( '/', $name );
769
- }
770
 
771
- // Clean this Variable
772
- $name = array_map( 'sanitize_title_with_dashes', $name );
773
-
774
- $template_names[ $cache_name_key ] = $name;
775
  }
776
 
777
- // Cache file location and existence.
778
- if (
779
- ! isset( $file_exists[ $cache_name_key ] )
780
- || ! isset( $files[ $cache_name_key ] )
781
- ) {
782
- // Check if the file exists
783
- $files[ $cache_name_key ] = $file = $this->get_template_file( $name );
784
-
785
- // Check if it's a valid variable
786
- if ( ! $file ) {
787
- return $file_exists[ $cache_name_key ] = false;
788
- }
789
 
790
- // Before we load the file we check if it exists
791
- if ( ! file_exists( $file ) ) {
792
- return $file_exists[ $cache_name_key ] = false;
793
- }
794
 
795
- $file_exists[ $cache_name_key ] = true;
796
- }
797
-
798
- // If the file doesn't exist, bail.
799
- if ( ! $file_exists[ $cache_name_key ] ) {
800
  return false;
801
  }
802
 
803
- // Use filename stored in cache.
804
- $file = $files[ $cache_name_key ];
805
- $name = $template_names[ $cache_name_key ];
806
- $origin_folder_appendix = array_diff( $this->folder, $this->template_origin_base_folder );
807
-
808
- if ( $origin_namespace = $this->template_get_origin_namespace( $file ) ) {
809
- $legacy_namespace = array_merge( (array) $origin_namespace, $name );
810
- $namespace = array_merge( (array) $origin_namespace, $origin_folder_appendix, $name );
811
- } else {
812
- $legacy_namespace = $name;
813
- $namespace = array_merge( $origin_folder_appendix, $legacy_namespace );
814
- }
815
-
816
- // Setup the Hook name.
817
- $legacy_hook_name = implode( '/', $legacy_namespace );
818
- $hook_name = implode( '/', $namespace );
819
-
820
- $prev_hook_name = $this->get_template_current_hook_name();
821
-
822
- // Store the current hook name for the purposes of entry-points.
823
- $this->set_template_current_hook_name( $hook_name );
824
-
825
- /**
826
- * Allow users to filter the HTML before rendering
827
- *
828
- * @since 4.11.0
829
- *
830
- * @param string $html The initial HTML
831
- * @param string $file Complete path to include the PHP File
832
- * @param array $name Template name
833
- * @param self $template Current instance of the Tribe__Template
834
- */
835
- $pre_html = apply_filters( 'tribe_template_pre_html', null, $file, $name, $this );
836
-
837
- /**
838
- * Allow users to filter the HTML by the name before rendering
839
- *
840
- * E.g.:
841
- * `tribe_template_pre_html:events/blocks/parts/details`
842
- * `tribe_template_pre_html:events/embed`
843
- * `tribe_template_pre_html:tickets/login-to-purchase`
844
- *
845
- * @since 4.11.0
846
- *
847
- * @param string $html The initial HTML
848
- * @param string $file Complete path to include the PHP File
849
- * @param array $name Template name
850
- * @param self $template Current instance of the Tribe__Template
851
- */
852
- $pre_html = apply_filters( "tribe_template_pre_html:$hook_name", $pre_html, $file, $name, $this );
853
-
854
- if ( null !== $pre_html ) {
855
- return $pre_html;
856
  }
857
 
858
  ob_start();
@@ -864,7 +541,7 @@ class Tribe__Template {
864
  * Fires an Action before including the template file
865
  *
866
  * @since 4.6.2
867
- * @since 4.7.20 The $name param no longer contains the extension
868
  *
869
  * @param string $file Complete path to include the PHP File
870
  * @param array $name Template name
@@ -872,23 +549,6 @@ class Tribe__Template {
872
  */
873
  do_action( 'tribe_template_before_include', $file, $name, $this );
874
 
875
- /**
876
- * Fires an Action for a given template name before including the template file
877
- *
878
- * E.g.:
879
- * `tribe_template_before_include:events/blocks/parts/details`
880
- * `tribe_template_before_include:events/embed`
881
- * `tribe_template_before_include:tickets/login-to-purchase`
882
- *
883
- * @deprecated 4.11.0
884
- * @since 4.7.20
885
- *
886
- * @param string $file Complete path to include the PHP File
887
- * @param array $name Template name
888
- * @param self $template Current instance of the Tribe__Template
889
- */
890
- do_action( "tribe_template_before_include:$legacy_hook_name", $file, $name, $this );
891
-
892
  /**
893
  * Fires an Action for a given template name before including the template file
894
  *
@@ -905,13 +565,29 @@ class Tribe__Template {
905
  */
906
  do_action( "tribe_template_before_include:$hook_name", $file, $name, $this );
907
 
908
- $this->template_safe_include( $file );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
909
 
910
  /**
911
  * Fires an Action after including the template file
912
  *
913
  * @since 4.6.2
914
- * @since 4.7.20 The $name param no longer contains the extension
915
  *
916
  * @param string $file Complete path to include the PHP File
917
  * @param array $name Template name
@@ -919,23 +595,6 @@ class Tribe__Template {
919
  */
920
  do_action( 'tribe_template_after_include', $file, $name, $this );
921
 
922
- /**
923
- * Fires an Action for a given template name after including the template file
924
- *
925
- * E.g.:
926
- * `tribe_template_after_include:events/blocks/parts/details`
927
- * `tribe_template_after_include:events/embed`
928
- * `tribe_template_after_include:tickets/login-to-purchase`
929
- *
930
- * @deprecated 4.11.0
931
- * @since 4.7.20
932
- *
933
- * @param string $file Complete path to include the PHP File
934
- * @param array $name Template name
935
- * @param self $template Current instance of the Tribe__Template
936
- */
937
- do_action( "tribe_template_after_include:$legacy_hook_name", $file, $name, $this );
938
-
939
  /**
940
  * Fires an Action for a given template name after including the template file
941
  *
@@ -959,7 +618,7 @@ class Tribe__Template {
959
  * Allow users to filter the final HTML
960
  *
961
  * @since 4.6.2
962
- * @since 4.7.20 The $name param no longer contains the extension
963
  *
964
  * @param string $html The final HTML
965
  * @param string $file Complete path to include the PHP File
@@ -968,24 +627,6 @@ class Tribe__Template {
968
  */
969
  $html = apply_filters( 'tribe_template_html', $html, $file, $name, $this );
970
 
971
- /**
972
- * Allow users to filter the final HTML by the name
973
- *
974
- * E.g.:
975
- * `tribe_template_html:events/blocks/parts/details`
976
- * `tribe_template_html:events/embed`
977
- * `tribe_template_html:tickets/login-to-purchase`
978
- *
979
- * @deprecated 4.11.0
980
- * @since 4.7.20
981
- *
982
- * @param string $html The final HTML
983
- * @param string $file Complete path to include the PHP File
984
- * @param array $name Template name
985
- * @param self $template Current instance of the Tribe__Template
986
- */
987
- $html = apply_filters( "tribe_template_html:$legacy_hook_name", $html, $file, $name, $this );
988
-
989
  /**
990
  * Allow users to filter the final HTML by the name
991
  *
@@ -1003,146 +644,13 @@ class Tribe__Template {
1003
  */
1004
  $html = apply_filters( "tribe_template_html:$hook_name", $html, $file, $name, $this );
1005
 
1006
- // Tries to hook container entry points in the HTML.
1007
- $html = $this->template_hook_container_entry_points( $html );
1008
-
1009
  if ( $echo ) {
1010
  echo $html;
1011
  }
1012
 
1013
- // Revert the current hook name.
1014
- $this->set_template_current_hook_name( $prev_hook_name );
1015
-
1016
- return $html;
1017
- }
1018
-
1019
- /**
1020
- * Run the hooks for the container entry points.
1021
- *
1022
- * @since 4.12.1
1023
- *
1024
- * @param string $html The html of the current template.
1025
- *
1026
- * @return string|false Either the final entry point content HTML or `false` if no entry point could be found or set to false.
1027
- */
1028
- private function template_hook_container_entry_points( $html ) {
1029
-
1030
- $matches = $this->get_entry_point_matches( $html );
1031
- $html_matches = $matches[0];
1032
-
1033
- if ( 0 === count( $html_matches ) ) {
1034
- return $html;
1035
- }
1036
-
1037
- $html_tags = $matches['tag'];
1038
- $html_tags_ends = $matches['is_end'];
1039
-
1040
- // Get first and last tags.
1041
- $first_tag = reset( $html_tags );
1042
- $last_tag = end( $html_tags );
1043
-
1044
- // Determine if first last tags are tag ends.
1045
- $first_tag_is_end = '/' === reset( $html_tags_ends );
1046
- $last_tag_is_end = '/' === end( $html_tags_ends );
1047
-
1048
- // When first and last tag are not the same, bail.
1049
- if ( $first_tag !== $last_tag ) {
1050
- return $html;
1051
- }
1052
-
1053
- // If the first tag is a html tag end, bail.
1054
- if ( $first_tag_is_end ) {
1055
- return $html;
1056
- }
1057
-
1058
- // If the last tag is not and html tag end, bail.
1059
- if ( ! $last_tag_is_end ) {
1060
- return $html;
1061
- }
1062
-
1063
- $first_tag_html = reset( $html_matches );
1064
- $last_tag_html = end( $html_matches );
1065
-
1066
- $open_container_entry_point_html = $this->do_entry_point( 'after_container_open', false );
1067
- $close_container_entry_point_html = $this->do_entry_point( 'before_container_close', false );
1068
-
1069
- $html = Strings::replace_first( $first_tag_html, $first_tag_html . $open_container_entry_point_html, $html );
1070
- $html = Strings::replace_last( $last_tag_html, $close_container_entry_point_html . $last_tag_html, $html );
1071
-
1072
  return $html;
1073
  }
1074
 
1075
- /**
1076
- * Based on a path it determines what is the namespace that should be used.
1077
- *
1078
- * @since 4.11.0
1079
- *
1080
- * @param string $path Which file we are going to load.
1081
- *
1082
- * @return string|false The found namespace for that path or false.
1083
- */
1084
- public function template_get_origin_namespace( $path ) {
1085
- $matching_namespace = false;
1086
- /**
1087
- * Allows more namespaces to be added based on the path of the file we are loading.
1088
- *
1089
- * @since 4.11.0
1090
- *
1091
- * @param array $namespace_map Indexed array containing the namespace as the key and path to `strpos`.
1092
- * @param string $path Path we will do the `strpos` to validate a given namespace.
1093
- * @param self $template Current instance of the template class.
1094
- */
1095
- $namespace_map = (array) apply_filters( 'tribe_template_origin_namespace_map', [], $path, $this );
1096
-
1097
- foreach ( $namespace_map as $namespace => $contains_string ) {
1098
- // Skip when we dont have the namespace path.
1099
- if ( false === strpos( $path, $contains_string ) ) {
1100
- continue;
1101
- }
1102
-
1103
- $matching_namespace = $namespace;
1104
-
1105
- // Once the first namespace is found it breaks out.
1106
- break;
1107
- }
1108
-
1109
- if ( empty( $matching_namespace ) && ! empty( $this->origin->template_namespace ) ) {
1110
- $matching_namespace = $this->origin->template_namespace;
1111
- }
1112
-
1113
- return $matching_namespace;
1114
- }
1115
-
1116
- /**
1117
- * Includes a give PHP inside of a safe context.
1118
- *
1119
- * This method is required to prevent template files messing with local variables used inside of the
1120
- * `self::template` method. Also shelters the template loading from any possible variables that could
1121
- * be overwritten by the context.
1122
- *
1123
- * @since 4.11.0
1124
- *
1125
- * @param string $file Which file will be included with safe context.
1126
- *
1127
- * @return void
1128
- */
1129
- public function template_safe_include( $file ) {
1130
- // We use this instance variable to prevent collisions.
1131
- $this->template_current_file_path = $file;
1132
- unset( $file );
1133
-
1134
- // Only do this if really needed (by default it wont).
1135
- if ( true === $this->template_context_extract && ! empty( $this->context ) ) {
1136
- // Make any provided variables available in the template variable scope.
1137
- extract( $this->context ); // @phpcs:ignore
1138
- }
1139
-
1140
- include $this->template_current_file_path;
1141
-
1142
- // After the include we reset the variable.
1143
- unset( $this->template_current_file_path );
1144
- }
1145
-
1146
  /**
1147
  * Sets a number of values at the same time.
1148
  *
@@ -1193,38 +701,4 @@ class Tribe__Template {
1193
  public function get_values() {
1194
  return array_merge( $this->get_global_values(), $this->get_local_values() );
1195
  }
1196
-
1197
- /**
1198
- * Get the Entry Point Matches.
1199
- *
1200
- * @since 4.12.1
1201
- *
1202
- * @param string $html The html of the current template.
1203
- *
1204
- * @return array An array of matches from the regular expression.
1205
- */
1206
- private function get_entry_point_matches( $html ) {
1207
- // Set up cache key using current hook name.
1208
- $hook_name = $this->get_template_current_hook_name();
1209
- $key = "tribe_template_entry_point_cache:{$hook_name}";
1210
-
1211
- // Get cache instance.
1212
- $cache = tribe_cache();
1213
-
1214
- // Get cached value (if set).
1215
- $cached = $cache[ $key ];
1216
-
1217
- if ( false !== $cached ) {
1218
- return $cached;
1219
- }
1220
-
1221
- $regexp = '/<(?<is_end>\/)*(?<tag>[A-Z0-9]*)(?:\b)*[^>]*>/mi';
1222
-
1223
- preg_match_all( $regexp, $html, $matches );
1224
-
1225
- $cache[ $key ] = $matches;
1226
-
1227
- return $matches;
1228
- }
1229
-
1230
  }
1
  <?php
2
 
 
 
3
  class Tribe__Template {
4
  /**
5
  * The folders into which we will look for the template.
47
  protected $template_origin_base_folder = [ 'src', 'views' ];
48
 
49
  /**
50
+ * Allow chaing if class will extract data from the local context
51
  *
52
  * @since 4.6.2
53
  *
55
  */
56
  protected $template_context_extract = false;
57
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Base template for where to look for template
60
  *
73
  */
74
  protected $template_folder_lookup = false;
75
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * Configures the class origin plugin path
78
  *
90
  if ( is_string( $origin ) ) {
91
  // Origin needs to be a class with a `instance` method
92
  if ( class_exists( $origin ) && method_exists( $origin, 'instance' ) ) {
93
+ $origin = call_user_func( array( $origin, 'instance' ) );
94
  }
95
  }
96
 
97
+ if ( empty( $origin->plugin_path ) && empty( $origin->pluginPath ) && ! is_dir( $origin ) ) {
 
 
 
 
98
  throw new InvalidArgumentException( 'Invalid Origin Class for Template Instance' );
99
  }
100
 
101
+ if ( ! is_string( $origin ) ) {
 
 
 
 
 
 
 
102
  $this->origin = $origin;
103
+ $this->template_base_path = untrailingslashit( ! empty( $this->origin->plugin_path ) ? $this->origin->plugin_path : $this->origin->pluginPath );
104
+ } else {
105
+ $this->template_base_path = untrailingslashit( (array) explode( '/', $origin ) );
 
 
 
106
  }
107
 
108
  return $this;
134
  return $this;
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
137
  /**
138
  * Configures the class with the base folder in relation to the Origin
139
  *
140
  * @since 4.7.20
141
  *
142
+ * @param mixed $use Should we look for template files in the list of folders
143
  *
144
  * @return self
145
  */
149
  return $this;
150
  }
151
 
 
 
 
 
 
 
 
 
 
 
 
152
  /**
153
  * Configures the class global context
154
  *
181
  return $this;
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  /**
185
  * Sets a Index inside of the global or local context
186
  * Final to prevent extending the class when the `get` already exists on the child class
263
  *
264
  * @return array
265
  */
266
+ public function merge_context( $context = array(), $file = null, $name = null ) {
267
  // Allow for simple null usage as well as array() for nothing
268
  if ( is_null( $context ) ) {
269
+ $context = array();
270
  }
271
 
272
+ // Applies local context on top of Global one
273
+ $context = wp_parse_args( (array) $context, $this->global );
274
 
275
  /**
276
  * Allows filtering the Local context
317
  * in the theme's directory.
318
  *
319
  * @since 4.7.20
 
320
  *
321
+ * @return array
 
 
322
  */
323
+ protected function get_template_public_namespace() {
324
+ $namespace = array(
325
  'tribe',
326
+ );
327
 
328
+ if ( ! empty( $this->origin->template_namespace ) ) {
 
 
329
  $namespace[] = $this->origin->template_namespace;
330
  }
331
 
360
  }
361
 
362
  /**
363
+ * Fetches the path for locating files given a base folder normally theme related
364
  *
365
  * @since 4.7.20
 
366
  *
367
+ * @param mixed $base Base path to look into
 
368
  *
369
+ * @return string
370
  */
371
+ protected function get_template_public_path( $base ) {
372
 
373
  // Craft the plugin Path
374
+ $path = array_merge( (array) $base, (array) $this->get_template_public_namespace() );
375
 
376
  // Pick up if the folder needs to be aded to the public template path.
377
  $folder = array_diff( $this->folder, $this->get_template_origin_base_folder() );
402
  * @return array
403
  */
404
  protected function get_template_path_list() {
405
+ $folders = array();
406
+
407
+ // Only look into public folders if we tell to use folders
408
+ if ( $this->template_folder_lookup ) {
409
+ $folders[] = array(
410
+ 'id' => 'child-theme',
411
+ 'priority' => 10,
412
+ 'path' => $this->get_template_public_path( STYLESHEETPATH ),
413
+ );
414
+ $folders[] = array(
415
+ 'id' => 'parent-theme',
416
+ 'priority' => 15,
417
+ 'path' => $this->get_template_public_path( TEMPLATEPATH ),
418
+ );
419
+ }
420
 
421
+ $folders[] = array(
422
+ 'id' => 'plugin',
423
+ 'priority' => 20,
424
+ 'path' => $this->get_template_plugin_path(),
425
+ );
426
 
427
  /**
428
  * Allows filtering of the list of folders in which we will look for the
433
  * @param array $folders Complete path to include the base public folder
434
  * @param self $template Current instance of the Tribe__Template
435
  */
436
+ $folders = apply_filters( 'tribe_template_path_list', $folders, $this );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
 
438
  uasort( $folders, 'tribe_sort_by_priority' );
439
 
456
  $name = (array) explode( '/', $name );
457
  }
458
 
459
+ $folders = $this->get_template_path_list();
 
 
460
 
461
  foreach ( $folders as $folder ) {
462
+ $folder['path'] = trim( $folder['path'] );
463
+ if ( ! $folder['path'] ) {
464
  continue;
465
  }
466
 
472
 
473
  // Skip non-existent files
474
  if ( file_exists( $file ) ) {
475
+ /**
476
+ * A more Specific Filter that will include the template name
477
+ *
478
+ * @since 4.6.2
479
+ * @since 4.7.20 The $name param no longers contains the extension
480
+ *
481
+ * @param string $file Complete path to include the PHP File
482
+ * @param array $name Template name
483
+ * @param self $template Current instance of the Tribe__Template
484
+ */
485
+ return apply_filters( 'tribe_template_file', $file, $name, $this );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  }
487
  }
488
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  // Couldn't find a template on the Stack
490
  return false;
491
  }
492
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  /**
494
  * A very simple method to include a Template, allowing filtering and additions using hooks.
495
  *
496
  * @since 4.6.2
497
  *
498
+ * @param string $name Which file we are talking about including
499
+ * @param array $context Any context data you need to expose to this file
500
+ * @param boolean $echo If we should also print the Template
 
501
  *
502
  * @return string|false Either the final content HTML or `false` if no template could be found.
503
  */
504
+ public function template( $name, $context = array(), $echo = true ) {
505
+ // If name is String make it an Array
506
+ if ( is_string( $name ) ) {
507
+ $name = (array) explode( '/', $name );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  }
509
 
510
+ // Clean this Variable
511
+ $name = array_map( 'sanitize_title_with_dashes', $name );
 
 
 
 
 
 
 
512
 
513
+ if ( ! empty( $this->origin->template_namespace ) ) {
514
+ $namespace = array_merge( (array) $this->origin->template_namespace, $name );
515
+ } else {
516
+ $namespace = $name;
517
  }
518
 
519
+ // Setup the Hook name
520
+ $hook_name = implode( '/', $namespace );
 
 
 
 
 
 
 
 
 
 
521
 
522
+ // Check if the file exists
523
+ $file = $this->get_template_file( $name );
 
 
524
 
525
+ // Check if it's a valid variable
526
+ if ( ! $file ) {
 
 
 
527
  return false;
528
  }
529
 
530
+ // Before we load the file we check if it exists
531
+ if ( ! file_exists( $file ) ) {
532
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  }
534
 
535
  ob_start();
541
  * Fires an Action before including the template file
542
  *
543
  * @since 4.6.2
544
+ * @since 4.7.20 The $name param no longers contains the extension
545
  *
546
  * @param string $file Complete path to include the PHP File
547
  * @param array $name Template name
549
  */
550
  do_action( 'tribe_template_before_include', $file, $name, $this );
551
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
  /**
553
  * Fires an Action for a given template name before including the template file
554
  *
565
  */
566
  do_action( "tribe_template_before_include:$hook_name", $file, $name, $this );
567
 
568
+ // Only do this if really needed (by default it wont).
569
+ if ( true === $this->template_context_extract && ! empty( $this->context ) ) {
570
+ // We don't allow Extrating of a variable called $name
571
+ if ( isset( $this->context['name'] ) ) {
572
+ unset( $this->context['name'] );
573
+ }
574
+
575
+ // We don't allow the extraction of a variable called `$file`.
576
+ if ( isset( $this->context['file'] ) ) {
577
+ unset( $this->context['file'] );
578
+ }
579
+
580
+ // Make any provided variables available in the template variable scope.
581
+ extract( $this->context ); // @codingStandardsIgnoreLine
582
+ }
583
+
584
+ include $file;
585
 
586
  /**
587
  * Fires an Action after including the template file
588
  *
589
  * @since 4.6.2
590
+ * @since 4.7.20 The $name param no longers contains the extension
591
  *
592
  * @param string $file Complete path to include the PHP File
593
  * @param array $name Template name
595
  */
596
  do_action( 'tribe_template_after_include', $file, $name, $this );
597
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
598
  /**
599
  * Fires an Action for a given template name after including the template file
600
  *
618
  * Allow users to filter the final HTML
619
  *
620
  * @since 4.6.2
621
+ * @since 4.7.20 The $name param no longers contains the extension
622
  *
623
  * @param string $html The final HTML
624
  * @param string $file Complete path to include the PHP File
627
  */
628
  $html = apply_filters( 'tribe_template_html', $html, $file, $name, $this );
629
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
  /**
631
  * Allow users to filter the final HTML by the name
632
  *
644
  */
645
  $html = apply_filters( "tribe_template_html:$hook_name", $html, $file, $name, $this );
646
 
 
 
 
647
  if ( $echo ) {
648
  echo $html;
649
  }
650
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651
  return $html;
652
  }
653
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
654
  /**
655
  * Sets a number of values at the same time.
656
  *
701
  public function get_values() {
702
  return array_merge( $this->get_global_values(), $this->get_local_values() );
703
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
704
  }
common/src/Tribe/Traits/Cache_User.php CHANGED
@@ -125,21 +125,4 @@ trait Cache_User {
125
  }
126
  }
127
  }
128
-
129
- /**
130
- * Resets the instance caches for the this instance.
131
- *
132
- * @since 4.11.0
133
- *
134
- * @return string[] A list of the emptied cache properties.
135
- */
136
- public function reset_caches() {
137
- $emptied = [];
138
- foreach ( array_keys( $this->caches ) as $key ) {
139
- $emptied[] = $key;
140
- $this->{"{$key}_cache"} = [];
141
- }
142
-
143
- return $emptied;
144
- }
145
  }
125
  }
126
  }
127
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
common/src/Tribe/Utils/Array.php CHANGED
@@ -442,84 +442,5 @@ if ( ! class_exists( 'Tribe__Utils__Array' ) ) {
442
 
443
  return $default;
444
  }
445
-
446
- /**
447
- * Discards everything other than array values having string keys and scalar values, ensuring a
448
- * one-dimensional, associative array result.
449
- *
450
- * @link https://www.php.net/manual/language.types.array.php Keys cast to non-strings will be discarded.
451
- *
452
- * @since 4.12.2
453
- *
454
- * @param array $array
455
- *
456
- * @return array Associative or empty array.
457
- */
458
- public static function filter_to_flat_scalar_associative_array( array $array ) {
459
- $result = [];
460
-
461
- if ( ! is_array( $array ) ) {
462
- return $result;
463
- }
464
-
465
- foreach ( $array as $k => $v ) {
466
- if ( ! is_string( $k ) ) {
467
- continue;
468
- }
469
-
470
- if ( ! is_scalar( $v ) ) {
471
- continue;
472
- }
473
-
474
- $result[ $k ] = $v;
475
- }
476
-
477
- return $result;
478
- }
479
-
480
- /**
481
- * Build an array from migrating aliased key values to their canonical key values, removing all alias keys.
482
- *
483
- * If the original array has values for both the alias and its canonical, keep the canonical's value and
484
- * discard the alias' value.
485
- *
486
- * @since 4.12.2
487
- *
488
- * @param array $original An associative array of values, such as passed shortcode arguments.
489
- * @param array $alias_map An associative array of aliases: key as alias, value as mapped canonical.
490
- * Example: [ 'alias' => 'canonical', 'from' => 'to', 'that' => 'becomes_this' ]
491
- *
492
- * @return array
493
- */
494
- public static function parse_associative_array_alias( array $original, array $alias_map ) {
495
- // Ensure array values.
496
- $original = (array) $original;
497
- $alias_map = static::filter_to_flat_scalar_associative_array( (array) $alias_map );
498
-
499
- // Fail gracefully if alias array wasn't setup as [ 'from' => 'to' ].
500
- if ( empty( $alias_map ) ) {
501
- return $original;
502
- }
503
-
504
- $result = $original;
505
-
506
- // Parse aliases.
507
- foreach ( $alias_map as $from => $to ) {
508
- // If this alias isn't in use, go onto the next.
509
- if ( ! isset( $result[ $from ] ) ) {
510
- continue;
511
- }
512
-
513
- // Only allow setting alias value if canonical value is not already present.
514
- if ( ! isset( $result[ $to ] ) ) {
515
- $result[ $to ] = $result[ $from ];
516
- }
517
-
518
- // Always remove the alias key.
519
- unset( $result[ $from ] );
520
- }
521
-
522
- return $result;
523
- }
524
  }
525
  }
442
 
443
  return $default;
444
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  }
446
  }
common/src/Tribe/Utils/Collection_Trait.php CHANGED
@@ -152,27 +152,14 @@ trait Collection_Trait {
152
  * {@inheritDoc}
153
  */
154
  public function serialize() {
155
- $to_serialize = $this->all();
156
-
157
- if ( method_exists( $this, 'before_serialize' ) ) {
158
- $to_serialize = $this->before_serialize( $this->all() );
159
- }
160
-
161
- return serialize( $to_serialize );
162
  }
163
 
164
  /**
165
  * {@inheritDoc}
166
  */
167
  public function unserialize( $serialized ) {
168
- $to_unserialize = $serialized;
169
-
170
- if ( method_exists( $this, 'custom_unserialize' ) ) {
171
- $this->items = $this->custom_unserialize( $to_unserialize );
172
- return;
173
- }
174
-
175
- $this->items = unserialize( $to_unserialize );
176
  }
177
 
178
  /**
152
  * {@inheritDoc}
153
  */
154
  public function serialize() {
155
+ return serialize( $this->all() );
 
 
 
 
 
 
156
  }
157
 
158
  /**
159
  * {@inheritDoc}
160
  */
161
  public function unserialize( $serialized ) {
162
+ $this->items = unserialize( $serialized );
 
 
 
 
 
 
 
163
  }
164
 
165
  /**
common/src/Tribe/Utils/Date_I18n.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- /**
3
- * Extends DateTime and includes translation capabilities.
4
- *
5
- * @package Tribe\Utils
6
- * @since 4.11.0
7
- */
8
- namespace Tribe\Utils;
9
-
10
- use Tribe__Date_Utils as Dates;
11
- use DateTime;
12
- use DateTimeImmutable;
13
-
14
- /**
15
- * Class Date i18n
16
- *
17
- * @package Tribe\Utils
18
- * @since 4.11.0
19
- */
20
- class Date_I18n extends DateTime {
21
- /**
22
- * {@inheritDoc}
23
- *
24
- * @return Date_I18n Localizable variation of DateTime.
25
- */
26
- public static function createFromImmutable( $datetime ) {
27
- $date_object = new self;
28
- $date_object->setTimestamp( $datetime->getTimestamp() );
29
- $date_object->setTimezone( $datetime->getTimezone() );
30
- return $date_object;
31
- }
32
-
33
- /**
34
- * Returns a translated string using the params from this DateTime instance.
35
- *
36
- * @since 4.11.0
37
- *
38
- * @param string $date_format Format to be used in the translation.
39
- *
40
- * @return string Translated date.
41
- */
42
- public function format_i18n( $date_format ) {
43
- $unix_with_tz = $this->getTimestamp() + $this->getOffset();
44
- $translated = date_i18n( $date_format, $unix_with_tz );
45
-
46
- return $translated;
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Utils/Date_I18n_Immutable.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- /**
3
- * Extends DateTimeImmutable and includes translation capabilities.
4
- *
5
- * @since 4.11.0
6
- * @package Tribe\Utils
7
- */
8
-
9
- namespace Tribe\Utils;
10
-
11
- use DateTimeImmutable;
12
-
13
- /**
14
- * Class Date i18n Immutable
15
- *
16
- * @since 4.11.0
17
- * @package Tribe\Utils
18
- */
19
- class Date_I18n_Immutable extends DateTimeImmutable {
20
- /**
21
- * {@inheritDoc}
22
- *
23
- * @return Date_I18n_Immutable Localizable variation of DateTimeImmutable.
24
- */
25
- public static function createFromMutable( $datetime ) {
26
- $date_object = new self;
27
- $date_object = $date_object->setTimestamp( $datetime->getTimestamp() );
28
- $date_object = $date_object->setTimezone( $datetime->getTimezone() );
29
-
30
- return $date_object;
31
- }
32
-
33
- /**
34
- * Returns a translated string using the params from this Immutable DateTime instance.
35
- *
36
- * @since 4.11.0
37
- *
38
- * @param string $date_format Format to be used in the translation.
39
- *
40
- * @return string Translated date.
41
- */
42
- public function format_i18n( $date_format ) {
43
- $unix_with_tz = $this->getTimestamp() + $this->getOffset();
44
- $translated = date_i18n( $date_format, $unix_with_tz );
45
-
46
- return $translated;
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Utils/Post_Thumbnail.php CHANGED
@@ -147,8 +147,6 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
147
  * @return array An array of objects containing the post thumbnail data.
148
  */
149
  public function fetch_data() {
150
- static $cache_thumbnail = [];
151
-
152
  if ( ! $this->exists() ) {
153
  return [];
154
  }
@@ -157,58 +155,44 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
157
  return $this->data;
158
  }
159
 
 
160
  $image_sizes = $this->get_image_sizes();
161
  $thumbnail_id = $this->thumbnail_id;
162
 
163
- $cache_key = empty( $thumbnail_id ) ? -1 : $thumbnail_id;
164
-
165
- if ( empty( $cache_thumbnail[ $cache_key ] ) ) {
166
- $thumbnail_data = array_combine(
167
- $image_sizes,
168
- array_map(
169
- static function( $size ) use ( $thumbnail_id ) {
170
- static $cache_size_data = [];
171
-
172
- $size_data_cache_key = empty( $thumbnail_id ) ? -1 : $thumbnail_id;
173
- $size_data_cache_key = "{$size_data_cache_key}:{$size}";
174
-
175
- if ( ! isset( $cache_size_data[ $size_data_cache_key ] ) ) {
176
- $cache_size_data[ $size_data_cache_key ] = wp_get_attachment_image_src( $thumbnail_id, $size );
177
- }
178
-
179
- $size_data = $cache_size_data[ $size_data_cache_key ];
180
-
181
- if ( false === $size_data ) {
182
- return (object) [
183
- 'url' => '',
184
- 'width' => '',
185
- 'height' => '',
186
- 'is_intermediate' => false,
187
- ];
188
- }
189
 
 
190
  return (object) [
191
- 'url' => Arr::get( $size_data, 0, '' ),
192
- 'width' => Arr::get( $size_data, 1, '' ),
193
- 'height' => Arr::get( $size_data, 2, '' ),
194
- 'is_intermediate' => (bool) Arr::get( $size_data, 3, false ),
195
  ];
196
- },
197
- $image_sizes
198
- )
199
- );
200
 
201
- $srcset = wp_get_attachment_image_srcset( $thumbnail_id );
202
- $thumbnail_data['srcset'] = ! empty( $srcset ) ? $srcset : false;
 
 
 
 
 
 
 
 
203
 
204
- $title = get_the_title( $thumbnail_id );
205
- $thumbnail_data['title'] = ! empty( $title ) ? $title : false;
206
 
207
- $alt = trim( strip_tags( get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true ) ) );
208
- $thumbnail_data['alt'] = ! empty( $alt ) ? $alt : false;
209
 
210
- $cache_thumbnail[ $cache_key ] = $thumbnail_data;
211
- }
212
 
213
  /**
214
  * Filters the post thumbnail data and information that will be returned for a specific post.
@@ -220,7 +204,7 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
220
  * @param array $thumbnail_data The thumbnail data for the post.
221
  * @param int $post_id The ID of the post the data is for.
222
  */
223
- $thumbnail_data = apply_filters( 'tribe_post_thumbnail_data', $cache_thumbnail[ $cache_key ], $this->post_id );
224
 
225
  $this->resolved();
226
 
@@ -286,22 +270,17 @@ class Post_Thumbnail implements \ArrayAccess, \Serializable {
286
  $data = $this->fetch_data();
287
  $data['post_id'] = $this->post_id;
288
 
289
- return wp_json_encode( $data );
290
  }
291
 
292
  /**
293
  * {@inheritDoc}
294
  */
295
  public function unserialize( $serialized ) {
296
- $data = json_decode( $serialized, true );
297
- array_walk( $data, static function ( &$data_entry ) {
298
- if ( is_array( $data_entry ) ) {
299
- $data_entry = (object) $data_entry;
300
- }
301
- } );
302
  $this->post_id = $data['post_id'];
303
  unset( $data['post_id'] );
304
- $this->data = ! empty( $data ) ? $data : null;
305
  }
306
 
307
  /**
147
  * @return array An array of objects containing the post thumbnail data.
148
  */
149
  public function fetch_data() {
 
 
150
  if ( ! $this->exists() ) {
151
  return [];
152
  }
155
  return $this->data;
156
  }
157
 
158
+ $post_id = $this->post_id;
159
  $image_sizes = $this->get_image_sizes();
160
  $thumbnail_id = $this->thumbnail_id;
161
 
162
+ $thumbnail_data = array_combine(
163
+ $image_sizes,
164
+ array_map(
165
+ static function ( $size ) use ( $thumbnail_id ) {
166
+ $size_data = wp_get_attachment_image_src( $thumbnail_id, $size );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
+ if ( false === $size_data ) {
169
  return (object) [
170
+ 'url' => '',
171
+ 'width' => '',
172
+ 'height' => '',
173
+ 'is_intermediate' => false,
174
  ];
175
+ }
 
 
 
176
 
177
+ return (object) [
178
+ 'url' => Arr::get( $size_data, 0, '' ),
179
+ 'width' => Arr::get( $size_data, 1, '' ),
180
+ 'heigth' => Arr::get( $size_data, 2, '' ),
181
+ 'is_intermediate' => (bool) Arr::get( $size_data, 3, false ),
182
+ ];
183
+ },
184
+ $image_sizes
185
+ )
186
+ );
187
 
188
+ $srcset = wp_get_attachment_image_srcset( $thumbnail_id );
189
+ $thumbnail_data['srcset'] = ! empty( $srcset ) ? $srcset : false;
190
 
191
+ $title = get_the_title( $thumbnail_id );
192
+ $thumbnail_data['title'] = ! empty( $title ) ? $title : false;
193
 
194
+ $alt = trim( strip_tags( get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true ) ) );
195
+ $thumbnail_data['alt'] = ! empty( $alt ) ? $alt : false;
196
 
197
  /**
198
  * Filters the post thumbnail data and information that will be returned for a specific post.
204
  * @param array $thumbnail_data The thumbnail data for the post.
205
  * @param int $post_id The ID of the post the data is for.
206
  */
207
+ $thumbnail_data = apply_filters( 'tribe_post_thumbnail_data', $thumbnail_data, $post_id );
208
 
209
  $this->resolved();
210
 
270
  $data = $this->fetch_data();
271
  $data['post_id'] = $this->post_id;
272
 
273
+ return serialize( $data );
274
  }
275
 
276
  /**
277
  * {@inheritDoc}
278
  */
279
  public function unserialize( $serialized ) {
280
+ $data = unserialize( $serialized );
 
 
 
 
 
281
  $this->post_id = $data['post_id'];
282
  unset( $data['post_id'] );
283
+ $this->data = $data;
284
  }
285
 
286
  /**
common/src/Tribe/Utils/Strings.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
- /**
3
- * String Utilities
4
- *
5
- * @since 4.12.1
6
- * @package Tribe\Utils
7
- */
8
-
9
- namespace Tribe\Utils;
10
-
11
- /**
12
- * Class Strings
13
- *
14
- * @since 4.12.1
15
- *
16
- * @package Tribe\Utils
17
- */
18
- class Strings {
19
-
20
- /**
21
- * Replace the first occurrence of a given value in the string.
22
- *
23
- * @since 4.12.1
24
- *
25
- * @param string $search The string to search for and replace.
26
- * @param string $replace The replacement string.
27
- * @param string $subject The string to do the search and replace from.
28
- *
29
- * @return string The string with the first occurrence of a given value replaced.
30
- */
31
- public static function replace_first( $search, $replace, $subject ) {
32
- if ( '' === $search ) {
33
- return $subject;
34
- }
35
-
36
- $position = strpos( $subject, $search );
37
-
38
- if ( $position !== false ) {
39
- return substr_replace( $subject, $replace, $position, strlen( $search ) );
40
- }
41
-
42
- return $subject;
43
- }
44
-
45
- /**
46
- * Replace the last occurrence of a given value in the string.
47
- *
48
- * @since 4.12.1
49
- *
50
- * @param string $search The string to search for and replace.
51
- * @param string $replace The replacement string.
52
- * @param string $subject The string to do the search and replace from.
53
- *
54
- * @return string The string with the last occurrence of a given value replaced.
55
- */
56
- public static function replace_last( $search, $replace, $subject ) {
57
- $position = strrpos( $subject, $search );
58
-
59
- if ( $position !== false ) {
60
- return substr_replace( $subject, $replace, $position, strlen( $search ) );
61
- }
62
-
63
- return $subject;
64
- }
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/Tribe/Validate.php CHANGED
@@ -239,10 +239,7 @@ if ( ! class_exists( 'Tribe__Validate' ) ) {
239
 
240
  // esc_url_raw does the work of validating chars, but returns the checked string with a
241
  // prepended URL protocol; so let's use strpos to match the values.
242
- if (
243
- ! empty( $maybe_valid_value )
244
- && false !== strpos( $maybe_valid_value, $this->value )
245
- ) {
246
  $this->result->valid = true;
247
  $this->value = sanitize_title( $this->value );
248
  } else {
239
 
240
  // esc_url_raw does the work of validating chars, but returns the checked string with a
241
  // prepended URL protocol; so let's use strpos to match the values.
242
+ if ( false !== strpos( $maybe_valid_value, $this->value ) ) {
 
 
 
243
  $this->result->valid = true;
244
  $this->value = sanitize_title( $this->value );
245
  } else {
common/src/Tribe/Validator/Base.php CHANGED
@@ -158,9 +158,7 @@ class Tribe__Validator__Base implements Tribe__Validator__Interface {
158
  public function is_image( $image ) {
159
  if ( $this->is_numeric( $image ) ) {
160
  return wp_attachment_is_image( $image );
161
- }
162
-
163
- if ( is_string( $image ) ) {
164
  $response = wp_remote_head( $image );
165
 
166
  if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
158
  public function is_image( $image ) {
159
  if ( $this->is_numeric( $image ) ) {
160
  return wp_attachment_is_image( $image );
161
+ } elseif ( is_string( $image ) ) {
 
 
162
  $response = wp_remote_head( $image );
163
 
164
  if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
common/src/Tribe/View_Helpers.php CHANGED
@@ -20,18 +20,10 @@ if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
20
  * @return array The countries array.
21
  */
22
  public static function constructCountries( $postId = '', $useDefault = true ) {
23
- static $cache_var_name = __METHOD__;
24
-
25
- $countries = tribe_get_var( $cache_var_name, null );
26
-
27
- if ( $countries ) {
28
- return $countries;
29
- }
30
-
31
  $eventCountries = tribe_get_option( 'tribeEventsCountries' );
32
 
33
  if ( $eventCountries != '' ) {
34
- $countries = [];
35
 
36
  $country_rows = explode( "\n", $eventCountries );
37
  foreach ( $country_rows as $crow ) {
@@ -73,11 +65,11 @@ if ( ! class_exists( 'Tribe__View_Helpers' ) ) {
73
  $countries = array( '' => $selectCountry ) + $countries;
74
  array_unique( $countries );
75
  }
76
- }
77
 
78
- tribe_set_var( $cache_var_name, $countries );
79
-
80
- return $countries;
 
81
  }
82
 
83
  /**
20
  * @return array The countries array.
21
  */
22
  public static function constructCountries( $postId = '', $useDefault = true ) {
 
 
 
 
 
 
 
 
23
  $eventCountries = tribe_get_option( 'tribeEventsCountries' );
24
 
25
  if ( $eventCountries != '' ) {
26
+ $countries = array();
27
 
28
  $country_rows = explode( "\n", $eventCountries );
29
  foreach ( $country_rows as $crow ) {
65
  $countries = array( '' => $selectCountry ) + $countries;
66
  array_unique( $countries );
67
  }
 
68
 
69
+ return $countries;
70
+ } else {
71
+ return $countries;
72
+ }
73
  }
74
 
75
  /**
common/src/admin-views/tribe-options-display.php CHANGED
@@ -31,12 +31,12 @@ $displayTab = array(
31
  )
32
  . '</p>',
33
  ),
34
- 'datepickerFormat' => [
35
  'type' => 'dropdown',
36
  'label' => esc_html__( 'Compact Date Format', 'tribe-common' ),
37
  'tooltip' => esc_html__( 'Select the date format used for elements with minimal space, such as in datepickers.', 'tribe-common' ),
38
- 'default' => 1,
39
- 'options' => [
40
  '0' => date( 'Y-m-d', $sample_date ),
41
  '1' => date( 'n/j/Y', $sample_date ),
42
  '2' => date( 'm/d/Y', $sample_date ),
@@ -49,13 +49,13 @@ $displayTab = array(
49
  '9' => date( 'Y.m.d', $sample_date ),
50
  '10' => date( 'm.d.Y', $sample_date ),
51
  '11' => date( 'd.m.Y', $sample_date ),
52
- ],
53
  'validation_type' => 'options',
54
- ],
55
- 'tribe-form-content-end' => [
56
  'type' => 'html',
57
  'html' => '</div>',
58
- ],
59
  )
60
  ),
61
  );
31
  )
32
  . '</p>',
33
  ),
34
+ 'datepickerFormat' => array(
35
  'type' => 'dropdown',
36
  'label' => esc_html__( 'Compact Date Format', 'tribe-common' ),
37
  'tooltip' => esc_html__( 'Select the date format used for elements with minimal space, such as in datepickers.', 'tribe-common' ),
38
+ 'default' => 'Y-m-d',
39
+ 'options' => array(
40
  '0' => date( 'Y-m-d', $sample_date ),
41
  '1' => date( 'n/j/Y', $sample_date ),
42
  '2' => date( 'm/d/Y', $sample_date ),
49
  '9' => date( 'Y.m.d', $sample_date ),
50
  '10' => date( 'm.d.Y', $sample_date ),
51
  '11' => date( 'd.m.Y', $sample_date ),
52
+ ),
53
  'validation_type' => 'options',
54
+ ),
55
+ 'tribe-form-content-end' => array(
56
  'type' => 'html',
57
  'html' => '</div>',
58
+ ),
59
  )
60
  ),
61
  );
common/src/functions/template-tags/date.php CHANGED
@@ -277,8 +277,6 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
277
  * @return string|null Date
278
  */
279
  function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
280
- static $cache_var_name = __FUNCTION__;
281
-
282
  if ( is_null( $event ) ) {
283
  global $post;
284
  $event = $post;
@@ -292,23 +290,15 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
292
  return '';
293
  }
294
 
295
- $start_dates = tribe_get_var( $cache_var_name, [] );
296
- $cache_key = "{$event->ID}:{$display_time}:{$date_format}:{$timezone}";
297
-
298
- if ( ! isset( $start_dates[ $cache_key ] ) ) {
299
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
300
- $display_time = false;
301
- }
302
-
303
- // @todo move timezones to Common
304
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
305
- $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
306
- } else {
307
- return null;
308
- }
309
 
310
- $start_dates[ $cache_key ] = tribe_format_date( $start_date, $display_time, $date_format );
311
- tribe_set_var( $cache_var_name, $start_dates );
 
 
 
312
  }
313
 
314
  /**
@@ -317,7 +307,7 @@ if ( ! function_exists( 'tribe_get_start_date' ) ) {
317
  * @param string $start_date
318
  * @param WP_Post $event
319
  */
320
- return apply_filters( 'tribe_get_start_date', $start_dates[ $cache_key ], $event );
321
  }
322
  }
323
 
@@ -339,8 +329,6 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
339
  * @return string|null Date
340
  */
341
  function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
342
- static $cache_var_name = __FUNCTION__;
343
-
344
  if ( is_null( $event ) ) {
345
  global $post;
346
  $event = $post;
@@ -354,23 +342,15 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
354
  return '';
355
  }
356
 
357
- $end_dates = tribe_get_var( $cache_var_name, [] );
358
- $cache_key = "{$event->ID}:{$display_time}:{$date_format}:{$timezone}";
359
-
360
- if ( ! isset( $end_dates[ $cache_key ] ) ) {
361
- if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
362
- $display_time = false;
363
- }
364
-
365
- // @todo move timezones to Common
366
- if ( class_exists( 'Tribe__Events__Timezones' ) ) {
367
- $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID );
368
- } else {
369
- return null;
370
- }
371
 
372
- $end_dates[ $cache_key ] = tribe_format_date( $end_date, $display_time, $date_format );
373
- tribe_set_var( $cache_var_name, $end_dates );
 
 
 
374
  }
375
 
376
  /**
@@ -379,7 +359,7 @@ if ( ! function_exists( 'tribe_get_end_date' ) ) {
379
  * @param string $end_date
380
  * @param WP_Post $event
381
  */
382
- return apply_filters( 'tribe_get_end_date', $end_dates[ $cache_key ], $event );
383
  }
384
  }
385
 
277
  * @return string|null Date
278
  */
279
  function tribe_get_start_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
 
 
280
  if ( is_null( $event ) ) {
281
  global $post;
282
  $event = $post;
290
  return '';
291
  }
292
 
293
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
294
+ $display_time = false;
295
+ }
 
 
 
 
 
 
 
 
 
 
 
296
 
297
+ // @todo move timezones to Common
298
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
299
+ $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
300
+ } else {
301
+ return null;
302
  }
303
 
304
  /**
307
  * @param string $start_date
308
  * @param WP_Post $event
309
  */
310
+ return apply_filters( 'tribe_get_start_date', tribe_format_date( $start_date, $display_time, $date_format ), $event );
311
  }
312
  }
313
 
329
  * @return string|null Date
330
  */
331
  function tribe_get_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
 
 
332
  if ( is_null( $event ) ) {
333
  global $post;
334
  $event = $post;
342
  return '';
343
  }
344
 
345
+ if ( Tribe__Date_Utils::is_all_day( get_post_meta( $event->ID, '_EventAllDay', true ) ) ) {
346
+ $display_time = false;
347
+ }
 
 
 
 
 
 
 
 
 
 
 
348
 
349
+ // @todo move timezones to Common
350
+ if ( class_exists( 'Tribe__Events__Timezones' ) ) {
351
+ $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID );
352
+ } else {
353
+ return null;
354
  }
355
 
356
  /**
359
  * @param string $end_date
360
  * @param WP_Post $event
361
  */
362
+ return apply_filters( 'tribe_get_end_date', tribe_format_date( $end_date, $display_time, $date_format ), $event );
363
  }
364
  }
365
 
common/src/functions/template-tags/general.php CHANGED
@@ -215,15 +215,7 @@ if ( ! function_exists( 'tribe_get_time_format' ) ) {
215
  * @return mixed|void
216
  */
217
  function tribe_get_time_format( ) {
218
- static $cache_var_name = __FUNCTION__;
219
-
220
- $format = tribe_get_var( $cache_var_name, null );
221
-
222
- if ( ! $format ) {
223
- $format = get_option( 'time_format' );
224
- tribe_set_var( $cache_var_name, $format );
225
- }
226
-
227
  return apply_filters( 'tribe_time_format', $format );
228
  }
229
  }//end if
@@ -765,17 +757,4 @@ if ( ! function_exists( 'tribe_context' ) ) {
765
 
766
  return $context;
767
  }
768
- }
769
-
770
- if ( ! function_exists( 'tribe_cache' ) ) {
771
- /**
772
- * Returns the current Tribe Cache instance.
773
- *
774
- * @since 4.11.2
775
- *
776
- * @return Tribe__Cache The current cache instance.
777
- */
778
- function tribe_cache() {
779
- return tribe( 'cache' );
780
- }
781
- }
215
  * @return mixed|void
216
  */
217
  function tribe_get_time_format( ) {
218
+ $format = get_option( 'time_format' );
 
 
 
 
 
 
 
 
219
  return apply_filters( 'tribe_time_format', $format );
220
  }
221
  }//end if
757
 
758
  return $context;
759
  }
760
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/functions/template-tags/html.php CHANGED
@@ -68,7 +68,7 @@ function tribe_required_label( $required, $echo = true ) {
68
  if ( $required ) {
69
  $required_string = '<span class="screen-reader-text">'
70
  . esc_html_x( '(required)', 'The associated field is required.', 'tribe-common' )
71
- . '</span><span class="tribe-required" aria-hidden="true" role="presentation">*</span>';
72
 
73
  if ( ! $echo ) {
74
  return $required_string;
68
  if ( $required ) {
69
  $required_string = '<span class="screen-reader-text">'
70
  . esc_html_x( '(required)', 'The associated field is required.', 'tribe-common' )
71
+ . '</span><span class="tribe-required" aria-hidden=”true role=”presentation”>*</span>';
72
 
73
  if ( ! $echo ) {
74
  return $required_string;
common/src/functions/template-tags/post.php CHANGED
@@ -11,9 +11,9 @@
11
  *
12
  * @param string $more_link_text Optional. Content for when there is more text.
13
  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
14
- * @param WP_Post|object|int $post_id Optional. WP_Post instance or Post ID/object. Default is null.
15
  *
16
- * @return string
17
  */
18
  function tribe_get_the_content( $more_link_text = null, $strip_teaser = false, $post_id = null ) {
19
  global $post, $wp_version;
@@ -30,17 +30,14 @@ function tribe_get_the_content( $more_link_text = null, $strip_teaser = false, $
30
  $content = get_the_content( $more_link_text, $strip_teaser );
31
  }
32
 
33
- if ( ! doing_filter( 'the_content' ) ) {
34
- /**
35
- * Filters the post content.
36
- *
37
- * @since 0.71 of WordPress
38
- *
39
- * @param string $content Content of the current post.
40
- */
41
- $content = apply_filters( 'the_content', $content );
42
- }
43
-
44
  $content = str_replace( ']]>', ']]&gt;', $content );
45
 
46
  $post = $previous_post;
@@ -58,7 +55,7 @@ function tribe_get_the_content( $more_link_text = null, $strip_teaser = false, $
58
  *
59
  * @param string $more_link_text Optional. Content for when there is more text.
60
  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
61
- * @param WP_Post|object|int $post_id Optional. WP_Post instance or Post ID/object. Default is null.
62
  *
63
  * @return void
64
  */
@@ -66,32 +63,3 @@ function tribe_the_content( $more_link_text = null, $strip_teaser = false, $post
66
  echo tribe_get_the_content( $more_link_text, $strip_teaser, $post_id );
67
  }
68
 
69
- /**
70
- * Wrapper for post_class function that allows us to in-memory cache
71
- *
72
- * @since 4.11.0
73
- *
74
- * @param string|string[] $class Space-separated string or array of class names to add to the class list.
75
- * @param int|WP_Post $post Optional. Post ID or post object.
76
- *
77
- * @return string[] Array of class names.
78
- */
79
- function tribe_get_post_class( $class, $post ) {
80
- static $post_classes = [];
81
-
82
- if ( is_numeric( $post ) ) {
83
- $post_id = $post;
84
- } else {
85
- $post_id = $post->ID;
86
- }
87
-
88
- if ( ! isset( $post_classes[ $post_id ] ) ) {
89
- $post_classes[ $post_id ] = get_post_class( [], $post );
90
- }
91
-
92
- if ( ! is_array( $class ) ) {
93
- $class = explode( ' ', $class );
94
- }
95
-
96
- return array_merge( $class, $post_classes[ $post_id ] );
97
- }
11
  *
12
  * @param string $more_link_text Optional. Content for when there is more text.
13
  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
14
+ * @param WP_Post|object|int $post Optional. WP_Post instance or Post ID/object. Default is null.
15
  *
16
+ * @return void
17
  */
18
  function tribe_get_the_content( $more_link_text = null, $strip_teaser = false, $post_id = null ) {
19
  global $post, $wp_version;
30
  $content = get_the_content( $more_link_text, $strip_teaser );
31
  }
32
 
33
+ /**
34
+ * Filters the post content.
35
+ *
36
+ * @since 0.71 of WordPress
37
+ *
38
+ * @param string $content Content of the current post.
39
+ */
40
+ $content = apply_filters( 'the_content', $content );
 
 
 
41
  $content = str_replace( ']]>', ']]&gt;', $content );
42
 
43
  $post = $previous_post;
55
  *
56
  * @param string $more_link_text Optional. Content for when there is more text.
57
  * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false.
58
+ * @param WP_Post|object|int $post Optional. WP_Post instance or Post ID/object. Default is null.
59
  *
60
  * @return void
61
  */
63
  echo tribe_get_the_content( $more_link_text, $strip_teaser, $post_id );
64
  }
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
common/src/functions/utils.php CHANGED
@@ -156,7 +156,7 @@ if ( ! function_exists( 'tribe_get_global_query_object' ) ) {
156
  *
157
  * @since 4.7.8
158
  *
159
- * @return WP_Query The $wp_query, the $wp_the_query if $wp_query empty, null otherwise.
160
  */
161
  function tribe_get_global_query_object() {
162
  global $wp_query;
156
  *
157
  * @since 4.7.8
158
  *
159
+ * @return object The $wp_query, the $wp_the_query if $wp_query empty, null otherwise.
160
  */
161
  function tribe_get_global_query_object() {
162
  global $wp_query;
common/src/modules/components/form/index.js ADDED
@@ -0,0 +1 @@
 
1
+ export { default as Select } from './select';
common/src/modules/components/form/select/component.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { noop, partial, find } from 'lodash';
7
+ import classnames from 'classnames';
8
+ import {
9
+ Dropdown,
10
+ Dashicon,
11
+ } from '@wordpress/components';
12
+ import { ScrollTo, ScrollArea } from 'react-scroll-to';
13
+
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+ import { PreventBlockClose } from '@moderntribe/common/components';
18
+ import './style.pcss';
19
+
20
+ export default class Select extends PureComponent {
21
+ static propTypes = {
22
+ options: PropTypes.shape( {
23
+ label: PropTypes.string,
24
+ value: PropTypes.any,
25
+ } ),
26
+ onOptionClick: PropTypes.func.isRequired,
27
+ optionClassName: PropTypes.string,
28
+ isOpen: PropTypes.bool.isRequired,
29
+ value: PropTypes.any,
30
+ className: PropTypes.string,
31
+ }
32
+
33
+ static defaultProps = {
34
+ onOptionClick: noop,
35
+ isOpen: true,
36
+ optionClassName: '',
37
+ }
38
+
39
+ _onOptionClick = ( onClose, value, e ) => {
40
+ this.props.onOptionClick( value, e );
41
+ onClose();
42
+ }
43
+
44
+ get selected() {
45
+ return find( this.props.options, option => option.value === this.props.value );
46
+ }
47
+
48
+ get label() {
49
+ const selected = this.selected;
50
+ return selected && selected.label;
51
+ }
52
+
53
+ renderOptions = ( onClose ) => (
54
+ this.props.options.map( ( option ) => (
55
+ <button
56
+ className={ classnames(
57
+ 'tribe-common-form-select__options__option',
58
+ this.props.optionClassName
59
+ ) }
60
+ key={ option.value }
61
+ onClick={ partial( this._onOptionClick, onClose, option.value ) }
62
+ role="menuitem"
63
+ type="button"
64
+ value={ option.value }
65
+ >
66
+ { option.label }
67
+ </button>
68
+ ) )
69
+ )
70
+
71
+ renderToggle = ( { onToggle, isOpen } ) => (
72
+ <div className="tribe-common-form-select__toggle">
73
+ <button
74
+ type="button"
75
+ aria-expanded={ isOpen }
76
+ onClick={ onToggle }
77
+ >
78
+ <span>{ this.label }</span>
79
+ <Dashicon
80
+ className="btn--icon"
81
+ icon={ isOpen ? 'arrow-up' : 'arrow-down' }
82
+ />
83
+ </button>
84
+ </div>
85
+ )
86
+
87
+ renderContent = ( { onClose } ) => (
88
+ <ScrollTo>
89
+ { () => (
90
+ <PreventBlockClose>
91
+ <ScrollArea
92
+ role="menu"
93
+ className={ classnames( 'tribe-common-form-select__options' ) }
94
+ >
95
+ { this.renderOptions( onClose ) }
96
+ </ScrollArea>
97
+ </PreventBlockClose>
98
+ ) }
99
+ </ScrollTo>
100
+
101
+ );
102
+
103
+ render() {
104
+ return (
105
+ <Dropdown
106
+ className={ classnames( 'tribe-common-form-select',
107
+ this.props.className
108
+ ) }
109
+ position="bottom center"
110
+ contentClassName="tribe-common-form-select__content"
111
+ renderToggle={ this.renderToggle }
112
+ renderContent={ this.renderContent }
113
+ />
114
+ );
115
+ }
116
+ }
common/src/modules/components/form/select/index.js ADDED
@@ -0,0 +1 @@
 
1
+ export { default } from './component';
common/src/modules/components/form/select/style.pcss ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-common-form-select {
2
+ display: flex;
3
+
4
+ & > div {
5
+ flex: 0 0 auto;
6
+ min-width: 193px;
7
+ }
8
+
9
+ &__toggle {
10
+ background-color: #FFF;
11
+ border-radius: 2px;
12
+ border: 2px solid #EAEBEC;
13
+
14
+ & button {
15
+ align-items: center;
16
+ background-color: #FEFFFE;
17
+ border: none;
18
+ color: #545D66;
19
+ display: flex;
20
+ font-family: Helvetica, sans-serif;
21
+ font-size: 16px;
22
+ font-weight: 400;
23
+ font-weight: normal;
24
+ justify-content: center;
25
+ line-height: 1.5;
26
+ padding: 6px 10px;
27
+ text-align: left;
28
+ text-decoration: none;
29
+ width: 100%;
30
+
31
+ & > span {
32
+ flex: 1;
33
+ }
34
+ }
35
+ }
36
+
37
+ &__options {
38
+
39
+ &__option {
40
+ background: transparent;
41
+ border: 0;
42
+ color: #555d66;
43
+ cursor: pointer;
44
+ display: block;
45
+ line-height: 20px;
46
+ padding: 5px 12px;
47
+ text-align: left;
48
+ width: 100%;
49
+
50
+ &:hover {
51
+ background-color: #009fd4;
52
+ color: #fff;
53
+ }
54
+ }
55
+ }
56
+ }
common/src/modules/components/index.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ /* eslint-disable max-len */
2
+ export { default as PluginBlockHooks } from '@moderntribe/common/components/plugin-block-hooks';
3
+ export { default as PreventBlockClose } from '@moderntribe/common/components/prevent-block-close';
4
+ export * from './form';
5
+
common/src/modules/components/plugin-block-hooks/__tests__/__snapshots__/plugin-block-hooks.spec.js.snap ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`PluginBlockHooks should match snapshot 1`] = `
4
+ <div
5
+ className="tribe-common__plugin-block-hook"
6
+ >
7
+ <InnerBlocks
8
+ template={
9
+ Array [
10
+ Array [
11
+ "tribe/event-datetime",
12
+ Object {},
13
+ ],
14
+ Array [
15
+ "tribe/event-pro-recurring",
16
+ Object {},
17
+ ],
18
+ Array [
19
+ "tribe/event-pro-exclusion",
20
+ Object {},
21
+ ],
22
+ ]
23
+ }
24
+ templateInsertUpdatesSelection={false}
25
+ />
26
+ </div>
27
+ `;
28
+
29
+ exports[`PluginBlockHooks should not hook in unregistered blocks 1`] = `
30
+ <div
31
+ className="tribe-common__plugin-block-hook"
32
+ >
33
+ <InnerBlocks
34
+ template={
35
+ Array [
36
+ Array [
37
+ "tribe/event-datetime",
38
+ Object {},
39
+ ],
40
+ Array [
41
+ "tribe/event-pro-recurring",
42
+ Object {},
43
+ ],
44
+ Array [
45
+ "tribe/event-pro-exclusion",
46
+ Object {},
47
+ ],
48
+ ]
49
+ }
50
+ templateInsertUpdatesSelection={false}
51
+ />
52
+ </div>
53
+ `;
54
+
55
+ exports[`PluginBlockHooks should only render events templates 1`] = `
56
+ <div
57
+ className="tribe-common__plugin-block-hook"
58
+ >
59
+ <InnerBlocks
60
+ template={
61
+ Array [
62
+ Array [
63
+ "tribe/event-datetime",
64
+ Object {},
65
+ ],
66
+ ]
67
+ }
68
+ templateInsertUpdatesSelection={false}
69
+ />
70
+ </div>
71
+ `;
72
+
73
+ exports[`PluginBlockHooks should only render events-pro templates 1`] = `
74
+ <div
75
+ className="tribe-common__plugin-block-hook"
76
+ >
77
+ <InnerBlocks
78
+ template={
79
+ Array [
80
+ Array [
81
+ "tribe/event-pro-recurring",
82
+ Object {},
83
+ ],
84
+ Array [
85
+ "tribe/event-pro-exclusion",
86
+ Object {},
87
+ ],
88
+ ]
89
+ }
90
+ templateInsertUpdatesSelection={false}
91
+ />
92
+ </div>
93
+ `;
94
+
95
+ exports[`PluginBlockHooks should recursively hook blocks 1`] = `
96
+ <div
97
+ className="tribe-common__plugin-block-hook"
98
+ >
99
+ <InnerBlocks
100
+ template={
101
+ Array [
102
+ Array [
103
+ "tribe/event-pro-recurring",
104
+ Object {},
105
+ ],
106
+ Array [
107
+ "tribe/event-cool-container1",
108
+ Object {},
109
+ Array [
110
+ Array [
111
+ "tribe/event-pro-recurring",
112
+ Object {},
113
+ ],
114
+ Array [
115
+ "tribe/event-cool-container2",
116
+ Object {},
117
+ Array [
118
+ Array [
119
+ "tribe/event-pro-recurring",
120
+ Object {},
121
+ ],
122
+ ],
123
+ ],
124
+ ],
125
+ ],
126
+ ]
127
+ }
128
+ templateInsertUpdatesSelection={false}
129
+ />
130
+ </div>
131
+ `;
common/src/modules/components/plugin-block-hooks/__tests__/plugin-block-hooks.spec.js ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+
7
+ /**
8
+ * Internal Dependencies
9
+ */
10
+ import PluginBlockHooks from '../component';
11
+
12
+ jest.mock( '@wordpress/editor', () => ( {
13
+ InnerBlocks: 'InnerBlocks',
14
+ } ) );
15
+ jest.mock( '@wordpress/data', () => ( {
16
+ select: jest.fn( () => ( {
17
+ getBlockTypes: jest.fn( () => ( [
18
+ { name: 'tribe/event-datetime' },
19
+ { name: 'tribe/event-pro-recurring' },
20
+ { name: 'tribe/event-pro-exclusion' },
21
+ { name: 'tribe/event-cool-container1' },
22
+ { name: 'tribe/event-cool-container2' },
23
+ ] ) ),
24
+ } ) ),
25
+ } ) );
26
+
27
+ describe( 'PluginBlockHooks', () => {
28
+ let props;
29
+ beforeEach( () => {
30
+ props = {
31
+ plugins: [ 'events', 'events-pro', 'events-cool' ],
32
+ pluginTemplates: {
33
+ 'events': [
34
+ [ 'tribe/event-datetime', {}],
35
+ ],
36
+ 'events-pro': [
37
+ [ 'tribe/event-pro-recurring', {}],
38
+ [ 'tribe/event-pro-exclusion', {}],
39
+ ],
40
+ },
41
+ };
42
+ } );
43
+
44
+ test( 'should match snapshot', () => {
45
+ const component = renderer.create(
46
+ <PluginBlockHooks { ...props } />
47
+ );
48
+ expect( component.toJSON() ).toMatchSnapshot();
49
+ } );
50
+ test( 'should only render events templates', () => {
51
+ props.plugins = props.plugins.filter( plugin => plugin === 'events' );
52
+ const component = renderer.create(
53
+ <PluginBlockHooks { ...props } />
54
+ );
55
+ expect( component.toJSON() ).toMatchSnapshot();
56
+ } );
57
+ test( 'should only render events-pro templates', () => {
58
+ props.plugins = props.plugins.filter( plugin => plugin === 'events-pro' );
59
+ const component = renderer.create(
60
+ <PluginBlockHooks { ...props } />
61
+ );
62
+ expect( component.toJSON() ).toMatchSnapshot();
63
+ } );
64
+ test( 'should not hook in unregistered blocks', () => {
65
+ props.pluginTemplates.events.push( [ 'i-dont-exist', {}] );
66
+ const component = renderer.create(
67
+ <PluginBlockHooks { ...props } />
68
+ );
69
+ expect( component.toJSON() ).toMatchSnapshot();
70
+ } );
71
+ test( 'should recursively hook blocks', () => {
72
+ delete props.pluginTemplates.events;
73
+ delete props.pluginTemplates[ 'events-pro' ];
74
+ props.pluginTemplates[ 'events-cool' ] = [
75
+ [ 'tribe/event-pro-recurring', {}],
76
+ [ 'tribe/event-cool-container1', {}, [
77
+ [ 'tribe/event-pro-recurring', {}],
78
+ [ 'tribe/event-cool-container2', {}, [
79
+ [ 'tribe/event-pro-recurring', {}],
80
+ [ 'dont-register-me', {}],
81
+ ] ],
82
+ [ 'dont-register-2me', {}],
83
+ ],
84
+ [ 'dont-register-me', {}],
85
+ ],
86
+ ];
87
+ const component = renderer.create(
88
+ <PluginBlockHooks { ...props } />
89
+ );
90
+ expect( component.toJSON() ).toMatchSnapshot();
91
+ } );
92
+ } );
common/src/modules/components/plugin-block-hooks/component.js ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { map, reduce, includes, isArray } from 'lodash';
7
+ import { InnerBlocks } from '@wordpress/editor';
8
+ import { select } from '@wordpress/data';
9
+ import './style.pcss';
10
+
11
+ /**
12
+ * Allows for dynamic plugin templates based on current plugins available
13
+ * utilizing InnerBlocks api
14
+ *
15
+ * @export
16
+ * @class PluginBlockHooks
17
+ * @extends {PureComponent}
18
+ */
19
+ export default class PluginBlockHooks extends PureComponent {
20
+ static propTypes = {
21
+ allowedBlocks: PropTypes.arrayOf( PropTypes.string ),
22
+ layouts: PropTypes.oneOfType( [
23
+ PropTypes.object,
24
+ PropTypes.arrayOf( PropTypes.object ),
25
+ ] ),
26
+ /**
27
+ * Plugins to be used
28
+ */
29
+ plugins: PropTypes.arrayOf( PropTypes.string ).isRequired,
30
+ /**
31
+ * Plugin template structure needed to properly
32
+ * register new templates for each plugin
33
+ *
34
+ *
35
+ * ```js
36
+ * {
37
+ * 'events': [
38
+ * [ 'tribe/event-datetime', {}],
39
+ * ],
40
+ * 'events-pro': [
41
+ * [ 'tribe/event-pro-recurring', {}],
42
+ * [ 'tribe/event-pro-exclusion', {}],
43
+ * ],
44
+ * 'events-cool': [
45
+ * [ 'tribe/event-cool-container', {}, [
46
+ * [ 'tribe/event-cool-column', {}],
47
+ * [ 'tribe/event-cool-column', {}],
48
+ * ]]
49
+ * ],
50
+ * }
51
+ * ```
52
+ */
53
+ pluginTemplates: PropTypes.objectOf( PropTypes.arrayOf( PropTypes.array ) ),
54
+ templateInsertUpdatesSelection: PropTypes.bool.isRequired,
55
+ templateLock: PropTypes.oneOf( [
56
+ 'all',
57
+ 'insert',
58
+ false,
59
+ ] ),
60
+ }
61
+
62
+ static defaultProps = {
63
+ templateInsertUpdatesSelection: false,
64
+ }
65
+
66
+ /**
67
+ * Registered block names from core
68
+ *
69
+ * @readonly
70
+ * @memberof PluginBlockHooks
71
+ * @returns {Array} block names
72
+ */
73
+ get registeredBlockNames() {
74
+ const blockTypes = select( 'core/blocks' ).getBlockTypes();
75
+ return map( blockTypes, block => block.name );
76
+ }
77
+
78
+ /**
79
+ * Template for InnerBlocks
80
+ *
81
+ * @readonly
82
+ * @memberof PluginBlockHooks
83
+ * @returns {Array} template
84
+ */
85
+ get template() {
86
+ const blockNames = this.registeredBlockNames;
87
+ return this.props.plugins.reduce( ( acc, plugin ) => {
88
+ const pluginTemplate = this.props.pluginTemplates[ plugin ];
89
+ if ( pluginTemplate ) {
90
+ // Block needs to be registered, otherwise it's dropped
91
+ const blockTemplates = this.filterPluginTemplates( blockNames, pluginTemplate );
92
+ return [
93
+ ...acc,
94
+ ...blockTemplates,
95
+ ];
96
+ }
97
+ return acc;
98
+ }, [] );
99
+ }
100
+
101
+ /**
102
+ * Recursively filters out unregistered blocks
103
+ *
104
+ * @param {Array} blockNames block names currently registered
105
+ * @param {Array} pluginTemplate Template for plugins
106
+ * @returns {Array} Array of plugin template
107
+ */
108
+ filterPluginTemplates( blockNames, pluginTemplate ) {
109
+ return reduce( pluginTemplate, ( acc, [ name, attributes, nestedBlockTemplates ] ) => {
110
+ if ( includes( blockNames, name ) ) {
111
+ const blockTemplate = isArray( nestedBlockTemplates )
112
+ ? [ name, attributes, /* Recursive call */ this.filterPluginTemplates( blockNames, nestedBlockTemplates ) ] // eslint-disable-line max-len
113
+ : [ name, attributes ];
114
+
115
+ return [
116
+ ...acc,
117
+ blockTemplate,
118
+ ];
119
+ }
120
+
121
+ return acc;
122
+ }, [] );
123
+ }
124
+
125
+ render() {
126
+ return (
127
+ <div className="tribe-common__plugin-block-hook">
128
+ <InnerBlocks
129
+ allowedBlocks={ this.props.allowedBlocks }
130
+ layouts={ this.props.layouts }
131
+ template={ this.template }
132
+ templateInsertUpdatesSelection={ this.props.templateInsertUpdatesSelection }
133
+ templateLock={ this.props.templateLock }
134
+ />
135
+ </div>
136
+ );
137
+ }
138
+ }
common/src/modules/components/plugin-block-hooks/container.js ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { connect } from 'react-redux';
5
+ import { compose } from 'redux';
6
+
7
+ /**
8
+ * Internal Dependencies
9
+ */
10
+ import { selectors } from '@moderntribe/common/data/plugins';
11
+ import { withStore } from '@moderntribe/common/hoc';
12
+ import PluginBlockHooks from './component';
13
+
14
+ const mapStateToProps = ( state, ownProps ) => ( {
15
+ plugins: selectors.getPlugins( state ),
16
+ } );
17
+
18
+ export default compose(
19
+ withStore(),
20
+ connect( mapStateToProps ),
21
+ )( PluginBlockHooks );
common/src/modules/components/plugin-block-hooks/index.js ADDED
@@ -0,0 +1 @@
 
1
+ export { default } from './container';
common/src/modules/components/plugin-block-hooks/style.pcss ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-common__plugin-block-hook {
2
+
3
+ & .editor-inner-blocks {
4
+
5
+ & .editor-block-list__layout {
6
+ margin: 0;
7
+
8
+ & .editor-block-list__block {
9
+ margin: 0;
10
+ max-width: 100% !important;
11
+ padding: 0;
12
+
13
+ &.is-selected > .editor-block-list__block-edit:before,
14
+ &.is-selected-parent > .editor-block-list__block-edit:before,
15
+ &.is-hovered > .editor-block-list__block-edit:before {
16
+ outline: none;
17
+ }
18
+
19
+ & .editor-block-list__block-edit {
20
+ margin: 0;
21
+
22
+ &:before {
23
+ outline: none;
24
+ }
25
+
26
+ & .editor-block-contextual-toolbar {
27
+ display: none;
28
+ }
29
+ }
30
+
31
+ {
32
+ outline: none;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
common/src/modules/components/prevent-block-close/__tests__/component.spec.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import PreventBlockClose from '../component';
3
+
4
+ describe( 'PreventBlockClose', () => {
5
+ test( 'should match snapshot', () => {
6
+ const component = mount(
7
+ <PreventBlockClose>
8
+ <span>Test children</span>
9
+ </PreventBlockClose>
10
+ );
11
+ const child = component.find( 'span' );
12
+ expect( child ).toHaveLength( 1 );
13
+ expect( child.text() ).toEqual( "Test children" );
14
+ } );
15
+ } );
common/src/modules/components/prevent-block-close/component.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+
7
+ /**
8
+ * Internal Dependencies
9
+ */
10
+ import { intercept, EVENT_NAMESPACE } from '@moderntribe/common/hoc/with-block-closer';
11
+
12
+ export default class PreventBlockClose extends PureComponent {
13
+ static propTypes = {
14
+ children: PropTypes.node.isRequired,
15
+ }
16
+
17
+ nodeRef = React.createRef();
18
+
19
+ componentDidMount() {
20
+ this.node.addEventListener( EVENT_NAMESPACE, intercept );
21
+ }
22
+
23
+ componentWillUnmount() {
24
+ this.node.removeEventListener( EVENT_NAMESPACE, intercept );
25
+ }
26
+
27
+ get node() {
28
+ return this.nodeRef.current;
29
+ }
30
+
31
+ render() {
32
+ return (
33
+ <div ref={ this.nodeRef }>
34
+ { this.props.children }
35
+ </div>
36
+ );
37
+ }
38
+ }
common/src/modules/components/prevent-block-close/index.js ADDED
@@ -0,0 +1 @@
 
1
+ export { default } from './component';
common/src/modules/data/__tests__/utils.test.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+
6
+ describe( 'prefix', () => {
7
+ it( 'Should return the prefix', () => {
8
+ expect( PREFIX_COMMON_STORE ).toBe('@@MT/COMMON');
9
+ } );
10
+ } );
common/src/modules/data/editor/post-types.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ export const EVENT = 'tribe_events';
2
+ export const VENUE = 'tribe_venue';
3
+ export const ORGANIZER = 'tribe_organizer';
common/src/modules/data/forms/__tests__/__snapshots__/actions.test.js.snap ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`[STORE] - Form actions Add volatile action 1`] = `
4
+ Object {
5
+ "payload": Object {
6
+ "id": 20,
7
+ },
8
+ "type": "@@MT/COMMON/ADD_VOLATILE_ID",
9
+ }
10
+ `;
11
+
12
+ exports[`[STORE] - Form actions Clear form action 1`] = `
13
+ Object {
14
+ "payload": Object {
15
+ "id": 20,
16
+ },
17
+ "type": "@@MT/COMMON/CLEAR_FORM",
18
+ }
19
+ `;
20
+
21
+ exports[`[STORE] - Form actions Create draft entry 1`] = `
22
+ Object {
23
+ "payload": Object {
24
+ "fields": Object {
25
+ "title": "Modern Tribe",
26
+ },
27
+ "id": 20,
28
+ },
29
+ "type": "@@MT/COMMON/CREATE_FORM_DRAFT",
30
+ }
31
+ `;
32
+
33
+ exports[`[STORE] - Form actions Edit the entry action 1`] = `
34
+ Object {
35
+ "payload": Object {
36
+ "fields": Object {
37
+ "title": "Tribe",
38
+ },
39
+ "id": 20,
40
+ },
41
+ "type": "@@MT/COMMON/EDIT_FORM_ENTRY",
42
+ }
43
+ `;
44
+
45
+ exports[`[STORE] - Form actions Register form action 1`] = `
46
+ Object {
47
+ "payload": Object {
48
+ "id": 20,
49
+ "type": "tribe_organizers",
50
+ },
51
+ "type": "@@MT/COMMON/ADD_FORM",
52
+ }
53
+ `;
54
+
55
+ exports[`[STORE] - Form actions Remove volatile action 1`] = `
56
+ Object {
57
+ "payload": Object {
58
+ "id": 20,
59
+ },
60
+ "type": "@@MT/COMMON/REMOVE_VOLATILE_ID",
61
+ }
62
+ `;
63
+
64
+ exports[`[STORE] - Form actions Set saving action 1`] = `
65
+ Object {
66
+ "payload": Object {
67
+ "id": 20,
68
+ "saving": true,
69
+ },
70
+ "type": "@@MT/COMMON/SET_SAVING_FORM",
71
+ }
72
+ `;
73
+
74
+ exports[`[STORE] - Form actions Set saving action 2`] = `
75
+ Object {
76
+ "payload": Object {
77
+ "id": 20,
78
+ "saving": false,
79
+ },
80
+ "type": "@@MT/COMMON/SET_SAVING_FORM",
81
+ }
82
+ `;
83
+
84
+ exports[`[STORE] - Form actions Set submit form 1`] = `
85
+ Object {
86
+ "payload": Object {
87
+ "id": 20,
88
+ },
89
+ "type": "@@MT/COMMON/SUBMIT_FORM",
90
+ }
91
+ `;
92
+
93
+ exports[`[STORE] - form thunk actions Maybe remove entry action with details 1`] = `
94
+ Array [
95
+ Object {
96
+ "meta": Object {
97
+ "actions": Object {
98
+ "success": [Function],
99
+ },
100
+ "path": "tribe_venue/21",
101
+ },
102
+ "type": "@@MT/COMMON/WP_REQUEST",
103
+ },
104
+ ]
105
+ `;
106
+
107
+ exports[`[STORE] - form thunk actions Maybe remove entry action without details 1`] = `Array []`;
108
+
109
+ exports[`[STORE] - form thunk actions Send the form action when creating 1`] = `
110
+ Array [
111
+ Object {
112
+ "meta": Object {
113
+ "actions": Object {
114
+ "error": [Function],
115
+ "start": [Function],
116
+ "success": [Function],
117
+ },
118
+ "params": Object {
119
+ "body": "{\\"title\\":\\"Modern Tribe\\"}",
120
+ "method": "POST",
121
+ },
122
+ "path": "tribe_organizer",
123
+ },
124
+ "type": "@@MT/COMMON/WP_REQUEST",
125
+ },
126
+ ]
127
+ `;
128
+
129
+ exports[`[STORE] - form thunk actions Send the form when editing 1`] = `
130
+ Array [
131
+ Object {
132
+ "meta": Object {
133
+ "actions": Object {
134
+ "error": [Function],
135
+ "start": [Function],
136
+ "success": [Function],
137
+ },
138
+ "params": Object {
139
+ "body": "{\\"title\\":\\"Tribe\\"}",
140
+ "method": "PUT",
141
+ },
142
+ "path": "tribe_venue/21",
143
+ },
144
+ "type": "@@MT/COMMON/WP_REQUEST",
145
+ },
146
+ ]
147
+ `;
common/src/modules/data/forms/__tests__/actions.test.js ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import configureStore from 'redux-mock-store';
5
+ import thunk from 'redux-thunk';
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { actions } from '@moderntribe/common/data/forms';
10
+
11
+ const middlewares = [ thunk ];
12
+ const mockStore = configureStore( middlewares );
13
+
14
+ describe( '[STORE] - Form actions', () => {
15
+ test( 'Register form action', () => {
16
+ expect( actions.registerForm( 20, 'tribe_organizers' ) ).toMatchSnapshot();
17
+ } );
18
+
19
+ test( 'Create draft entry', () => {
20
+ expect( actions.createDraft( 20, { title: 'Modern Tribe' } ) ).toMatchSnapshot();
21
+ } );
22
+
23
+ test( 'Edit the entry action', () => {
24
+ expect( actions.editEntry( 20, { title: 'Tribe' } ) ).toMatchSnapshot();
25
+ } );
26
+
27
+ test( 'Clear form action', () => {
28
+ expect( actions.clearForm( 20 ) ).toMatchSnapshot();
29
+ } );
30
+
31
+ test( 'Set submit form', () => {
32
+ expect( actions.setSubmit( 20 ) ).toMatchSnapshot();
33
+ } );
34
+
35
+ test( 'Set saving action', () => {
36
+ expect( actions.setSaving( 20, true ) ).toMatchSnapshot();
37
+ expect( actions.setSaving( 20, false ) ).toMatchSnapshot();
38
+ } );
39
+
40
+ test( 'Add volatile action', () => {
41
+ expect( actions.addVolatile( 20 ) ).toMatchSnapshot();
42
+ } );
43
+
44
+ test( 'Remove volatile action', () => {
45
+ expect( actions.removeVolatile( 20 ) ).toMatchSnapshot();
46
+ } );
47
+ } );
48
+
49
+ describe( '[STORE] - form thunk actions', () => {
50
+ let store = {};
51
+ beforeAll( () => {
52
+ store = mockStore( {
53
+ events: {
54
+ },
55
+ forms: {
56
+ byId: {
57
+ 20: {
58
+ create: true,
59
+ type: 'tribe_organizer',
60
+ fields: {},
61
+ },
62
+ 21: {
63
+ create: false,
64
+ type: 'tribe_venue',
65
+ fields: {
66
+ id: 21,
67
+ },
68
+ },
69
+ },
70
+ volatile: [],
71
+ },
72
+ } );
73
+ } );
74
+
75
+ afterEach( () => store.clearActions() );
76
+
77
+ test( 'Send the form action when creating', () => {
78
+ store.dispatch( actions.sendForm( 20, { title: 'Modern Tribe' } ) );
79
+ expect( store.getActions() ).toMatchSnapshot();
80
+ } );
81
+
82
+ test( 'Send the form when editing', () => {
83
+ store.dispatch( actions.sendForm( 21, { title: 'Tribe' } ) );
84
+ expect( store.getActions() ).toMatchSnapshot();
85
+ } );
86
+
87
+ test( 'Maybe remove entry action without details', () => {
88
+ store.dispatch( actions.maybeRemoveEntry( 20, {} ) );
89
+ expect( store.getActions() ).toMatchSnapshot();
90
+ } );
91
+
92
+ test( 'Maybe remove entry action with details', () => {
93
+ store.dispatch( actions.maybeRemoveEntry( 21, { id: 21, title: 'Modern Tribe' } ) );
94
+ expect( store.getActions() ).toMatchSnapshot();
95
+ } );
96
+ } );
common/src/modules/data/forms/__tests__/reducer.test.js ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import reducer, { actions } from '@moderntribe/common/data/forms';
5
+ import form, { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
6
+
7
+ jest.mock( '@moderntribe/common/data/forms/reducers/form', () => {
8
+ const original = require.requireActual( '@moderntribe/common/data/forms/reducers/form' );
9
+ return {
10
+ __esModule: true,
11
+ ...original,
12
+ default: jest.fn( ( state = original.DEFAULT_STATE ) => state ),
13
+ };
14
+ } );
15
+
16
+ jest.mock( '@moderntribe/common/data/forms/reducers/volatile', () => {
17
+ return {
18
+ __esModule: true,
19
+ default: jest.fn( ( state = [] ) => state ),
20
+ };
21
+ } );
22
+
23
+ describe( '[STORE] - form reducer', () => {
24
+ beforeEach( () => {
25
+ form.mockClear();
26
+ } );
27
+
28
+ it( 'Should return the default state', () => {
29
+ expect( reducer( undefined, {} ) ).toEqual( { byId: {}, volatile: [] } );
30
+ } );
31
+
32
+ it( 'Should add a new form', () => {
33
+ const state = {
34
+ byId: {},
35
+ volatile: [],
36
+ };
37
+ expect( reducer( state, actions.registerForm( 20, 'tribe_organizer' ) ) ).toEqual( {
38
+ byId: {
39
+ 20: DEFAULT_STATE,
40
+ },
41
+ volatile: [],
42
+ } );
43
+ } );
44
+
45
+ it( 'Should pass the actions to the child reducer when block not present', () => {
46
+ const groupAction = [
47
+ actions.registerForm( 10, 'tribe_venue' ),
48
+ actions.editEntry( 20, { title: 'Modern tribe' } ),
49
+ actions.createDraft( 20, { title: 'Tribe' } ),
50
+ actions.setSubmit( 20 ),
51
+ actions.clearForm( 20 ),
52
+ actions.setSaving( 20, true ),
53
+ ];
54
+
55
+ groupAction.forEach( ( action ) => {
56
+ reducer( {}, action );
57
+ expect( form ).toHaveBeenCalledWith( undefined, action );
58
+ expect( form ).toHaveBeenCalledTimes( 1 );
59
+ form.mockClear();
60
+ } );
61
+ } );
62
+
63
+ it( 'It should pass the block to the child reducer', () => {
64
+ const groupAction = [
65
+ actions.registerForm( 10, 'tribe_venue' ),
66
+ actions.editEntry( 20, { title: 'Modern tribe' } ),
67
+ actions.createDraft( 20, { title: 'Tribe' } ),
68
+ actions.setSubmit( 20 ),
69
+ actions.clearForm( 20 ),
70
+ actions.setSaving( 20, true ),
71
+ ];
72
+
73
+ const state = {
74
+ byId: {
75
+ 10: DEFAULT_STATE,
76
+ 20: DEFAULT_STATE,
77
+ },
78
+ };
79
+
80
+ groupAction.forEach( ( action ) => {
81
+ reducer( state, action );
82
+ expect( form ).toHaveBeenCalledWith( DEFAULT_STATE, action );
83
+ expect( form ).toHaveBeenCalledTimes( 1 );
84
+ form.mockClear();
85
+ } );
86
+ } );
87
+ } );
88
+
common/src/modules/data/forms/__tests__/selectors.test.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { selectors } from '@moderntribe/common/data/forms';
5
+ import { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
6
+
7
+ const state = {
8
+ events: {
9
+ },
10
+ forms: {
11
+ byId: {
12
+ 99: {
13
+ ...DEFAULT_STATE,
14
+ type: 'tribe_organizers',
15
+ create: true,
16
+ fields: {
17
+ name: 'Modern Tribe',
18
+ description: 'The Next Generation of Digital Agency',
19
+ },
20
+ },
21
+ 100: {
22
+ ...DEFAULT_STATE,
23
+ edit: true,
24
+ },
25
+ 101: {
26
+ ...DEFAULT_STATE,
27
+ submit: true,
28
+ },
29
+ 102: {
30
+ ...DEFAULT_STATE,
31
+ saving: true,
32
+ },
33
+ },
34
+ volatile: [ 100, 102 ],
35
+ },
36
+ };
37
+
38
+ describe( '[STORE] - Forms selectors', () => {
39
+ it( 'Should return the forms blocks', () => {
40
+ expect( selectors.formSelector( state, { name: 99 } ) ).toEqual( state.forms.byId[ '99' ] );
41
+ expect( selectors.formSelector( state, { name: 100 } ) ).toEqual( state.forms.byId[ '100' ] );
42
+ expect( selectors.formSelector( state, { name: 200 } ) ).toBe( undefined );
43
+ } );
44
+
45
+ it( 'Should return the form type', () => {
46
+ expect( selectors.getFormType( state, { name: 99 } ) ).toBe( 'tribe_organizers' );
47
+ expect( selectors.getFormType( state, { name: 100 } ) ).toBe( DEFAULT_STATE.type );
48
+ } );
49
+
50
+ it( 'Should return the edit value', () => {
51
+ expect( selectors.getFormEdit( state, { name: 100 } ) ).toBe( true );
52
+ expect( selectors.getFormEdit( state, { name: 99 } ) ).toBe( false );
53
+ expect( selectors.getFormEdit( state, { name: 101 } ) ).toBe( false );
54
+ expect( selectors.getFormEdit( state, { name: 102 } ) ).toBe( false );
55
+ } );
56
+
57
+ it( 'Should return the create value', () => {
58
+ expect( selectors.getFormCreate( state, { name: 99 } ) ).toBe( true );
59
+ expect( selectors.getFormCreate( state, { name: 100 } ) ).toBe( false );
60
+ expect( selectors.getFormCreate( state, { name: 101 } ) ).toBe( false );
61
+ expect( selectors.getFormCreate( state, { name: 102 } ) ).toBe( false );
62
+ } );
63
+
64
+ it( 'Should return the submit value', () => {
65
+ expect( selectors.getFormSubmit( state, { name: 101 } ) ).toBe( true );
66
+ expect( selectors.getFormSubmit( state, { name: 99 } ) ).toBe( false );
67
+ expect( selectors.getFormSubmit( state, { name: 100 } ) ).toBe( false );
68
+ expect( selectors.getFormSubmit( state, { name: 102 } ) ).toBe( false );
69
+ } );
70
+
71
+ it( 'Should return the saving value', () => {
72
+ expect( selectors.getFormSaving( state, { name: 102 } ) ).toBe( true );
73
+ expect( selectors.getFormSaving( state, { name: 99 } ) ).toBe( false );
74
+ expect( selectors.getFormSaving( state, { name: 100 } ) ).toBe( false );
75
+ expect( selectors.getFormSaving( state, { name: 101 } ) ).toBe( false );
76
+ } );
77
+
78
+ it( 'Should return the form fields', () => {
79
+ expect( selectors.getFormFields( state, { name: 99 } ) )
80
+ .toEqual( state.forms.byId[ '99' ].fields );
81
+ expect( selectors.getFormFields( state, { name: 100 } ) ).toEqual( {} );
82
+ expect( selectors.getFormFields( state, { name: 101 } ) ).toEqual( {} );
83
+ expect( selectors.getFormFields( state, { name: 102 } ) ).toEqual( {} );
84
+ } );
85
+
86
+ it( 'Should return the volatile fields', () => {
87
+ expect( selectors.getVolatile( state ) ).toEqual( [ 100, 102 ] );
88
+ } );
89
+ } );
common/src/modules/data/forms/__tests__/types.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { types } from '@moderntribe/common/data/forms';
5
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
6
+
7
+ describe( '[STORE] - Form types', () => {
8
+ it( 'Should return the types values', () => {
9
+ expect( types.REMOVE_VOLATILE_ID ).toBe( `${ PREFIX_COMMON_STORE }/REMOVE_VOLATILE_ID` );
10
+ expect( types.ADD_VOLATILE_ID ).toBe( `${ PREFIX_COMMON_STORE }/ADD_VOLATILE_ID` );
11
+ expect( types.ADD_FORM ).toBe( `${ PREFIX_COMMON_STORE }/ADD_FORM` );
12
+ expect( types.SET_SAVING_FORM ).toBe( `${ PREFIX_COMMON_STORE }/SET_SAVING_FORM` );
13
+ expect( types.SUBMIT_FORM ).toBe( `${ PREFIX_COMMON_STORE }/SUBMIT_FORM` );
14
+ expect( types.CREATE_FORM_DRAFT ).toBe( `${ PREFIX_COMMON_STORE }/CREATE_FORM_DRAFT` );
15
+ expect( types.EDIT_FORM_ENTRY ).toBe( `${ PREFIX_COMMON_STORE }/EDIT_FORM_ENTRY` );
16
+ expect( types.SET_FORM_FIELDS ).toBe( `${ PREFIX_COMMON_STORE }/SET_FORM_FIELDS` );
17
+ expect( types.CLEAR_FORM ).toBe( `${ PREFIX_COMMON_STORE }/CLEAR_FORM` );
18
+ } );
19
+ } );
common/src/modules/data/forms/actions.js ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { isEmpty, get } from 'lodash';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { actions as requestActions } from '@moderntribe/common/store/middlewares/request';
10
+
11
+ import * as types from './types';
12
+ import * as selectors from './selectors';
13
+
14
+ export const registerForm = ( id, type ) => ( {
15
+ type: types.ADD_FORM,
16
+ payload: {
17
+ id,
18
+ type,
19
+ },
20
+ } );
21
+
22
+ export const clearForm = ( id ) => ( {
23
+ type: types.CLEAR_FORM,
24
+ payload: {
25
+ id,
26
+ },
27
+ } );
28
+
29
+ export const createDraft = ( id, fields ) => ( {
30
+ type: types.CREATE_FORM_DRAFT,
31
+ payload: {
32
+ id,
33
+ fields,
34
+ },
35
+ } );
36
+
37
+ export const editEntry = ( id, fields ) => ( {
38
+ type: types.EDIT_FORM_ENTRY,
39
+ payload: {
40
+ id,
41
+ fields,
42
+ },
43
+ } );
44
+
45
+ export const setSubmit = ( id ) => ( {
46
+ type: types.SUBMIT_FORM,
47
+ payload: {
48
+ id,
49
+ },
50
+ } );
51
+
52
+ export const setSaving = ( id, saving ) => ( {
53
+ type: types.SET_SAVING_FORM,
54
+ payload: {
55
+ id,
56
+ saving,
57
+ },
58
+ } );
59
+
60
+ export const addVolatile = ( id ) => ( {
61
+ type: types.ADD_VOLATILE_ID,
62
+ payload: {
63
+ id,
64
+ },
65
+ } );
66
+
67
+ export const removeVolatile = ( id ) => ( {
68
+ type: types.REMOVE_VOLATILE_ID,
69
+ payload: {
70
+ id,
71
+ },
72
+ } );
73
+
74
+ export const sendForm = ( id, fields = {}, completed ) => ( dispatch, getState ) => {
75
+ const state = getState();
76
+ const props = { name: id };
77
+ const type = selectors.getFormType( state, props );
78
+ const create = selectors.getFormCreate( state, props );
79
+ const details = selectors.getFormFields( state, props );
80
+ const saving = selectors.getFormSaving( state, props );
81
+
82
+ if ( saving ) {
83
+ return;
84
+ }
85
+
86
+ const path = create
87
+ ? `${ type }`
88
+ : `${ type }/${ details.id }`;
89
+
90
+ const options = {
91
+ path,
92
+ params: {
93
+ method: create ? 'POST' : 'PUT',
94
+ body: JSON.stringify( fields ),
95
+ },
96
+ actions: {
97
+ start: () => dispatch( setSaving( id, true ) ),
98
+ success: ( { body } ) => {
99
+ const postID = get( body, 'id', '' );
100
+
101
+ if ( create && postID ) {
102
+ dispatch( addVolatile( postID ) );
103
+ }
104
+ completed( body );
105
+ dispatch( clearForm( id ) );
106
+ dispatch( setSaving( id, false ) );
107
+ },
108
+ error: () => {
109
+ dispatch( clearForm( id ) );
110
+ dispatch( setSaving( id, false ) );
111
+ },
112
+ },
113
+ };
114
+ dispatch( requestActions.wpRequest( options ) );
115
+ };
116
+
117
+ const deleteEntry = ( dispatch ) => ( path ) => ( { body } ) => {
118
+ const { id, status } = body;
119
+
120
+ if ( 'draft' !== status ) {
121
+ dispatch( removeVolatile( id ) );
122
+ return;
123
+ }
124
+
125
+ const options = {
126
+ path,
127
+ params: {
128
+ method: 'DELETE',
129
+ },
130
+ actions: {
131
+ success: () => dispatch( removeVolatile( id ) ),
132
+ },
133
+ };
134
+ dispatch( requestActions.wpRequest( options ) );
135
+ };
136
+
137
+ export const maybeRemoveEntry = ( id, details = {} ) => ( dispatch, getState ) => {
138
+ const state = getState();
139
+ const type = selectors.getFormType( state, { name: id } );
140
+
141
+ if ( isEmpty( details ) ) {
142
+ return;
143
+ }
144
+
145
+ const path = `${ type }/${ details.id }`;
146
+ const options = {
147
+ path,
148
+ actions: {
149
+ success: deleteEntry( dispatch )( path ),
150
+ },
151
+ };
152
+ dispatch( requestActions.wpRequest( options ) );
153
+ };
common/src/modules/data/forms/index.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import reducer from './reducer';
5
+
6
+ import * as types from './types';
7
+ import * as actions from './actions';
8
+ import * as selectors from './selectors';
9
+
10
+ export default reducer;
11
+
12
+ export { types, actions, selectors };
common/src/modules/data/forms/reducer.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { combineReducers } from 'redux';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import * as types from './types';
10
+ import { form, volatile } from './reducers';
11
+
12
+ const byId = ( state = {}, action ) => {
13
+ switch ( action.type ) {
14
+ case types.ADD_FORM:
15
+ case types.CLEAR_FORM:
16
+ case types.SET_FORM_FIELDS:
17
+ case types.CREATE_FORM_DRAFT:
18
+ case types.EDIT_FORM_ENTRY:
19
+ case types.SUBMIT_FORM:
20
+ case types.SET_SAVING_FORM:
21
+ return {
22
+ ...state,
23
+ [ action.payload.id ]: form( state[ action.payload.id ], action ),
24
+ };
25
+ default:
26
+ return state;
27
+ }
28
+ };
29
+
30
+ export default combineReducers( {
31
+ byId,
32
+ volatile,
33
+ } );
common/src/modules/data/forms/reducers/__tests__/__snapshots__/form.test.js.snap ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`[STORE] - form reducer Should add a new form 1`] = `
4
+ Object {
5
+ "create": false,
6
+ "edit": false,
7
+ "fields": Object {},
8
+ "saving": false,
9
+ "submit": false,
10
+ "type": "tribe_organizers",
11
+ }
12
+ `;
13
+
14
+ exports[`[STORE] - form reducer Should clear a form 1`] = `
15
+ Object {
16
+ "create": false,
17
+ "edit": false,
18
+ "fields": Object {},
19
+ "saving": false,
20
+ "submit": false,
21
+ "type": "tribe_organizers",
22
+ }
23
+ `;
24
+
25
+ exports[`[STORE] - form reducer Should create a form draft 1`] = `
26
+ Object {
27
+ "create": true,
28
+ "edit": false,
29
+ "fields": Object {
30
+ "id": 20,
31
+ "title": "Modern Tribe",
32
+ },
33
+ "saving": false,
34
+ "submit": false,
35
+ "type": "tribe_events",
36
+ }
37
+ `;
38
+
39
+ exports[`[STORE] - form reducer Should edit the form entry 1`] = `
40
+ Object {
41
+ "create": false,
42
+ "edit": true,
43
+ "fields": Object {
44
+ "description": "",
45
+ "title": "Tribe",
46
+ },
47
+ "saving": false,
48
+ "submit": false,
49
+ "type": "tribe_events",
50
+ }
51
+ `;
52
+
53
+ exports[`[STORE] - form reducer Should submit the form 1`] = `
54
+ Object {
55
+ "create": false,
56
+ "edit": false,
57
+ "fields": Object {},
58
+ "saving": false,
59
+ "submit": true,
60
+ "type": "tribe_events",
61
+ }
62
+ `;
63
+
64
+ exports[`[STORE] - form reducer Should toggle the saving form flag 1`] = `
65
+ Object {
66
+ "create": false,
67
+ "edit": false,
68
+ "fields": Object {},
69
+ "saving": true,
70
+ "submit": false,
71
+ "type": "tribe_events",
72
+ }
73
+ `;
74
+
75
+ exports[`[STORE] - form reducer Should toggle the saving form flag 2`] = `
76
+ Object {
77
+ "create": false,
78
+ "edit": false,
79
+ "fields": Object {},
80
+ "saving": false,
81
+ "submit": false,
82
+ "type": "tribe_events",
83
+ }
84
+ `;
common/src/modules/data/forms/reducers/__tests__/form.test.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { form } from '@moderntribe/common/data/forms/reducers';
5
+ import { actions } from '@moderntribe/common/data/forms';
6
+ import { DEFAULT_STATE } from '@moderntribe/common/data/forms/reducers/form';
7
+
8
+ describe( '[STORE] - form reducer', () => {
9
+ it( 'Should return the default state', () => {
10
+ expect( form( undefined, {} ) ).toEqual( DEFAULT_STATE );
11
+ } );
12
+
13
+ it( 'Should add a new form', () => {
14
+ expect( form( DEFAULT_STATE, actions.registerForm( 20, 'tribe_organizers' ) ) ).toMatchSnapshot();
15
+ } );
16
+
17
+ it( 'Should clear a form', () => {
18
+ const state = {
19
+ ...DEFAULT_STATE,
20
+ type: 'tribe_organizers',
21
+ };
22
+ expect( form( state, actions.clearForm( 20 ) ) ).toMatchSnapshot();
23
+ } );
24
+
25
+ it( 'Should create a form draft', () => {
26
+ const fields = {
27
+ id: 20,
28
+ title: 'Modern Tribe',
29
+ };
30
+ expect( form( DEFAULT_STATE, actions.createDraft( 20, fields ) ) ).toMatchSnapshot();
31
+ } );
32
+
33
+ it( 'Should toggle the saving form flag', () => {
34
+ expect( form( DEFAULT_STATE, actions.setSaving( 20, true ) ) ).toMatchSnapshot();
35
+ expect( form( DEFAULT_STATE, actions.setSaving( 20, false ) ) ).toMatchSnapshot();
36
+ } );
37
+
38
+ it( 'Should edit the form entry', () => {
39
+ const fields = {
40
+ title: 'Tribe',
41
+ description: '',
42
+ };
43
+ expect( form( DEFAULT_STATE, actions.editEntry( 20, fields ) ) ).toMatchSnapshot();
44
+ } );
45
+
46
+ it( 'Should submit the form', () => {
47
+ expect( form( DEFAULT_STATE, actions.setSubmit( 20 ) ) ).toMatchSnapshot();
48
+ } );
49
+ } );
common/src/modules/data/forms/reducers/__tests__/volatile.test.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { volatile } from '@moderntribe/common/data/forms/reducers';
5
+ import { actions } from '@moderntribe/common/data/forms';
6
+
7
+ describe( '[STORE] - Volatile reducer', () => {
8
+ it( 'Should return the default state', () => {
9
+ expect( volatile( undefined, {} ) ).toEqual( [] );
10
+ } );
11
+
12
+ it( 'Should add a new volatile value', () => {
13
+ expect( volatile( [], actions.addVolatile( 20 ) ) ).toEqual( [ 20 ] );
14
+ expect( volatile( [ 20 ], actions.addVolatile( 10 ) ) ).toEqual( [ 20, 10 ] );
15
+ } );
16
+
17
+ it( 'Should remove a volatile value', () => {
18
+ expect( volatile( [], actions.removeVolatile( 20 ) ) ).toEqual( [] );
19
+ expect( volatile( [ 20, 10 ], actions.removeVolatile( 20 ) ) ).toEqual( [ 10 ] );
20
+ expect( volatile( [ 20, 10 ], actions.removeVolatile( 10 ) ) ).toEqual( [ 20 ] );
21
+ expect( volatile( [ 10 ], actions.removeVolatile( 10 ) ) ).toEqual( [] );
22
+ } );
23
+ } );
common/src/modules/data/forms/reducers/form.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { EVENT } from '@moderntribe/common/data/editor/post-types';
5
+ import * as types from '@moderntribe/common/data/forms/types';
6
+
7
+ export const DEFAULT_STATE = {
8
+ edit: false,
9
+ create: false,
10
+ submit: false,
11
+ saving: false,
12
+ fields: {},
13
+ type: EVENT,
14
+ };
15
+
16
+ export default ( state = DEFAULT_STATE, action ) => {
17
+ switch ( action.type ) {
18
+ case types.ADD_FORM:
19
+ return {
20
+ ...state,
21
+ type: action.payload.type,
22
+ };
23
+ case types.CLEAR_FORM:
24
+ return {
25
+ ...state,
26
+ ...DEFAULT_STATE,
27
+ type: state.type,
28
+ };
29
+ case types.CREATE_FORM_DRAFT:
30
+ return {
31
+ ...state,
32
+ submit: false,
33
+ edit: false,
34
+ create: true,
35
+ fields: action.payload.fields,
36
+ };
37
+ case types.SET_SAVING_FORM:
38
+ return {
39
+ ...state,
40
+ saving: action.payload.saving,
41
+ };
42
+ case types.EDIT_FORM_ENTRY:
43
+ return {
44
+ ...state,
45
+ create: false,
46
+ submit: false,
47
+ edit: true,
48
+ fields: action.payload.fields,
49
+ };
50
+ case types.SUBMIT_FORM:
51
+ return {
52
+ ...state,
53
+ submit: true,
54
+ };
55
+ default:
56
+ return state;
57
+ }
58
+ };
common/src/modules/data/forms/reducers/index.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ export { default as form } from './form';
2
+ export { default as volatile } from './volatile';
common/src/modules/data/forms/reducers/volatile.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import * as types from '@moderntribe/common/data/forms/types';
5
+
6
+ export default ( state = [], action ) => {
7
+ switch ( action.type ) {
8
+ case types.ADD_VOLATILE_ID:
9
+ return [ ...state, action.payload.id ];
10
+ case types.REMOVE_VOLATILE_ID:
11
+ return state.filter( ( id ) => id !== action.payload.id );
12
+ default:
13
+ return state;
14
+ }
15
+ };
common/src/modules/data/forms/selectors.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { createSelector } from 'reselect';
5
+ import { DEFAULT_STATE } from './reducers/form';
6
+
7
+ export const formSelector = ( state, props ) => state.forms.byId[ props.name ];
8
+
9
+ export const getFormType = createSelector(
10
+ [ formSelector ],
11
+ ( block ) => block ? block.type : DEFAULT_STATE.type
12
+ );
13
+
14
+ export const getFormEdit = createSelector(
15
+ [ formSelector ],
16
+ ( block ) => block ? block.edit : DEFAULT_STATE.edit
17
+ );
18
+
19
+ export const getFormCreate = createSelector(
20
+ [ formSelector ],
21
+ ( block ) => block ? block.create : DEFAULT_STATE.create,
22
+ );
23
+
24
+ export const getFormSubmit = createSelector(
25
+ [ formSelector ],
26
+ ( block ) => block ? block.submit : DEFAULT_STATE.submit
27
+ );
28
+
29
+ export const getFormFields = createSelector(
30
+ [ formSelector ],
31
+ ( block ) => block ? block.fields : DEFAULT_STATE.fields,
32
+ );
33
+
34
+ export const getFormSaving = createSelector(
35
+ [ formSelector ],
36
+ ( block ) => block ? block.saving : DEFAULT_STATE.saving
37
+ );
38
+
39
+ export const getVolatile = ( state ) => state.forms.volatile;
common/src/modules/data/forms/types.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+
6
+ export const ADD_FORM = `${ PREFIX_COMMON_STORE }/ADD_FORM`;
7
+ export const SET_FORM_FIELDS = `${ PREFIX_COMMON_STORE }/SET_FORM_FIELDS`;
8
+ export const CREATE_FORM_DRAFT = `${ PREFIX_COMMON_STORE }/CREATE_FORM_DRAFT`;
9
+ export const EDIT_FORM_ENTRY = `${ PREFIX_COMMON_STORE }/EDIT_FORM_ENTRY`;
10
+ export const SUBMIT_FORM = `${ PREFIX_COMMON_STORE }/SUBMIT_FORM`;
11
+ export const CLEAR_FORM = `${ PREFIX_COMMON_STORE }/CLEAR_FORM`;
12
+ export const SET_SAVING_FORM = `${ PREFIX_COMMON_STORE }/SET_SAVING_FORM`;
13
+
14
+ export const ADD_VOLATILE_ID = `${ PREFIX_COMMON_STORE }/ADD_VOLATILE_ID`;
15
+ export const REMOVE_VOLATILE_ID = `${ PREFIX_COMMON_STORE }/REMOVE_VOLATILE_ID`;
common/src/modules/data/index.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal Dependencies
3
+ */
4
+ import * as editor from './editor/post-types';
5
+ import * as forms from './forms';
6
+ import * as plugins from './plugins';
7
+ export { default } from './reducers';
8
+
9
+ export { editor, forms, plugins };
common/src/modules/data/plugins/__tests__/__snapshots__/actions.test.js.snap ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Plugin actions Add Plugin 1`] = `
4
+ Object {
5
+ "payload": Object {
6
+ "name": "events",
7
+ },
8
+ "type": "@@MT/COMMON/ADD_PLUGIN",
9
+ }
10
+ `;
11
+
12
+ exports[`Plugin actions Remove Plugin 1`] = `
13
+ Object {
14
+ "payload": Object {
15
+ "name": "events",
16
+ },
17
+ "type": "@@MT/COMMON/REMOVE_PLUGIN",
18
+ }
19
+ `;
common/src/modules/data/plugins/__tests__/actions.test.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { actions } from '@moderntribe/common/data/plugins';
5
+
6
+ describe( 'Plugin actions', () => {
7
+ test( 'Add Plugin', () => {
8
+ expect( actions.addPlugin( 'events' ) ).toMatchSnapshot();
9
+ } );
10
+
11
+ test( 'Remove Plugin', () => {
12
+ expect( actions.removePlugin( 'events' ) ).toMatchSnapshot();
13
+ } );
14
+ } );
common/src/modules/data/plugins/__tests__/reducer.test.js ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import reducer, { actions } from '@moderntribe/common/data/plugins';
5
+
6
+ describe( 'Plugins reducer', () => {
7
+ it( 'Should return the default state', () => {
8
+ expect( reducer( undefined, {} ) ).toEqual( [] );
9
+ } );
10
+
11
+ it( 'Should add a new plugin as active', () => {
12
+ expect( reducer( {}, actions.addPlugin( 'events' ) ) ).toEqual( [ 'events' ] );
13
+ } );
14
+
15
+ it( 'Should avoid adding duplicates entries', () => {
16
+ const state = reducer( {}, actions.addPlugin( 'events' ) );
17
+ expect( reducer( state, actions.addPlugin( 'events' ) ) ).toEqual( [ 'events' ] );
18
+ } );
19
+
20
+ it( 'Should remove the plugin from the reducer', () => {
21
+ const state = reducer( {}, actions.addPlugin( 'events' ) );
22
+ expect( state ).toEqual( [ 'events' ] );
23
+ expect( reducer( state, actions.removePlugin( 'events' ) ) ).toEqual( [] );
24
+ } );
25
+ } );
common/src/modules/data/plugins/__tests__/selectors.test.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { selectors } from '@moderntribe/common/data/plugins';
5
+
6
+ describe( 'Plugin selectors', () => {
7
+ let state;
8
+
9
+ beforeEach( () => {
10
+ state = {
11
+ plugins: [ 'events' ],
12
+ };
13
+ } );
14
+
15
+ it( 'should have plugin', () => {
16
+ expect( selectors.hasPlugin( state, 'events' ) ).toEqual( true );
17
+ expect( selectors.hasPlugin( state )( 'events' ) ).toEqual( true );
18
+ } );
19
+ it( 'should not have plugin', () => {
20
+ expect( selectors.hasPlugin( state, 'events-pro' ) ).toEqual( false );
21
+ expect( selectors.hasPlugin( state )( 'events-pro' ) ).toEqual( false );
22
+ } );
23
+ } );
common/src/modules/data/plugins/__tests__/types.test.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+ import { types } from '@moderntribe/common/data/plugins';
6
+
7
+ describe( 'Plugin types', () => {
8
+ it( 'Should return the types with a prefix', () => {
9
+ expect( types.ADD_PLUGIN ).toBe( `${ PREFIX_COMMON_STORE }/ADD_PLUGIN` );
10
+ expect( types.REMOVE_PLUGIN ).toBe( `${ PREFIX_COMMON_STORE }/REMOVE_PLUGIN` );
11
+ } );
12
+ } );
common/src/modules/data/plugins/actions.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import * as types from './types';
5
+
6
+ export const addPlugin = ( name ) => ( {
7
+ type: types.ADD_PLUGIN,
8
+ payload: {
9
+ name,
10
+ },
11
+ } );
12
+
13
+ export const removePlugin = ( name ) => ( {
14
+ type: types.REMOVE_PLUGIN,
15
+ payload: {
16
+ name,
17
+ },
18
+ } );
common/src/modules/data/plugins/constants.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ export const EVENTS_PLUGIN = 'events';
2
+ export const EVENTS_PRO_PLUGIN = 'events-pro';
3
+ export const TICKETS = 'tickets';
4
+ export const TICKETS_PLUS = 'tickets-plus';
common/src/modules/data/plugins/index.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import reducer from './reducer';
5
+ import * as types from './types';
6
+ import * as actions from './actions';
7
+ import * as selectors from './selectors';
8
+ import * as constants from './constants';
9
+ import * as proptypes from './proptypes';
10
+
11
+ export default reducer;
12
+ export { types, actions, selectors, constants, proptypes };
common/src/modules/data/plugins/proptypes.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import PropTypes from 'prop-types';
5
+
6
+ //
7
+ // ─── VENDOR ─────────────────────────────────────────────────────────────────────
8
+ //
9
+
10
+ export const ReactSelectOption = PropTypes.shape( {
11
+ label: PropTypes.string.isRequired,
12
+ value: PropTypes.any.isRequired,
13
+ } );
14
+
15
+ export const ReactSelectOptions = PropTypes.arrayOf( ReactSelectOption );
common/src/modules/data/plugins/reducer.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { uniq } from 'lodash';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { types } from '@moderntribe/common/data/plugins';
10
+
11
+ export default ( state = [], action ) => {
12
+ switch ( action.type ) {
13
+ case types.ADD_PLUGIN:
14
+ return uniq( [ ...state, action.payload.name ] );
15
+ case types.REMOVE_PLUGIN:
16
+ return [ ...state ].filter( ( pluginName ) => pluginName !== action.payload.name );
17
+ default:
18
+ return state;
19
+ }
20
+ };
common/src/modules/data/plugins/selectors.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { includes } from 'lodash';
5
+ import { curry } from 'lodash/fp';
6
+
7
+ export const getPlugins = ( state ) => state.plugins;
8
+
9
+ export const hasPlugin = curry( ( state, plugin ) => includes( getPlugins( state ), plugin ) );
common/src/modules/data/plugins/types.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+
6
+ export const ADD_PLUGIN = `${ PREFIX_COMMON_STORE }/ADD_PLUGIN`;
7
+ export const REMOVE_PLUGIN = `${ PREFIX_COMMON_STORE }/REMOVE_PLUGIN`;
common/src/modules/data/reducers.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { setupCreateReducer } from '@nfen/redux-reducer-injector';
5
+ import forms from './forms';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import plugins from './plugins';
11
+
12
+ export default setupCreateReducer( {
13
+ plugins,
14
+ forms,
15
+ } );
common/src/modules/data/utils.js ADDED
@@ -0,0 +1 @@
 
1
+ export const PREFIX_COMMON_STORE = '@@MT/COMMON';
common/src/modules/elements/accordion/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Accordion Element renders an accordion 1`] = `
4
+ <div
5
+ aria-multiselectable="true"
6
+ className="tribe-editor__accordion"
7
+ role="tablist"
8
+ >
9
+ <article
10
+ className="tribe-editor__accordion__row"
11
+ >
12
+ <button
13
+ aria-controls="accordion-content-123"
14
+ aria-expanded="false"
15
+ aria-selected="false"
16
+ className="tribe-editor__button tribe-editor__accordion__row-header header-class"
17
+ id="accordion-header-123"
18
+ onClick={[Function]}
19
+ role="tab"
20
+ type="button"
21
+ >
22
+ this is header
23
+ </button>
24
+ <div
25
+ aria-hidden="true"
26
+ aria-labelledby="accordion-header-123"
27
+ className="tribe-editor__accordion__row-content content-class"
28
+ id="accordion-content-123"
29
+ role="tabpanel"
30
+ >
31
+ this is a content
32
+ </div>
33
+ </article>
34
+ </div>
35
+ `;
36
+
37
+ exports[`Accordion Element renders an accordion with wrapper class 1`] = `
38
+ <div
39
+ aria-multiselectable="true"
40
+ className="tribe-editor__accordion test-class"
41
+ role="tablist"
42
+ >
43
+ <article
44
+ className="tribe-editor__accordion__row"
45
+ >
46
+ <button
47
+ aria-controls="accordion-content-123"
48
+ aria-expanded="false"
49
+ aria-selected="false"
50
+ className="tribe-editor__button tribe-editor__accordion__row-header header-class"
51
+ id="accordion-header-123"
52
+ onClick={[Function]}
53
+ role="tab"
54
+ type="button"
55
+ >
56
+ this is header
57
+ </button>
58
+ <div
59
+ aria-hidden="true"
60
+ aria-labelledby="accordion-header-123"
61
+ className="tribe-editor__accordion__row-content content-class"
62
+ id="accordion-content-123"
63
+ role="tabpanel"
64
+ >
65
+ this is a content
66
+ </div>
67
+ </article>
68
+ </div>
69
+ `;
70
+
71
+ exports[`Accordion Element renders null 1`] = `null`;
common/src/modules/elements/accordion/__tests__/element.test.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+ import { noop } from 'lodash';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import { Accordion } from '@moderntribe/common/elements';
12
+
13
+ let rows;
14
+
15
+ describe( 'Accordion Element', () => {
16
+ beforeEach( () => {
17
+ rows = [
18
+ {
19
+ accordionId: '123',
20
+ content: 'this is a content',
21
+ contentClassName: 'content-class',
22
+ header: 'this is header',
23
+ headerClassName: 'header-class',
24
+ onClick: noop,
25
+ onClose: noop,
26
+ onOpen: noop,
27
+ },
28
+ ];
29
+ } );
30
+
31
+ it( 'renders null', () => {
32
+ const component = renderer.create( <Accordion /> );
33
+ expect( component.toJSON() ).toMatchSnapshot();
34
+ } );
35
+
36
+ it( 'renders an accordion', () => {
37
+ const component = renderer.create( <Accordion rows={ rows } /> );
38
+ expect( component.toJSON() ).toMatchSnapshot();
39
+ } );
40
+
41
+ it( 'renders an accordion with wrapper class', () => {
42
+ const component = renderer.create( <Accordion className="test-class" rows={ rows } /> );
43
+ expect( component.toJSON() ).toMatchSnapshot();
44
+ } );
45
+ } );
common/src/modules/elements/accordion/element.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Row from './row/template';
12
+ import './style.pcss';
13
+
14
+ const Accordion = ( {
15
+ className,
16
+ containerAttrs,
17
+ rows,
18
+ } ) => (
19
+ rows.length
20
+ ? (
21
+ <div
22
+ aria-multiselectable="true"
23
+ className={ classNames(
24
+ 'tribe-editor__accordion',
25
+ className,
26
+ ) }
27
+ role="tablist"
28
+ { ...containerAttrs }
29
+ >
30
+ { rows.map( ( row, index ) => (
31
+ <Row key={ index } { ...row } />
32
+ ) ) }
33
+ </div>
34
+ )
35
+ : null
36
+ );
37
+
38
+ Accordion.defaultProps = {
39
+ containerAttrs: {},
40
+ rows: [],
41
+ };
42
+
43
+ Accordion.propTypes = {
44
+ className: PropTypes.string,
45
+ containerAttrs: PropTypes.object,
46
+ rows: PropTypes.arrayOf( PropTypes.shape( {
47
+ accordionId: PropTypes.string.isRequired,
48
+ content: PropTypes.node,
49
+ contentClassName: PropTypes.string,
50
+ header: PropTypes.node,
51
+ headerClassName: PropTypes.string,
52
+ onClick: PropTypes.func,
53
+ onClose: PropTypes.func,
54
+ onOpen: PropTypes.func,
55
+ } ).isRequired ).isRequired,
56
+ };
57
+
58
+ export default Accordion;
common/src/modules/elements/accordion/row/__tests__/__snapshots__/template.test.js.snap ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Accordion Row Element renders an accordion row 1`] = `
4
+ <article
5
+ className="tribe-editor__accordion__row"
6
+ >
7
+ <button
8
+ aria-controls="accordion-content-123"
9
+ aria-expanded="false"
10
+ aria-selected="false"
11
+ className="tribe-editor__button tribe-editor__accordion__row-header header-class"
12
+ data-attr="header-attr-value"
13
+ id="accordion-header-123"
14
+ onClick={[Function]}
15
+ role="tab"
16
+ type="button"
17
+ >
18
+ this is header
19
+ </button>
20
+ <div
21
+ aria-hidden="true"
22
+ aria-labelledby="accordion-header-123"
23
+ className="tribe-editor__accordion__row-content content-class"
24
+ data-attr="content-attr-value"
25
+ id="accordion-content-123"
26
+ role="tabpanel"
27
+ >
28
+ this is a content
29
+ </div>
30
+ </article>
31
+ `;
common/src/modules/elements/accordion/row/__tests__/template.test.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import Row from '@moderntribe/common/elements/accordion/row/template';
10
+
11
+ let row;
12
+
13
+ describe( 'Accordion Row Element', () => {
14
+ beforeEach( () => {
15
+ row = {
16
+ accordionId: '123',
17
+ content: 'this is a content',
18
+ contentAttrs: { 'data-attr': 'content-attr-value' },
19
+ contentClassName: 'content-class',
20
+ header: 'this is header',
21
+ headerAttrs: { 'data-attr': 'header-attr-value' },
22
+ headerClassName: 'header-class',
23
+ onClick: jest.fn(),
24
+ onClose: jest.fn(),
25
+ onOpen: jest.fn(),
26
+ };
27
+ } );
28
+
29
+ it( 'renders an accordion row', () => {
30
+ const component = renderer.create( <Row { ...row } /> );
31
+ expect( component.toJSON() ).toMatchSnapshot();
32
+ } );
33
+
34
+ it( 'executes onClick handler', () => {
35
+ const component = mount( <Row { ...row } /> );
36
+ component.find( 'button' ).simulate( 'click' );
37
+ expect( row.onClick ).toHaveBeenCalled();
38
+ expect( row.onClick ).toHaveBeenCalledTimes( 1 );
39
+ } );
40
+
41
+ it( 'executes onOpen and onClose handlers', async () => {
42
+ const component = mount( <Row { ...row } /> );
43
+ component.find( 'button' ).simulate( 'click' );
44
+ await setTimeout( () => {
45
+ component.find( 'button' ).simulate( 'click' );
46
+ setTimeout( () => {
47
+ expect( row.onOpen ).toHaveBeenCalled();
48
+ expect( row.onOpen ).toHaveBeenCalledTimes( 1 );
49
+ expect( row.onClose ).toHaveBeenCalled();
50
+ expect( row.onClose ).toHaveBeenCalledTimes( 1 );
51
+ expect( row.onClick ).toHaveBeenCalled();
52
+ expect( row.onClick ).toHaveBeenCalledTimes( 2 );
53
+ }, 250 );
54
+ }, 250 );
55
+ } );
56
+ } );
common/src/modules/elements/accordion/row/template.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Button from '@moderntribe/common/elements/button/element';
12
+ import { slide } from '@moderntribe/common/utils';
13
+
14
+ class Row extends PureComponent {
15
+ static propTypes = {
16
+ accordionId: PropTypes.string.isRequired,
17
+ content: PropTypes.node,
18
+ contentAttrs: PropTypes.object,
19
+ contentClassName: PropTypes.string,
20
+ header: PropTypes.node,
21
+ headerAttrs: PropTypes.object,
22
+ headerClassName: PropTypes.string,
23
+ onClick: PropTypes.func,
24
+ onClose: PropTypes.func,
25
+ onOpen: PropTypes.func,
26
+ };
27
+
28
+ static defaultProps = {
29
+ contentAttrs: {},
30
+ headerAttrs: {},
31
+ };
32
+
33
+ constructor( props ) {
34
+ super( props );
35
+ this.state = {
36
+ isActive: false,
37
+ };
38
+ this.headerId = `accordion-header-${ this.props.accordionId }`;
39
+ this.contentId = `accordion-content-${ this.props.accordionId }`;
40
+ }
41
+
42
+ getHeaderAttrs = () => {
43
+ const _isActive = this.state.isActive ? 'true' : 'false';
44
+ return {
45
+ 'aria-controls': this.contentId,
46
+ 'aria-expanded': _isActive,
47
+ 'aria-selected': _isActive,
48
+ id: this.headerId,
49
+ role: 'tab',
50
+ ...this.props.headerAttrs,
51
+ };
52
+ };
53
+
54
+ getContentAttrs = () => ( {
55
+ 'aria-hidden': this.state.isActive ? 'false' : 'true',
56
+ 'aria-labelledby': this.headerId,
57
+ id: this.contentId,
58
+ role: 'tabpanel',
59
+ ...this.props.contentAttrs,
60
+ } );
61
+
62
+ onClose = ( parent, e ) => () => {
63
+ parent.classList.remove( 'closing' );
64
+ parent.classList.add( 'closed' );
65
+ this.props.onClose && this.props.onClose( e );
66
+ };
67
+
68
+ onOpen = ( parent, e ) => () => {
69
+ parent.classList.remove( 'opening' );
70
+ parent.classList.add( 'open' );
71
+ this.props.onOpen && this.props.onOpen( e );
72
+ };
73
+
74
+ onClick = ( e ) => {
75
+ const { contentId, onClick } = this.props;
76
+ const parent = e.currentTarget.parentNode;
77
+ const content = e.currentTarget.nextElementSibling;
78
+
79
+ this.state.isActive
80
+ ? parent.classList.add( 'closing' )
81
+ : parent.classList.add( 'opening' );
82
+ this.state.isActive
83
+ ? slide.up( content, contentId, 200, this.onClose( parent, e ) )
84
+ : slide.down( content, contentId, 200, this.onOpen( parent, e ) );
85
+
86
+ onClick && onClick( e );
87
+ this.setState( ( state ) => ( { isActive: ! state.isActive } ) );
88
+ };
89
+
90
+ render() {
91
+ const {
92
+ content,
93
+ contentClassName,
94
+ header,
95
+ headerClassName,
96
+ } = this.props;
97
+
98
+ return (
99
+ <article
100
+ className={ classNames(
101
+ 'tribe-editor__accordion__row',
102
+ { active: this.state.isActive },
103
+ ) }
104
+ >
105
+ <Button
106
+ className={ classNames(
107
+ 'tribe-editor__accordion__row-header',
108
+ headerClassName,
109
+ ) }
110
+ onClick={ ( e ) => this.onClick( e ) }
111
+ { ...this.getHeaderAttrs() }
112
+ >
113
+ { header }
114
+ </Button>
115
+ <div
116
+ className={ classNames(
117
+ 'tribe-editor__accordion__row-content',
118
+ contentClassName,
119
+ ) }
120
+ { ...this.getContentAttrs() }
121
+ >
122
+ { content }
123
+ </div>
124
+ </article>
125
+ );
126
+ }
127
+ }
128
+
129
+ export default Row;
common/src/modules/elements/accordion/style.pcss ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ .tribe-editor__accordion__row-content {
2
+ max-height: 0;
3
+ overflow: hidden;
4
+
5
+ &.active {
6
+ max-height: none;
7
+ }
8
+ }
common/src/modules/elements/block-icon/index.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { TEC } from '@moderntribe/common/icons';
10
+ import './style.pcss';
11
+
12
+ export default () => (
13
+ <div className="tribe-editor__icons__container tribe-editor__icons--tec">
14
+ <TEC />
15
+ </div>
16
+ );
common/src/modules/elements/block-icon/style.pcss ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .editor-block-inspector__card {
2
+ .tribe-editor__icons__container {
3
+ padding: 4px;
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+
8
+ svg {
9
+ width: 28px;
10
+ height: 28px;
11
+ }
12
+ }
13
+
14
+ .tribe-editor__icons--tec {
15
+ background-color: #199FD1;
16
+ }
17
+ }
18
+
19
+
20
+ button[class^='editor-block-list-item-tribe-'], button[class*=' editor-block-list-item-tribe-'] {
21
+ svg {
22
+ color: #16a0d6;
23
+ }
24
+ }
common/src/modules/elements/button/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Button Element renders button 1`] = `
4
+ <button
5
+ className="tribe-editor__button"
6
+ onClick={[Function]}
7
+ type="button"
8
+ />
9
+ `;
10
+
11
+ exports[`Button Element renders button with class 1`] = `
12
+ <button
13
+ className="tribe-editor__button test-class"
14
+ onClick={[Function]}
15
+ type="button"
16
+ />
17
+ `;
18
+
19
+ exports[`Button Element renders button with extra attributes 1`] = `
20
+ <button
21
+ className="tribe-editor__button"
22
+ hello="world"
23
+ onClick={[Function]}
24
+ test="one-two-three"
25
+ type="button"
26
+ />
27
+ `;
28
+
29
+ exports[`Button Element renders button with label 1`] = `
30
+ <button
31
+ className="tribe-editor__button"
32
+ onClick={[Function]}
33
+ type="button"
34
+ >
35
+ Hello
36
+ </button>
37
+ `;
38
+
39
+ exports[`Button Element renders button with onClick handler 1`] = `
40
+ <button
41
+ className="tribe-editor__button"
42
+ onClick={[MockFunction]}
43
+ type="button"
44
+ />
45
+ `;
46
+
47
+ exports[`Button Element renders button with set type 1`] = `
48
+ <button
49
+ className="tribe-editor__button"
50
+ onClick={[Function]}
51
+ type="submit"
52
+ />
53
+ `;
54
+
55
+ exports[`Button Element renders disabled button 1`] = `
56
+ <button
57
+ className="tribe-editor__button"
58
+ disabled={true}
59
+ onClick={[Function]}
60
+ type="button"
61
+ />
62
+ `;
common/src/modules/elements/button/__tests__/element.test.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { Button } from '@moderntribe/common/elements';
11
+
12
+ describe( 'Button Element', () => {
13
+ it( 'renders button', () => {
14
+ const component = renderer.create( <Button /> );
15
+ expect( component.toJSON() ).toMatchSnapshot();
16
+ } );
17
+
18
+ it( 'renders button with class', () => {
19
+ const component = renderer.create( <Button className="test-class" /> );
20
+ expect( component.toJSON() ).toMatchSnapshot();
21
+ } );
22
+
23
+ it( 'renders disabled button', () => {
24
+ const component = renderer.create( <Button isDisabled={ true } /> );
25
+ expect( component.toJSON() ).toMatchSnapshot();
26
+ } );
27
+
28
+ it( 'renders button with label', () => {
29
+ const component = renderer.create( <Button>Hello</Button> );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+
33
+ it( 'renders button with onClick handler', () => {
34
+ const onClick = jest.fn();
35
+ const component = renderer.create( <Button onClick={ onClick } /> );
36
+ expect( component.toJSON() ).toMatchSnapshot();
37
+ } );
38
+
39
+ it( 'executes the onClick handler', () => {
40
+ const onClick = jest.fn();
41
+ const component = mount( <Button onClick={ onClick } /> );
42
+ component.find( 'button' ).simulate( 'click' );
43
+ expect( onClick ).toHaveBeenCalled();
44
+ expect( onClick ).toHaveBeenCalledTimes( 1 );
45
+ } );
46
+
47
+ it( 'renders button with set type', () => {
48
+ const component = renderer.create( <Button type="submit" /> );
49
+ expect( component.toJSON() ).toMatchSnapshot();
50
+ } );
51
+
52
+ it( 'renders button with extra attributes', () => {
53
+ const attrs = {
54
+ test: 'one-two-three',
55
+ hello: 'world',
56
+ };
57
+ const component = renderer.create( <Button { ...attrs } /> );
58
+ expect( component.toJSON() ).toMatchSnapshot();
59
+ } );
60
+ } );
common/src/modules/elements/button/element.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { noop } from 'lodash';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import './style.pcss';
13
+
14
+ class Button extends PureComponent {
15
+ static defaultProps = {
16
+ onClick: noop,
17
+ type: 'button',
18
+ };
19
+
20
+ static propTypes = {
21
+ className: PropTypes.oneOfType( [
22
+ PropTypes.string,
23
+ PropTypes.arrayOf( PropTypes.string ),
24
+ PropTypes.object,
25
+ ] ),
26
+ isDisabled: PropTypes.bool,
27
+ children: PropTypes.node,
28
+ onClick: PropTypes.func,
29
+ type: PropTypes.string,
30
+ };
31
+
32
+ render() {
33
+ const {
34
+ children,
35
+ className,
36
+ isDisabled,
37
+ onClick,
38
+ type,
39
+ ...rest
40
+ } = this.props;
41
+
42
+ return (
43
+ <button
44
+ className={ classNames( 'tribe-editor__button', className ) }
45
+ disabled={ isDisabled }
46
+ type={ type }
47
+ onClick={ onClick }
48
+ { ...rest }
49
+ >
50
+ { children }
51
+ </button>
52
+ );
53
+ }
54
+ }
55
+
56
+ export default Button;
common/src/modules/elements/button/style.pcss ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* basic styles are in .tribe-editor__btn, this is kepted for backward compatibility */
2
+ .tribe-editor__btn--label {
3
+ background-color: transparent;
4
+ border: none;
5
+ padding: 0;
6
+ margin: 0;
7
+ text-align: left;
8
+ }
9
+
10
+ .tribe-editor__button {
11
+
12
+ &,
13
+ /* extra editor-styles-wrapper class to override gutenberg styles */
14
+ .editor-styles-wrapper & {
15
+
16
+ background-color: transparent;
17
+ border: none;
18
+ padding: 0;
19
+ margin: 0;
20
+ font-family: 'Helvetica', 'sans-serif';
21
+ cursor: pointer;
22
+
23
+ &[disabled] {
24
+ cursor: default;
25
+ }
26
+ }
27
+ }
28
+
29
+ .tribe-editor__button--sm {
30
+
31
+ &,
32
+ /* extra editor-styles-wrapper class to override gutenberg styles */
33
+ .editor-styles-wrapper & {
34
+
35
+ background-color: #009fd4;
36
+ color: #ffffff;
37
+ padding: 11px 16px 9px;
38
+ font-size: 15px;
39
+ font-weight: bold;
40
+ line-height: 18px;
41
+ transition: background-color 0.2s ease;
42
+
43
+ &:hover,
44
+ &:focus {
45
+ background-color: #007bb4;
46
+ }
47
+
48
+ &[disabled] {
49
+
50
+ &,
51
+ &:hover,
52
+ &:focus {
53
+ background-color: #f3f4f5;
54
+ color: #8d949b;
55
+ }
56
+ }
57
+ }
58
+ }
common/src/modules/elements/checkbox-input/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Input element Should render the component 1`] = `
4
+ <input
5
+ className="tribe-editor__input tribe-editor__input--checkbox"
6
+ type="checkbox"
7
+ />
8
+ `;
9
+
10
+ exports[`Input element Should render the component with checked 1`] = `
11
+ <input
12
+ checked={true}
13
+ className="tribe-editor__input tribe-editor__input--checkbox"
14
+ type="checkbox"
15
+ />
16
+ `;
17
+
18
+ exports[`Input element Should render the component with checked 2`] = `
19
+ <input
20
+ checked={false}
21
+ className="tribe-editor__input tribe-editor__input--checkbox"
22
+ type="checkbox"
23
+ />
24
+ `;
25
+
26
+ exports[`Input element Should render the component with class 1`] = `
27
+ <input
28
+ className="tribe-editor__input tribe-editor__input--checkbox checkbox-class"
29
+ type="checkbox"
30
+ />
31
+ `;
32
+
33
+ exports[`Input element Should render the component with extra props 1`] = `
34
+ <input
35
+ className="tribe-editor__input tribe-editor__input--checkbox"
36
+ id="checkbox-id"
37
+ type="checkbox"
38
+ />
39
+ `;
40
+
41
+ exports[`Input element Should render the component with onChange handler 1`] = `
42
+ <input
43
+ className="tribe-editor__input tribe-editor__input--checkbox"
44
+ onChange={[Function]}
45
+ type="checkbox"
46
+ />
47
+ `;
common/src/modules/elements/checkbox-input/__tests__/element.test.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import { noop } from 'lodash';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import CheckboxInput from '../element.js';
11
+
12
+ describe( 'Input element', () => {
13
+ it( 'Should render the component', () => {
14
+ const component = renderer.create( <CheckboxInput /> );
15
+ expect( component.toJSON() ).toMatchSnapshot();
16
+ } );
17
+
18
+ it( 'Should render the component with checked', () => {
19
+ const component1 = renderer.create( <CheckboxInput checked={ true } /> );
20
+ expect( component1.toJSON() ).toMatchSnapshot();
21
+ const component2 = renderer.create( <CheckboxInput checked={ false } /> );
22
+ expect( component2.toJSON() ).toMatchSnapshot();
23
+ } );
24
+
25
+ it( 'Should render the component with class', () => {
26
+ const component = renderer.create( <CheckboxInput className="checkbox-class" /> );
27
+ expect( component.toJSON() ).toMatchSnapshot();
28
+ } );
29
+
30
+ it( 'Should render the component with onChange handler', () => {
31
+ const component = renderer.create( <CheckboxInput onChange={ noop } /> );
32
+ expect( component.toJSON() ).toMatchSnapshot();
33
+ } );
34
+
35
+ it( 'Should render the component with extra props', () => {
36
+ const component = renderer.create( <CheckboxInput id="checkbox-id" /> );
37
+ expect( component.toJSON() ).toMatchSnapshot();
38
+ } );
39
+ } );
common/src/modules/elements/checkbox-input/element.js ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Input from '@moderntribe/common/elements/input/element';
12
+ import './style.pcss';
13
+
14
+ const CheckboxInput = ( {
15
+ checked,
16
+ className,
17
+ onChange,
18
+ ...rest
19
+ } ) => (
20
+ <Input
21
+ checked={ checked }
22
+ className={ classNames( 'tribe-editor__input--checkbox', className ) }
23
+ onChange={ onChange }
24
+ type="checkbox"
25
+ { ...rest }
26
+ />
27
+ );
28
+
29
+ CheckboxInput.propTypes = {
30
+ checked: PropTypes.bool,
31
+ className: PropTypes.string,
32
+ onChange: PropTypes.func,
33
+ };
34
+
35
+ export default CheckboxInput;
common/src/modules/elements/checkbox-input/style.pcss ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* increased specificity required to override gutenberg editor styles */
2
+ input[type=checkbox].tribe-editor__input--checkbox {
3
+ background-color: #ffffff;
4
+ border: 1px solid #E0E5E9;
5
+ border-radius: 0;
6
+
7
+ &:focus {
8
+ border: 1px solid #E0E5E9;
9
+ box-shadow: 0 0 0 1px #E0E5E9;
10
+ }
11
+
12
+ &:checked {
13
+ background-color: #ffffff;
14
+ border: 1px solid #E0E5E9;
15
+
16
+ &:focus {
17
+ border: 1px solid #E0E5E9;
18
+ box-shadow: 0 0 0 1px #E0E5E9;
19
+ }
20
+
21
+ &:before {
22
+ color: #11A0D2;
23
+ }
24
+ }
25
+ }
common/src/modules/elements/checkbox/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Checkbox Element renders checkbox 1`] = `
4
+ <div
5
+ className="tribe-editor__checkbox"
6
+ >
7
+ <input
8
+ checked={false}
9
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
10
+ onChange={[Function]}
11
+ type="checkbox"
12
+ />
13
+ <label
14
+ className="tribe-editor__checkbox__label"
15
+ />
16
+ </div>
17
+ `;
18
+
19
+ exports[`Checkbox Element renders checkbox with class 1`] = `
20
+ <div
21
+ className="tribe-editor__checkbox test-class"
22
+ >
23
+ <input
24
+ checked={false}
25
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
26
+ onChange={[Function]}
27
+ type="checkbox"
28
+ />
29
+ <label
30
+ className="tribe-editor__checkbox__label"
31
+ />
32
+ </div>
33
+ `;
34
+
35
+ exports[`Checkbox Element renders checkbox with id 1`] = `
36
+ <div
37
+ className="tribe-editor__checkbox"
38
+ >
39
+ <input
40
+ checked={false}
41
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
42
+ id="test-id"
43
+ onChange={[Function]}
44
+ type="checkbox"
45
+ />
46
+ <label
47
+ className="tribe-editor__checkbox__label"
48
+ htmlFor="test-id"
49
+ />
50
+ </div>
51
+ `;
52
+
53
+ exports[`Checkbox Element renders checkbox with label 1`] = `
54
+ <div
55
+ className="tribe-editor__checkbox"
56
+ >
57
+ <input
58
+ checked={false}
59
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
60
+ onChange={[Function]}
61
+ type="checkbox"
62
+ />
63
+ <label
64
+ className="tribe-editor__checkbox__label"
65
+ >
66
+ Test Label
67
+ </label>
68
+ </div>
69
+ `;
70
+
71
+ exports[`Checkbox Element renders checkbox with name 1`] = `
72
+ <div
73
+ className="tribe-editor__checkbox"
74
+ >
75
+ <input
76
+ checked={false}
77
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
78
+ name="test-name"
79
+ onChange={[Function]}
80
+ type="checkbox"
81
+ />
82
+ <label
83
+ className="tribe-editor__checkbox__label"
84
+ />
85
+ </div>
86
+ `;
87
+
88
+ exports[`Checkbox Element renders checkbox with onChange handler 1`] = `
89
+ <div
90
+ className="tribe-editor__checkbox"
91
+ >
92
+ <input
93
+ checked={false}
94
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
95
+ onChange={[MockFunction]}
96
+ type="checkbox"
97
+ />
98
+ <label
99
+ className="tribe-editor__checkbox__label"
100
+ />
101
+ </div>
102
+ `;
103
+
104
+ exports[`Checkbox Element renders checkbox with value 1`] = `
105
+ <div
106
+ className="tribe-editor__checkbox"
107
+ >
108
+ <input
109
+ checked={false}
110
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
111
+ onChange={[Function]}
112
+ type="checkbox"
113
+ value="Test Value"
114
+ />
115
+ <label
116
+ className="tribe-editor__checkbox__label"
117
+ />
118
+ </div>
119
+ `;
120
+
121
+ exports[`Checkbox Element renders checked checkbox 1`] = `
122
+ <div
123
+ className="tribe-editor__checkbox"
124
+ >
125
+ <input
126
+ checked={true}
127
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
128
+ onChange={[Function]}
129
+ type="checkbox"
130
+ />
131
+ <label
132
+ className="tribe-editor__checkbox__label"
133
+ />
134
+ </div>
135
+ `;
136
+
137
+ exports[`Checkbox Element renders disabled checkbox 1`] = `
138
+ <div
139
+ className="tribe-editor__checkbox"
140
+ >
141
+ <input
142
+ checked={false}
143
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
144
+ disabled={true}
145
+ onChange={[Function]}
146
+ type="checkbox"
147
+ />
148
+ <label
149
+ className="tribe-editor__checkbox__label"
150
+ />
151
+ </div>
152
+ `;
153
+
154
+ exports[`Checkbox Element renders unchecked checkbox 1`] = `
155
+ <div
156
+ className="tribe-editor__checkbox"
157
+ >
158
+ <input
159
+ checked={false}
160
+ className="tribe-editor__input tribe-editor__input--checkbox tribe-editor__checkbox__input"
161
+ onChange={[Function]}
162
+ type="checkbox"
163
+ />
164
+ <label
165
+ className="tribe-editor__checkbox__label"
166
+ />
167
+ </div>
168
+ `;
common/src/modules/elements/checkbox/__tests__/element.test.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { Checkbox } from '@moderntribe/common/elements';
10
+
11
+ describe( 'Checkbox Element', () => {
12
+ it( 'renders checkbox', () => {
13
+ const component = renderer.create( <Checkbox /> );
14
+ expect( component.toJSON() ).toMatchSnapshot();
15
+ } );
16
+
17
+ it( 'renders checked checkbox', () => {
18
+ const component = renderer.create( <Checkbox checked={ true } /> );
19
+ expect( component.toJSON() ).toMatchSnapshot();
20
+ } );
21
+
22
+ it( 'renders unchecked checkbox', () => {
23
+ const component = renderer.create( <Checkbox checked={ false } /> );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+
27
+ it( 'renders checkbox with class', () => {
28
+ const component = renderer.create( <Checkbox className="test-class" /> );
29
+ expect( component.toJSON() ).toMatchSnapshot();
30
+ } );
31
+
32
+ it( 'renders disabled checkbox', () => {
33
+ const component = renderer.create( <Checkbox disabled={ true } /> );
34
+ expect( component.toJSON() ).toMatchSnapshot();
35
+ } );
36
+
37
+ it( 'renders checkbox with id', () => {
38
+ const component = renderer.create( <Checkbox id="test-id" /> );
39
+ expect( component.toJSON() ).toMatchSnapshot();
40
+ } );
41
+
42
+ it( 'renders checkbox with label', () => {
43
+ const component = renderer.create( <Checkbox label="Test Label" /> );
44
+ expect( component.toJSON() ).toMatchSnapshot();
45
+ } );
46
+
47
+ it( 'renders checkbox with name', () => {
48
+ const component = renderer.create( <Checkbox name="test-name" /> );
49
+ expect( component.toJSON() ).toMatchSnapshot();
50
+ } );
51
+
52
+ it( 'renders checkbox with value', () => {
53
+ const component = renderer.create( <Checkbox value="Test Value" /> );
54
+ expect( component.toJSON() ).toMatchSnapshot();
55
+ } );
56
+
57
+ it( 'renders checkbox with onChange handler', () => {
58
+ const onChange = jest.fn();
59
+ const component = renderer.create( <Checkbox onChange={ onChange } /> );
60
+ expect( component.toJSON() ).toMatchSnapshot();
61
+ } );
62
+
63
+ it( 'executes checkbox with onChange handler', () => {
64
+ const onChange = jest.fn();
65
+ const component = mount( <Checkbox onChange={ onChange } /> );
66
+ component.find( 'input' ).simulate( 'change' );
67
+ expect( onChange ).toHaveBeenCalled();
68
+ expect( onChange ).toHaveBeenCalledTimes( 1 );
69
+ } );
70
+ } );
common/src/modules/elements/checkbox/element.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { noop } from 'lodash';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { CheckboxInput } from '@moderntribe/common/elements';
13
+
14
+ const Checkbox = ( {
15
+ checked,
16
+ className,
17
+ disabled,
18
+ id,
19
+ label,
20
+ onChange,
21
+ name,
22
+ value,
23
+ } ) => {
24
+ return (
25
+ <div className={ classNames( 'tribe-editor__checkbox', className ) }>
26
+ <CheckboxInput
27
+ checked={ checked }
28
+ className="tribe-editor__checkbox__input"
29
+ disabled={ disabled }
30
+ id={ id }
31
+ name={ name }
32
+ onChange={ onChange }
33
+ value={ value }
34
+ />
35
+ <label
36
+ className="tribe-editor__checkbox__label"
37
+ htmlFor={ id }
38
+ >
39
+ { label }
40
+ </label>
41
+ </div>
42
+ );
43
+ };
44
+
45
+ Checkbox.defaultProps = {
46
+ checked: false,
47
+ onChange: noop,
48
+ }
49
+
50
+ Checkbox.propTypes = {
51
+ checked: PropTypes.bool.isRequired,
52
+ className: PropTypes.string,
53
+ disabled: PropTypes.bool,
54
+ id: PropTypes.string,
55
+ label: PropTypes.node,
56
+ name: PropTypes.string,
57
+ onChange: PropTypes.func,
58
+ value: PropTypes.string,
59
+ };
60
+
61
+ export default Checkbox;
common/src/modules/elements/counter/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Counter Element renders counter 1`] = `
4
+ <div
5
+ className="tribe-editor__counter"
6
+ >
7
+ <span
8
+ className="tribe-editor__counter__count"
9
+ />
10
+ <span
11
+ className="tribe-editor__counter__label"
12
+ />
13
+ </div>
14
+ `;
15
+
16
+ exports[`Counter Element renders counter with class 1`] = `
17
+ <div
18
+ className="tribe-editor__counter test-class"
19
+ >
20
+ <span
21
+ className="tribe-editor__counter__count"
22
+ />
23
+ <span
24
+ className="tribe-editor__counter__label"
25
+ />
26
+ </div>
27
+ `;
28
+
29
+ exports[`Counter Element renders counter with count 1`] = `
30
+ <div
31
+ className="tribe-editor__counter"
32
+ >
33
+ <span
34
+ className="tribe-editor__counter__count"
35
+ >
36
+ 42
37
+ </span>
38
+ <span
39
+ className="tribe-editor__counter__label"
40
+ />
41
+ </div>
42
+ `;
43
+
44
+ exports[`Counter Element renders counter with label 1`] = `
45
+ <div
46
+ className="tribe-editor__counter"
47
+ >
48
+ <span
49
+ className="tribe-editor__counter__count"
50
+ />
51
+ <span
52
+ className="tribe-editor__counter__label"
53
+ >
54
+ test-label
55
+ </span>
56
+ </div>
57
+ `;
common/src/modules/elements/counter/__tests__/element.test.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { Counter } from '@moderntribe/common/elements';
11
+
12
+ describe( 'Counter Element', () => {
13
+ it( 'renders counter', () => {
14
+ const component = renderer.create( <Counter /> );
15
+ expect( component.toJSON() ).toMatchSnapshot();
16
+ } );
17
+
18
+ it( 'renders counter with class', () => {
19
+ const component = renderer.create( <Counter className="test-class" /> );
20
+ expect( component.toJSON() ).toMatchSnapshot();
21
+ } );
22
+
23
+ it( 'renders counter with count', () => {
24
+ const component = renderer.create( <Counter count={ 42 } /> );
25
+ expect( component.toJSON() ).toMatchSnapshot();
26
+ } );
27
+
28
+ it( 'renders counter with label', () => {
29
+ const component = renderer.create( <Counter label="test-label" /> );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+ } );
common/src/modules/elements/counter/element.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.pcss';
12
+
13
+ const Counter = ( {
14
+ className,
15
+ count,
16
+ label,
17
+ } ) => (
18
+ <div className={ classNames(
19
+ 'tribe-editor__counter',
20
+ className,
21
+ ) }>
22
+ <span className="tribe-editor__counter__count">
23
+ { count }
24
+ </span>
25
+ <span className="tribe-editor__counter__label">
26
+ { label }
27
+ </span>
28
+ </div>
29
+ );
30
+
31
+ Counter.propTypes = {
32
+ className: PropTypes.string,
33
+ count: PropTypes.number,
34
+ label: PropTypes.string,
35
+ };
36
+
37
+ export default Counter;
common/src/modules/elements/counter/style.pcss ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__counter {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: center;
5
+ }
6
+
7
+ .tribe-editor__counter__count {
8
+ flex: none;
9
+ color: #AEB4BB;
10
+ font-size: 32px;
11
+ font-weight: bold;
12
+ line-height: 40px;
13
+ margin-bottom: 10px;
14
+ }
15
+
16
+ .tribe-editor__counter__label {
17
+ flex: none;
18
+ color: #AEB4BB;
19
+ font-size: 12px;
20
+ line-height: 14px;
21
+ letter-spacing: 0.04px;
22
+ }
common/src/modules/elements/creatable-select/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`CreatableSelect element Should render the component 1`] = `
4
+ <div
5
+ className="css-10nd86i tribe-editor__creatable-select"
6
+ onKeyDown={[Function]}
7
+ >
8
+ <div
9
+ className="css-vj8t7z tribe-editor__creatable-select__control"
10
+ onMouseDown={[Function]}
11
+ onTouchEnd={[Function]}
12
+ >
13
+ <div
14
+ className="css-1hwfws3 tribe-editor__creatable-select__value-container"
15
+ >
16
+ <div
17
+ className="css-1492t68 tribe-editor__creatable-select__placeholder"
18
+ >
19
+ Select...
20
+ </div>
21
+ <div
22
+ className="css-1g6gooi"
23
+ >
24
+ <div
25
+ className="tribe-editor__creatable-select__input"
26
+ style={
27
+ Object {
28
+ "display": "inline-block",
29
+ }
30
+ }
31
+ >
32
+ <input
33
+ aria-autocomplete="list"
34
+ autoCapitalize="none"
35
+ autoComplete="off"
36
+ autoCorrect="off"
37
+ disabled={false}
38
+ id="react-select-2-input"
39
+ onBlur={[Function]}
40
+ onChange={[Function]}
41
+ onFocus={[Function]}
42
+ spellCheck="false"
43
+ style={
44
+ Object {
45
+ "background": 0,
46
+ "border": 0,
47
+ "boxSizing": "content-box",
48
+ "color": "inherit",
49
+ "fontSize": "inherit",
50
+ "opacity": 1,
51
+ "outline": 0,
52
+ "padding": 0,
53
+ "width": "1px",
54
+ }
55
+ }
56
+ tabIndex="0"
57
+ type="text"
58
+ value=""
59
+ />
60
+ <div
61
+ style={
62
+ Object {
63
+ "height": 0,
64
+ "left": 0,
65
+ "overflow": "scroll",
66
+ "position": "absolute",
67
+ "top": 0,
68
+ "visibility": "hidden",
69
+ "whiteSpace": "pre",
70
+ }
71
+ }
72
+ >
73
+
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ <div
79
+ className="css-1wy0on6 tribe-editor__creatable-select__indicators"
80
+ >
81
+ <div
82
+ aria-hidden="true"
83
+ className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
84
+ onMouseDown={[Function]}
85
+ onTouchEnd={[Function]}
86
+ >
87
+ <span
88
+ className="tribe-editor__creatable-select__dropdown-indicator"
89
+ >
90
+ arrow-down
91
+ </span>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ `;
97
+
98
+ exports[`CreatableSelect element Should render the component with class 1`] = `
99
+ <div
100
+ className="css-10nd86i tribe-editor__creatable-select test-class"
101
+ onKeyDown={[Function]}
102
+ >
103
+ <div
104
+ className="css-vj8t7z tribe-editor__creatable-select__control"
105
+ onMouseDown={[Function]}
106
+ onTouchEnd={[Function]}
107
+ >
108
+ <div
109
+ className="css-1hwfws3 tribe-editor__creatable-select__value-container"
110
+ >
111
+ <div
112
+ className="css-1492t68 tribe-editor__creatable-select__placeholder"
113
+ >
114
+ Select...
115
+ </div>
116
+ <div
117
+ className="css-1g6gooi"
118
+ >
119
+ <div
120
+ className="tribe-editor__creatable-select__input"
121
+ style={
122
+ Object {
123
+ "display": "inline-block",
124
+ }
125
+ }
126
+ >
127
+ <input
128
+ aria-autocomplete="list"
129
+ autoCapitalize="none"
130
+ autoComplete="off"
131
+ autoCorrect="off"
132
+ disabled={false}
133
+ id="react-select-3-input"
134
+ onBlur={[Function]}
135
+ onChange={[Function]}
136
+ onFocus={[Function]}
137
+ spellCheck="false"
138
+ style={
139
+ Object {
140
+ "background": 0,
141
+ "border": 0,
142
+ "boxSizing": "content-box",
143
+ "color": "inherit",
144
+ "fontSize": "inherit",
145
+ "opacity": 1,
146
+ "outline": 0,
147
+ "padding": 0,
148
+ "width": "1px",
149
+ }
150
+ }
151
+ tabIndex="0"
152
+ type="text"
153
+ value=""
154
+ />
155
+ <div
156
+ style={
157
+ Object {
158
+ "height": 0,
159
+ "left": 0,
160
+ "overflow": "scroll",
161
+ "position": "absolute",
162
+ "top": 0,
163
+ "visibility": "hidden",
164
+ "whiteSpace": "pre",
165
+ }
166
+ }
167
+ >
168
+
169
+ </div>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ <div
174
+ className="css-1wy0on6 tribe-editor__creatable-select__indicators"
175
+ >
176
+ <div
177
+ aria-hidden="true"
178
+ className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
179
+ onMouseDown={[Function]}
180
+ onTouchEnd={[Function]}
181
+ >
182
+ <span
183
+ className="tribe-editor__creatable-select__dropdown-indicator"
184
+ >
185
+ arrow-down
186
+ </span>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ `;
192
+
193
+ exports[`CreatableSelect element Should render the component with extra props 1`] = `
194
+ <div
195
+ className="css-10nd86i tribe-editor__creatable-select"
196
+ onKeyDown={[Function]}
197
+ >
198
+ <div
199
+ className="css-vj8t7z tribe-editor__creatable-select__control"
200
+ onMouseDown={[Function]}
201
+ onTouchEnd={[Function]}
202
+ >
203
+ <div
204
+ className="css-1hwfws3 tribe-editor__creatable-select__value-container"
205
+ >
206
+ <div
207
+ className="css-1492t68 tribe-editor__creatable-select__placeholder"
208
+ >
209
+ Select...
210
+ </div>
211
+ <input
212
+ className="css-14uuagi"
213
+ disabled={false}
214
+ id="react-select-4-input"
215
+ onBlur={[Function]}
216
+ onChange={[Function]}
217
+ onFocus={[Function]}
218
+ readOnly={true}
219
+ tabIndex="0"
220
+ value=""
221
+ />
222
+ </div>
223
+ <div
224
+ className="css-1wy0on6 tribe-editor__creatable-select__indicators"
225
+ >
226
+ <div
227
+ aria-hidden="true"
228
+ className="css-1ep9fjw tribe-editor__creatable-select__indicator tribe-editor__creatable-select__dropdown-indicator"
229
+ onMouseDown={[Function]}
230
+ onTouchEnd={[Function]}
231
+ >
232
+ <span
233
+ className="tribe-editor__creatable-select__dropdown-indicator"
234
+ >
235
+ arrow-down
236
+ </span>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ </div>
241
+ `;
common/src/modules/elements/creatable-select/__tests__/element.test.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import CreatableSelect from '../element.js';
10
+
11
+ const options = [
12
+ { label: 'Test 1', value: 'test-1' },
13
+ { label: 'Test 2', value: 'test-2' },
14
+ ];
15
+
16
+ describe( 'CreatableSelect element', () => {
17
+ it( 'Should render the component', () => {
18
+ const component = renderer.create( <CreatableSelect options={ options } /> );
19
+ expect( component.toJSON() ).toMatchSnapshot();
20
+ } );
21
+
22
+ it( 'Should render the component with class', () => {
23
+ const component = renderer.create( <CreatableSelect options={ options } className="test-class" /> );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+
27
+ it( 'Should render the component with extra props', () => {
28
+ const component = renderer.create( <CreatableSelect options={ options } isSearchable={ false } /> );
29
+ expect( component.toJSON() ).toMatchSnapshot();
30
+ } );
31
+ } );
common/src/modules/elements/creatable-select/element.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { components } from 'react-select';
8
+ import ReactCreatableSelect from 'react-select/lib/Creatable';
9
+ import { Dashicon } from '@wordpress/components';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import './style.pcss';
15
+
16
+ const DropdownIndicator = ( props ) => (
17
+ components.DropdownIndicator && (
18
+ <components.DropdownIndicator { ...props }>
19
+ <Dashicon
20
+ className="tribe-editor__creatable-select__dropdown-indicator"
21
+ icon={ 'arrow-down' }
22
+ />
23
+ </components.DropdownIndicator>
24
+ )
25
+ );
26
+
27
+ const IndicatorSeparator = () => null;
28
+
29
+ /**
30
+ * There seems to be an issue with Creatable and a custom isValidNewOption
31
+ * prop needs to be passed in for this to work.
32
+ *
33
+ * See:
34
+ * - https://github.com/JedWatson/react-select/issues/2630
35
+ * - https://github.com/JedWatson/react-select/issues/2944
36
+ */
37
+ const CreatableSelect = ( { className, ...rest } ) => (
38
+ <ReactCreatableSelect
39
+ className={ classNames( 'tribe-editor__creatable-select', className ) }
40
+ classNamePrefix="tribe-editor__creatable-select"
41
+ components={ { DropdownIndicator, IndicatorSeparator } }
42
+ { ...rest }
43
+ />
44
+ );
45
+
46
+ CreatableSelect.propTypes = {
47
+ className: PropTypes.string,
48
+ };
49
+
50
+ export default CreatableSelect;
common/src/modules/elements/creatable-select/style.pcss ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__creatable-select {
2
+
3
+ .tribe-editor__creatable-select__control {
4
+ height: 40px;
5
+ border: 1px solid #E1E3E6;
6
+ border-radius: 3px;
7
+ background-color: #FFFFFF;
8
+
9
+ &:hover {
10
+ border: 1px solid #E1E3E6;
11
+ }
12
+
13
+ &--is-focused {
14
+ box-shadow: none;
15
+ }
16
+ }
17
+
18
+ .tribe-editor__creatable-select__value-container {
19
+ padding: 2px 5px 2px 15px;
20
+ }
21
+
22
+ .tribe-editor__creatable-select__single-value {
23
+ margin: 0;
24
+ max-width: calc(100% - 15px);
25
+ font-size: 16px;
26
+ line-height: 1.5;
27
+ }
28
+
29
+ .tribe-editor__creatable-select__input {
30
+ font-size: 16px;
31
+
32
+ & > input {
33
+ margin: 0;
34
+ line-height: 1.5;
35
+
36
+ &,
37
+ &:focus {
38
+ box-shadow: none;
39
+ }
40
+ }
41
+ }
42
+
43
+ svg.tribe-editor__creatable-select__dropdown-indicator {
44
+ fill: #555D66;
45
+ }
46
+
47
+ .tribe-editor__creatable-select__menu {
48
+ margin: 0;
49
+ border: 1px solid #E1E3E6;
50
+ border-top: none;
51
+ border-radius: 0;
52
+ border-bottom-left-radius: 3px;
53
+ border-bottom-right-radius: 3px;
54
+ box-shadow: none;
55
+ transform: translateY(-7px);
56
+ }
57
+
58
+ .tribe-editor__creatable-select__menu-list {
59
+ padding: 0;
60
+ }
61
+
62
+ .tribe-editor__creatable-select__option {
63
+ font-size: 16px;
64
+ line-height: 1.5;
65
+ padding: 3px 15px;
66
+
67
+ &--is-focused {
68
+ background-color: #E7F5FA;
69
+ }
70
+
71
+ &--is-selected {
72
+ background-color: #11A0D2;
73
+ }
74
+ }
75
+ }
common/src/modules/elements/day-picker-input/element.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import classNames from 'classnames';
6
+ import 'react-day-picker/lib/style.css';
7
+ import ReactDayPickerInput from 'react-day-picker/DayPickerInput';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import './style.pcss';
13
+
14
+ const DayPickerInput = ( props ) => (
15
+ <ReactDayPickerInput
16
+ classNames={ {
17
+ container: classNames(
18
+ 'tribe-editor__day-picker-input',
19
+ 'DayPickerInput',
20
+ ),
21
+ overlayWrapper: classNames(
22
+ 'tribe-editor__day-picker-input__overlay-wrapper',
23
+ 'DayPickerInput-OverlayWrapper',
24
+ ),
25
+ overlay: classNames(
26
+ 'tribe-editor__day-picker-input__overlay',
27
+ 'DayPickerInput-Overlay',
28
+ ),
29
+ } }
30
+ { ...props }
31
+ />
32
+ );
33
+
34
+ export default DayPickerInput;
common/src/modules/elements/day-picker-input/style.pcss ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__day-picker-input.DayPickerInput {
2
+
3
+ & > input {
4
+ border: 1px solid #e1e3e6;
5
+ color: #545d66;
6
+ font-size: 16px;
7
+ line-height: 24px;
8
+ padding: 7px 15px;
9
+ width: 100%;
10
+ height: 40px;
11
+
12
+ &:disabled {
13
+ color: #AEB4BB;
14
+ }
15
+ }
16
+ }
17
+
18
+ /* -----------------------------------------------------------
19
+ DayPicker Input Calender Styles
20
+ ----------------------------------------------------------- */
21
+
22
+ .tribe-editor__day-picker-input {
23
+
24
+ .DayPickerInput-Overlay {
25
+ padding: 20px;
26
+ z-index: 10;
27
+ }
28
+
29
+ .DayPicker {
30
+ width: 100%;
31
+ }
32
+
33
+ .DayPicker-Month {
34
+ margin: 0;
35
+ }
36
+
37
+ .DayPicker-Caption > div,
38
+ .DayPicker-Weekday,
39
+ .DayPicker-Day {
40
+ color: #545d66;
41
+ font-family: 'Helvetica', 'sans-serif';
42
+ font-weight: normal;
43
+ }
44
+
45
+ .DayPicker-Caption > div {
46
+ font-size: 16px;
47
+ margin-bottom: 12px;
48
+ text-align: center;
49
+ }
50
+
51
+ .DayPicker-Weekday {
52
+ font-size: 12px;
53
+ }
54
+
55
+ .DayPicker-Day {
56
+ font-size: 14px;
57
+
58
+ &:hover {
59
+ color: #007bb4;
60
+ background-color: #ffffff;
61
+ }
62
+ }
63
+
64
+ .DayPicker-Day--today {
65
+ color: #545D66;
66
+ }
67
+
68
+ .DayPicker-Day--disabled {
69
+ pointer-events: none;
70
+ color: #cccccc;
71
+ }
72
+
73
+ .DayPicker-Day--selected:not(.DayPicker-Day--outside) {
74
+ border-radius: 0;
75
+ background-color: #009fd4;
76
+ color: #ffffff;
77
+
78
+ &:hover {
79
+ background-color: #007bb4;
80
+ color: #ffffff;
81
+ }
82
+ }
83
+
84
+ .DayPicker-NavButton--prev {
85
+ left: 0;
86
+ top: 0;
87
+ }
88
+
89
+ .DayPicker-NavButton--next {
90
+ right: 0;
91
+ top: 0;
92
+ }
93
+
94
+ .DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside) {
95
+
96
+ &:hover {
97
+ background-color: #ffffff;
98
+ }
99
+ }
100
+
101
+ .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside) {
102
+ background-color: #e7f5fa;
103
+ color: #545d66;
104
+
105
+ &:hover {
106
+ color: #007bb4;
107
+ }
108
+ }
109
+ }
common/src/modules/elements/heading/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<Heading> <h1> 1`] = `
4
+ <h1
5
+ className="tribe-editor__heading tribe-editor__heading--h1"
6
+ >
7
+ Modern Tribe
8
+ </h1>
9
+ `;
10
+
11
+ exports[`<Heading> <h2> 1`] = `
12
+ <h2
13
+ className="tribe-editor__heading tribe-editor__heading--h2"
14
+ >
15
+ Modern Tribe
16
+ </h2>
17
+ `;
18
+
19
+ exports[`<Heading> <h3> 1`] = `
20
+ <h3
21
+ className="tribe-editor__heading tribe-editor__heading--h3"
22
+ >
23
+ Modern Tribe
24
+ </h3>
25
+ `;
26
+
27
+ exports[`<Heading> <h4> 1`] = `
28
+ <h4
29
+ className="tribe-editor__heading tribe-editor__heading--h4"
30
+ >
31
+ Modern Tribe
32
+ </h4>
33
+ `;
34
+
35
+ exports[`<Heading> <h5> 1`] = `
36
+ <h5
37
+ className="tribe-editor__heading tribe-editor__heading--h5"
38
+ >
39
+ Modern Tribe
40
+ </h5>
41
+ `;
42
+
43
+ exports[`<Heading> <h6> 1`] = `
44
+ <h6
45
+ className="tribe-editor__heading tribe-editor__heading--h6"
46
+ >
47
+ Modern Tribe
48
+ </h6>
49
+ `;
common/src/modules/elements/heading/__tests__/element.test.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ import Heading from '../element';
4
+
5
+ describe( '<Heading>', () => {
6
+ test( '<h1>', () => {
7
+ const component = renderer.create(
8
+ <Heading level={ 1 }>Modern Tribe</Heading>,
9
+ );
10
+ expect( component.toJSON() ).toMatchSnapshot();
11
+ } );
12
+
13
+ test( '<h2>', () => {
14
+ const component = renderer.create(
15
+ <Heading level={ 2 }>Modern Tribe</Heading>,
16
+ );
17
+ expect( component.toJSON() ).toMatchSnapshot();
18
+ } );
19
+
20
+ test( '<h3>', () => {
21
+ const component = renderer.create(
22
+ <Heading level={ 3 }>Modern Tribe</Heading>,
23
+ );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+
27
+ test( '<h4>', () => {
28
+ const component = renderer.create(
29
+ <Heading level={ 4 }>Modern Tribe</Heading>,
30
+ );
31
+ expect( component.toJSON() ).toMatchSnapshot();
32
+ } );
33
+
34
+ test( '<h5>', () => {
35
+ const component = renderer.create(
36
+ <Heading level={ 5 }>Modern Tribe</Heading>,
37
+ );
38
+ expect( component.toJSON() ).toMatchSnapshot();
39
+ } );
40
+
41
+ test( '<h6>', () => {
42
+ const component = renderer.create(
43
+ <Heading level={ 6 }>Modern Tribe</Heading>,
44
+ );
45
+ expect( component.toJSON() ).toMatchSnapshot();
46
+ } );
47
+ } );
common/src/modules/elements/heading/element.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.pcss';
12
+
13
+ const Heading = ( { level, children, className } ) => {
14
+ const HeadingLevel = `h${ level }`;
15
+ const headingClassName = classNames(
16
+ 'tribe-editor__heading',
17
+ `tribe-editor__heading--h${ level }`,
18
+ className,
19
+ );
20
+ return (
21
+ <HeadingLevel className={ headingClassName }>
22
+ { children }
23
+ </HeadingLevel>
24
+ );
25
+ };
26
+
27
+ Heading.propTypes = {
28
+ children: PropTypes.node.isRequired,
29
+ level: PropTypes.oneOf( [ 1, 2, 3, 4, 5, 6 ] ).isRequired,
30
+ };
31
+
32
+ export default Heading;
common/src/modules/elements/heading/style.pcss ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__heading {
2
+ font-family: 'Helvetica', 'Arial', 'sans-serif';
3
+ color: #000;
4
+ }
5
+
6
+ .tribe-editor__heading--h1 {
7
+ font-size: 2.375rem; /* 38pts */
8
+ }
9
+
10
+ .tribe-editor__heading--h2 {
11
+ font-size: 1.3125rem; /* 21pts */
12
+ }
13
+
14
+ .tribe-editor__heading--h3 {
15
+ font-size: 1rem; /* 16pts */
16
+ }
common/src/modules/elements/image-upload/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ImageUpload renders the component 1`] = `
4
+ <div
5
+ className="tribe-editor__image-upload"
6
+ >
7
+ <div
8
+ className="tribe-editor__image-upload__content"
9
+ >
10
+ <button>
11
+ Media Upload
12
+ </button>
13
+ </div>
14
+ </div>
15
+ `;
16
+
17
+ exports[`ImageUpload renders upload image button 1`] = `
18
+ <div
19
+ className="tribe-editor__image-upload"
20
+ >
21
+ <div
22
+ className="tribe-editor__image-upload__content"
23
+ >
24
+ <button>
25
+ Media Upload
26
+ </button>
27
+ </div>
28
+ </div>
29
+ `;
30
+
31
+ exports[`ImageUpload renders uploaded image 1`] = `
32
+ <div
33
+ className="tribe-editor__image-upload tribe-editor__image-upload--has-image"
34
+ >
35
+ <div
36
+ className="tribe-editor__image-upload__content"
37
+ >
38
+ <div
39
+ className="tribe-editor__image-upload__image-wrapper"
40
+ >
41
+ <img
42
+ alt="test-alt"
43
+ className="tribe-editor__image tribe-editor__image-upload__image"
44
+ src="test-src"
45
+ />
46
+ <button
47
+ className="tribe-editor__button tribe-editor__image-upload__remove-button"
48
+ onClick={[MockFunction]}
49
+ type="button"
50
+ >
51
+ <span>
52
+ icon
53
+ </span>
54
+ <span
55
+ className="tribe-editor__image-upload__remove-button-text"
56
+ >
57
+ remove
58
+ </span>
59
+ </button>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ `;
64
+
65
+ exports[`ImageUpload renders with class 1`] = `
66
+ <div
67
+ className="tribe-editor__image-upload test-class"
68
+ >
69
+ <div
70
+ className="tribe-editor__image-upload__content"
71
+ >
72
+ <button>
73
+ Media Upload
74
+ </button>
75
+ </div>
76
+ </div>
77
+ `;
78
+
79
+ exports[`ImageUpload renders with description 1`] = `
80
+ <div
81
+ className="tribe-editor__image-upload"
82
+ >
83
+ <div
84
+ className="tribe-editor__image-upload__content"
85
+ >
86
+ <p
87
+ className="tribe-editor__image-upload__description"
88
+ >
89
+ The Next Generation of Digital Agency
90
+ </p>
91
+ <button>
92
+ Media Upload
93
+ </button>
94
+ </div>
95
+ </div>
96
+ `;
97
+
98
+ exports[`ImageUpload renders with title 1`] = `
99
+ <div
100
+ className="tribe-editor__image-upload"
101
+ >
102
+ <h3
103
+ className="tribe-editor__image-upload__title"
104
+ >
105
+ Modern Tribe
106
+ </h3>
107
+ <div
108
+ className="tribe-editor__image-upload__content"
109
+ >
110
+ <button>
111
+ Media Upload
112
+ </button>
113
+ </div>
114
+ </div>
115
+ `;
116
+
117
+ exports[`renderImage renders the image and button 1`] = `
118
+ <div
119
+ className="tribe-editor__image-upload__image-wrapper"
120
+ >
121
+ <img
122
+ alt="test-alt"
123
+ className="tribe-editor__image tribe-editor__image-upload__image"
124
+ src="test-src"
125
+ />
126
+ <button
127
+ className="tribe-editor__button tribe-editor__image-upload__remove-button"
128
+ disabled={false}
129
+ onClick={[MockFunction]}
130
+ type="button"
131
+ >
132
+ <span>
133
+ icon
134
+ </span>
135
+ <span
136
+ className="tribe-editor__image-upload__remove-button-text"
137
+ >
138
+ remove
139
+ </span>
140
+ </button>
141
+ </div>
142
+ `;
143
+
144
+ exports[`renderImage renders the image and disabled button 1`] = `
145
+ <div
146
+ className="tribe-editor__image-upload__image-wrapper"
147
+ >
148
+ <img
149
+ alt="test-alt"
150
+ className="tribe-editor__image tribe-editor__image-upload__image"
151
+ src="test-src"
152
+ />
153
+ <button
154
+ className="tribe-editor__button tribe-editor__image-upload__remove-button"
155
+ disabled={true}
156
+ onClick={[MockFunction]}
157
+ type="button"
158
+ >
159
+ <span>
160
+ icon
161
+ </span>
162
+ <span
163
+ className="tribe-editor__image-upload__remove-button-text"
164
+ >
165
+ remove
166
+ </span>
167
+ </button>
168
+ </div>
169
+ `;
170
+
171
+ exports[`renderImageUploadButton renders the button 1`] = `
172
+ <button
173
+ className="tribe-editor__button tribe-editor__button--sm tribe-editor__image-upload__upload-button"
174
+ disabled={false}
175
+ onClick={[MockFunction]}
176
+ type="button"
177
+ >
178
+ label
179
+ </button>
180
+ `;
181
+
182
+ exports[`renderImageUploadButton renders the button disabled 1`] = `
183
+ <button
184
+ className="tribe-editor__button tribe-editor__button--sm tribe-editor__image-upload__upload-button"
185
+ disabled={true}
186
+ onClick={[MockFunction]}
187
+ type="button"
188
+ >
189
+ label
190
+ </button>
191
+ `;
common/src/modules/elements/image-upload/__tests__/element.test.js ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import ImageUpload, {
10
+ renderImageUploadButton,
11
+ renderImage,
12
+ } from '@moderntribe/common/elements/image-upload/element';
13
+
14
+ jest.mock( '@wordpress/editor', () => ( {
15
+ MediaUpload: () => ( <button>Media Upload</button> ),
16
+ } ) );
17
+
18
+ jest.mock( '@moderntribe/common/icons', () => ( {
19
+ Close: () => <span>icon</span>,
20
+ } ) );
21
+
22
+ describe( 'renderImageUploadButton', () => {
23
+ const open = jest.fn();
24
+
25
+ afterEach( () => {
26
+ open.mockClear();
27
+ } );
28
+
29
+ it( 'renders the button', () => {
30
+ const component = renderer.create( renderImageUploadButton( false, 'label' )( { open } ) );
31
+ expect( component.toJSON() ).toMatchSnapshot();
32
+ } );
33
+
34
+ it( 'renders the button disabled', () => {
35
+ const component = renderer.create( renderImageUploadButton( true, 'label' )( { open } ) );
36
+ expect( component.toJSON() ).toMatchSnapshot();
37
+ } );
38
+
39
+ it( 'executes the open action when the mediaUpload is fired', () => {
40
+ const component = mount( renderImageUploadButton( false, 'label' )( { open } ) );
41
+ component.find( 'button' ).simulate( 'click' );
42
+ expect( open ).toHaveBeenCalled();
43
+ expect( open ).toHaveBeenCalledTimes( 1 );
44
+ } );
45
+ } );
46
+
47
+ describe( 'renderImage', () => {
48
+ const onRemove = jest.fn();
49
+ const image = {
50
+ id: 42,
51
+ src: 'test-src',
52
+ alt: 'test-alt',
53
+ };
54
+
55
+ afterEach( () => {
56
+ onRemove.mockClear();
57
+ } );
58
+
59
+ it( 'renders the image and button', () => {
60
+ const component = renderer.create( renderImage( false, image, onRemove ) );
61
+ expect( component.toJSON() ).toMatchSnapshot();
62
+ } );
63
+
64
+ it( 'renders the image and disabled button', () => {
65
+ const component = renderer.create( renderImage( true, image, onRemove ) );
66
+ expect( component.toJSON() ).toMatchSnapshot();
67
+ } );
68
+
69
+ it( 'executes onRemove on click', () => {
70
+ const component = mount( renderImage( false, image, onRemove ) );
71
+ component.find( 'button' ).simulate( 'click' );
72
+ expect( onRemove ).toHaveBeenCalled();
73
+ expect( onRemove ).toHaveBeenCalledTimes( 1 );
74
+ } );
75
+ } );
76
+
77
+ describe( 'ImageUpload', () => {
78
+ const onRemove = jest.fn();
79
+ const onSelect = jest.fn();
80
+ let image;
81
+
82
+ beforeEach( () => {
83
+ image = {
84
+ id: 0,
85
+ src: '',
86
+ alt: '',
87
+ };
88
+ } );
89
+
90
+ afterEach( () => {
91
+ onRemove.mockClear();
92
+ onSelect.mockClear();
93
+ } );
94
+
95
+ it( 'renders the component', () => {
96
+ const component = renderer.create(
97
+ <ImageUpload
98
+ image={ image }
99
+ onSelect={ onSelect }
100
+ onRemove={ onRemove }
101
+ />
102
+ );
103
+ expect( component.toJSON() ).toMatchSnapshot();
104
+ } );
105
+
106
+ it( 'renders with title', () => {
107
+ const component = renderer.create(
108
+ <ImageUpload
109
+ image={ image }
110
+ onSelect={ onSelect }
111
+ onRemove={ onRemove }
112
+ title="Modern Tribe"
113
+ />
114
+ );
115
+ expect( component.toJSON() ).toMatchSnapshot();
116
+ } );
117
+
118
+ it( 'renders with description', () => {
119
+ const component = renderer.create(
120
+ <ImageUpload
121
+ image={ image }
122
+ onSelect={ onSelect}
123
+ onRemove={ onRemove }
124
+ description="The Next Generation of Digital Agency"
125
+ />
126
+ );
127
+ expect( component.toJSON() ).toMatchSnapshot();
128
+ } );
129
+
130
+ it( 'renders with class', () => {
131
+ const component = renderer.create(
132
+ <ImageUpload
133
+ image={ image }
134
+ onSelect={ onSelect }
135
+ onRemove={ onRemove }
136
+ className="test-class"
137
+ />
138
+ );
139
+ expect( component.toJSON() ).toMatchSnapshot();
140
+ } );
141
+
142
+ it( 'renders uploaded image', () => {
143
+ image = {
144
+ id: 42,
145
+ src: 'test-src',
146
+ alt: 'test-alt',
147
+ };
148
+ const component = renderer.create(
149
+ <ImageUpload
150
+ image={ image }
151
+ onSelect={ onSelect }
152
+ onRemove={ onRemove }
153
+ />
154
+ );
155
+ expect( component.toJSON() ).toMatchSnapshot();
156
+ } );
157
+
158
+ it( 'renders upload image button', () => {
159
+ const component = renderer.create(
160
+ <ImageUpload
161
+ image={ image }
162
+ onSelect={ onSelect }
163
+ onRemove={ onRemove }
164
+ />
165
+ );
166
+ expect( component.toJSON() ).toMatchSnapshot();
167
+ } );
168
+ } );
common/src/modules/elements/image-upload/element.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { noop } from 'lodash';
8
+
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ import { __ } from '@wordpress/i18n';
13
+ import { MediaUpload } from '@wordpress/editor';
14
+
15
+ /**
16
+ * Internal dependencies
17
+ */
18
+ import { Button, Image } from '@moderntribe/common/elements';
19
+ import { Close as CloseIcon } from '@moderntribe/common/icons';
20
+ import './style.pcss';
21
+
22
+ export const renderImageUploadButton = ( disabled, label ) => ( { open } ) => (
23
+ <Button
24
+ onClick={ open }
25
+ className={ [ 'tribe-editor__button--sm', 'tribe-editor__image-upload__upload-button' ] }
26
+ disabled={ disabled }
27
+ >
28
+ { label }
29
+ </Button>
30
+ );
31
+
32
+ export const renderImage = ( disabled, image, onRemove ) => (
33
+ <div className="tribe-editor__image-upload__image-wrapper">
34
+ <Image
35
+ src={ image.src }
36
+ alt={ image.alt }
37
+ className="tribe-editor__image-upload__image"
38
+ />
39
+ <Button
40
+ className="tribe-editor__image-upload__remove-button"
41
+ onClick={ onRemove }
42
+ disabled={ disabled }
43
+ >
44
+ <CloseIcon />
45
+ <span className="tribe-editor__image-upload__remove-button-text">
46
+ { __( 'remove', 'tribe-common' ) }
47
+ </span>
48
+ </Button>
49
+ </div>
50
+ );
51
+
52
+ const ImageUpload = ( {
53
+ buttonDisabled,
54
+ buttonLabel,
55
+ className,
56
+ description,
57
+ image,
58
+ onRemove,
59
+ onSelect,
60
+ removeButtonDisabled,
61
+ title,
62
+ } ) => {
63
+ const hasImageClass = { 'tribe-editor__image-upload--has-image': image.id };
64
+
65
+ return (
66
+ <div className={ classNames(
67
+ 'tribe-editor__image-upload',
68
+ hasImageClass,
69
+ className,
70
+ ) }>
71
+ { title && <h3 className="tribe-editor__image-upload__title">{ title }</h3> }
72
+ <div className="tribe-editor__image-upload__content">
73
+ { description && (
74
+ <p className="tribe-editor__image-upload__description">{ description }</p>
75
+ ) }
76
+ {
77
+ image.id
78
+ ? renderImage( removeButtonDisabled, image, onRemove )
79
+ : (
80
+ <MediaUpload
81
+ onSelect={ onSelect }
82
+ type="image"
83
+ render={ renderImageUploadButton( buttonDisabled, buttonLabel ) }
84
+ value={ image.id }
85
+ />
86
+ )
87
+ }
88
+ </div>
89
+ </div>
90
+ );
91
+ };
92
+
93
+ ImageUpload.propTypes = {
94
+ buttonDisabled: PropTypes.bool,
95
+ buttonLabel: PropTypes.string,
96
+ className: PropTypes.string,
97
+ description: PropTypes.string,
98
+ image: PropTypes.shape( {
99
+ alt: PropTypes.string.isRequired,
100
+ id: PropTypes.number.isRequired,
101
+ src: PropTypes.string.isRequired,
102
+ } ).isRequired,
103
+ onRemove: PropTypes.func.isRequired,
104
+ onSelect: PropTypes.func.isRequired,
105
+ removeButtonDisabled: PropTypes.bool,
106
+ title: PropTypes.string,
107
+ };
108
+
109
+ ImageUpload.defaultProps = {
110
+ onRemove: noop,
111
+ onSelect: noop,
112
+ };
113
+
114
+ export default ImageUpload;
common/src/modules/elements/image-upload/style.pcss ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__image-upload {}
2
+
3
+ .tribe-editor__image-upload__title {
4
+
5
+ /* extra classes to override gutenberg styles for h3 */
6
+ .edit-post-visual-editor .editor-block-list__block & {
7
+ padding: 0;
8
+ margin: 0 0 12px;
9
+ color: #000000;
10
+ font-size: 15px;
11
+ font-weight: bold;
12
+ line-height: 18px;
13
+ }
14
+ }
15
+
16
+ .tribe-editor__image-upload__content {
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+
21
+ .tribe-editor__image-upload--has-image & {
22
+ align-items: flex-start;
23
+ }
24
+ }
25
+
26
+ p.tribe-editor__image-upload__description {
27
+
28
+ .tribe-editor__image-upload__content & {
29
+ flex: none;
30
+ width: 52%;
31
+ font-family: Helvetica, sans-serif, arial;
32
+ font-size: 14px;
33
+ color: #545D66;
34
+ line-height: 18px;
35
+ margin: 0;
36
+ }
37
+ }
38
+
39
+ .tribe-editor__image-upload__upload-button {
40
+ flex: none;
41
+ margin-right: 10px;
42
+ }
43
+
44
+ .tribe-editor__image-upload__image-wrapper {
45
+ flex: none;
46
+ width: 42%;
47
+ max-width: 325px;
48
+ padding-left: 25px;
49
+ position: relative;
50
+ }
51
+
52
+ .tribe-editor__image-upload__remove-button {
53
+ position: absolute;
54
+ top: 10px;
55
+ right: 10px;
56
+ width: 32px;
57
+ height: 32px;
58
+ padding: 8px;
59
+ border-radius: 50%;
60
+ background-color: #F8F9FB;
61
+
62
+ & > svg {
63
+
64
+ &,
65
+ & path {
66
+ fill: #545D66;
67
+ }
68
+ }
69
+
70
+ &:hover,
71
+ &:focus {
72
+
73
+ & > svg {
74
+
75
+ &,
76
+ & path {
77
+ fill: #009FD4;
78
+ }
79
+ }
80
+ }
81
+
82
+ &:disabled {
83
+
84
+ &,
85
+ &:hover,
86
+ &:focus {
87
+
88
+ & > svg {
89
+
90
+ &,
91
+ & path {
92
+ fill: #AEB4BB;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ /* visually hide remove button text */
100
+ .tribe-editor__image-upload__remove-button-text {
101
+ border: 0;
102
+ clip: rect(0 0 0 0);
103
+ height: 1px;
104
+ margin: -1px;
105
+ overflow: hidden;
106
+ padding: 0;
107
+ position: absolute;
108
+ width: 1px;
109
+ }
common/src/modules/elements/image/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Image Element renders image 1`] = `
4
+ <img
5
+ alt="test-alt"
6
+ className="tribe-editor__image"
7
+ src="test-src"
8
+ />
9
+ `;
10
+
11
+ exports[`Image Element renders image with class 1`] = `
12
+ <img
13
+ alt="test-alt"
14
+ className="tribe-editor__image test-class"
15
+ src="test-src"
16
+ />
17
+ `;
18
+
19
+ exports[`Image Element renders image with extra props 1`] = `
20
+ <img
21
+ alt="test-alt"
22
+ className="tribe-editor__image"
23
+ height="42"
24
+ src="test-src"
25
+ width="42"
26
+ />
27
+ `;
common/src/modules/elements/image/__tests__/element.test.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { Image } from '@moderntribe/common/elements';
10
+
11
+ let imageProps;
12
+
13
+ describe( 'Image Element', () => {
14
+ beforeEach( () => {
15
+ imageProps = {
16
+ src: 'test-src',
17
+ alt: 'test-alt',
18
+ };
19
+ } );
20
+
21
+ it( 'renders image', () => {
22
+ const component = renderer.create( <Image { ...imageProps } /> );
23
+ expect( component.toJSON() ).toMatchSnapshot();
24
+ } );
25
+
26
+ it( 'renders image with class', () => {
27
+ imageProps.className = 'test-class';
28
+ const component = renderer.create( <Image { ...imageProps } /> );
29
+ expect( component.toJSON() ).toMatchSnapshot();
30
+ } );
31
+
32
+ it( 'renders image with extra props', () => {
33
+ imageProps.width = "42";
34
+ imageProps.height = "42";
35
+ const component = renderer.create( <Image { ...imageProps } /> );
36
+ expect( component.toJSON() ).toMatchSnapshot();
37
+ } );
38
+ } );
common/src/modules/elements/image/element.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ const Image = ( {
9
+ alt,
10
+ className,
11
+ src,
12
+ ...rest,
13
+ } ) => (
14
+ <img
15
+ src={ src }
16
+ alt={ alt }
17
+ className={ classNames( 'tribe-editor__image', className ) }
18
+ { ...rest }
19
+ />
20
+ );
21
+
22
+ Image.propTypes = {
23
+ alt: PropTypes.string.isRequired,
24
+ className: PropTypes.string,
25
+ src: PropTypes.string.isRequired,
26
+ };
27
+
28
+ export default Image;
common/src/modules/elements/index.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export { default as Accordion } from './accordion/element';
2
+ export { default as BlockIcon } from '@moderntribe/common/elements/block-icon';
3
+ export { default as Button } from './button/element';
4
+
5
+ export { default as Counter } from './counter/element';
6
+ export { default as Image } from './image/element';
7
+ export { default as ImageUpload } from './image-upload/element';
8
+ export { default as LabeledItem } from './labeled-item/element';
9
+ export { default as LabelWithLink } from './label-with-link/element';
10
+ export { default as LabelWithModal } from './label-with-modal/element';
11
+ export { default as Link } from './link/element';
12
+ export { default as ModalButton } from './modal-button/element';
13
+ export { default as TimePicker } from './time-picker/element';
14
+ export { default as Tooltip } from './tooltip/element';
15
+ export { default as DayPickerInput } from './day-picker-input/element';
16
+ export { default as CreatableSelect } from './creatable-select/element';
17
+ export { default as Placeholder } from './placeholder/element';
18
+ export { default as Heading } from './heading/element';
19
+ export { default as Paragraph } from './paragraph/element';
20
+
21
+ // Inputs
22
+ export { default as Input } from './input/element';
23
+ export { default as UrlInput } from './url-input/element';
24
+ export { default as NumberInput } from './number-input/element';
25
+ export { default as Radio } from './radio/element';
26
+ export { default as RadioInput } from './radio-input/element';
27
+ export { default as Checkbox } from './checkbox/element';
28
+ export { default as CheckboxInput } from './checkbox-input/element';
29
+ export { default as Select } from './select/element';
30
+ export { default as Textarea } from './textarea/element';
31
+
32
+ /**
33
+ * @todo move this into Editor Module
34
+ */
35
+
36
+ import './style.pcss'
common/src/modules/elements/input/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Input element Should render the component 1`] = `
4
+ <input
5
+ className="tribe-editor__input"
6
+ type="text"
7
+ />
8
+ `;
9
+
10
+ exports[`Input element Should render the component with class 1`] = `
11
+ <input
12
+ className="tribe-editor__input input-class"
13
+ type="text"
14
+ />
15
+ `;
16
+
17
+ exports[`Input element Should render the component with extra props 1`] = `
18
+ <input
19
+ className="tribe-editor__input"
20
+ onChange={[Function]}
21
+ type="text"
22
+ />
23
+ `;
common/src/modules/elements/input/__tests__/element.test.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+ import { noop } from 'lodash';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Input from '../element.js';
12
+
13
+ describe( 'Input element', () => {
14
+ it( 'Should render the component', () => {
15
+ const component = renderer.create( <Input type="text" /> );
16
+ expect( component.toJSON() ).toMatchSnapshot();
17
+ } );
18
+
19
+ it( 'Should render the component with class', () => {
20
+ const component = renderer.create( <Input type="text" className="input-class" /> );
21
+ expect( component.toJSON() ).toMatchSnapshot();
22
+ } );
23
+
24
+ it( 'Should render the component with extra props', () => {
25
+ const component = renderer.create( <Input type="text" onChange={ noop } /> );
26
+ expect( component.toJSON() ).toMatchSnapshot();
27
+ } );
28
+ } );
common/src/modules/elements/input/element.js ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.pcss';
12
+
13
+ const Input = ( {
14
+ className,
15
+ type,
16
+ ...rest,
17
+ } ) => (
18
+ <input
19
+ className={ classNames( 'tribe-editor__input', className ) }
20
+ type={ type }
21
+ { ...rest }
22
+ />
23
+ );
24
+
25
+ Input.propTypes = {
26
+ className: PropTypes.string,
27
+ type: PropTypes.string.isRequired,
28
+ };
29
+
30
+ export default Input;
common/src/modules/elements/input/style.pcss ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* increased specificity required to override gutenberg editor styles */
2
+ input.tribe-editor__input {
3
+
4
+ /* this list will grow with more input types used */
5
+ &[type=number],
6
+ &[type=text] {
7
+ color: #000000;
8
+ font-size: 16px;
9
+ line-height: 24px;
10
+ border: 1px solid #E1E3E6;
11
+ padding: 7px 15px;
12
+ margin: 0;
13
+ height: 40px;
14
+
15
+ &:focus {
16
+ color: #000000;
17
+ box-shadow: none;
18
+ outline: none;
19
+ }
20
+
21
+ &:disabled {
22
+ color: #AEB4BB;
23
+ }
24
+ }
25
+ }
common/src/modules/elements/label-with-link/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Label With Link Element renders a label with link 1`] = `
4
+ <div
5
+ className="tribe-editor__labeled-item tribe-editor__label-with-link"
6
+ >
7
+ <span
8
+ className="tribe-editor__labeled-item__label"
9
+ />
10
+ <a
11
+ className="tribe-editor__link tribe-editor__label-with-link__link"
12
+ href="#"
13
+ >
14
+ test-text
15
+ </a>
16
+ </div>
17
+ `;
18
+
19
+ exports[`Label With Link Element renders a label with link with class 1`] = `
20
+ <div
21
+ className="tribe-editor__labeled-item tribe-editor__label-with-link test-class"
22
+ >
23
+ <span
24
+ className="tribe-editor__labeled-item__label"
25
+ />
26
+ <a
27
+ className="tribe-editor__link tribe-editor__label-with-link__link"
28
+ href="#"
29
+ >
30
+ test-text
31
+ </a>
32
+ </div>
33
+ `;
34
+
35
+ exports[`Label With Link Element renders a label with link with label 1`] = `
36
+ <div
37
+ className="tribe-editor__labeled-item tribe-editor__label-with-link"
38
+ >
39
+ <span
40
+ className="tribe-editor__labeled-item__label"
41
+ >
42
+ test label
43
+ </span>
44
+ <a
45
+ className="tribe-editor__link tribe-editor__label-with-link__link"
46
+ href="#"
47
+ >
48
+ test-text
49
+ </a>
50
+ </div>
51
+ `;
common/src/modules/elements/label-with-link/__tests__/element.test.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import LabelWithLink from '../element';
10
+
11
+ describe( 'Label With Link Element', () => {
12
+ it( 'renders a label with link', () => {
13
+ const component = renderer.create(
14
+ <LabelWithLink linkHref="#" linkText="test-text" />
15
+ );
16
+ expect( component.toJSON() ).toMatchSnapshot();
17
+ } );
18
+
19
+ it( 'renders a label with link with class', () => {
20
+ const component = renderer.create(
21
+ <LabelWithLink linkHref="#" linkText="test-text" className="test-class" />
22
+ );
23
+ expect( component.toJSON() ).toMatchSnapshot();
24
+ } );
25
+
26
+ it( 'renders a label with link with label', () => {
27
+ const component = renderer.create(
28
+ <LabelWithLink linkHref="#" linkText="test-text" label="test label" />
29
+ );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+ } );
common/src/modules/elements/label-with-link/element.js ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Button from '@moderntribe/common/elements/button/element';
12
+ import LabeledItem from '@moderntribe/common/elements/labeled-item/element';
13
+ import Link from '@moderntribe/common/elements/link/element';
14
+ import './style.pcss';
15
+
16
+ const LabelWithLink = ( {
17
+ className,
18
+ label,
19
+ linkDisabled,
20
+ linkHref,
21
+ linkTarget,
22
+ linkText,
23
+ } ) => {
24
+ const getLink = () => {
25
+ const linkClass = 'tribe-editor__label-with-link__link';
26
+
27
+ return linkDisabled
28
+ ? (
29
+ <Button
30
+ className={ classNames( linkClass, `${ linkClass }--disabled` ) }
31
+ disabled={ true }
32
+ >
33
+ { linkText }
34
+ </Button>
35
+ )
36
+ : (
37
+ <Link
38
+ className={ linkClass }
39
+ href={ linkHref }
40
+ target={ linkTarget }
41
+ >
42
+ { linkText }
43
+ </Link>
44
+ );
45
+ };
46
+
47
+ return (
48
+ <LabeledItem
49
+ className={ classNames( 'tribe-editor__label-with-link', className ) }
50
+ label={ label }
51
+ >
52
+ { getLink() }
53
+ </LabeledItem>
54
+ );
55
+ };
56
+
57
+ LabelWithLink.propTypes = {
58
+ className: PropTypes.string,
59
+ label: PropTypes.node,
60
+ linkDisabled: PropTypes.bool,
61
+ linkHref: PropTypes.string.isRequired,
62
+ linkTarget: PropTypes.string,
63
+ linkText: PropTypes.string,
64
+ };
65
+
66
+ export default LabelWithLink;
common/src/modules/elements/label-with-link/style.pcss ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__label-with-link {
2
+
3
+ .tribe-editor__rsvp &,
4
+ .tribe-editor__ticket & {
5
+ display: flex;
6
+ align-items: center;
7
+ background-color: #FFFFFF;
8
+ padding: 10px 17px;
9
+ border: 1px solid #E1E3E6;
10
+ }
11
+
12
+ .tribe-editor__labeled-item__label {
13
+
14
+ .tribe-editor__rsvp &,
15
+ .tribe-editor__ticket & {
16
+ flex: auto;
17
+ color: #545D66;
18
+ font-size: 15px;
19
+ font-weight: bold;
20
+ line-height: 18px;
21
+ letter-spacing: 0.38px;
22
+ padding-right: 10px;
23
+ }
24
+ }
25
+
26
+ .tribe-editor__label-with-link__link {
27
+
28
+ .tribe-editor__rsvp &,
29
+ .tribe-editor__ticket & {
30
+ flex: none;
31
+ color: #009FD4;
32
+ font-size: 15px;
33
+ font-weight: bold;
34
+ line-height: 18px;
35
+ letter-spacing: 0.38px;
36
+ text-decoration: none;
37
+ box-shadow: none;
38
+ transition: color 0.2s ease;
39
+
40
+ &:hover,
41
+ &:focus {
42
+ color: #007BB4;
43
+ }
44
+ }
45
+ }
46
+
47
+ .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled {
48
+
49
+ .tribe-editor__rsvp &,
50
+ .tribe-editor__ticket & {
51
+ color: #AEB4BB;
52
+ }
53
+ }
54
+ }
common/src/modules/elements/label-with-modal/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Label With Modal Element renders a label with modal 1`] = `
4
+ <div
5
+ className="tribe-editor__labeled-item tribe-editor__label-with-modal"
6
+ >
7
+ <span
8
+ className="tribe-editor__labeled-item__label"
9
+ />
10
+ <div
11
+ className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
12
+ >
13
+ <button
14
+ className="tribe-editor__button tribe-editor__modal-button__button"
15
+ onClick={[Function]}
16
+ type="button"
17
+ />
18
+ </div>
19
+ </div>
20
+ `;
21
+
22
+ exports[`Label With Modal Element renders a label with modal with class 1`] = `
23
+ <div
24
+ className="tribe-editor__labeled-item tribe-editor__label-with-modal test-class"
25
+ >
26
+ <span
27
+ className="tribe-editor__labeled-item__label"
28
+ />
29
+ <div
30
+ className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
31
+ >
32
+ <button
33
+ className="tribe-editor__button tribe-editor__modal-button__button"
34
+ onClick={[Function]}
35
+ type="button"
36
+ />
37
+ </div>
38
+ </div>
39
+ `;
40
+
41
+ exports[`Label With Modal Element renders a label with modal with label 1`] = `
42
+ <div
43
+ className="tribe-editor__labeled-item tribe-editor__label-with-modal"
44
+ >
45
+ <span
46
+ className="tribe-editor__labeled-item__label"
47
+ >
48
+ test label
49
+ </span>
50
+ <div
51
+ className="tribe-editor__modal-button tribe-editor__label-with-modal__modal-button"
52
+ >
53
+ <button
54
+ className="tribe-editor__button tribe-editor__modal-button__button"
55
+ onClick={[Function]}
56
+ type="button"
57
+ />
58
+ </div>
59
+ </div>
60
+ `;
common/src/modules/elements/label-with-modal/__tests__/element.test.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import LabelWithModal from '@moderntribe/common/elements/label-with-modal/element';
10
+
11
+ describe( 'Label With Modal Element', () => {
12
+ it( 'renders a label with modal', () => {
13
+ const component = renderer.create( <LabelWithModal /> );
14
+ expect( component.toJSON() ).toMatchSnapshot();
15
+ } );
16
+
17
+ it( 'renders a label with modal with class', () => {
18
+ const component = renderer.create( <LabelWithModal className="test-class" /> );
19
+ expect( component.toJSON() ).toMatchSnapshot();
20
+ } );
21
+
22
+ it( 'renders a label with modal with label', () => {
23
+ const component = renderer.create( <LabelWithModal label="test label" /> );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+ } );
common/src/modules/elements/label-with-modal/element.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { noop } from 'lodash';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import LabeledItem from '@moderntribe/common/elements/labeled-item/element';
13
+ import ModalButton from '@moderntribe/common/elements/modal-button/element';
14
+ import './style.pcss';
15
+
16
+ const LabelWithModal = ( {
17
+ className,
18
+ isOpen,
19
+ label,
20
+ modalButtonDisabled,
21
+ modalButtonLabel,
22
+ modalClassName,
23
+ modalContent,
24
+ modalOverlayClassName,
25
+ modalTitle,
26
+ onClick,
27
+ onClose,
28
+ onOpen,
29
+ } ) => (
30
+ <LabeledItem
31
+ className={ classNames( 'tribe-editor__label-with-modal', className ) }
32
+ label={ label }
33
+ >
34
+ <ModalButton
35
+ className="tribe-editor__label-with-modal__modal-button"
36
+ disabled={ modalButtonDisabled }
37
+ isOpen={ isOpen }
38
+ label={ modalButtonLabel }
39
+ modalClassName={ modalClassName }
40
+ modalContent={ modalContent }
41
+ modalOverlayClassName={ modalOverlayClassName }
42
+ modalTitle={ modalTitle }
43
+ onClick={ onClick }
44
+ onClose={ onClose }
45
+ onOpen={ onOpen }
46
+ />
47
+ </LabeledItem>
48
+ );
49
+
50
+ LabelWithModal.defaultProps = {
51
+ onClick: noop,
52
+ onClose: noop,
53
+ onOpen: noop,
54
+ };
55
+
56
+ LabelWithModal.propTypes = {
57
+ className: PropTypes.string,
58
+ isOpen: PropTypes.bool,
59
+ label: PropTypes.node,
60
+ modalButtonDisabled: PropTypes.bool,
61
+ modalButtonLabel: PropTypes.string,
62
+ modalClassName: PropTypes.string,
63
+ modalContent: PropTypes.node,
64
+ modalOverlayClassName: PropTypes.string,
65
+ modalTitle: PropTypes.string,
66
+ onClick: PropTypes.func,
67
+ onClose: PropTypes.func,
68
+ onOpen: PropTypes.func,
69
+ };
70
+
71
+ export default LabelWithModal;
common/src/modules/elements/label-with-modal/style.pcss ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__label-with-modal {
2
+ display: flex;
3
+ align-items: center;
4
+ background-color: #FFFFFF;
5
+ padding: 11px 17px;
6
+ border: 1px solid #E1E3E6;
7
+ height: 40px;
8
+ }
9
+
10
+ .tribe-editor__labeled-item__label {
11
+
12
+ .tribe-editor__label-with-modal & {
13
+ flex: auto;
14
+ color: #545D66;
15
+ font-size: 15px;
16
+ font-weight: bold;
17
+ line-height: 18px;
18
+ letter-spacing: 0.38px;
19
+ }
20
+ }
21
+
22
+ .tribe-editor__label-with-modal__modal-button {
23
+
24
+ .tribe-editor__label-with-modal & {
25
+ flex: none;
26
+ }
27
+ }
28
+
29
+ .tribe-editor__modal-button__button {
30
+
31
+ .tribe-editor__label-with-modal & {
32
+ color: #009FD4;
33
+ font-size: 15px;
34
+ font-weight: bold;
35
+ line-height: 18px;
36
+ letter-spacing: 0.38px;
37
+ transition: color 0.2s ease;
38
+
39
+ &:hover,
40
+ &:focus {
41
+ color: #007BB4;
42
+ }
43
+
44
+ &:disabled {
45
+
46
+ &,
47
+ &:hover,
48
+ &:focus {
49
+ color: #AEB4BB;
50
+ }
51
+ }
52
+ }
53
+ }
common/src/modules/elements/labeled-item/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Labeled Item Element renders labeled item 1`] = `
4
+ <div
5
+ className="tribe-editor__labeled-item"
6
+ >
7
+ <span
8
+ className="tribe-editor__labeled-item__label"
9
+ />
10
+ Test
11
+ </div>
12
+ `;
13
+
14
+ exports[`Labeled Item Element renders labeled item with class 1`] = `
15
+ <div
16
+ className="tribe-editor__labeled-item test-class"
17
+ >
18
+ <span
19
+ className="tribe-editor__labeled-item__label"
20
+ />
21
+ Test
22
+ </div>
23
+ `;
24
+
25
+ exports[`Labeled Item Element renders labeled item with label 1`] = `
26
+ <div
27
+ className="tribe-editor__labeled-item"
28
+ >
29
+ <span
30
+ className="tribe-editor__labeled-item__label"
31
+ >
32
+ test label
33
+ </span>
34
+ Test
35
+ </div>
36
+ `;
37
+
38
+ exports[`Labeled Item Element renders labeled item with label element and for id 1`] = `
39
+ <div
40
+ className="tribe-editor__labeled-item"
41
+ >
42
+ <label
43
+ className="tribe-editor__labeled-item__label"
44
+ htmlFor="test-id"
45
+ >
46
+ test label
47
+ </label>
48
+ Test
49
+ </div>
50
+ `;
common/src/modules/elements/labeled-item/__tests__/element.test.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { LabeledItem } from '@moderntribe/common/elements';
10
+
11
+ describe( 'Labeled Item Element', () => {
12
+ it( 'renders labeled item', () => {
13
+ const component = renderer.create( <LabeledItem>Test</LabeledItem> );
14
+ expect( component.toJSON() ).toMatchSnapshot();
15
+ } );
16
+
17
+ it( 'renders labeled item with class', () => {
18
+ const component = renderer.create( <LabeledItem className="test-class">Test</LabeledItem> );
19
+ expect( component.toJSON() ).toMatchSnapshot();
20
+ } );
21
+
22
+ it( 'renders labeled item with label', () => {
23
+ const component = renderer.create( <LabeledItem label="test label">Test</LabeledItem> );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+
27
+ it( 'renders labeled item with label element and for id', () => {
28
+ const component = renderer.create(
29
+ <LabeledItem
30
+ label="test label"
31
+ isLabel={ true }
32
+ forId="test-id"
33
+ >
34
+ Test
35
+ </LabeledItem>
36
+ );
37
+ expect( component.toJSON() ).toMatchSnapshot();
38
+ } );
39
+ } );
common/src/modules/elements/labeled-item/element.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ const LabeledItem = ( {
9
+ className,
10
+ forId,
11
+ isLabel,
12
+ label,
13
+ children,
14
+ } ) => {
15
+ const renderLabel = (
16
+ isLabel
17
+ ? (
18
+ <label className="tribe-editor__labeled-item__label" htmlFor={ forId }>
19
+ { label }
20
+ </label>
21
+ )
22
+ : (
23
+ <span className="tribe-editor__labeled-item__label">
24
+ { label }
25
+ </span>
26
+ )
27
+ );
28
+
29
+ return (
30
+ <div className={ classNames(
31
+ 'tribe-editor__labeled-item',
32
+ className,
33
+ ) }>
34
+ { renderLabel }
35
+ { children }
36
+ </div>
37
+ );
38
+ };
39
+
40
+ LabeledItem.defaultProps = {
41
+ isLabel: false,
42
+ };
43
+
44
+ LabeledItem.propTypes = {
45
+ className: PropTypes.string,
46
+ isLabel: PropTypes.bool.isRequired,
47
+ forId: PropTypes.string,
48
+ label: PropTypes.node,
49
+ children: PropTypes.node.isRequired,
50
+ };
51
+
52
+ export default LabeledItem;
common/src/modules/elements/link/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Link Element renders button with class 1`] = `
4
+ <a
5
+ className="tribe-editor__link test-class"
6
+ href="#"
7
+ >
8
+ label
9
+ </a>
10
+ `;
11
+
12
+ exports[`Link Element renders button with prop 1`] = `
13
+ <a
14
+ className="tribe-editor__link"
15
+ href="#"
16
+ title="title"
17
+ >
18
+ label
19
+ </a>
20
+ `;
21
+
22
+ exports[`Link Element renders button with target 1`] = `
23
+ <a
24
+ className="tribe-editor__link"
25
+ href="#"
26
+ rel="noopener noreferrer"
27
+ target="_blank"
28
+ >
29
+ label
30
+ </a>
31
+ `;
32
+
33
+ exports[`Link Element renders link 1`] = `
34
+ <a
35
+ className="tribe-editor__link"
36
+ href="#"
37
+ >
38
+ label
39
+ </a>
40
+ `;
common/src/modules/elements/link/__tests__/element.test.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import Link from '../element.js';
10
+
11
+ describe( 'Link Element', () => {
12
+ it( 'renders link', () => {
13
+ const component = renderer.create(
14
+ <Link href="#">label</Link>
15
+ );
16
+ expect( component.toJSON() ).toMatchSnapshot();
17
+ } );
18
+
19
+ it( 'renders button with class', () => {
20
+ const component = renderer.create(
21
+ <Link className="test-class" href="#">label</Link>
22
+ );
23
+ expect( component.toJSON() ).toMatchSnapshot();
24
+ } );
25
+
26
+ it( 'renders button with target', () => {
27
+ const component = renderer.create(
28
+ <Link href="#" target="_blank">label</Link>
29
+ );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+
33
+ it( 'renders button with prop', () => {
34
+ const component = renderer.create(
35
+ <Link href="#" title="title">label</Link>
36
+ );
37
+ expect( component.toJSON() ).toMatchSnapshot();
38
+ } );
39
+ } );
common/src/modules/elements/link/element.js ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ const Link = ( {
9
+ children,
10
+ className,
11
+ href,
12
+ target,
13
+ ...props,
14
+ } ) => {
15
+ const getProps = () => {
16
+ const elemProps = { ...props };
17
+
18
+ if ( target === '_blank' ) {
19
+ elemProps.rel = 'noopener noreferrer';
20
+ }
21
+
22
+ return elemProps;
23
+ };
24
+
25
+ return (
26
+ <a
27
+ className={ classNames( 'tribe-editor__link', className ) }
28
+ href={ href }
29
+ target={ target }
30
+ { ...getProps() }
31
+ >
32
+ { children }
33
+ </a>
34
+ );
35
+ };
36
+
37
+ Link.propTypes = {
38
+ children: PropTypes.node,
39
+ className: PropTypes.string,
40
+ href: PropTypes.string.isRequired,
41
+ target: PropTypes.string,
42
+ };
43
+
44
+ export default Link;
common/src/modules/elements/modal-button/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Modal Button Element renders a modal button 1`] = `
4
+ <div
5
+ className="tribe-editor__modal-button"
6
+ >
7
+ <button
8
+ className="tribe-editor__button tribe-editor__modal-button__button"
9
+ onClick={[Function]}
10
+ type="button"
11
+ />
12
+ </div>
13
+ `;
14
+
15
+ exports[`Modal Button Element renders a modal button with class 1`] = `
16
+ <div
17
+ className="tribe-editor__modal-button test-class"
18
+ >
19
+ <button
20
+ className="tribe-editor__button tribe-editor__modal-button__button"
21
+ onClick={[Function]}
22
+ type="button"
23
+ />
24
+ </div>
25
+ `;
26
+
27
+ exports[`Modal Button Element renders a modal button with label 1`] = `
28
+ <div
29
+ className="tribe-editor__modal-button"
30
+ >
31
+ <button
32
+ className="tribe-editor__button tribe-editor__modal-button__button"
33
+ onClick={[Function]}
34
+ type="button"
35
+ >
36
+ Test Label
37
+ </button>
38
+ </div>
39
+ `;
40
+
41
+ exports[`Modal Button Element renders a modal button with onClick handler 1`] = `
42
+ <div
43
+ className="tribe-editor__modal-button"
44
+ >
45
+ <button
46
+ className="tribe-editor__button tribe-editor__modal-button__button"
47
+ onClick={[Function]}
48
+ type="button"
49
+ />
50
+ </div>
51
+ `;
common/src/modules/elements/modal-button/__tests__/element.test.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import { noop } from 'lodash';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import ModalButton from '@moderntribe/common/elements/modal-button/element';
11
+
12
+ describe( 'Modal Button Element', () => {
13
+ it( 'renders a modal button', () => {
14
+ const component = renderer.create( <ModalButton /> );
15
+ expect( component.toJSON() ).toMatchSnapshot();
16
+ } );
17
+
18
+ it( 'renders a modal button with class', () => {
19
+ const component = renderer.create( <ModalButton className="test-class" /> );
20
+ expect( component.toJSON() ).toMatchSnapshot();
21
+ } );
22
+
23
+ it( 'renders a modal button with onClick handler', () => {
24
+ const component = renderer.create( <ModalButton onClick={ noop } /> );
25
+ expect( component.toJSON() ).toMatchSnapshot();
26
+ } );
27
+
28
+ it( 'renders a modal button with label', () => {
29
+ const component = renderer.create( <ModalButton label="Test Label" /> );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+
33
+ it( 'executes onClick and onOpen handlers', () => {
34
+ const props = {
35
+ onClick: jest.fn(),
36
+ onOpen: jest.fn(),
37
+ };
38
+
39
+ const component = mount( <ModalButton { ...props } /> );
40
+ component.find( 'button.tribe-editor__modal-button__button' ).simulate( 'click' );
41
+ expect( props.onClick ).toHaveBeenCalled();
42
+ expect( props.onClick ).toHaveBeenCalledTimes( 1 );
43
+ expect( props.onOpen ).toHaveBeenCalled();
44
+ expect( props.onOpen ).toHaveBeenCalledTimes( 1 );
45
+ } );
46
+ } );
common/src/modules/elements/modal-button/element.js ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * WordPress dependencies
10
+ */
11
+ import { Modal } from '@wordpress/components';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import Button from '@moderntribe/common/elements/button/element';
17
+
18
+ class ModalButton extends PureComponent {
19
+ static propTypes = {
20
+ className: PropTypes.string,
21
+ disabled: PropTypes.bool,
22
+ isOpen: PropTypes.bool,
23
+ label: PropTypes.string,
24
+ modalClassName: PropTypes.string,
25
+ modalContent: PropTypes.node,
26
+ modalOverlayClassName: PropTypes.string,
27
+ modalTitle: PropTypes.string,
28
+ onClick: PropTypes.func,
29
+ onClose: PropTypes.func,
30
+ onOpen: PropTypes.func,
31
+ };
32
+
33
+ constructor( props ) {
34
+ super( props );
35
+ this.state = {
36
+ isOpen: false,
37
+ };
38
+ }
39
+
40
+ onClick = ( e ) => {
41
+ this.props.onClick && this.props.onClick( e );
42
+ this.onOpen();
43
+ this.props.isOpen === undefined && this.setState( { isOpen: true } );
44
+ };
45
+
46
+ onRequestClose = (e) => {
47
+ this.onClose(e);
48
+ this.props.isOpen === undefined && this.setState( { isOpen: false } );
49
+ }
50
+
51
+ onOpen = () => this.props.onOpen && this.props.onOpen();
52
+
53
+ onClose = (e) => this.props.onClose && this.props.onClose(e);
54
+
55
+ preventClick = (e) => e.stopPropagation();
56
+
57
+ preventBlur = (e) => e.stopPropagation();
58
+
59
+ renderModal = () => {
60
+ const {
61
+ modalClassName,
62
+ modalContent,
63
+ modalOverlayClassName,
64
+ modalTitle,
65
+ } = this.props;
66
+
67
+ const isOpen = this.props.isOpen !== undefined ? this.props.isOpen : this.state.isOpen;
68
+
69
+ return ( isOpen && (
70
+ <Modal
71
+ className={ classNames(
72
+ 'tribe-editor__modal-button__modal-content',
73
+ modalClassName,
74
+ ) }
75
+ onRequestClose={ this.onRequestClose }
76
+ overlayClassName={ classNames(
77
+ 'tribe-editor__modal-button__modal-overlay',
78
+ modalOverlayClassName,
79
+ ) }
80
+ title={ modalTitle }
81
+ >
82
+ { modalContent }
83
+ </Modal>
84
+ ) );
85
+ };
86
+
87
+ render() {
88
+ const { className, disabled, label } = this.props;
89
+ return (
90
+ <div className={ classNames(
91
+ 'tribe-editor__modal-button',
92
+ className,
93
+ ) }>
94
+ <Button
95
+ className="tribe-editor__modal-button__button"
96
+ onClick={ this.onClick }
97
+ disabled={ disabled }
98
+ >
99
+ { label }
100
+ </Button>
101
+ { this.renderModal() }
102
+ </div>
103
+ );
104
+ }
105
+ }
106
+
107
+ export default ModalButton;
common/src/modules/elements/number-input/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Input element Should render the component 1`] = `
4
+ <input
5
+ className="tribe-editor__input tribe-editor__input--number"
6
+ type="number"
7
+ />
8
+ `;
9
+
10
+ exports[`Input element Should render the component with class 1`] = `
11
+ <input
12
+ className="tribe-editor__input tribe-editor__input--number input-class"
13
+ type="number"
14
+ />
15
+ `;
16
+
17
+ exports[`Input element Should render the component with extra props 1`] = `
18
+ <input
19
+ className="tribe-editor__input tribe-editor__input--number"
20
+ id="input-id"
21
+ type="number"
22
+ />
23
+ `;
24
+
25
+ exports[`Input element Should render the component with max 1`] = `
26
+ <input
27
+ className="tribe-editor__input tribe-editor__input--number"
28
+ max={42}
29
+ type="number"
30
+ />
31
+ `;
32
+
33
+ exports[`Input element Should render the component with min 1`] = `
34
+ <input
35
+ className="tribe-editor__input tribe-editor__input--number"
36
+ min={-42}
37
+ type="number"
38
+ />
39
+ `;
40
+
41
+ exports[`Input element Should render the component with onChange handler 1`] = `
42
+ <input
43
+ className="tribe-editor__input tribe-editor__input--number"
44
+ onChange={[Function]}
45
+ type="number"
46
+ />
47
+ `;
48
+
49
+ exports[`Input element Should render the component with step 1`] = `
50
+ <input
51
+ className="tribe-editor__input tribe-editor__input--number"
52
+ step={10}
53
+ type="number"
54
+ />
55
+ `;
common/src/modules/elements/number-input/__tests__/element.test.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import { noop } from 'lodash';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import NumberInput from '../element.js';
11
+
12
+ describe( 'Input element', () => {
13
+ it( 'Should render the component', () => {
14
+ const component = renderer.create( <NumberInput /> );
15
+ expect( component.toJSON() ).toMatchSnapshot();
16
+ } );
17
+
18
+ it( 'Should render the component with class', () => {
19
+ const component = renderer.create( <NumberInput className="input-class" /> );
20
+ expect( component.toJSON() ).toMatchSnapshot();
21
+ } );
22
+
23
+ it( 'Should render the component with max', () => {
24
+ const component = renderer.create( <NumberInput max={ 42 } /> );
25
+ expect( component.toJSON() ).toMatchSnapshot();
26
+ } );
27
+
28
+ it( 'Should render the component with min', () => {
29
+ const component = renderer.create( <NumberInput min={ -42 } /> );
30
+ expect( component.toJSON() ).toMatchSnapshot();
31
+ } );
32
+
33
+ it( 'Should render the component with onChange handler', () => {
34
+ const component = renderer.create( <NumberInput onChange={ noop } /> );
35
+ expect( component.toJSON() ).toMatchSnapshot();
36
+ } );
37
+
38
+ it( 'Should render the component with step', () => {
39
+ const component = renderer.create( <NumberInput step={ 10 } /> );
40
+ expect( component.toJSON() ).toMatchSnapshot();
41
+ } );
42
+
43
+ it( 'Should render the component with extra props', () => {
44
+ const component = renderer.create( <NumberInput id="input-id" /> );
45
+ expect( component.toJSON() ).toMatchSnapshot();
46
+ } );
47
+ } );
common/src/modules/elements/number-input/element.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Input from '@moderntribe/common/elements/input/element';
12
+
13
+ const NumberInput = ( {
14
+ className,
15
+ max,
16
+ min,
17
+ onChange,
18
+ step,
19
+ ...rest
20
+ } ) => (
21
+ <Input
22
+ className={ classNames( 'tribe-editor__input--number', className ) }
23
+ max={ max }
24
+ min={ min }
25
+ onChange={ onChange }
26
+ step={ step }
27
+ type="number"
28
+ { ...rest }
29
+ />
30
+ );
31
+
32
+ NumberInput.propTypes = {
33
+ className: PropTypes.string,
34
+ max: PropTypes.number,
35
+ min: PropTypes.number,
36
+ onChange: PropTypes.func,
37
+ step: PropTypes.number,
38
+ };
39
+
40
+ export default NumberInput;
common/src/modules/elements/paragraph/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<Paragraph> default paragraph 1`] = `
4
+ <p
5
+ className="tribe-editor__paragraph tribe-editor__paragraph--medium"
6
+ >
7
+ Modern Tribe
8
+ </p>
9
+ `;
10
+
11
+ exports[`<Paragraph> smaller paragraph 1`] = `
12
+ <p
13
+ className="tribe-editor__paragraph tribe-editor__paragraph--small"
14
+ >
15
+ Modern Tribe
16
+ </p>
17
+ `;
common/src/modules/elements/paragraph/__tests__/element.test.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+
3
+ import Paragraph, { SIZES } from '../element';
4
+
5
+ describe( '<Paragraph>', () => {
6
+ test( 'default paragraph', () => {
7
+ const component = renderer.create(
8
+ <Paragraph>Modern Tribe</Paragraph>,
9
+ );
10
+ expect( component.toJSON() ).toMatchSnapshot();
11
+ } );
12
+
13
+ test( 'smaller paragraph', () => {
14
+ const component = renderer.create(
15
+ <Paragraph size={ SIZES.small }>Modern Tribe</Paragraph>,
16
+ );
17
+ expect( component.toJSON() ).toMatchSnapshot();
18
+ } );
19
+ } );
common/src/modules/elements/paragraph/element.js ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.pcss';
12
+
13
+ export const SIZES = {
14
+ medium: 'medium',
15
+ small: 'small',
16
+ };
17
+
18
+ const Paragraph = ( { children, size, className } ) => (
19
+ <p
20
+ className={
21
+ classNames(
22
+ 'tribe-editor__paragraph',
23
+ `tribe-editor__paragraph--${ size }`,
24
+ className,
25
+ )
26
+ }
27
+ >
28
+ { children }
29
+ </p>
30
+ );
31
+
32
+ Paragraph.propTypes = {
33
+ children: PropTypes.node.isRequired,
34
+ size: PropTypes.oneOf( Object.keys( SIZES ) ),
35
+ };
36
+
37
+ Paragraph.defaultProps = {
38
+ size: SIZES.medium,
39
+ };
40
+
41
+ export default Paragraph;
common/src/modules/elements/paragraph/style.pcss ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__paragraph {
2
+ font-family: 'Helvetica', 'Arial', 'sans-serif';
3
+ line-height: 1.5;
4
+ font-weight: normal;
5
+
6
+ &--medium {
7
+ /* 16pt */
8
+ font-size: 1rem;
9
+ }
10
+
11
+ &--small {
12
+ /* 14pt */
13
+ font-size: 0.875rem;
14
+ }
15
+
16
+ a {
17
+ color: #11A0D2;
18
+
19
+ &:hover {
20
+ text-decoration: none;
21
+ color: #007BB4;
22
+ }
23
+ }
24
+ }
common/src/modules/elements/placeholder/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`<Placeholder> component Custom Class name attached 1`] = `
4
+ <div
5
+ className="tribe-editor__placeholder custom-class-name"
6
+ >
7
+ Custom Text
8
+ </div>
9
+ `;
10
+
11
+ exports[`<Placeholder> component Default behavior 1`] = `
12
+ <div
13
+ className="tribe-editor__placeholder"
14
+ >
15
+ Custom Text
16
+ </div>
17
+ `;
common/src/modules/elements/placeholder/__tests__/element.test.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import Placeholder from '../element';
3
+
4
+ describe( '<Placeholder> component', () => {
5
+ test( 'Default behavior', () => {
6
+ const component = renderer.create(
7
+ <Placeholder>Custom Text</Placeholder>
8
+ );
9
+ expect( component.toJSON() ).toMatchSnapshot();
10
+ } );
11
+
12
+ test( 'Custom Class name attached', () => {
13
+ const component = renderer.create(
14
+ <Placeholder className='custom-class-name'>Custom Text</Placeholder>
15
+ );
16
+ expect( component.toJSON() ).toMatchSnapshot();
17
+ } );
18
+ } );
common/src/modules/elements/placeholder/element.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import './style.pcss';
12
+
13
+ const Placeholder = ( { children, className } ) => (
14
+ <div className={ classNames( 'tribe-editor__placeholder', className ) }>
15
+ { children }
16
+ </div>
17
+ );
18
+
19
+ Placeholder.propTypes = {
20
+ children: PropTypes.node.isRequired,
21
+ };
22
+
23
+ export default Placeholder;
common/src/modules/elements/placeholder/style.pcss ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__placeholder {
2
+ border: 2px dashed #E1E3E6;
3
+ padding: 12px 15px 14px;
4
+ text-align: center;
5
+ font-family: 'Helvetica', 'Arial', 'sans-serif';
6
+ font-size: 1rem;
7
+ line-height: 1.5;
8
+ font-weight: bold;
9
+ color: #8D949B;
10
+ min-width: 260px;
11
+ display: inline-block;
12
+ }
common/src/modules/elements/radio-input/element.js ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Input from '@moderntribe/common/elements/input/element';
12
+
13
+ const RadioInput = ( { checked, className, onChange, ...rest } ) => (
14
+ <Input
15
+ checked={ checked }
16
+ className={ classNames( 'tribe-editor__input--radio', className ) }
17
+ onChange={ onChange }
18
+ type="radio"
19
+ { ...rest }
20
+ />
21
+ );
22
+
23
+ RadioInput.propTypes = {
24
+ checked: PropTypes.bool,
25
+ className: PropTypes.string,
26
+ onChange: PropTypes.func,
27
+ };
28
+
29
+ export default RadioInput;
common/src/modules/elements/radio/element.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import { noop } from 'lodash';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { RadioInput } from '@moderntribe/common/elements';
13
+
14
+ const Radio = ( { checked, className, disabled, id, label, onChange, name, value } ) => (
15
+ <div className={ classNames( 'tribe-editor__radio', className ) }>
16
+ <RadioInput
17
+ checked={ checked }
18
+ className="tribe-editor__radio__input"
19
+ disabled={ disabled }
20
+ id={ id }
21
+ name={ name }
22
+ onChange={ onChange }
23
+ value={ value }
24
+ />
25
+ <label
26
+ className="tribe-editor__radio_label"
27
+ htmlFor={ id }
28
+ >
29
+ { label }
30
+ </label>
31
+ </div>
32
+ );
33
+
34
+ Radio.defaultProps = {
35
+ checked: false,
36
+ onChange: noop,
37
+ };
38
+
39
+ Radio.propTypes = {
40
+ checked: PropTypes.bool.isRequired,
41
+ className: PropTypes.string,
42
+ disabled: PropTypes.bool,
43
+ id: PropTypes.string,
44
+ label: PropTypes.string,
45
+ name: PropTypes.string,
46
+ onChange: PropTypes.func,
47
+ value: PropTypes.string,
48
+ };
49
+
50
+ export default Radio;
common/src/modules/elements/select/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Select element Should render the component 1`] = `
4
+ <div
5
+ className="css-10nd86i tribe-editor__select"
6
+ onKeyDown={[Function]}
7
+ >
8
+ <div
9
+ className="css-vj8t7z tribe-editor__select__control"
10
+ onMouseDown={[Function]}
11
+ onTouchEnd={[Function]}
12
+ >
13
+ <div
14
+ className="css-1hwfws3 tribe-editor__select__value-container"
15
+ >
16
+ <div
17
+ className="css-1492t68 tribe-editor__select__placeholder"
18
+ >
19
+ Select...
20
+ </div>
21
+ <div
22
+ className="css-1g6gooi"
23
+ >
24
+ <div
25
+ className="tribe-editor__select__input"
26
+ style={
27
+ Object {
28
+ "display": "inline-block",
29
+ }
30
+ }
31
+ >
32
+ <input
33
+ aria-autocomplete="list"
34
+ autoCapitalize="none"
35
+ autoComplete="off"
36
+ autoCorrect="off"
37
+ disabled={false}
38
+ id="react-select-2-input"
39
+ onBlur={[Function]}
40
+ onChange={[Function]}
41
+ onFocus={[Function]}
42
+ spellCheck="false"
43
+ style={
44
+ Object {
45
+ "background": 0,
46
+ "border": 0,
47
+ "boxSizing": "content-box",
48
+ "color": "inherit",
49
+ "fontSize": "inherit",
50
+ "opacity": 1,
51
+ "outline": 0,
52
+ "padding": 0,
53
+ "width": "1px",
54
+ }
55
+ }
56
+ tabIndex="0"
57
+ type="text"
58
+ value=""
59
+ />
60
+ <div
61
+ style={
62
+ Object {
63
+ "height": 0,
64
+ "left": 0,
65
+ "overflow": "scroll",
66
+ "position": "absolute",
67
+ "top": 0,
68
+ "visibility": "hidden",
69
+ "whiteSpace": "pre",
70
+ }
71
+ }
72
+ >
73
+
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ <div
79
+ className="css-1wy0on6 tribe-editor__select__indicators"
80
+ >
81
+ <div
82
+ aria-hidden="true"
83
+ className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
84
+ onMouseDown={[Function]}
85
+ onTouchEnd={[Function]}
86
+ >
87
+ <span
88
+ className="tribe-editor__select__dropdown-indicator"
89
+ >
90
+ arrow-down
91
+ </span>
92
+ </div>
93
+ </div>
94
+ </div>
95
+ </div>
96
+ `;
97
+
98
+ exports[`Select element Should render the component with class 1`] = `
99
+ <div
100
+ className="css-10nd86i tribe-editor__select test-class"
101
+ onKeyDown={[Function]}
102
+ >
103
+ <div
104
+ className="css-vj8t7z tribe-editor__select__control"
105
+ onMouseDown={[Function]}
106
+ onTouchEnd={[Function]}
107
+ >
108
+ <div
109
+ className="css-1hwfws3 tribe-editor__select__value-container"
110
+ >
111
+ <div
112
+ className="css-1492t68 tribe-editor__select__placeholder"
113
+ >
114
+ Select...
115
+ </div>
116
+ <div
117
+ className="css-1g6gooi"
118
+ >
119
+ <div
120
+ className="tribe-editor__select__input"
121
+ style={
122
+ Object {
123
+ "display": "inline-block",
124
+ }
125
+ }
126
+ >
127
+ <input
128
+ aria-autocomplete="list"
129
+ autoCapitalize="none"
130
+ autoComplete="off"
131
+ autoCorrect="off"
132
+ disabled={false}
133
+ id="react-select-3-input"
134
+ onBlur={[Function]}
135
+ onChange={[Function]}
136
+ onFocus={[Function]}
137
+ spellCheck="false"
138
+ style={
139
+ Object {
140
+ "background": 0,
141
+ "border": 0,
142
+ "boxSizing": "content-box",
143
+ "color": "inherit",
144
+ "fontSize": "inherit",
145
+ "opacity": 1,
146
+ "outline": 0,
147
+ "padding": 0,
148
+ "width": "1px",
149
+ }
150
+ }
151
+ tabIndex="0"
152
+ type="text"
153
+ value=""
154
+ />
155
+ <div
156
+ style={
157
+ Object {
158
+ "height": 0,
159
+ "left": 0,
160
+ "overflow": "scroll",
161
+ "position": "absolute",
162
+ "top": 0,
163
+ "visibility": "hidden",
164
+ "whiteSpace": "pre",
165
+ }
166
+ }
167
+ >
168
+
169
+ </div>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ <div
174
+ className="css-1wy0on6 tribe-editor__select__indicators"
175
+ >
176
+ <div
177
+ aria-hidden="true"
178
+ className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
179
+ onMouseDown={[Function]}
180
+ onTouchEnd={[Function]}
181
+ >
182
+ <span
183
+ className="tribe-editor__select__dropdown-indicator"
184
+ >
185
+ arrow-down
186
+ </span>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ `;
192
+
193
+ exports[`Select element Should render the component with extra props 1`] = `
194
+ <div
195
+ className="css-10nd86i tribe-editor__select"
196
+ onKeyDown={[Function]}
197
+ >
198
+ <div
199
+ className="css-vj8t7z tribe-editor__select__control"
200
+ onMouseDown={[Function]}
201
+ onTouchEnd={[Function]}
202
+ >
203
+ <div
204
+ className="css-1hwfws3 tribe-editor__select__value-container"
205
+ >
206
+ <div
207
+ className="css-1492t68 tribe-editor__select__placeholder"
208
+ >
209
+ Select...
210
+ </div>
211
+ <input
212
+ className="css-14uuagi"
213
+ disabled={false}
214
+ id="react-select-4-input"
215
+ onBlur={[Function]}
216
+ onChange={[Function]}
217
+ onFocus={[Function]}
218
+ readOnly={true}
219
+ tabIndex="0"
220
+ value=""
221
+ />
222
+ </div>
223
+ <div
224
+ className="css-1wy0on6 tribe-editor__select__indicators"
225
+ >
226
+ <div
227
+ aria-hidden="true"
228
+ className="css-1ep9fjw tribe-editor__select__indicator tribe-editor__select__dropdown-indicator"
229
+ onMouseDown={[Function]}
230
+ onTouchEnd={[Function]}
231
+ >
232
+ <span
233
+ className="tribe-editor__select__dropdown-indicator"
234
+ >
235
+ arrow-down
236
+ </span>
237
+ </div>
238
+ </div>
239
+ </div>
240
+ </div>
241
+ `;
common/src/modules/elements/select/__tests__/element.test.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import Select from '../element.js';
10
+
11
+ const options = [
12
+ { label: 'Test 1', value: 'test-1' },
13
+ { label: 'Test 2', value: 'test-2' },
14
+ ];
15
+
16
+ describe( 'Select element', () => {
17
+ it( 'Should render the component', () => {
18
+ const component = renderer.create( <Select options={ options } /> );
19
+ expect( component.toJSON() ).toMatchSnapshot();
20
+ } );
21
+
22
+ it( 'Should render the component with class', () => {
23
+ const component = renderer.create( <Select options={ options } className="test-class" /> );
24
+ expect( component.toJSON() ).toMatchSnapshot();
25
+ } );
26
+
27
+ it( 'Should render the component with extra props', () => {
28
+ const component = renderer.create( <Select options={ options } isSearchable={ false } /> );
29
+ expect( component.toJSON() ).toMatchSnapshot();
30
+ } );
31
+ } );
common/src/modules/elements/select/element.js ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+ import ReactSelect, { components } from 'react-select';
8
+ import { Dashicon } from '@wordpress/components';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import './style.pcss';
14
+
15
+ const DropdownIndicator = ( props ) => (
16
+ components.DropdownIndicator && (
17
+ <components.DropdownIndicator { ...props }>
18
+ <Dashicon
19
+ className="tribe-editor__select__dropdown-indicator"
20
+ icon={ 'arrow-down' }
21
+ />
22
+ </components.DropdownIndicator>
23
+ )
24
+ );
25
+
26
+ const IndicatorSeparator = () => null;
27
+
28
+ const Select = ( { className, ...rest } ) => (
29
+ <ReactSelect
30
+ className={ classNames( 'tribe-editor__select', className ) }
31
+ classNamePrefix="tribe-editor__select"
32
+ components={ { DropdownIndicator, IndicatorSeparator } }
33
+ { ...rest }
34
+ />
35
+ );
36
+
37
+ Select.propTypes = {
38
+ className: PropTypes.string,
39
+ };
40
+
41
+ export default Select;
common/src/modules/elements/select/style.pcss ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__select {
2
+
3
+ .tribe-editor__select__control {
4
+ height: 46px;
5
+ border: 1px solid #E1E3E6;
6
+ border-radius: 3px;
7
+ background-color: #FFFFFF;
8
+
9
+ &:hover {
10
+ border: 1px solid #E1E3E6;
11
+ }
12
+
13
+ &--is-focused {
14
+ box-shadow: none;
15
+ }
16
+ }
17
+
18
+ .tribe-editor__select__value-container {
19
+ padding: 2px 10px 2px 15px;
20
+ }
21
+
22
+ .tribe-editor__select__single-value {
23
+ margin: 0;
24
+ max-width: calc(100% - 15px);
25
+ font-size: 16px;
26
+ line-height: 1.5;
27
+ }
28
+
29
+ .tribe-editor__select__input {
30
+ font-size: 16px;
31
+
32
+ & > input {
33
+ margin: 0;
34
+ line-height: 1.5;
35
+ }
36
+ }
37
+
38
+ svg.tribe-editor__select__dropdown-indicator {
39
+ fill: #555D66;
40
+ }
41
+
42
+ .tribe-editor__select__menu {
43
+ margin: 0;
44
+ border: 1px solid #E1E3E6;
45
+ border-top: none;
46
+ border-radius: 0;
47
+ border-bottom-left-radius: 3px;
48
+ border-bottom-right-radius: 3px;
49
+ box-shadow: none;
50
+ transform: translateY(-7px);
51
+ z-index: 10;
52
+ }
53
+
54
+ .tribe-editor__select__menu-list {
55
+ padding: 0;
56
+ }
57
+
58
+ .tribe-editor__select__option {
59
+ font-size: 16px;
60
+ line-height: 1.5;
61
+ padding: 3px 15px;
62
+
63
+ &--is-focused {
64
+ background-color: #E7F5FA;
65
+ }
66
+
67
+ &--is-selected {
68
+ background-color: #11A0D2;
69
+ }
70
+ }
71
+
72
+ &--is-disabled {
73
+
74
+ svg.tribe-editor__select__dropdown-indicator {
75
+ fill: #AEB4BB;
76
+ }
77
+ }
78
+ }
common/src/modules/elements/style.pcss ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ .post-type-tribe_events .editor-styles-wrapper {
2
+ max-width: none!important;
3
+ }
common/src/modules/elements/textarea/element.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+
12
+ const Textarea = ( { className, ...rest } ) => (
13
+ <textarea className={ classNames( 'tribe-editor__textarea', className ) } { ...rest } />
14
+ );
15
+
16
+ Textarea.propTypes = {
17
+ className: PropTypes.string,
18
+ };
19
+
20
+ export default Textarea;
common/src/modules/elements/time-picker/element.js ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { Fragment } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import moment from 'moment';
7
+ import { noop } from 'lodash';
8
+ import classNames from 'classnames';
9
+ import { ScrollTo, ScrollArea } from 'react-scroll-to';
10
+
11
+ /**
12
+ * WordPress dependencies
13
+ */
14
+ import {
15
+ Dropdown,
16
+ Dashicon,
17
+ } from '@wordpress/components';
18
+ import { __ } from '@wordpress/i18n';
19
+
20
+ /**
21
+ * Internal dependencies
22
+ */
23
+ import { PreventBlockClose } from '@moderntribe/common/components';
24
+ import Button from '@moderntribe/common/elements/button/element';
25
+ import Input from '@moderntribe/common/elements/input/element';
26
+ import {
27
+ date as dateUtil,
28
+ moment as momentUtil,
29
+ time as timeUtil,
30
+ TribePropTypes,
31
+ } from '@moderntribe/common/utils';
32
+ import './style.pcss';
33
+
34
+ const TimePicker = ( {
35
+ allDay,
36
+ current,
37
+ disabled,
38
+ end,
39
+ onBlur,
40
+ onChange,
41
+ onClick,
42
+ onFocus,
43
+ showAllDay,
44
+ start,
45
+ step,
46
+ timeFormat,
47
+ } ) => {
48
+
49
+ const renderLabel = ( onAllDayClick ) => {
50
+ if ( allDay ) {
51
+ return (
52
+ <Button
53
+ className="tribe-editor__timepicker__all-day-btn"
54
+ disabled={ disabled }
55
+ onClick={ onAllDayClick }
56
+ >
57
+ { __( 'All Day', 'tribe-common' ) }
58
+ </Button>
59
+ );
60
+ }
61
+
62
+ return (
63
+ <Input
64
+ className="tribe-editor__timepicker__input"
65
+ disabled={ disabled }
66
+ onBlur={ onBlur }
67
+ onChange={ onChange }
68
+ onFocus={ onFocus }
69
+ type="text"
70
+ value={ current }
71
+ />
72
+ );
73
+ };
74
+
75
+ const renderToggle = ( { onToggle, isOpen } ) => (
76
+ <Fragment>
77
+ { renderLabel( onToggle ) }
78
+ <Button
79
+ aria-expanded={ isOpen }
80
+ className="tribe-editor__timepicker__toggle-btn"
81
+ disabled={ disabled }
82
+ onClick={ onToggle }
83
+ >
84
+ <Dashicon
85
+ className="tribe-editor__timepicker__toggle-btn-icon"
86
+ icon={ isOpen ? 'arrow-up' : 'arrow-down' }
87
+ />
88
+ </Button>
89
+ </Fragment>
90
+ );
91
+
92
+ const getItems = () => {
93
+ const items = [];
94
+
95
+ const startSeconds = timeUtil.toSeconds( start, timeUtil.TIME_FORMAT_HH_MM );
96
+ const endSeconds = timeUtil.toSeconds( end, timeUtil.TIME_FORMAT_HH_MM );
97
+
98
+ const currentMoment = moment( current, momentUtil.TIME_FORMAT );
99
+
100
+ for ( let time = startSeconds; time <= endSeconds; time += step ) {
101
+ let isCurrent = false;
102
+ if ( currentMoment.isValid() ) {
103
+ const currentTime = momentUtil.toTime24Hr( currentMoment );
104
+ isCurrent = time === timeUtil.toSeconds( currentTime, timeUtil.TIME_FORMAT_HH_MM );
105
+ }
106
+
107
+ items.push( {
108
+ value: time,
109
+ text: formatLabel( time ),
110
+ isCurrent,
111
+ } );
112
+ }
113
+
114
+ return items;
115
+ };
116
+
117
+ const formatLabel = ( seconds ) => {
118
+ return momentUtil.setTimeInSeconds( moment(), seconds ).format( momentUtil.toFormat( timeFormat ) );
119
+ };
120
+
121
+ const renderItem = ( item, onClose ) => {
122
+ const itemClasses = {
123
+ 'tribe-editor__timepicker__item': true,
124
+ 'tribe-editor__timepicker__item--current': item.isCurrent && ! allDay,
125
+ };
126
+
127
+ return (
128
+ <Button
129
+ key={ `time-${ item.value }` }
130
+ className={ classNames( itemClasses ) }
131
+ value={ item.value }
132
+ onClick={ () => onClick( item.value, onClose ) }
133
+ >
134
+ { item.text }
135
+ </Button>
136
+ );
137
+ };
138
+
139
+ const renderContent = ( { onClose } ) => (
140
+ <ScrollTo>
141
+ { () => (
142
+ <PreventBlockClose>
143
+ <ScrollArea
144
+ key="tribe-element-timepicker-items"
145
+ className="tribe-editor__timepicker__items"
146
+ >
147
+ { showAllDay && renderItem(
148
+ { text: __( 'All Day', 'tribe-common' ), value: 'all-day' },
149
+ onClose,
150
+ ) }
151
+ { getItems().map( ( item ) => renderItem( item, onClose ) ) }
152
+ </ScrollArea>
153
+ </PreventBlockClose>
154
+ ) }
155
+ </ScrollTo>
156
+ );
157
+
158
+ return (
159
+ <div
160
+ key="tribe-element-timepicker"
161
+ className="tribe-editor__timepicker"
162
+ >
163
+ <Dropdown
164
+ className="tribe-editor__timepicker__toggle"
165
+ contentClassName="tribe-editor__timepicker__content"
166
+ position="bottom center"
167
+ renderToggle={ renderToggle }
168
+ renderContent={ renderContent }
169
+ />
170
+ </div>
171
+ );
172
+ };
173
+
174
+ TimePicker.defaultProps = {
175
+ allDay: false,
176
+ onBlur: noop,
177
+ onChange: noop,
178
+ onClick: noop,
179
+ onFocus: noop,
180
+ step: timeUtil.HALF_HOUR_IN_SECONDS,
181
+ timeFormat: dateUtil.FORMATS.WP.time,
182
+ };
183
+
184
+ TimePicker.propTypes = {
185
+ /**
186
+ * TribePropTypes.timeFormat check for string formatted as a time
187
+ * using 24h clock in hh:mm format
188
+ * e.g. 00:24, 03:57, 21:12
189
+ */
190
+ allDay: PropTypes.bool,
191
+ current: PropTypes.string,
192
+ disabled: PropTypes.bool,
193
+ end: TribePropTypes.timeFormat.isRequired,
194
+ onBlur: PropTypes.func,
195
+ onChange: PropTypes.func,
196
+ onClick: PropTypes.func,
197
+ onFocus: PropTypes.func,
198
+ showAllDay: PropTypes.bool,
199
+ start: TribePropTypes.timeFormat.isRequired,
200
+ step: PropTypes.number,
201
+ timeFormat: PropTypes.string,
202
+ };
203
+
204
+ export default TimePicker;
common/src/modules/elements/time-picker/style.pcss ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__timepicker {
2
+ display: inline-block;
3
+ }
4
+
5
+ .tribe-editor__timepicker__toggle {
6
+ background-color: #FFF;
7
+ border: 1px solid #e1e3e6;
8
+ border-radius: 2px;
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+
13
+ input.tribe-editor__timepicker__input[type="text"] {
14
+ font-family: Helvetica, sans-serif;
15
+ font-size: 14px;
16
+ line-height: 1.5;
17
+ padding: 6px 0 6px 10px;
18
+ border: none;
19
+ width: 80px;
20
+ }
21
+
22
+ button.tribe-editor__timepicker__toggle-btn {
23
+ padding: 10px;
24
+
25
+ &:disabled > svg.dashicon {
26
+ fill: #AEB4BB;
27
+ }
28
+ }
29
+
30
+ button.tribe-editor__timepicker__all-day-btn {
31
+ color: #545D66;
32
+ line-height: 20px;
33
+ padding: 6px 10px 6px;
34
+ text-decoration: none;
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+ }
39
+ }
40
+
41
+ .tribe-editor__timepicker__content {
42
+
43
+ &.components-popover {
44
+
45
+ .components-popover__content {
46
+ min-width: 110px;
47
+ }
48
+ }
49
+
50
+ .tribe-editor__timepicker__items {
51
+ height: 250px;
52
+ overflow: auto;
53
+
54
+ .components-placeholder {
55
+ height: inherit;
56
+ }
57
+ }
58
+
59
+ .tribe-editor__timepicker__item {
60
+ display: block;
61
+ width: 100%;
62
+ color: #555d66;
63
+ padding: 5px 12px;
64
+ cursor: pointer;
65
+ border-bottom: 1px solid #e2e4e7;
66
+ line-height: 20px;
67
+ background: transparent;
68
+ text-align: left;
69
+
70
+ &:hover,
71
+ &:focus {
72
+ background-color: #e7f5fa;
73
+ }
74
+
75
+ &--current {
76
+ color: #ffffff;
77
+ background-color: #009fd4;
78
+
79
+ &:hover,
80
+ &:focus {
81
+ color: #ffffff;
82
+ background-color: #009fd4;
83
+ }
84
+ }
85
+ }
86
+ }
common/src/modules/elements/tooltip/__tests__/__snapshots__/element.test.js.snap ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Tooltip Element renders a tooltip 1`] = `
4
+ <div>
5
+ <span>
6
+ here is the tooltip text
7
+ </span>
8
+ <span>
9
+ bottom left
10
+ </span>
11
+ <span>
12
+ <button
13
+ aria-label="here is the tooltip text"
14
+ className="tribe-editor__button tribe-editor__tooltip-label label-class-name"
15
+ onClick={[Function]}
16
+ type="button"
17
+ >
18
+ some label
19
+ </button>
20
+ </span>
21
+ </div>
22
+ `;
common/src/modules/elements/tooltip/__tests__/element.test.js ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+ import renderer from 'react-test-renderer';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import Tooltip from '@moderntribe/common/elements/tooltip/element';
11
+
12
+ jest.mock( '@wordpress/components', () => ( {
13
+ Tooltip: ({ text, position, children }) => (
14
+ <div>
15
+ <span>{ text }</span>
16
+ <span>{ position }</span>
17
+ <span>{ children }</span>
18
+ </div>
19
+ ),
20
+ } ) );
21
+
22
+ describe( 'Tooltip Element', () => {
23
+ it( 'renders a tooltip', () => {
24
+ const props = {
25
+ label: 'some label',
26
+ labelClassName: 'label-class-name',
27
+ position: 'bottom left',
28
+ text: 'here is the tooltip text',
29
+ };
30
+ const component = renderer.create( <Tooltip { ...props } />)
31
+ expect( component.toJSON() ).toMatchSnapshot()
32
+ } );
33
+ } );
common/src/modules/elements/tooltip/element.js ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { PureComponent } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * WordPress dependencies
10
+ */
11
+ import { Tooltip as WpTooltip } from '@wordpress/components';
12
+
13
+ /**
14
+ * Internal dependencies
15
+ */
16
+ import { Button } from '@moderntribe/common/elements';
17
+
18
+ class Tooltip extends PureComponent {
19
+ static defaultProps = {
20
+ position: 'top right',
21
+ text: '',
22
+ };
23
+
24
+ static propTypes = {
25
+ disabled: PropTypes.bool,
26
+ label: PropTypes.node,
27
+ labelClassName: PropTypes.string,
28
+ position: PropTypes.oneOf( [
29
+ 'top left',
30
+ 'top center',
31
+ 'top right',
32
+ 'bottom left',
33
+ 'bottom center',
34
+ 'bottom right',
35
+ ] ),
36
+ text: PropTypes.string,
37
+ };
38
+
39
+ render() {
40
+ const { disabled, label, labelClassName, position, text } = this.props;
41
+
42
+ return (
43
+ <WpTooltip text={ text } position={ position }>
44
+ <Button
45
+ aria-label={ text }
46
+ className={ classNames( 'tribe-editor__tooltip-label', labelClassName ) }
47
+ disabled={ disabled }
48
+ >
49
+ { label }
50
+ </Button>
51
+ </WpTooltip>
52
+ );
53
+ }
54
+ }
55
+
56
+ export default Tooltip;
common/src/modules/elements/tooltip/style.pcss ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .components-tooltip {
2
+
3
+ .components-popover__content {
4
+ white-space: normal;
5
+ min-width: 350px;
6
+ max-width: 600px;
7
+ }
8
+
9
+ &:not(.is-mobile) {
10
+ .components-popover__content {
11
+ min-width: 350px;
12
+ }
13
+ }
14
+ }
common/src/modules/elements/url-input/element.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External Dependencies
3
+ */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import classNames from 'classnames';
7
+
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import Input from '@moderntribe/common/elements/input/element';
12
+
13
+ const UrlInput = ( { checked, className, onChange, ...rest } ) => (
14
+ <Input
15
+ type="url"
16
+ className={ classNames( 'tribe-editor__input--url', className ) }
17
+ onChange={ onChange }
18
+ { ...rest }
19
+ />
20
+ );
21
+
22
+ UrlInput.propTypes = {
23
+ className: PropTypes.string,
24
+ onChange: PropTypes.func,
25
+ };
26
+
27
+ export default UrlInput;
common/src/modules/hoc/__tests__/__snapshots__/with-form.test.js.snap ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`HOC - With Form Should register the postType by dispatching the actions 1`] = `
4
+ Array [
5
+ Object {
6
+ "payload": Object {
7
+ "id": "posts",
8
+ "type": "post",
9
+ },
10
+ "type": "@@MT/COMMON/ADD_FORM",
11
+ },
12
+ ]
13
+ `;
14
+
15
+ exports[`HOC - With Form Should render a component 1`] = `
16
+ <div>
17
+ With Form!
18
+ </div>
19
+ `;
common/src/modules/hoc/__tests__/__snapshots__/with-save-data.test.js.snap ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`HOC - With Details Should render a component 1`] = `
4
+ <div
5
+ attributes={
6
+ Object {
7
+ "description": "",
8
+ "organizers": Array [],
9
+ "title": "Modern Tribe",
10
+ }
11
+ }
12
+ description="The Next Generation of Digital Agency"
13
+ isolated={false}
14
+ name="tribe/event"
15
+ onBlockCreated={[Function]}
16
+ onBlockRemoved={[Function]}
17
+ organizers={Array []}
18
+ setAttributes={[MockFunction]}
19
+ setInitialState={
20
+ [MockFunction] {
21
+ "calls": Array [
22
+ Array [
23
+ Object {
24
+ "attributes": Object {
25
+ "description": "",
26
+ "organizers": Array [],
27
+ "title": "Modern Tribe",
28
+ },
29
+ "description": "The Next Generation of Digital Agency",
30
+ "get": [Function],
31
+ "isolated": false,
32
+ "name": "tribe/event",
33
+ "onBlockCreated": [Function],
34
+ "onBlockRemoved": [Function],
35
+ "organizers": Array [],
36
+ "setAttributes": [MockFunction],
37
+ "setInitialState": [MockFunction] {
38
+ "calls": [Circular],
39
+ "results": Array [
40
+ Object {
41
+ "isThrow": false,
42
+ "value": undefined,
43
+ },
44
+ ],
45
+ },
46
+ "title": "Modern Tribe!",
47
+ },
48
+ ],
49
+ ],
50
+ "results": Array [
51
+ Object {
52
+ "isThrow": false,
53
+ "value": undefined,
54
+ },
55
+ ],
56
+ }
57
+ }
58
+ title="Modern Tribe!"
59
+ >
60
+ With Save Data!
61
+ </div>
62
+ `;
common/src/modules/hoc/__tests__/__snapshots__/with-store.test.js.snap ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`HOC - With Store Should add the store property 1`] = `
4
+ <div
5
+ store={
6
+ Object {
7
+ "dispatch": [Function],
8
+ "getState": [Function],
9
+ "injectReducers": [Function],
10
+ "injectedReducers": Object {},
11
+ "replaceReducer": [Function],
12
+ "run": [Function],
13
+ "subscribe": [Function],
14
+ Symbol(observable): [Function],
15
+ }
16
+ }
17
+ />
18
+ `;
common/src/modules/hoc/__tests__/with-form.test.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import renderer from 'react-test-renderer';
5
+ import React from 'react';
6
+ import configureStore from 'redux-mock-store';
7
+ import thunk from 'redux-thunk';
8
+
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import { withForm } from '@moderntribe/common/hoc';
13
+
14
+ const initialState = {
15
+ events: {
16
+ },
17
+ forms: {
18
+ byId: {},
19
+ },
20
+ };
21
+ // here it is possible to pass in any middleware if needed into //configureStore
22
+ const mockStore = configureStore( [ thunk ] );
23
+ const store = mockStore( initialState );
24
+
25
+ const Block = () => <div>With Form!</div>;
26
+ let setFormID;
27
+ let Wrapper;
28
+ let component;
29
+ let instance;
30
+
31
+ describe( 'HOC - With Form', () => {
32
+ beforeEach( () => {
33
+ setFormID = jest.fn( () => 'posts' );
34
+ Wrapper = withForm( setFormID )( Block );
35
+ component = renderer.create( <Wrapper store={ store } postType="post"/> );
36
+ instance = component.root;
37
+ } );
38
+
39
+ afterEach( () => {
40
+ mockStore( initialState );
41
+ store.clearActions();
42
+ setFormID.mockClear();
43
+ } );
44
+
45
+ it( 'Should render a component', () => {
46
+ expect( component.toJSON() ).toMatchSnapshot();
47
+ } );
48
+
49
+ it( 'Should render the inner component', () => {
50
+ expect( instance ).not.toBe( null );
51
+ expect( () => instance.findByType( Block ) ).not.toThrowError();
52
+ } );
53
+
54
+ it( 'Should attach the form properties', () => {
55
+ const expected = {
56
+ edit: false,
57
+ create: false,
58
+ fields: {},
59
+ submit: false,
60
+ };
61
+ expect( instance.findByType( Block ).props ).toMatchObject( expected );
62
+ } );
63
+
64
+ it( 'Should have properties as functions', () => {
65
+ const props = instance.findByType( Block ).props;
66
+ const expectedProps = [
67
+ 'maybeRemoveEntry',
68
+ 'setSubmit',
69
+ 'sendForm',
70
+ 'editEntry',
71
+ 'createDraft',
72
+ ];
73
+
74
+ expectedProps.forEach( ( property ) => {
75
+ expect( props[ property ] ).not.toBeUndefined();
76
+ expect( typeof props[ property ] ).toBe( 'function' );
77
+ } );
78
+ } );
79
+
80
+ it( 'Should register the postType by dispatching the actions', () => {
81
+ expect( store.getActions() ).toMatchSnapshot();
82
+ } );
83
+
84
+ it( 'Should register the ID of the form', () => {
85
+ expect( setFormID ).toHaveBeenCalled();
86
+ expect( setFormID ).toHaveBeenCalledTimes( 3 );
87
+ } );
88
+ } );
89
+
common/src/modules/hoc/__tests__/with-save-data.test.js ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import renderer from 'react-test-renderer';
5
+ import React from 'react';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { withSaveData } from '@moderntribe/common/hoc';
11
+
12
+ const Block = ( props ) => <div { ...props }>With Save Data!</div>;
13
+ const props = {
14
+ name: 'tribe/event',
15
+ setInitialState: jest.fn(),
16
+ setAttributes: jest.fn(),
17
+ title: 'Modern Tribe!',
18
+ description: 'The Next Generation of Digital Agency',
19
+ organizers: [],
20
+ attributes: {
21
+ title: 'Modern Tribe',
22
+ description: '',
23
+ organizers: [],
24
+ },
25
+ };
26
+
27
+ describe( 'HOC - With Details', () => {
28
+ let Wrapper;
29
+ let component;
30
+ let instance;
31
+
32
+ beforeEach( () => {
33
+ Wrapper = withSaveData()( Block );
34
+ component = renderer.create( <Wrapper { ...props } /> );
35
+ instance = component.root;
36
+ } );
37
+
38
+ afterEach( () => {
39
+ props.setInitialState.mockClear();
40
+ props.setAttributes.mockClear();
41
+ component.getInstance().unregisterBlock();
42
+ } );
43
+
44
+ it( 'Should render a component', () => {
45
+ expect( component.toJSON() ).toMatchSnapshot();
46
+ } );
47
+
48
+ it( 'Should render the inner component', () => {
49
+ expect( instance ).not.toBe( null );
50
+ expect( () => instance.findByType( Block ) ).not.toThrowError();
51
+ } );
52
+
53
+ it( 'Should set the initial state', () => {
54
+ expect( props.setInitialState ).toHaveBeenCalled();
55
+ expect( props.setInitialState ).toHaveBeenCalledTimes( 1 );
56
+ } );
57
+
58
+ it( 'Should generate the attributes', () => {
59
+ const HOC = component.getInstance();
60
+ expect( HOC.attrs ).toEqual( props.attributes );
61
+ } );
62
+
63
+ it( 'Should generate the keys', () => {
64
+ const HOC = component.getInstance();
65
+ expect( HOC.keys ).toEqual( Object.keys( props.attributes ) );
66
+ } );
67
+
68
+ it( 'Simulate componentDidUpdate call', () => {
69
+ const wrapper = shallow( <Wrapper { ...props } /> );
70
+ const wrapperInstance = wrapper.instance();
71
+ expect( wrapperInstance.calculateDiff() ).toEqual( {
72
+ description: 'The Next Generation of Digital Agency',
73
+ title: 'Modern Tribe!',
74
+ } );
75
+ wrapper.setProps( {
76
+ attributes: {
77
+ title: 'Modern Tribe!',
78
+ description: 'The Next Generation of Digital Agency',
79
+ organizers: [],
80
+ }
81
+ } );
82
+ expect( wrapperInstance.calculateDiff() ).toEqual( {} );
83
+ wrapper.setProps( {
84
+ organizers: [ 3 ],
85
+ attributes: {
86
+ title: 'Modern Tribe!',
87
+ description: 'The Next Generation of Digital Agency',
88
+ organizers: [ 3 ],
89
+ },
90
+ } );
91
+ expect( wrapperInstance.calculateDiff() ).toEqual( {} );
92
+ wrapper.setProps( {
93
+ organizers: [ 2, 3 ],
94
+ attributes: {
95
+ title: 'Modern Tribe!',
96
+ description: 'The Next Generation of Digital Agency',
97
+ organizers: [ 3, 2 ],
98
+ },
99
+ } );
100
+ expect( wrapperInstance.calculateDiff() ).toEqual( { organizers: [ 2, 3 ] } );
101
+ wrapperInstance.unregisterBlock();
102
+ } );
103
+
104
+ it( 'Should calculate the diff', () => {
105
+ const HOC = component.getInstance();
106
+ const expected = {
107
+ title: props.title,
108
+ description: props.description,
109
+ };
110
+ expect( HOC.calculateDiff() ).toEqual( expected );
111
+ } );
112
+
113
+ it( 'Should count a single block', () => {
114
+ const HOC = component.getInstance();
115
+ expect( HOC.blockCount() ).toBe( 1 );
116
+ } );
117
+ } );
118
+
119
+ describe( 'HOC - With Details on multiple instances', () => {
120
+ afterEach( () => {
121
+ props.setInitialState.mockClear();
122
+ props.setAttributes.mockClear();
123
+ } );
124
+
125
+ it( 'Should register the initial state just once', () => {
126
+ const WrapperComponent = withSaveData()( Block );
127
+
128
+ renderer.create( <WrapperComponent { ...props } /> );
129
+ renderer.create( <WrapperComponent { ...props } /> );
130
+ renderer.create( <WrapperComponent { ...props } /> );
131
+
132
+ expect( props.setInitialState ).toHaveBeenCalled();
133
+ expect( props.setInitialState ).toHaveBeenCalledTimes( 1 );
134
+ } );
135
+
136
+ it( 'Should register the state multiple times on non isolated instances', () => {
137
+ const WrapperComponent = withSaveData()( Block );
138
+ props.isolated = true;
139
+ renderer.create( <WrapperComponent { ...props } /> );
140
+ renderer.create( <WrapperComponent { ...props } /> );
141
+ renderer.create( <WrapperComponent { ...props } /> );
142
+
143
+ expect( props.setInitialState ).toHaveBeenCalled();
144
+ expect( props.setInitialState ).toHaveBeenCalledTimes( 3 );
145
+ } );
146
+ } );
147
+
148
+ describe( 'HOC - test life cycle callbacks', () => {
149
+ let Wrapper;
150
+ let component;
151
+ let instance;
152
+ let properties = {};
153
+
154
+ beforeAll( () => {
155
+ props.onBlockCreated = jest.fn();
156
+ props.onBlockRemoved = jest.fn();
157
+ });
158
+
159
+ beforeEach( () => {
160
+ Wrapper = withSaveData()( Block );
161
+ component = renderer.create( <Wrapper { ...props } /> );
162
+ instance = component.root;
163
+ properties = instance.props;
164
+ } );
165
+
166
+ afterEach( () => {
167
+ props.setInitialState.mockClear();
168
+ props.setAttributes.mockClear();
169
+ props.onBlockCreated.mockClear();
170
+ props.onBlockRemoved.mockClear();
171
+ } );
172
+
173
+ afterAll( () => {
174
+ delete props.onBlockCreated;
175
+ delete props.onBlockRemoved;
176
+ } );
177
+
178
+ it( 'Should call the onBlockCreated callback on mount', () => {
179
+ expect( props.onBlockCreated ).toHaveBeenCalled();
180
+ expect( props.onBlockCreated ).toHaveBeenCalledWith( properties );
181
+ expect( props.onBlockRemoved ).not.toHaveBeenCalled();
182
+ } );
183
+
184
+ it( 'Should call the onBlockRemoved callback on unmount of the block', () => {
185
+ component.unmount();
186
+ expect( props.onBlockCreated ).toHaveBeenCalled();
187
+ expect( props.onBlockCreated ).toHaveBeenCalledWith( properties );
188
+ expect( props.onBlockRemoved ).toHaveBeenCalled();
189
+ expect( props.onBlockRemoved ).toHaveBeenCalledWith( properties );
190
+ } );
191
+ } );
common/src/modules/hoc/__tests__/with-selected.test.js ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { withSelected } from '@moderntribe/common/hoc';
10
+
11
+ const Block = () => ( <div>With Selected!</div> );
12
+
13
+ describe( 'withSelected', () => {
14
+ let HOC;
15
+ const onFocus = jest.fn();
16
+ const onBlur = jest.fn();
17
+ const props = {
18
+ onBlockFocus: onFocus,
19
+ onBlockBlur: onBlur,
20
+ };
21
+
22
+ beforeEach( () => {
23
+ HOC = withSelected()( Block );
24
+ } );
25
+
26
+ afterEach( () => {
27
+ props.onBlockFocus.mockClear();
28
+ props.onBlockBlur.mockClear();
29
+ } );
30
+
31
+ test( 'onBlur called when is not selected on mount', () => {
32
+ props.isSelected = false;
33
+ const component = mount( <HOC { ...props } /> );
34
+ expect( props.onBlockBlur ).toHaveBeenCalled();
35
+ expect( props.onBlockFocus ).not.toHaveBeenCalled();
36
+ } );
37
+
38
+ test( 'onFocus called when is selected on mount', () => {
39
+ props.isSelected = true;
40
+ const component = mount( <HOC { ...props } /> );
41
+ expect( props.onBlockFocus ).toHaveBeenCalled();
42
+ expect( props.onBlockBlur ).not.toHaveBeenCalled();
43
+ } );
44
+
45
+ test( 'trigger focus when isSelected changes after mounted', () => {
46
+ props.isSelected = false;
47
+ const component = mount( <HOC { ...props } /> );
48
+ expect( props.onBlockBlur ).toHaveBeenCalled();
49
+ expect( props.onBlockFocus ).not.toHaveBeenCalled();
50
+
51
+ props.onBlockBlur.mockClear();
52
+ props.onBlockFocus.mockClear();
53
+
54
+ component.setProps( { isSelected: true } );
55
+
56
+ expect( props.onBlockFocus ).toHaveBeenCalled();
57
+ expect( props.onBlockBlur ).not.toHaveBeenCalled();
58
+ } );
59
+
60
+ test( 'trigger onBlur when isSelected changes after mounted', () => {
61
+ props.isSelected = true;
62
+ const component = mount( <HOC { ...props } /> );
63
+ expect( props.onBlockFocus ).toHaveBeenCalled();
64
+ expect( props.onBlockBlur ).not.toHaveBeenCalled();
65
+
66
+ props.onBlockBlur.mockClear();
67
+ props.onBlockFocus.mockClear();
68
+
69
+ component.setProps( { isSelected: false } );
70
+
71
+ expect( props.onBlockBlur ).toHaveBeenCalled();
72
+ expect( props.onBlockFocus ).not.toHaveBeenCalled();
73
+ } );
74
+
75
+ test( 'blue and focus on the different props changes', () => {
76
+ props.isSelected = false;
77
+ const component = mount( <HOC { ...props } /> );
78
+ expect( props.onBlockBlur ).toHaveBeenCalled();
79
+ expect( props.onBlockFocus ).not.toHaveBeenCalled();
80
+
81
+ props.onBlockBlur.mockClear();
82
+ props.onBlockFocus.mockClear();
83
+
84
+ component.setProps( { isSelected: true } );
85
+
86
+ expect( props.onBlockFocus ).toHaveBeenCalled();
87
+ expect( props.onBlockBlur ).not.toHaveBeenCalled();
88
+
89
+ props.onBlockBlur.mockClear();
90
+ props.onBlockFocus.mockClear();
91
+
92
+ component.setProps( { isSelected: false } );
93
+
94
+ expect( props.onBlockBlur ).toHaveBeenCalled();
95
+ expect( props.onBlockFocus ).not.toHaveBeenCalled();
96
+ } );
97
+ } );
common/src/modules/hoc/__tests__/with-store.test.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import renderer from 'react-test-renderer';
5
+ import React from 'react';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { withStore } from '@moderntribe/common/hoc';
11
+
12
+ describe( 'HOC - With Store', () => {
13
+ it( 'Should add the store property', () => {
14
+ const Block = ( props ) => <div { ...props } />;
15
+ const Wrapper = withStore()( Block );
16
+ const component = renderer.create( <Wrapper /> );
17
+ expect( component.toJSON() ).toMatchSnapshot();
18
+
19
+ const instance = component.root;
20
+ expect( instance ).not.toBe( null );
21
+ const props = instance.findByType( Block ).props;
22
+ expect( props ).toHaveProperty( 'store' );
23
+ const { store } = props;
24
+ expect( store ).toHaveProperty( 'dispatch' );
25
+ expect( store ).toHaveProperty( 'getState' );
26
+ } );
27
+ } );
28
+
common/src/modules/hoc/index.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ export { default as withStore } from './with-store';
2
+ export { default as withSaveData } from './with-save-data';
3
+ export { default as withForm } from './with-form';
4
+ export { default as withBlockCloser } from './with-block-closer';
5
+ export { default as withSelected } from './with-selected';
common/src/modules/hoc/with-block-closer.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable max-len */
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import React, { PureComponent } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import { noop } from 'lodash';
8
+
9
+ const ESCAPE_KEY = 27;
10
+ export const EVENT_NAMESPACE = 'tribe:click:proxy';
11
+ export const dispatch = ( e ) => {
12
+ e.target.dispatchEvent( new CustomEvent( EVENT_NAMESPACE, { bubbles: true } ) );
13
+ };
14
+ export const intercept = e => e.stopPropagation();
15
+
16
+ export default ( WrappedComponent ) => {
17
+ /**
18
+ * Prevents clicks on block or blacklisted DOM elements
19
+ * from closing the block
20
+ *
21
+ * @class WithBlockCloser
22
+ * @extends {PureComponent}
23
+ */
24
+ class WithBlockCloser extends PureComponent {
25
+ static displayName = `WithBlockCloser( ${ WrappedComponent.displayName || WrappedComponent.name || 'Component ' }`
26
+
27
+ static propTypes = {
28
+ onClose: PropTypes.func.isRequired,
29
+ classNameClickBlacklist: PropTypes.arrayOf( PropTypes.string ).isRequired,
30
+ isOpen: PropTypes.bool.isRequired,
31
+ };
32
+
33
+ static defaultProps = {
34
+ classNameClickBlacklist: [ '.edit-post-sidebar' ],
35
+ onClose: noop,
36
+ isOpen: false,
37
+ }
38
+
39
+ nodeRef = React.createRef();
40
+ _eventNamespace = EVENT_NAMESPACE;
41
+
42
+ /**
43
+ * dispatches custom events
44
+ *
45
+ * @memberof WithBlockCloser
46
+ * @param {Event} e event
47
+ */
48
+ _dispatchClickProxyEvent = dispatch;
49
+
50
+ // Prevent CustomEvents from propagating to document proxy listeners
51
+ _interceptClickProxyEvent = intercept;
52
+
53
+ /**
54
+ * keydown handler
55
+ *
56
+ * @memberof WithBlockCloser
57
+ * @param {Event} e event
58
+ */
59
+ handleKeyDown = ( e ) => {
60
+ if ( e.keyCode === ESCAPE_KEY ) {
61
+ this.props.onClose();
62
+ }
63
+ }
64
+
65
+ handleClick = () => this.props.onClose()
66
+
67
+ componentDidMount() {
68
+ this.props.isOpen && this._addEventListeners();
69
+ }
70
+
71
+ componentDidUpdate( prevProps ) {
72
+ if ( prevProps.isOpen !== this.props.isOpen ) {
73
+ this.props.isOpen
74
+ ? this._addEventListeners()
75
+ : this._removeEventListeners();
76
+ }
77
+ }
78
+
79
+ componentWillUnmount() {
80
+ this._removeEventListeners();
81
+ }
82
+
83
+ get blacklistedNodes() {
84
+ const classNames = this.props.classNameClickBlacklist.join( ', ' );
85
+ return Array.from( document.querySelectorAll( classNames ) );
86
+ }
87
+
88
+ get node() {
89
+ return this.nodeRef.current;
90
+ }
91
+
92
+ _addEventListeners() {
93
+ // Intercept custom events bubbled in block or blacklisted nodes
94
+ this.node.addEventListener( this._eventNamespace, this._interceptClickProxyEvent );
95
+ this.blacklistedNodes.forEach(
96
+ node => node.addEventListener( this._eventNamespace, this._interceptClickProxyEvent )
97
+ );
98
+
99
+ // Wait to receive custom events, if not intercepted, then go to click handler
100
+ document.addEventListener( this._eventNamespace, this.handleClick );
101
+ // Dispatch custom event on regular clicks
102
+ document.addEventListener( 'click', this._dispatchClickProxyEvent );
103
+
104
+ // Close on certain keypresses
105
+ document.addEventListener( 'keydown', this.handleKeyDown );
106
+ }
107
+
108
+ _removeEventListeners() {
109
+ this.node.removeEventListener( this._eventNamespace, this._interceptClickProxyEvent );
110
+ this.blacklistedNodes.forEach(
111
+ node => node.removeEventListener( this._eventNamespace, this._interceptClickProxyEvent )
112
+ );
113
+
114
+ document.removeEventListener( 'keydown', this.handleKeyDown );
115
+ document.removeEventListener( this._eventNamespace, this.handleClick );
116
+ document.removeEventListener( 'click', this._dispatchClickProxyEvent );
117
+ }
118
+
119
+ render() {
120
+ return (
121
+ <div ref={ this.nodeRef }>
122
+ <WrappedComponent { ...this.props } />
123
+ </div>
124
+ );
125
+ }
126
+ }
127
+
128
+ return WithBlockCloser;
129
+ };
common/src/modules/hoc/with-form.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { Component } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { bindActionCreators } from 'redux';
7
+ import { connect } from 'react-redux';
8
+ import { noop } from 'lodash';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import { actions, selectors } from '@moderntribe/common/data/forms';
14
+
15
+ /**
16
+ * HOC that register a new object associated with set of fields for a form
17
+ *
18
+ * @param {function} getName Function used to set the name of the form, has a props param to generate the name
19
+ * @returns {function(*): *} Returns a function that takes a Component as argument and returns a component.
20
+ */
21
+ export default ( getName = noop ) => ( WrappedComponent ) => {
22
+ class WithForm extends Component {
23
+ static propTypes = {
24
+ registerForm: PropTypes.func,
25
+ postType: PropTypes.string,
26
+ };
27
+
28
+ componentDidMount() {
29
+ const name = getName( this.props );
30
+ const { registerForm, postType } = this.props;
31
+ registerForm( name, postType );
32
+ }
33
+
34
+ render() {
35
+ return <WrappedComponent { ...this.props } { ...this.additionalProps() } />;
36
+ }
37
+
38
+ additionalProps() {
39
+ const {
40
+ createDraft,
41
+ sendForm,
42
+ setSubmit,
43
+ editEntry,
44
+ maybeRemoveEntry,
45
+ } = this.props;
46
+ const name = getName( this.props );
47
+ return {
48
+ createDraft: ( fieldsObject ) => createDraft( name, fieldsObject ),
49
+ editEntry: ( fieldsObject ) => editEntry( name, fieldsObject ),
50
+ sendForm: ( fieldsObject, callback ) => sendForm( name, fieldsObject, callback ),
51
+ setSubmit: () => setSubmit( name ),
52
+ maybeRemoveEntry: ( details ) => maybeRemoveEntry( name, details ),
53
+ };
54
+ }
55
+ }
56
+
57
+ const mapStateToProps = ( state, props ) => {
58
+ const name = getName( props );
59
+ const modifiedProps = { name };
60
+ return {
61
+ edit: selectors.getFormEdit( state, modifiedProps ),
62
+ create: selectors.getFormCreate( state, modifiedProps ),
63
+ fields: selectors.getFormFields( state, modifiedProps ),
64
+ submit: selectors.getFormSubmit( state, modifiedProps ),
65
+ };
66
+ };
67
+
68
+ const mapDispatchToProps = ( dispatch ) => bindActionCreators( actions, dispatch );
69
+
70
+ return connect( mapStateToProps, mapDispatchToProps )( WithForm );
71
+ };
{src/modules/blocks → common/src/modules}/hoc/with-save-data.js RENAMED
@@ -1,9 +1,3 @@
1
- /**
2
- * @todo: This is just a holder for ET blocks until the block editor UX work.
3
- * The `withSaveData()` HOC needs to be removed from common. Until the
4
- * block editor UX work, this will live here.
5
- */
6
-
7
  /**
8
  * External dependencies
9
  */
@@ -158,3 +152,4 @@ export default ( selectedAttributes = null ) => ( WrappedComponent ) => {
158
 
159
  return WithSaveData;
160
  };
 
 
 
 
 
 
 
1
  /**
2
  * External dependencies
3
  */
152
 
153
  return WithSaveData;
154
  };
155
+
common/src/modules/hoc/with-selected.js ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React, { Component } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import {
7
+ noop,
8
+ } from 'lodash';
9
+
10
+ /**
11
+ * Higher order component that executes two functions:
12
+ *
13
+ * - `onBlockFocus` when the block is selected
14
+ * - `onBlockBlur` when the block losses focus after being selected
15
+ *
16
+ * @returns {function} Return a new HOC
17
+ */
18
+ export default () => ( WrappedComponent ) => {
19
+ class WithSelected extends Component {
20
+ static defaultProps = {
21
+ isSelected: false,
22
+ onBlockFocus: noop,
23
+ onBlockBlur: noop,
24
+ };
25
+
26
+ static propTypes = {
27
+ onBlockFocus: PropTypes.func,
28
+ onBlockBlur: PropTypes.func,
29
+ isSelected: PropTypes.bool,
30
+ };
31
+
32
+ componentDidMount() {
33
+ const { isSelected, onBlockFocus, onBlockBlur } = this.props;
34
+ if ( isSelected ) {
35
+ onBlockFocus();
36
+ } else {
37
+ onBlockBlur();
38
+ }
39
+ }
40
+
41
+ componentDidUpdate( prevProps ) {
42
+ const { isSelected, onBlockFocus, onBlockBlur } = this.props;
43
+
44
+ if ( prevProps.isSelected === isSelected ) {
45
+ return;
46
+ }
47
+
48
+ if ( isSelected ) {
49
+ onBlockFocus();
50
+ } else {
51
+ onBlockBlur();
52
+ }
53
+ }
54
+
55
+ render() {
56
+ return <WrappedComponent { ...this.props } />;
57
+ }
58
+ }
59
+
60
+ WithSelected.displayName = `WithIsSelected( ${ WrappedComponent.displayName || WrappedComponent.name || 'Component ' }`;
61
+
62
+ return WithSelected;
63
+ };
64
+
common/src/modules/hoc/with-store.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import React from 'react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { store } from '@moderntribe/common/store';
10
+
11
+ const getStore = () => store;
12
+
13
+ export default ( additionalProps = {} ) => ( WrappedComponent ) => {
14
+
15
+ const WithStore = ( props ) => {
16
+ const extraProps = {
17
+ ...additionalProps,
18
+ store: getStore(),
19
+ };
20
+
21
+ return <WrappedComponent { ...props } { ...extraProps } />;
22
+ };
23
+
24
+ return WithStore;
25
+
26
+ };
common/src/modules/package.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "@moderntribe/common",
3
+ "version": "0.3.2-alpha",
4
+ "description": "Common Blocks Editor modules",
5
+ "main": "src/resources/main.js",
6
+ "scripts": {},
7
+ "keywords": [
8
+ "gutenberg",
9
+ "common"
10
+ ],
11
+ "private": true,
12
+ "repository": "git+https://github.com/moderntribe/tribe-common.git",
13
+ "author": "Modern Tribe",
14
+ "license": "GPL-2.0-or-later",
15
+ "dependencies": {
16
+ }
17
+ }
common/src/modules/store/configure-store.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { createStore, applyMiddleware } from 'redux';
5
+ import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
6
+ import { augmentStore } from '@nfen/redux-reducer-injector';
7
+ import thunk from 'redux-thunk';
8
+ import createSagaMiddleware from 'redux-saga';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import reducer from '@moderntribe/common/data';
14
+ import { wpRequest } from './middlewares';
15
+
16
+ const sagaMiddleware = createSagaMiddleware();
17
+
18
+ export default () => {
19
+ if ( window.__tribe_common_store__ ) {
20
+ return window.__tribe_common_store__;
21
+ }
22
+
23
+ const middlewares = [
24
+ thunk,
25
+ sagaMiddleware,
26
+ wpRequest,
27
+ ];
28
+
29
+ const composeEnhancers = composeWithDevTools( { name: 'tribe/common' } );
30
+
31
+ const store = createStore( reducer( {} ), composeEnhancers( applyMiddleware( ...middlewares ) ) );
32
+ augmentStore( reducer, store );
33
+ store.run = sagaMiddleware.run;
34
+ window.__tribe_common_store__ = store;
35
+
36
+ return store;
37
+ };
common/src/modules/store/index.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import 'regenerator-runtime/runtime';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import configureStore from './configure-store';
10
+ import * as middlewares from './middlewares';
11
+
12
+ export const store = configureStore();
13
+ export { middlewares };
common/src/modules/store/middlewares/index.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ export { default as wpRequest } from './request';
2
+ import * as request from './request';
3
+ export { request };
common/src/modules/store/middlewares/request/__tests__/__snapshots__/actions.test.js.snap ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`[STORE] - Request actions WP Request action 1`] = `
4
+ Object {
5
+ "meta": Object {
6
+ "actions": Object {},
7
+ "path": "tribe_organizer/1225",
8
+ },
9
+ "type": "@@MT/COMMON/WP_REQUEST",
10
+ }
11
+ `;
common/src/modules/store/middlewares/request/__tests__/actions.test.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { actions } from '@moderntribe/common/store/middlewares/request';
5
+
6
+ describe( '[STORE] - Request actions', () => {
7
+ test( 'WP Request action', () => {
8
+ const meta = {
9
+ path: 'tribe_organizer/1225',
10
+ actions: {},
11
+ };
12
+ expect( actions.wpRequest( meta ) ).toMatchSnapshot();
13
+ } );
14
+ } );
common/src/modules/store/middlewares/request/__tests__/types.test.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+ import { types } from '@moderntribe/common/store/middlewares/request';
6
+
7
+ describe( '[STORE] - Request types', () => {
8
+ it( 'Should return the types values', () => {
9
+ expect( types.WP_REQUEST ).toBe( `${ PREFIX_COMMON_STORE }/WP_REQUEST` );
10
+ } );
11
+ } );
common/src/modules/store/middlewares/request/__tests__/utils.test.js ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { utils } from '@moderntribe/common/store/middlewares/request';
5
+
6
+ const wpParamsExpected = {
7
+ orderby: 'title',
8
+ status: [ 'draft', 'publish' ],
9
+ order: 'asc',
10
+ page: 1,
11
+ };
12
+
13
+ describe( 'Request utils', () => {
14
+ it( 'Should generate the WP params', () => {
15
+ expect( utils.toWpParams( {} ) ).toEqual( wpParamsExpected );
16
+ } );
17
+
18
+ it( 'Should order by relevance if has search', () => {
19
+ expect( utils.toWpParams( { search: 'tribe' } ) )
20
+ .toEqual( {
21
+ ...wpParamsExpected,
22
+ search: 'tribe',
23
+ orderby: 'relevance',
24
+ } );
25
+ } );
26
+
27
+ it( 'Should update the exclude parameter', () => {
28
+ expect( utils.toWpParams( { exclude: [] } ) ).toEqual( wpParamsExpected );
29
+ expect( utils.toWpParams( { exclude: [ 1, 2 ] } ) )
30
+ .toEqual( {
31
+ ...wpParamsExpected,
32
+ exclude: [ 1, 2 ],
33
+ } );
34
+ } );
35
+
36
+ it( 'Should generate a WP Query', () => {
37
+ expect( utils.toWPQuery() ).toBe( 'orderby=title&status=draft%2Cpublish&order=asc&page=1' );
38
+ expect( utils.toWPQuery( { search: 'Modern Tribe' } ) )
39
+ .toBe( 'orderby=relevance&status=draft%2Cpublish&order=asc&page=1&search=Modern%20Tribe' );
40
+ } );
41
+
42
+ it( 'Should return the total of pages', () => {
43
+ const headers = new Headers();
44
+ headers.append( 'x-wp-totalpages', 5 );
45
+ expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5' );
46
+ expect( utils.getTotalPages( headers ) ).toBe( 5 );
47
+
48
+ headers.set( 'x-wp-totalpages', '5' );
49
+ expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5' );
50
+ expect( utils.getTotalPages( headers ) ).toBe( 5 );
51
+
52
+ headers.set( 'x-wp-totalpages', '5.3' );
53
+ expect( headers.get( 'x-wp-totalpages' ) ).toBe( '5.3' );
54
+ expect( utils.getTotalPages( headers ) ).toBe( 5 );
55
+
56
+ headers.delete( 'x-wp-totalpages' );
57
+ headers.set( 'x-wp', 5 );
58
+ expect( utils.getTotalPages( headers ) ).toBe( 0 );
59
+ expect( utils.getTotalPages( new Headers() ) ).toBe( 0 );
60
+ } );
61
+ } );
common/src/modules/store/middlewares/request/__tests__/wp-request.test.js ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import wpRequest, { actions } from '@moderntribe/common/store/middlewares/request';
5
+
6
+ let create;
7
+ const nextMock = jest.fn();
8
+ const meta = {
9
+ path: '',
10
+ params: {},
11
+ actions: {
12
+ none: jest.fn(),
13
+ start: jest.fn(),
14
+ success: jest.fn(),
15
+ error: jest.fn(),
16
+ },
17
+ };
18
+
19
+ describe( '[STORE] - wp-request middleware', () => {
20
+ let _fetch;
21
+ beforeAll( () => {
22
+ create = () => {
23
+ const invoke = ( action ) => wpRequest()( nextMock )( action );
24
+ return { next: nextMock, invoke };
25
+ };
26
+ _fetch = global.fetch;
27
+ } );
28
+
29
+ afterEach( () => {
30
+ global.fetch = _fetch;
31
+ } );
32
+
33
+ afterEach( () => {
34
+ nextMock.mockClear();
35
+ meta.actions.start.mockClear();
36
+ meta.actions.error.mockClear();
37
+ meta.actions.none.mockClear();
38
+ meta.actions.success.mockClear();
39
+ window.wp.apiRequest = undefined;
40
+ } );
41
+
42
+ it( 'Should move through a unknown action', () => {
43
+ const { next, invoke } = create();
44
+ const action = { type: 'UNKNOWN' };
45
+ invoke( action );
46
+
47
+ expect( next ).toHaveBeenCalled();
48
+ expect( next ).toHaveBeenCalledTimes( 1 );
49
+ expect( next ).toHaveBeenCalledWith( action );
50
+ } );
51
+
52
+ it( 'Should execute the none action if the path is empty', () => {
53
+ const { next, invoke } = create();
54
+ const action = actions.wpRequest( meta );
55
+ invoke( action );
56
+
57
+ expect( next ).toHaveBeenCalled();
58
+ expect( next ).toHaveBeenCalledTimes( 1 );
59
+ expect( next ).toHaveBeenCalledWith( action );
60
+ expect( meta.actions.none ).toHaveBeenCalled();
61
+ expect( meta.actions.none ).toHaveBeenCalledTimes( 1 );
62
+ expect( meta.actions.none ).toHaveBeenLastCalledWith( meta.path );
63
+ expect( meta.actions.start ).not.toHaveBeenCalled();
64
+ expect( meta.actions.success ).not.toHaveBeenCalled();
65
+ expect( meta.actions.error ).not.toHaveBeenCalled();
66
+ } );
67
+
68
+ it( 'Should execute the correct actions on success', async () => {
69
+ const { invoke } = create();
70
+
71
+ const body = {
72
+ id: 1217,
73
+ date: '2018-05-26T23:07:05',
74
+ meta: {},
75
+ };
76
+
77
+ const headers = new Headers();
78
+
79
+ global.fetch = jest.fn().mockImplementation( () =>
80
+ Promise.resolve( {
81
+ ok: true,
82
+ status: 200,
83
+ json: () => body,
84
+ headers,
85
+ } ),
86
+ );
87
+
88
+ await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
89
+
90
+ expect.assertions( 8 );
91
+ expect( meta.actions.none ).not.toHaveBeenCalled();
92
+ expect( meta.actions.error ).not.toHaveBeenCalled();
93
+ expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
94
+ expect( meta.actions.start ).toHaveBeenCalled();
95
+ expect( meta.actions.start ).toHaveBeenCalledTimes( 1 );
96
+ expect( meta.actions.success ).toHaveBeenCalled();
97
+ expect( meta.actions.success )
98
+ .toHaveBeenCalledWith( { body, headers } );
99
+ expect( meta.actions.success ).toHaveBeenCalledTimes( 1 );
100
+ } );
101
+
102
+ it( 'execute success actions on 201 response code - creation code', async () => {
103
+ const { invoke } = create();
104
+
105
+ const body = {
106
+ id: 201,
107
+ date: '2018-05-26T23:07:05',
108
+ meta: {
109
+ title: 'Creating a post....'
110
+ },
111
+ };
112
+
113
+ const headers = new Headers();
114
+
115
+ global.fetch = jest.fn().mockImplementation( () =>
116
+ Promise.resolve( {
117
+ ok: true,
118
+ status: 201,
119
+ json: () => body,
120
+ headers,
121
+ } ),
122
+ );
123
+
124
+ await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
125
+
126
+ expect.assertions( 8 );
127
+ expect( meta.actions.none ).not.toHaveBeenCalled();
128
+ expect( meta.actions.error ).not.toHaveBeenCalled();
129
+ expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
130
+ expect( meta.actions.start ).toHaveBeenCalled();
131
+ expect( meta.actions.start ).toHaveBeenCalledTimes( 1 );
132
+ expect( meta.actions.success ).toHaveBeenCalled();
133
+ expect( meta.actions.success ).toHaveBeenCalledWith( { body, headers } );
134
+ expect( meta.actions.success ).toHaveBeenCalledTimes( 1 );
135
+ } );
136
+
137
+ it( 'Should reject on 404 status code', async () => {
138
+ const { invoke } = create();
139
+
140
+ global.fetch = jest.fn().mockImplementation( () => Promise.resolve( { status: 404 } ) );
141
+
142
+ const error = await invoke( actions.wpRequest( { ...meta, path: 'tribe_organizer/1217' } ) );
143
+ expect.assertions( 6 );
144
+ expect( meta.actions.none ).not.toHaveBeenCalled();
145
+ expect( meta.actions.success ).not.toHaveBeenCalled();
146
+ expect( meta.actions.start ).toHaveBeenCalled();
147
+ expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217', {} );
148
+ expect( meta.actions.error ).toHaveBeenCalled();
149
+ expect( meta.actions.error ).toHaveBeenCalledWith( error );
150
+ } );
151
+
152
+ it( 'Should execute the correct actions on failure', async () => {
153
+ const { invoke } = create();
154
+
155
+ global.fetch = jest.fn().mockImplementation( () => Promise.reject( 'Wrong path' ) );
156
+
157
+ const error = await invoke( actions.wpRequest( {
158
+ ...meta,
159
+ path: 'tribe_organizer/1217//////',
160
+ } ) );
161
+ expect.assertions( 6 );
162
+ expect( meta.actions.none ).not.toHaveBeenCalled();
163
+ expect( meta.actions.success ).not.toHaveBeenCalled();
164
+ expect( meta.actions.start ).toHaveBeenCalled();
165
+ expect( meta.actions.start ).toHaveBeenCalledWith( 'wp/v2/tribe_organizer/1217//////', {} );
166
+ expect( meta.actions.error ).toHaveBeenCalled();
167
+ expect( meta.actions.error ).toHaveBeenCalledWith( error );
168
+ } );
169
+ } );
common/src/modules/store/middlewares/request/actions.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import * as types from './types';
5
+
6
+ export const wpRequest = ( meta ) => ( {
7
+ type: types.WP_REQUEST,
8
+ meta,
9
+ } );
common/src/modules/store/middlewares/request/index.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import * as types from './types';
5
+ import * as actions from './actions';
6
+ import * as utils from './utils';
7
+
8
+ export { default } from './wp-request';
9
+ export { types, actions, utils };
common/src/modules/store/middlewares/request/types.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { PREFIX_COMMON_STORE } from '@moderntribe/common/data/utils';
5
+
6
+ export const WP_REQUEST = `${ PREFIX_COMMON_STORE }/WP_REQUEST`;
common/src/modules/store/middlewares/request/utils.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { isEmpty, isUndefined } from 'lodash';
5
+ import { stringify } from 'querystringify';
6
+
7
+ export const toWpParams = ( args = {} ) => {
8
+ const params = {
9
+ orderby: 'title',
10
+ status: [ 'draft', 'publish' ],
11
+ order: 'asc',
12
+ page: 1,
13
+ ...args,
14
+ };
15
+
16
+ if ( ! isUndefined( params.search ) && ! isEmpty( params.search ) ) {
17
+ params.orderby = 'relevance';
18
+ }
19
+
20
+ if ( isEmpty( params.exclude ) ) {
21
+ delete params.exclude;
22
+ }
23
+
24
+ return params;
25
+ };
26
+
27
+ export const toWPQuery = ( args = {} ) => stringify( toWpParams( args ) );
28
+
29
+ export const getTotalPages = ( headers ) => {
30
+ const totalPages = parseInt( headers.get( 'x-wp-totalpages' ), 10 );
31
+ return isNaN( totalPages ) ? 0 : totalPages;
32
+ };
common/src/modules/store/middlewares/request/wp-request.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { noop, get, inRange } from 'lodash';
5
+ import 'whatwg-fetch';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import { rest } from '@moderntribe/common/utils/globals';
11
+ import { types } from '@moderntribe/common/store/middlewares/request';
12
+
13
+ export default () => ( next ) => async ( action ) => {
14
+ if ( action.type !== types.WP_REQUEST ) {
15
+ return next( action );
16
+ }
17
+
18
+ const { meta = {} } = action;
19
+
20
+ const {
21
+ path = '',
22
+ params = {},
23
+ } = meta;
24
+
25
+ next( action );
26
+
27
+ const { url = '', nonce = {} } = rest();
28
+ const wpRESTNonce = nonce.wp_rest || '';
29
+ const namespaces = rest.namespaces || {};
30
+ const core = namespaces.core || 'wp/v2';
31
+ const BASE = `${ url }${ core }`;
32
+
33
+ const actions = {
34
+ start: noop,
35
+ success: noop,
36
+ error: noop,
37
+ none: noop,
38
+ ...get( meta, 'actions', {} ),
39
+ };
40
+
41
+ if ( path === '' ) {
42
+ actions.none( path );
43
+ return;
44
+ }
45
+
46
+ const endpoint = `${ BASE }/${ path }`;
47
+
48
+ actions.start( endpoint, params );
49
+
50
+ const headers = {
51
+ 'Accept': 'application/json',
52
+ 'Content-Type': 'application/json',
53
+ ...get( params, 'headers', {} ),
54
+ 'X-WP-Nonce': wpRESTNonce,
55
+ };
56
+
57
+ try {
58
+ const response = await fetch( endpoint, {
59
+ ...params,
60
+ credentials: 'include',
61
+ headers,
62
+ } );
63
+
64
+ const { status } = response;
65
+ // inRange includes 200 but excludes 300 from the range so it's from 200 up to 299
66
+ if ( ! inRange( status, 200, 300 ) ) {
67
+ throw response;
68
+ }
69
+ const body = await response.json();
70
+ actions.success( { body, headers: response.headers } );
71
+ return [ response, body ];
72
+ } catch ( error ) {
73
+ actions.error( error );
74
+ return error;
75
+ }
76
+ };
common/src/modules/utils/__tests__/__snapshots__/globals.test.js.snap ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Tests for globals.js Should match the default value for the globals values 1`] = `
4
+ Object {
5
+ "common": Object {
6
+ "countries": Object {},
7
+ "rest": Object {
8
+ "namespaces": Object {
9
+ "core": "wp/v2",
10
+ },
11
+ "nonce": Object {
12
+ "add_ticket_nonce": "0878f40fb2",
13
+ "wp_rest": "cedcd6967b",
14
+ },
15
+ "url": "http://gutenberg.local/wp-json/",
16
+ },
17
+ "settings": Object {},
18
+ "usStates": Object {},
19
+ },
20
+ "tec": Object {
21
+ "googleMap": Object {},
22
+ },
23
+ "tickets": Object {
24
+ "default_currency": "$",
25
+ "default_provider": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
26
+ "providers": Array [
27
+ Object {
28
+ "class": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
29
+ "currency": "$",
30
+ "currency_position": "prefix",
31
+ "name": "WooCommerce",
32
+ },
33
+ ],
34
+ },
35
+ }
36
+ `;
37
+
38
+ exports[`Tests for globals.js Should match the default value for the globals values 2`] = `
39
+ Object {
40
+ "common": Object {
41
+ "countries": Object {},
42
+ "rest": Object {
43
+ "namespaces": Object {
44
+ "core": "wp/v2",
45
+ },
46
+ "nonce": Object {
47
+ "add_ticket_nonce": "0878f40fb2",
48
+ "wp_rest": "cedcd6967b",
49
+ },
50
+ "url": "http://gutenberg.local/wp-json/",
51
+ },
52
+ "settings": Object {},
53
+ "usStates": Object {},
54
+ },
55
+ "tec": Object {
56
+ "googleMap": Object {},
57
+ },
58
+ "tickets": Object {
59
+ "default_currency": "$",
60
+ "default_provider": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
61
+ "providers": Array [
62
+ Object {
63
+ "class": "Tribe__Tickets_Plus__Commerce__WooCommerce__Main",
64
+ "currency": "$",
65
+ "currency_position": "prefix",
66
+ "name": "WooCommerce",
67
+ },
68
+ ],
69
+ },
70
+ }
71
+ `;
72
+
73
+ exports[`Tests for globals.js get default value 1`] = `Array []`;
74
+
75
+ exports[`Tests for globals.js rest value 1`] = `
76
+ Object {
77
+ "namespaces": Object {
78
+ "core": "wp/v2",
79
+ },
80
+ "nonce": Object {
81
+ "add_ticket_nonce": "0878f40fb2",
82
+ "wp_rest": "cedcd6967b",
83
+ },
84
+ "url": "http://gutenberg.local/wp-json/",
85
+ }
86
+ `;
87
+
88
+ exports[`Tests for globals.js rest value 2`] = `
89
+ Object {
90
+ "add_ticket_nonce": "0878f40fb2",
91
+ "wp_rest": "cedcd6967b",
92
+ }
93
+ `;
common/src/modules/utils/__tests__/__snapshots__/time.test.js.snap ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Tests for time.js fromMilliseconds() test 1`] = `"Argument \`ms\` provided to \`fromMilliseconds\` is not a number or is NaN."`;
4
+
5
+ exports[`Tests for time.js fromMilliseconds() test 2`] = `"Argument \`ms\` provided to \`fromMilliseconds\` is not a number or is NaN."`;
6
+
7
+ exports[`Tests for time.js fromMilliseconds() test 3`] = `"Argument \`format\` provided to \`formatTime\` is not a recognized format."`;
8
+
9
+ exports[`Tests for time.js fromSeconds() test 1`] = `"Argument \`s\` provided to \`fromSeconds\` is not a number or is NaN."`;
10
+
11
+ exports[`Tests for time.js fromSeconds() test 2`] = `"Argument \`s\` provided to \`fromSeconds\` is not a number or is NaN."`;
12
+
13
+ exports[`Tests for time.js fromSeconds() test 3`] = `"Argument \`format\` provided to \`formatTime\` is not a recognized format."`;
14
+
15
+ exports[`Tests for time.js toMilliseconds() test 1`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
16
+
17
+ exports[`Tests for time.js toMilliseconds() test 2`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
18
+
19
+ exports[`Tests for time.js toMilliseconds() test 3`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
20
+
21
+ exports[`Tests for time.js toMilliseconds() test 4`] = `"Argument \`time\` provided to \`toMilliseconds\` contains minutes or seconds greater than 59."`;
22
+
23
+ exports[`Tests for time.js toMilliseconds() test 5`] = `"Argument \`format\` provided to \`toMilliseconds\` is not a recognized format."`;
24
+
25
+ exports[`Tests for time.js toSeconds() test 1`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
26
+
27
+ exports[`Tests for time.js toSeconds() test 2`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
28
+
29
+ exports[`Tests for time.js toSeconds() test 3`] = `"Argument \`time\` provided to \`toMilliseconds\` is not a recognized format."`;
30
+
31
+ exports[`Tests for time.js toSeconds() test 4`] = `"Argument \`time\` provided to \`toMilliseconds\` contains minutes or seconds greater than 59."`;
32
+
33
+ exports[`Tests for time.js toSeconds() test 5`] = `"Argument \`format\` provided to \`toMilliseconds\` is not a recognized format."`;
common/src/modules/utils/__tests__/date.test.js ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { date, moment as momentUtil } from '@moderntribe/common/utils';
5
+ import moment from 'moment';
6
+
7
+ const {
8
+ FORMATS,
9
+ TODAY,
10
+ timezones,
11
+ timezonesAsSelectData,
12
+ toNaturalLanguage,
13
+ rangeToNaturalLanguage,
14
+ labelToDate,
15
+ } = date;
16
+
17
+ jest.mock( '@moderntribe/common/utils/timezone', () => ( {
18
+ getItems: () => [
19
+ {
20
+ options: [
21
+ {
22
+ key: 'America/Argentina/Buenos_Aires',
23
+ text: 'Argentina - Buenos Aires',
24
+ },
25
+ ],
26
+ },
27
+ {
28
+ options: [
29
+ {
30
+ key: 'America/Argentina/Catamarca',
31
+ text: 'Argentina - Catamarca',
32
+ },
33
+ ],
34
+ },
35
+ ],
36
+ } ) );
37
+
38
+ afterAll( () => {
39
+ jest.unmock( '@moderntribe/common/utils/timezone' );
40
+ } );
41
+
42
+ describe( 'Tests for date.js', () => {
43
+ test( 'formats', () => {
44
+ const draft = {
45
+ TIME: 'HH:mm:ss',
46
+ DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
47
+ WP: {
48
+ time: 'g:i a',
49
+ time24Hr: 'H:i',
50
+ date: 'F j, Y',
51
+ datetime: 'F j, Y g:i a',
52
+ dateNoYear: 'F j',
53
+ },
54
+ DATABASE: {
55
+ date: 'Y-m-d',
56
+ datetime: 'Y-m-d H:i:s',
57
+ time: 'H:i:s',
58
+ },
59
+ TIMEZONE: {
60
+ string: 'UTC',
61
+ },
62
+ };
63
+ expect( FORMATS ).toEqual( draft );
64
+ } );
65
+
66
+ test( 'today', () => {
67
+ const now = new Date();
68
+ expect( TODAY ).toBeInstanceOf( Date );
69
+ expect( TODAY ).hasOwnProperty( 'getDay' );
70
+ expect( TODAY.getDay() ).toEqual( now.getDay() );
71
+ } );
72
+
73
+ test( 'timezones', () => {
74
+ const expected = [
75
+ {
76
+ key: 'America/Argentina/Buenos_Aires',
77
+ text: 'Argentina - Buenos Aires',
78
+ },
79
+ {
80
+ key: 'America/Argentina/Catamarca',
81
+ text: 'Argentina - Catamarca',
82
+ },
83
+ ];
84
+ expect( timezones() ).toEqual( expected );
85
+ } );
86
+
87
+ test( 'timezonesAsSelectData', () => {
88
+ const expected = [
89
+ {
90
+ value: 'America/Argentina/Buenos_Aires',
91
+ label: 'Argentina - Buenos Aires',
92
+ },
93
+ {
94
+ value: 'America/Argentina/Catamarca',
95
+ label: 'Argentina - Catamarca',
96
+ },
97
+ ];
98
+ expect( timezonesAsSelectData() ).toEqual( expected );
99
+ } );
100
+
101
+ describe( 'toNaturalLanguage', () => {
102
+ it( 'Should return empty string when non parsed', () => {
103
+ const defaultDetail = { month: '', day: '', year: '', time: '' };
104
+ expect( toNaturalLanguage( {} ) ).toEqual( { moment: null, text: '', detail: defaultDetail, isValid: false } );
105
+ expect( toNaturalLanguage( { date: undefined } ) ).toEqual( {
106
+ moment: undefined,
107
+ text: '',
108
+ detail: defaultDetail,
109
+ isValid: false
110
+ } );
111
+ expect( toNaturalLanguage( { date: '' } ) ).toEqual( {
112
+ moment: '',
113
+ text: '',
114
+ detail: defaultDetail,
115
+ isValid: false
116
+ } );
117
+ } );
118
+
119
+ it( 'Should return the parsed date', () => {
120
+ expect( toNaturalLanguage( { date: '2018-05-04 17:00:00' } ) )
121
+ .toEqual( {
122
+ moment: momentUtil.toMoment( '2018-05-04 17:00:00' ),
123
+ text: 'May 4 2018 5:00 pm',
124
+ detail: {
125
+ month: 'May',
126
+ day: '4',
127
+ year: '2018',
128
+ time: '5:00 pm',
129
+ },
130
+ isValid: true,
131
+ } );
132
+ expect( toNaturalLanguage( { date: '2019-12-24 12:00:00' } ) )
133
+ .toEqual( {
134
+ moment: momentUtil.toMoment( '2019-12-24 12:00:00' ),
135
+ text: 'December 24 2019 12:00 pm',
136
+ detail: {
137
+ month: 'December',
138
+ day: '24',
139
+ year: '2019',
140
+ time: '12:00 pm',
141
+ },
142
+ isValid: true,
143
+ } );
144
+ } );
145
+ } );
146
+
147
+ describe( 'rangeToNaturalLanguage', () => {
148
+ it( 'Should return empty string when range is invalid', () => {
149
+ expect( rangeToNaturalLanguage( null, null ) ).toBe( '' );
150
+ expect( rangeToNaturalLanguage( undefined, undefined ) ).toBe( '' );
151
+ expect( rangeToNaturalLanguage( '', '' ) ).toBe( '' );
152
+ } );
153
+
154
+ it( 'Should return only the start date', () => {
155
+ expect( rangeToNaturalLanguage( '2019-12-24 12:00:00' ) )
156
+ .toBe( 'December 24 2019 at 12:00 pm' );
157
+ expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '' ) )
158
+ .toBe( 'December 24 2019 at 12:00 pm' );
159
+ } );
160
+
161
+ it( 'Should return the range with time on same day', () => {
162
+ expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2019-12-24 17:00:00' ) )
163
+ .toBe( 'December 24 2019 at 12:00 pm - 5:00 pm' );
164
+ } );
165
+
166
+ it( 'Should return the range without year on same year', () => {
167
+ expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2019-12-29 17:00:00' ) )
168
+ .toBe( 'December 24 2019 at 12:00 pm - December 29 at 5:00 pm' );
169
+ } );
170
+
171
+ it( 'Should return the range on different years', () => {
172
+ expect( rangeToNaturalLanguage( '2019-12-24 12:00:00', '2020-12-24 17:00:00' ) )
173
+ .toBe( 'December 24 2019 at 12:00 pm - December 24 2020 at 5:00 pm' );
174
+ } );
175
+ } );
176
+
177
+ describe( 'labelToDate - be aware chrono module is being mocked to avoid parsing', () => {
178
+ test( 'Default value when date is invalid', () => {
179
+ expect( labelToDate() ).toEqual( { start: null, end: null } );
180
+ } );
181
+
182
+ test( 'Valid dates', () => {
183
+ const momentDate = moment( '12-25-1995', 'MM-DD-YYYY' );
184
+ expect( labelToDate( momentDate ) )
185
+ .toEqual( { start: momentUtil.toDateTime( momentDate ), end: momentUtil.toDateTime( momentDate ) } );
186
+ } );
187
+ } );
188
+
189
+ } );
common/src/modules/utils/__tests__/dom.test.js ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import {
5
+ hasClass,
6
+ isRootNode,
7
+ searchParent,
8
+ } from '@moderntribe/common/utils/dom';
9
+
10
+ describe( 'Tests for dom.js', () => {
11
+ beforeAll( () => {
12
+ window.document.body.classList.add( 'one', 'two' );
13
+ } );
14
+
15
+ afterAll( () => {
16
+ window.document.body.classList.remove( 'one', 'two' );
17
+ } );
18
+
19
+ describe( 'hasClass dom utility', () => {
20
+ it( 'Should return false when the dom element does not have any class', () => {
21
+ expect( hasClass( window.document.body, [] ) ).toBe( false );
22
+ expect( hasClass( window.document.body, [ 'five', 'seven' ] ) ).toBe( false );
23
+ expect( hasClass( window.document.body, [ 'eight' ] ) ).toBe( false );
24
+ } );
25
+
26
+ it( 'Should return true whe the dom element has any of the classes', () => {
27
+ expect( hasClass( window.document.body, [ 'one', 'two' ] ) ).toBe( true );
28
+ expect( hasClass( window.document.body, [ 'two', 'one' ] ) ).toBe( true );
29
+ expect( hasClass( window.document.body, [ 'four', 'two' ] ) ).toBe( true );
30
+ expect( hasClass( window.document.body, [ 'one', 'five' ] ) ).toBe( true );
31
+ expect( hasClass( window.document.body, [ 'nostyle', 'six', 'seven', 'one' ] ) ).toBe( true );
32
+ } );
33
+ } );
34
+
35
+ test( 'Test for searchParent', () => {
36
+ expect( searchParent( null ) ).toBeFalsy();
37
+ const treeWithNode = {
38
+ parentNode: {
39
+ value: 10,
40
+ parentNode: {
41
+ value: 20,
42
+ },
43
+ },
44
+ };
45
+
46
+ const callback = jest.fn( ( node ) => node.value === 20 );
47
+ const result = searchParent( treeWithNode, callback );
48
+ expect( callback ).toBeCalled();
49
+ expect( callback ).toBeCalledWith( { value: 20 } );
50
+ expect( result ).toBeTruthy();
51
+
52
+ const treeWithoutNode = {
53
+ parentNode: {
54
+ parentNode: {
55
+ parentNode: {
56
+ top: {
57
+ document: 'global',
58
+ },
59
+ },
60
+ },
61
+ },
62
+ };
63
+
64
+ expect( searchParent( treeWithoutNode ) ).toBeFalsy();
65
+ } );
66
+
67
+ test( 'Test for isRootNode', () => {
68
+ expect( isRootNode( null ) ).toBeFalsy();
69
+ expect( isRootNode( 'text' ) ).toBeFalsy();
70
+ expect( isRootNode( window.document.body ) ).toBeFalsy();
71
+ expect( isRootNode( window.document ) ).toBeTruthy();
72
+ } );
73
+ } );
common/src/modules/utils/__tests__/globals.test.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import {
5
+ google,
6
+ mapsAPI,
7
+ settings,
8
+ list,
9
+ get,
10
+ config,
11
+ rest,
12
+ restNonce,
13
+ } from '@moderntribe/common/utils/globals';
14
+
15
+ describe( 'Tests for globals.js', () => {
16
+
17
+ beforeAll( () => {
18
+ window.tribe_editor_config = {
19
+ common: {
20
+ countries: {},
21
+ usStates: {},
22
+ settings: {},
23
+ rest: {
24
+ namespaces: {
25
+ core: 'wp/v2',
26
+ },
27
+ nonce: {
28
+ wp_rest: 'cedcd6967b',
29
+ add_ticket_nonce: '0878f40fb2',
30
+ },
31
+ url: 'http://gutenberg.local/wp-json/',
32
+ },
33
+ },
34
+ tec: {
35
+ googleMap: {},
36
+ },
37
+ tickets: {
38
+ providers: [ {
39
+ class: 'Tribe__Tickets_Plus__Commerce__WooCommerce__Main',
40
+ currency: '$',
41
+ currency_position: 'prefix',
42
+ name: 'WooCommerce',
43
+ } ],
44
+ default_provider: 'Tribe__Tickets_Plus__Commerce__WooCommerce__Main',
45
+ default_currency: '$',
46
+ },
47
+ };
48
+ } );
49
+
50
+ test( 'Should match the default value for the globals values', () => {
51
+ expect( get( 'random' ) ).toBe( undefined );
52
+ expect( get( 'google' ) ).toBe( undefined );
53
+ expect( google() ).toBe( undefined );
54
+ expect( get( 'tribe_editor_config' ) ).toMatchSnapshot();
55
+ expect( settings() ).toEqual( {} );
56
+ expect( mapsAPI() ).toEqual( {} );
57
+ expect( list() ).toEqual( {
58
+ countries: {},
59
+ us_states: {},
60
+ } );
61
+ expect( config() ).toMatchSnapshot();
62
+ } );
63
+
64
+ test( 'get default value', () => {
65
+ expect( get( 'UNKNOWN', 10 ) ).toBe( 10 );
66
+ expect( get( 'tribe_js_config', [] ) ).toMatchSnapshot();
67
+ } );
68
+
69
+ test( 'rest value', () => {
70
+ expect( rest() ).toMatchSnapshot();
71
+ expect( restNonce() ).toMatchSnapshot();
72
+ } );
73
+
74
+ afterAll( () => {
75
+ delete window.tribe_editor_config;
76
+ } );
77
+ } );
78
+
79
+ describe( 'Test default values on globals', () => {
80
+ test( 'rest default values', () => {
81
+ expect( rest() ).toEqual( {} );
82
+ expect( restNonce() ).toEqual( {} );
83
+ } );
84
+ } );
common/src/modules/utils/__tests__/input.test.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { sendValue } from '@moderntribe/common/utils/input';
5
+
6
+ describe( 'Tests for input.js', () => {
7
+ const event = {
8
+ target: {
9
+ value: 'Sample',
10
+ },
11
+ };
12
+
13
+ test( 'Callback being executed', () => {
14
+ const mockCallback = jest.fn();
15
+ sendValue( mockCallback )( event );
16
+ expect( mockCallback ).toHaveBeenCalled();
17
+ expect( mockCallback ).toHaveBeenCalledTimes( 1 );
18
+ expect( mockCallback ).toHaveBeenCalledWith( 'Sample' );
19
+ } );
20
+ } );
common/src/modules/utils/__tests__/moment.test.js ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import moment from 'moment/moment';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import {
10
+ date,
11
+ moment as momentUtil,
12
+ time,
13
+ } from '@moderntribe/common/utils';
14
+
15
+ const FORMAT = 'MM-DD-YYYY HH:mm:ss';
16
+
17
+ describe( 'Tests for moment.js', () => {
18
+ let console;
19
+ beforeAll( () => {
20
+ console = window.console;
21
+ window.console = {
22
+ ...console,
23
+ warn: jest.fn(),
24
+ };
25
+ } );
26
+
27
+ afterAll( () => {
28
+ window.console = console;
29
+ } );
30
+
31
+ test( 'TIME_FORMAT', () => {
32
+ expect( momentUtil.TIME_FORMAT ).toEqual( 'h:mm a' );
33
+ } );
34
+
35
+ test( 'roundTime', () => {
36
+ const test1 = momentUtil.roundTime(
37
+ moment( '05-09-2018 12:26:02', FORMAT ),
38
+ );
39
+ expect( test1 ).toBeInstanceOf( moment );
40
+ expect( test1.hour() ).toEqual( 12 );
41
+ expect( test1.minutes() ).toEqual( 0 );
42
+ expect( test1.seconds() ).toEqual( 0 );
43
+
44
+ const test2 = momentUtil.roundTime(
45
+ moment( '05-09-2018 15:30:02', FORMAT ),
46
+ );
47
+ expect( test2 ).toBeInstanceOf( moment );
48
+ expect( test2.hour() ).toEqual( 15 );
49
+ expect( test2.minutes() ).toEqual( 30 );
50
+ expect( test2.seconds() ).toEqual( 0 );
51
+
52
+ const test3 = momentUtil.roundTime(
53
+ moment( '05-09-2018 23:59:59', FORMAT ),
54
+ );
55
+ expect( test3 ).toBeInstanceOf( moment );
56
+ expect( test3.hour() ).toEqual( 23 );
57
+ expect( test3.minutes() ).toEqual( 30 );
58
+ expect( test3.seconds() ).toEqual( 0 );
59
+
60
+ const test4 = momentUtil.roundTime(
61
+ moment( '05-09-2018 08:01:59', FORMAT ),
62
+ );
63
+ expect( test4 ).toBeInstanceOf( moment );
64
+ expect( test4.hour() ).toEqual( 8 );
65
+ expect( test4.minutes() ).toEqual( 0 );
66
+ expect( test4.seconds() ).toEqual( 0 );
67
+ } );
68
+
69
+ test( 'toMoment', () => {
70
+ const input = momentUtil.toMoment( new Date( 'January 2, 2015 08:01:59 UTC' ).toISOString() );
71
+
72
+ expect( input ).toBeInstanceOf( moment );
73
+ expect( input.date() ).toEqual( 2 );
74
+ expect( input.month() ).toEqual( 0 );
75
+ expect( input.year() ).toEqual( 2015 );
76
+ expect( input.hour() ).toEqual( 8 );
77
+ expect( input.minutes() ).toEqual( 1 );
78
+ expect( input.seconds() ).toEqual( 59 );
79
+ expect( input.milliseconds() ).toEqual( 0 );
80
+ expect( input.format( FORMAT ) ).toEqual( '01-02-2015 08:01:59' );
81
+ } );
82
+
83
+ test( 'replaceDate', () => {
84
+ expect( () => momentUtil.replaceDate( 'Sample string', 123123 ) ).toThrowError();
85
+
86
+ const a = moment( '02-28-2010 14:24:40', FORMAT );
87
+ const b = moment( '05-10-2012 20:14:20', FORMAT );
88
+
89
+ const replaced = momentUtil.replaceDate( a, b );
90
+ expect( replaced ).toBeInstanceOf( moment );
91
+ expect( replaced.date() ).toEqual( 10 );
92
+ expect( replaced.month() ).toEqual( 4 );
93
+ expect( replaced.year() ).toEqual( 2012 );
94
+ expect( replaced.hour() ).toEqual( 14 );
95
+ expect( replaced.minute() ).toEqual( 24 );
96
+ expect( replaced.second() ).toEqual( 40 );
97
+ expect( replaced.format( FORMAT ) ).toEqual( '05-10-2012 14:24:40' );
98
+ } );
99
+
100
+ test( 'setTimeInSeconds', () => {
101
+ expect( () => momentUtil.setTimeInSeconds( 'Sample String', 123123 ) ).toThrowError();
102
+
103
+ const a = moment( '02-28-2010 14:24:40', FORMAT );
104
+ const SECONDS = ( 12.5 ) * 60 * 60;
105
+ const replaced = momentUtil.setTimeInSeconds( a, SECONDS );
106
+ expect( replaced ).toBeInstanceOf( moment );
107
+ expect( replaced.date() ).toEqual( 28 );
108
+ expect( replaced.month() ).toEqual( 1 );
109
+ expect( replaced.year() ).toEqual( 2010 );
110
+ expect( replaced.hour() ).toEqual( 12 );
111
+ expect( replaced.minute() ).toEqual( 30 );
112
+ expect( replaced.seconds() ).toEqual( 0 );
113
+ expect( replaced.milliseconds() ).toEqual( 0 );
114
+
115
+ const test2 = momentUtil.setTimeInSeconds( a, 0 );
116
+ expect( test2.date() ).toEqual( 28 );
117
+ expect( test2.month() ).toEqual( 1 );
118
+ expect( test2.year() ).toEqual( 2010 );
119
+ expect( test2.hour() ).toEqual( 0 );
120
+ expect( test2.minute() ).toEqual( 0 );
121
+ expect( test2.seconds() ).toEqual( 0 );
122
+ expect( test2.milliseconds() ).toEqual( 0 );
123
+ } );
124
+
125
+ test( 'totalSeconds', () => {
126
+ expect( momentUtil.totalSeconds( null ) ).toEqual( 0 );
127
+ expect( momentUtil.totalSeconds( new Date() ) ).toEqual( 0 );
128
+ expect( momentUtil.totalSeconds( moment().startOf( 'day' ) ) ).toEqual( 0 );
129
+ expect( momentUtil.totalSeconds( moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ) ) )
130
+ .toEqual( time.HALF_HOUR_IN_SECONDS );
131
+ } );
132
+
133
+ test( 'toDateTime', () => {
134
+ const converted = momentUtil.toDateTime( moment() );
135
+ expect( typeof converted ).toBe( 'string' );
136
+ const format = momentUtil.toFormat( date.FORMATS.DATABASE.datetime );
137
+ expect( converted ).toBe( moment().format( format ) );
138
+ } );
139
+
140
+ test( 'toDate', () => {
141
+ const converted = momentUtil.toDate( moment() );
142
+ expect( typeof converted ).toBe( 'string' );
143
+ expect( typeof converted ).toBe( 'string' );
144
+ const format = momentUtil.toFormat( date.FORMATS.WP.date );
145
+ expect( converted ).toBe( moment().format( format ) );
146
+ } );
147
+
148
+ test( 'toDateNoYear', () => {
149
+ const converted = momentUtil.toDateNoYear( moment() );
150
+ expect( typeof converted ).toBe( 'string' );
151
+ expect( converted ).toBe( moment().format( 'MMMM D' ) );
152
+ } );
153
+
154
+ test( 'toTime', () => {
155
+ const converted = momentUtil.toTime( moment() );
156
+ expect( typeof converted ).toBe( 'string' );
157
+ expect( converted ).toBe( moment().format( 'h:mm a' ) );
158
+ } );
159
+
160
+ test( 'toTime24Hr', () => {
161
+ const converted = momentUtil.toTime24Hr( moment() );
162
+ expect( typeof converted ).toBe( 'string' );
163
+ expect( converted ).toBe( moment().format( 'HH:mm' ) );
164
+ } );
165
+
166
+ test( 'toDatabaseDate', () => {
167
+ const converted = momentUtil.toDatabaseDate( moment() );
168
+ expect( typeof converted ).toBe( 'string' );
169
+ expect( converted ).toBe( moment().format( 'YYYY-MM-DD' ) );
170
+ } );
171
+
172
+ test( 'toDatabaseTime', () => {
173
+ const converted = momentUtil.toDatabaseTime( moment() );
174
+ expect( typeof converted ).toBe( 'string' );
175
+ expect( converted ).toBe( moment().format( 'HH:mm:ss' ) );
176
+ } );
177
+
178
+ test( 'toDatePicker', () => {
179
+ const converted = momentUtil.toDatePicker( moment() );
180
+ expect( typeof converted ).toBe( 'string' );
181
+ expect( converted ).toBe( moment().format( 'YYYY-MM-DDTHH:mm:ss' ) );
182
+ } );
183
+
184
+ test( 'isSameDay', () => {
185
+ expect( momentUtil.isSameDay() ).toBe( false );
186
+ expect( momentUtil.isSameDay( false, '' ) ).toBe( false );
187
+ expect( momentUtil.isSameDay( 0, null ) ).toBe( false );
188
+ expect( momentUtil.isSameDay( moment(), moment().endOf( 'day' ) ) ).toBeTruthy();
189
+ expect( momentUtil.isSameDay( moment().endOf( 'day' ), moment().endOf( 'day' ) ) ).toBeTruthy();
190
+ expect( momentUtil.isSameDay( moment(), moment().add( 10, 'days' ) ) ).toBeFalsy();
191
+ expect( momentUtil.isSameDay( new Date(), new Date() ) ).toBeTruthy();
192
+ } );
193
+
194
+ test( 'isSameMonth', () => {
195
+ const date = moment( 'October 8, 2018 5:30 pm', 'MMMM D, Y h:mm a' );
196
+
197
+ expect( momentUtil.isSameMonth() ).toBe( false );
198
+ expect( momentUtil.isSameMonth( false, '' ) ).toBe( false );
199
+ expect( momentUtil.isSameMonth( 0, null ) ).toBe( false );
200
+ expect( momentUtil.isSameMonth( date, date.clone().add( 24, 'days' ) ) ).toBe( false );
201
+ expect( momentUtil.isSameMonth( date, date.clone().add( 23, 'days' ) ) ).toBe( true );
202
+ expect( momentUtil.isSameMonth( date, date.clone().endOf( 'month' ) ) ).toBe( true );
203
+ expect( momentUtil.isSameMonth( date.clone().endOf( 'month' ), date.clone().endOf( 'month' ) ) ).toBe( true );
204
+ expect( momentUtil.isSameMonth( date, date.clone().add( 10, 'days' ) ) ).toBe( true );
205
+ expect( momentUtil.isSameMonth( date, date ) ).toBe( true );
206
+ } );
207
+
208
+ test( 'isSameYear', () => {
209
+ expect( momentUtil.isSameYear(
210
+ moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ),
211
+ moment( 'September 15, 2018 5:30 am', 'MMM D, YYYY k:m a' )
212
+ ) ).toBeTruthy();
213
+ expect( momentUtil.isSameYear(
214
+ moment( 'May 23, 2022 12:30 am', 'MMM D, YYYY k:m a' ),
215
+ moment( 'September 15, 2022 5:30 am', 'MMM D, YYYY k:m a' )
216
+ ) ).toBeTruthy();
217
+ expect( momentUtil.isSameYear(
218
+ moment( 'May 23, 2018 12:30 am', 'MMM D, YYYY k:m a' ),
219
+ moment( 'September 15, 2022 5:30 am', 'MMM D, YYYY k:m a' )
220
+ ) ).toBeFalsy();
221
+ } );
222
+
223
+ test( 'toMomentFromDate', () => {
224
+ expect( () => momentUtil.toMomentFromDate( '' ) ).toThrowError();
225
+ expect( () => momentUtil.toMomentFromDate( moment() ) ).toThrowError();
226
+ Date.now = jest.fn( () => '2018-05-04T05:23:19.000Z' );
227
+ const format = 'YYYY-MM-DD HH:mm:ss';
228
+ const now = new Date( 'December 17, 2015 03:24:00' );
229
+ expect( momentUtil.toMomentFromDate( now ) ).toBeInstanceOf( moment );
230
+ const expected = momentUtil.toMomentFromDate( now ).format( format );
231
+ expect( expected ).toBe( '2015-12-17 00:00:00' );
232
+ } );
233
+
234
+ test( 'toFormat', () => {
235
+ expect( momentUtil.toFormat( '' ) ).toEqual( '' );
236
+ expect( momentUtil.toFormat( 'Y-m-d H:i:s' ) ).toEqual( 'YYYY-MM-DD HH:mm:ss' );
237
+ expect( momentUtil.toFormat( 'F j, Y g:i a' ) ).toEqual( 'MMMM D, YYYY h:mm a' );
238
+ expect( momentUtil.toFormat( 'tLBIOPTZcr' ) ).toEqual( '' );
239
+ expect( momentUtil.toFormat( 'd' ) ).toEqual( 'DD' );
240
+ expect( momentUtil.toFormat( 'D' ) ).toEqual( 'ddd' );
241
+ expect( momentUtil.toFormat( 'j' ) ).toEqual( 'D' );
242
+ expect( momentUtil.toFormat( 'l' ) ).toEqual( 'dddd' );
243
+ expect( momentUtil.toFormat( 'N' ) ).toEqual( 'E' );
244
+ expect( momentUtil.toFormat( 'S' ) ).toEqual( 'o' );
245
+ expect( momentUtil.toFormat( 'w' ) ).toEqual( 'e' );
246
+ expect( momentUtil.toFormat( 'z' ) ).toEqual( 'DDD' );
247
+ expect( momentUtil.toFormat( 'W' ) ).toEqual( 'W' );
248
+ expect( momentUtil.toFormat( 'F' ) ).toEqual( 'MMMM' );
249
+ expect( momentUtil.toFormat( 'm' ) ).toEqual( 'MM' );
250
+ expect( momentUtil.toFormat( 'M' ) ).toEqual( 'MMM' );
251
+ expect( momentUtil.toFormat( 'n' ) ).toEqual( 'M' );
252
+ expect( momentUtil.toFormat( 'o' ) ).toEqual( 'YYYY' );
253
+ expect( momentUtil.toFormat( 'Y' ) ).toEqual( 'YYYY' );
254
+ expect( momentUtil.toFormat( 'y' ) ).toEqual( 'YY' );
255
+ expect( momentUtil.toFormat( 'a' ) ).toEqual( 'a' );
256
+ expect( momentUtil.toFormat( 'A' ) ).toEqual( 'A' );
257
+ expect( momentUtil.toFormat( 'g' ) ).toEqual( 'h' );
258
+ expect( momentUtil.toFormat( 'G' ) ).toEqual( 'H' );
259
+ expect( momentUtil.toFormat( 'h' ) ).toEqual( 'hh' );
260
+ expect( momentUtil.toFormat( 'H' ) ).toEqual( 'HH' );
261
+ expect( momentUtil.toFormat( 'i' ) ).toEqual( 'mm' );
262
+ expect( momentUtil.toFormat( 's' ) ).toEqual( 'ss' );
263
+ expect( momentUtil.toFormat( 'u' ) ).toEqual( 'SSS' );
264
+ expect( momentUtil.toFormat( 'e' ) ).toEqual( 'zz' );
265
+ expect( momentUtil.toFormat( 'U' ) ).toEqual( 'X' );
266
+ } );
267
+
268
+ describe( 'parseFormats', () => {
269
+ test( 'Use DB format', () => {
270
+ const format = 'YYYY-MM-DD HH:mm:ss';
271
+ const expected = momentUtil.parseFormats( '2019-11-19 22:32:00' );
272
+ expect( expected.format( format ) ).toBe( '2019-11-19 22:32:00' );
273
+ } );
274
+
275
+ test( 'Use WP datetime format', () => {
276
+ const format = 'MMMM D, YYYY h:mm a';
277
+ const expected = momentUtil.parseFormats( 'November 19, 2019 10:32 pm' );
278
+ expect( expected.format( format ) ).toBe( 'November 19, 2019 10:32 pm' );
279
+ } );
280
+
281
+ test( 'Invalid date', () => {
282
+ Date.now = jest.fn( () => new Date( 'July 1, 2018 00:07:31 UTC' ).toISOString() );
283
+ const format = 'YYYY-MM-DD HH:mm:ss';
284
+ const expected = momentUtil.parseFormats( 'No date!' );
285
+ expect( expected.format( format ) ).toBe( '2018-07-01 00:07:31' );
286
+ expect( window.console.warn ).toHaveBeenCalled();
287
+ } );
288
+ } );
289
+
290
+ describe( 'resetTimes', () => {
291
+ const format = 'YYYY-MM-DD HH:mm:ss';
292
+ it( 'Should add an hour in seconds', () => {
293
+ const startMoment = moment( new Date( 'July 19, 2018 19:30:00 UTC' ).toISOString() );
294
+ const { start, end } = momentUtil.resetTimes( startMoment );
295
+ expect( start.format( format ) ).toBe( '2018-07-19 19:30:00' );
296
+ expect( end.format( format ) ).toBe( '2018-07-19 20:30:00' );
297
+ } );
298
+
299
+ it( 'Should add hour in seconds on start of the day', () => {
300
+ const startMoment = moment( new Date( 'July 19, 2018 00:00:00 UTC' ).toISOString() );
301
+ const { start, end } = momentUtil.resetTimes( startMoment );
302
+ expect( start.format( format ) ).toBe( '2018-07-19 00:00:00' );
303
+ expect( end.format( format ) ).toBe( '2018-07-19 01:00:00' );
304
+ } );
305
+
306
+ it( 'Should prevent overflow to the next day', () => {
307
+ const startMoment = moment( new Date( 'July 19, 2018 23:59:59 UTC' ).toISOString() );
308
+ const { start, end } = momentUtil.resetTimes( startMoment );
309
+ expect( start.format( format ) ).toBe( '2018-07-19 22:59:59' );
310
+ expect( end.format( format ) ).toBe( '2018-07-19 23:59:59' );
311
+ } );
312
+ } );
313
+
314
+ describe( 'adjustStart', () => {
315
+ const format = 'YYYY-MM-DD HH:mm:ss';
316
+ it( 'Should keep the same order when start is before', () => {
317
+ const start = moment( new Date( 'July 10, 2018 14:30:00 UTC' ).toISOString() );
318
+ const end = moment( new Date( 'July 10, 2018 20:35:00 UTC' ).toISOString() );
319
+ const output = momentUtil.adjustStart( start, end );
320
+ expect( output.start.format( format ) ).toBe( '2018-07-10 14:30:00' );
321
+ expect( output.end.format( format ) ).toBe( '2018-07-10 20:35:00' );
322
+ } );
323
+
324
+ it( 'Should adjust the start and end time', () => {
325
+ const start = moment( new Date( 'July 10, 2018 20:35:00 UTC' ).toISOString() );
326
+ const end = moment( new Date( 'July 10, 2018 10:30:00 UTC' ).toISOString() );
327
+ const output = momentUtil.adjustStart( start, end );
328
+ expect( output.start.format( format ) ).toBe( '2018-07-10 20:35:00' );
329
+ expect( output.end.format( format ) ).toBe( '2018-07-10 21:35:00' );
330
+ } );
331
+ } );
332
+ } );
common/src/modules/utils/__tests__/number.test.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { percentage } from '@moderntribe/common/utils/number';
5
+
6
+ describe( 'percentage', () => {
7
+ test( 'with default values', () => {
8
+ expect( percentage() ).toBe( 0 );
9
+ } );
10
+
11
+ test( 'with non numbers', () => {
12
+ expect( () => percentage( 'modern', 'tribe' ) ).toThrow();
13
+ } );
14
+
15
+ test( 'limits outside 100 percent', () => {
16
+ expect( percentage( 120, 100 ) ).toBe( 120 );
17
+ expect( percentage( 1220, 100 ) ).toBe( 1220 );
18
+ expect( percentage( 101, 100 ) ).toBe( 101 );
19
+ expect( percentage( 100, 100 ) ).toBe( 100 );
20
+ } );
21
+
22
+ test( 'common cases', () => {
23
+ expect( percentage( 10, 100 ) ).toBe( 10 );
24
+ expect( percentage( 17, 100 ) ).toBe( 17 );
25
+ expect( percentage( 20, 1000 ) ).toBe( 2 );
26
+ expect( percentage( 155, 1000 ) ).toBe( 15.5 );
27
+ expect( percentage( 999, 1000 ) ).toBe( 99.9 );
28
+ expect( percentage( 1000, 1000 ) ).toBe( 100 );
29
+ } );
30
+
31
+ test( 'negative percentages', () => {
32
+ expect( percentage( -10, 100 ) ).toBe( -10 );
33
+ expect( percentage( -80, 100 ) ).toBe( -80 );
34
+ expect( percentage( -200, 100 ) ).toBe( -200 );
35
+ } );
36
+ } );
common/src/modules/utils/__tests__/proptypes.test.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { noop } from 'lodash';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import * as proptypes from '@moderntribe/common/utils/proptypes';
10
+
11
+ describe( 'Tests for proptypes utils', () => {
12
+ describe( 'createChainableValidator', () => {
13
+ it( 'should not return an error when prop is undefined and is not required', () => {
14
+ const props = {};
15
+ const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ) );
16
+ chainedValidator( props, 'time', 'component' );
17
+
18
+ expect( chainedValidator ).toHaveReturned();
19
+ expect( chainedValidator ).toHaveReturnedWith( null );
20
+ } );
21
+
22
+ it( 'should return an error when prop is undefined and is required', () => {
23
+ const props = {};
24
+ const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ).isRequired );
25
+ chainedValidator( props, 'time', 'component' );
26
+
27
+ expect( chainedValidator ).toHaveReturned();
28
+ expect( chainedValidator ).toHaveReturnedWith( Error( 'The prop `time` is marked as required in `component`, but its value is `undefined`.' ) );
29
+ } );
30
+
31
+ it( 'should return an error when prop is null and is required', () => {
32
+ const props = {
33
+ time: null,
34
+ };
35
+ const chainedValidator = jest.fn( proptypes.createChainableValidator( noop ).isRequired );
36
+ chainedValidator( props, 'time', 'component' );
37
+
38
+ expect( chainedValidator ).toHaveReturned();
39
+ expect( chainedValidator ).toHaveReturnedWith( Error( 'The prop `time` is marked as required in `component`, but its value is `null`.' ) );
40
+ } );
41
+
42
+ it( 'should call the validator when prop is provided, not undefined or null, and is not required', () => {
43
+ const props = {
44
+ time: '15:34',
45
+ };
46
+ const validator = jest.fn( noop );
47
+ const chainedValidator = jest.fn( proptypes.createChainableValidator( validator ) );
48
+ chainedValidator( props, 'time', 'component' );
49
+
50
+ expect( validator ).toHaveBeenCalled();
51
+ expect( validator ).toHaveBeenCalledTimes( 1 );
52
+ } );
53
+
54
+ it( 'should call the validator when prop is provided, not undefined or null, and is required', () => {
55
+ const props = {
56
+ time: '15:34',
57
+ };
58
+ const validator = jest.fn( noop );
59
+ const chainedValidator = jest.fn( proptypes.createChainableValidator( validator ).isRequired );
60
+ chainedValidator( props, 'time', 'component' );
61
+
62
+ expect( validator ).toHaveBeenCalled();
63
+ expect( validator ).toHaveBeenCalledTimes( 1 );
64
+ } );
65
+ } );
66
+
67
+ describe( 'timeRegex', () => {
68
+ it( 'should return true when provided proper time formatted string', () => {
69
+ expect( proptypes.timeRegex.test( '00:00' ) ).toEqual( true );
70
+ expect( proptypes.timeRegex.test( '23:59' ) ).toEqual( true );
71
+ expect( proptypes.timeRegex.test( '12:42' ) ).toEqual( true );
72
+ expect( proptypes.timeRegex.test( '03:01' ) ).toEqual( true );
73
+ expect( proptypes.timeRegex.test( '19:47' ) ).toEqual( true );
74
+ expect( proptypes.timeRegex.test( '05:56' ) ).toEqual( true );
75
+ expect( proptypes.timeRegex.test( '14:11' ) ).toEqual( true );
76
+ } );
77
+
78
+ it( 'should return false when not provided proper time formatted string', () => {
79
+ expect( proptypes.timeRegex.test( 'random string' ) ).toEqual( false );
80
+ expect( proptypes.timeRegex.test( '-00:00' ) ).toEqual( false );
81
+ expect( proptypes.timeRegex.test( '24:00' ) ).toEqual( false );
82
+ expect( proptypes.timeRegex.test( '00:60' ) ).toEqual( false );
83
+ expect( proptypes.timeRegex.test( '24:60' ) ).toEqual( false );
84
+ expect( proptypes.timeRegex.test( '75:93' ) ).toEqual( false );
85
+ expect( proptypes.timeRegex.test( '90:90' ) ).toEqual( false );
86
+ } );
87
+ } );
88
+
89
+ describe( 'timeFormat', () => {
90
+ it( 'should not return an error when provided proper time formatted string', () => {
91
+ const props = {
92
+ time: '15:34',
93
+ };
94
+ const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
95
+ timeFormat();
96
+
97
+ expect( timeFormat ).toHaveReturned();
98
+ expect( timeFormat ).toHaveReturnedWith( null );
99
+ } );
100
+
101
+ it( 'should return an error when not provided a string', () => {
102
+ const props = {
103
+ time: true,
104
+ };
105
+ const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
106
+ timeFormat();
107
+
108
+ expect( timeFormat ).toHaveReturned();
109
+ expect( timeFormat ).toHaveReturnedWith( Error( 'Invalid prop `time` of type `boolean` supplied to `component`, expected `string`.' ) );
110
+ } );
111
+
112
+ it( 'should return an error when not provided proper time format', () => {
113
+ const props = {
114
+ time: 'random string',
115
+ };
116
+ const timeFormat = jest.fn( () => proptypes.timeFormat( props, 'time', 'component' ) );
117
+ timeFormat();
118
+
119
+ expect( timeFormat ).toHaveReturned();
120
+ expect( timeFormat ).toHaveReturnedWith( Error( 'Invalid prop `time` format supplied to `component`, expected `hh:mm`.' ) );
121
+ } );
122
+ } );
123
+
124
+ describe( 'nullType', () => {
125
+ test( 'valid prop types', () => {
126
+ const props = {
127
+ name: null,
128
+ }
129
+ const format = jest.fn( () => proptypes.nullType( props, 'name', 'Test Type' ) );
130
+ format();
131
+ expect( format ).toHaveReturned();
132
+ expect( format ).toHaveReturnedWith( undefined );
133
+ } );
134
+
135
+ test( 'invalid prop types', () => {
136
+ const props = {
137
+ name: 'Modern Tribe',
138
+ }
139
+ const format = jest.fn( () => proptypes.nullType( props, 'name', 'Test Type' ) );
140
+ format();
141
+ expect( format ).toHaveReturned();
142
+ expect( format ).toHaveReturnedWith( Error( 'Invalid prop: `name` supplied to `Test Type`, expect null.') );
143
+ } );
144
+ } );
145
+ } );
common/src/modules/utils/__tests__/range.test.js ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import {
5
+ parseChars,
6
+ extractParts,
7
+ parser,
8
+ isFree,
9
+ } from '@moderntribe/common/utils/range';
10
+
11
+ describe( 'Tests for range.js', () => {
12
+ test( 'parseChars', () => {
13
+ expect( parseChars( '' ) ).toEqual( '' );
14
+ expect( parseChars( '12312312321321 123123123123' ) ).toEqual( '12312312321321 123123123123' );
15
+ expect( parseChars( '1"$!%$&/)=(=?^^Ǩ¨_:;' ) ).toEqual( '1' );
16
+ expect( parseChars( ',.-¨¨*^^?=)(/&%$·"!ª12' ) ).toEqual( ',.-12' );
17
+ expect( parseChars( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( '1-2-3-4-5-6,.-' );
18
+ } );
19
+
20
+ test( 'extractParts', () => {
21
+ expect( extractParts( '' ) ).toEqual( [] );
22
+ expect( extractParts( '12' ) ).toEqual( [ '12' ] );
23
+ expect( extractParts( '12 - 23' ) ).toEqual( [ '12', '23' ] );
24
+ expect( extractParts( '12.23 - ' ) ).toEqual( [ '12.23' ] );
25
+ expect( extractParts( '12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
26
+ expect( extractParts( '12.23 - - - - - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
27
+ expect( extractParts( '- - - - - 12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
28
+ expect( extractParts( '......,,,,12.23 - 5,10' ) ).toEqual( [ '12.23', '5.10' ] );
29
+ expect( extractParts( '.12.23 - 5,10.....,,,,' ) ).toEqual( [ '12.23', '5.10' ] );
30
+ expect( extractParts( '12.2.....3 ,-. 5,10' ) ).toEqual( [ '12.20', '5.10' ] );
31
+ expect( extractParts( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( [ '1', '2' ] );
32
+ expect( extractParts( '12.23 ,-. ----5,,,,,,10' ) ).toEqual( [ '12.23', '5' ] );
33
+ } );
34
+
35
+ test( 'parser', () => {
36
+ expect( parser( '' ) ).toEqual( '' );
37
+ expect( parser( 'cupidatat occaecat' ) ).toEqual( '' );
38
+ expect( parser( 'cupidatat 12 occaecat - 1,2' ) ).toEqual( '1.20 - 12' );
39
+ expect( parser( '1,2 cupidatat 12 occaecat' ) ).toEqual( '1.20' );
40
+ expect( parser( '1-2-1-1-1-1' ) ).toEqual( '1 - 2' );
41
+ expect( parser( '......,,,,12.23 - 5,10' ) ).toEqual( '5.10 - 12.23' );
42
+ expect( parser( '2.2.....3 ,-. 2,10' ) ).toEqual( '2.10 - 2.20' );
43
+ expect( parser( '12.23 ,-. ----5,,,,,,10' ) ).toEqual( '5 - 12.23' );
44
+ expect( parser( '1-2-3-!"·$%&4-5-6$,.-' ) ).toEqual( '1 - 2' );
45
+ expect( parser( ',.-¨¨*^^?=)(/&%$·"!ª12' ) ).toEqual( '12' );
46
+ expect( parser( '10 - 10' ) ).toEqual( '10' );
47
+ expect( parser( '0' ) ).toEqual( '' );
48
+ expect( parser( '0.0' ) ).toEqual( '' );
49
+ expect( parser( '0 -' ) ).toEqual( '' );
50
+ expect( parser( '0 - 0' ) ).toEqual( '' );
51
+ expect( parser( '0.0 - 0' ) ).toEqual( '' );
52
+ expect( parser( '0.0 - 0.5' ) ).toEqual( '0.00 - 0.50' );
53
+ } );
54
+
55
+ test( 'isFree', () => {
56
+ expect( isFree( '' ) ).toEqual( false );
57
+ expect( isFree( '0.12' ) ).toEqual( false );
58
+ expect( isFree( '0 - 0.12' ) ).toEqual( false );
59
+ expect( isFree( '0.12 - 0' ) ).toEqual( false );
60
+ expect( isFree( '0' ) ).toEqual( true );
61
+ expect( isFree( '0.0' ) ).toEqual( true );
62
+ expect( isFree( '0 - 0' ) ).toEqual( true );
63
+ expect( isFree( '0.0 - 0.0' ) ).toEqual( true );
64
+ } );
65
+ } );
common/src/modules/utils/__tests__/slide.test.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { checkRequestIds } from '@moderntribe/common/utils/slide';
5
+
6
+ describe( 'Tests for slide.js', () => {
7
+ it( 'should return null for up and down', () => {
8
+ const ids = checkRequestIds( 'test-id' );
9
+ expect( ids.up ).toEqual( null );
10
+ expect( ids.down ).toEqual( null );
11
+ } );
12
+ } );
common/src/modules/utils/__tests__/string.test.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import {
5
+ isTruthy,
6
+ isFalsy,
7
+ replaceWithObject,
8
+ getWords,
9
+ wordsAsList,
10
+ normalize,
11
+ toBlockName,
12
+ } from '@moderntribe/common/utils/string';
13
+
14
+ describe( 'Tests for string.js', () => {
15
+ test( 'isTruthy', () => {
16
+ expect( isTruthy( 'Sample string' ) ).toEqual( false );
17
+ expect( isTruthy( '0' ) ).toEqual( false );
18
+ expect( isTruthy( 'false' ) ).toEqual( false );
19
+ expect( isTruthy( '1' ) ).toEqual( true );
20
+ expect( isTruthy( 'yes' ) ).toEqual( true );
21
+ expect( isTruthy( 'true' ) ).toEqual( true );
22
+ } );
23
+
24
+ test( 'isFalsy', () => {
25
+ expect( isFalsy( 'Sample string' ) ).toEqual( false );
26
+ expect( isFalsy( '1' ) ).toEqual( false );
27
+ expect( isFalsy( 'true' ) ).toEqual( false );
28
+ expect( isFalsy( '' ) ).toEqual( true );
29
+ expect( isFalsy( '0' ) ).toEqual( true );
30
+ expect( isFalsy( 'no' ) ).toEqual( true );
31
+ expect( isFalsy( 'false' ) ).toEqual( true );
32
+ } );
33
+
34
+ test( 'replaceWithObject', () => {
35
+ expect( replaceWithObject() ).toEqual( '' );
36
+ expect( replaceWithObject( '', {} ) ).toEqual( '' );
37
+ expect( replaceWithObject( 'abcd' ) ).toEqual( 'abcd' );
38
+ expect( replaceWithObject( 'abcd', { z: 'a' } ) ).toEqual( 'abcd' );
39
+ expect( replaceWithObject( 'abcd', { a: 'b', c: 'd' } ) ).toEqual( 'bbdd' );
40
+ expect( replaceWithObject( 'abcd', { a: '', c: '' } ) ).toEqual( 'bd' );
41
+ } );
42
+
43
+ describe( 'getWords', () => {
44
+ test( 'when strings are formed correctly', () => {
45
+ expect( getWords( 'Modern Tribe' ) ).toEqual( [ 'Modern', 'Tribe' ] );
46
+ expect( getWords( 'The Next Generation of Digital Agency' ) )
47
+ .toEqual( [ 'The', 'Next', 'Generation', 'of', 'Digital', 'Agency' ] );
48
+ expect( getWords( 'A list with numbers: 1, 2, 3' ) )
49
+ .toEqual( [ 'A', 'list', 'with', 'numbers:', '1,', '2,', '3' ] );
50
+ } );
51
+
52
+ test( 'Words with multiple spaces on it', () => {
53
+ expect( getWords( ' Modern Tribe ' ) ).toEqual( [ 'Modern', 'Tribe' ] );
54
+ } );
55
+ } );
56
+
57
+ describe( 'applySeparatorsAsCheckboxList', () => {
58
+ test( 'Single word no separator is applied', () => {
59
+ expect( wordsAsList( [ 'Modern' ] ) ).toEqual( 'Modern' );
60
+ } );
61
+
62
+ test( 'Two words last separator is applied', () => {
63
+ expect( wordsAsList( getWords( 'Modern Tribe' ) ) ).toEqual( 'Modern & Tribe' );
64
+ expect( wordsAsList( getWords( 'Events Calendar' ), ',', ' - ' ) )
65
+ .toEqual( 'Events - Calendar' );
66
+ } );
67
+
68
+ test( 'A large number of words', () => {
69
+ expect(
70
+ wordsAsList( [ 'Dog', 'Cat', 'Hamster', 'Parrot', 'Spider', 'Goldfish' ] ),
71
+ ).toEqual( 'Dog, Cat, Hamster, Parrot, Spider & Goldfish' );
72
+ } );
73
+
74
+ test( 'Custom separators', () => {
75
+ expect(
76
+ wordsAsList( [ 'Dog', 'Cat', 'Hamster', 'Parrot', 'Spider', 'Goldfish' ], ' - ', ' => ' ),
77
+ ).toEqual( 'Dog - Cat - Hamster - Parrot - Spider => Goldfish' );
78
+ } );
79
+ } );
80
+
81
+ describe( 'normalize', () => {
82
+ test( 'single words', () => {
83
+ expect( normalize( 'modern' ) ).toEqual( 'modern' );
84
+ expect( normalize( 'TRIBE' ) ).toEqual( 'tribe' );
85
+ } );
86
+
87
+ test( 'multiple words', () => {
88
+ expect( normalize( 'Modern Tribe' ) ).toEqual( 'modern-tribe' );
89
+ expect( normalize( 'https://theeventscalendar.com/' ) )
90
+ .toEqual( 'httpstheeventscalendarcom' );
91
+ } );
92
+
93
+ test( 'Multiple spaces', () => {
94
+ expect( normalize( ' modern TriBe' ) ).toEqual( 'modern-tribe' );
95
+ } );
96
+
97
+ test( 'non words', () => {
98
+ expect( normalize( ' 12312321-,-.(()=^^ ¨¨:;:_¨¨Ç *¿?=)(/&%$·"!.+' ) ).toEqual( '' );
99
+ } );
100
+
101
+ test( 'non strings types', () => {
102
+ expect( normalize( undefined ) ).toBe( '' );
103
+ expect( normalize( [] ) ).toBe( '' );
104
+ expect( normalize( [] ) ).toBe( '' );
105
+ expect( normalize( null ) ).toBe( '' );
106
+ expect( normalize( 1 ) ).toBe( '' );
107
+ } );
108
+ } );
109
+
110
+ describe( 'toBlockName', () => {
111
+ test( 'words', () => {
112
+ expect( toBlockName( 'modern tribe' ) )
113
+ .toBe( 'moderntribe' );
114
+ expect( toBlockName( 'https://theeventscalendar.com/' ) )
115
+ .toBe( 'httpstheeventscalendarcom' );
116
+ } );
117
+
118
+ test( 'non valid characters of a block', () => {
119
+ expect( toBlockName( '_ecp_custom_2' ) ).toBe( 'ecpcustom2' );
120
+ expect( toBlockName( 'ecp-custom-2' ) ).toBe( 'ecp-custom-2' );
121
+ expect( toBlockName( '„…–~~}][‚|#¢∞ecp-custom-2;:_¨¨Ç¨^^=)(/&%$·"!' ) )
122
+ .toBe( 'ecp-custom-2' );
123
+ expect( toBlockName( '„…– ~~}] [‚|#¢∞ecp-custom-2;:_¨ ¨Ç¨^^=)(/ &%$·"!' ) )
124
+ .toBe( 'ecp-custom-2' );
125
+ } );
126
+
127
+ test( 'non strings types', () => {
128
+ expect( toBlockName( undefined ) ).toBe( '' );
129
+ expect( toBlockName( [] ) ).toBe( '' );
130
+ expect( toBlockName( [] ) ).toBe( '' );
131
+ expect( toBlockName( null ) ).toBe( '' );
132
+ expect( toBlockName( 1 ) ).toBe( '' );
133
+ } );
134
+ } );
135
+ } );
common/src/modules/utils/__tests__/time.test.js ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { time } from '@moderntribe/common/utils';
5
+ import { roundTime } from '../moment';
6
+
7
+ describe( 'Tests for time.js', () => {
8
+ test( 'MINUTE_IN_SECONDS', () => {
9
+ expect( time.MINUTE_IN_SECONDS ).toEqual( 60 );
10
+ } );
11
+
12
+ test( 'HALF_HOUR_IN_SECONDS', () => {
13
+ expect( time.HALF_HOUR_IN_SECONDS ).toEqual( 1800 );
14
+ } );
15
+
16
+ test( 'HOUR_IN_SECONDS', () => {
17
+ expect( time.HOUR_IN_SECONDS ).toEqual( 3600 );
18
+ } );
19
+
20
+ test( 'DAY_IN_SECONDS', () => {
21
+ expect( time.DAY_IN_SECONDS ).toEqual( 86400 );
22
+ } );
23
+
24
+ test( 'roundTime', () => {
25
+ expect( time.roundTime( '01:23:54.423', time.TIME_FORMAT_HH_MM_SS_SSS ) )
26
+ .toEqual( '01:00:00.000' );
27
+ expect( time.roundTime( '14:46:13.042', time.TIME_FORMAT_HH_MM_SS_SSS ) )
28
+ .toEqual( '14:30:00.000' );
29
+ expect( time.roundTime( '01:23:54', time.TIME_FORMAT_HH_MM_SS ) )
30
+ .toEqual( '01:00:00' );
31
+ expect( time.roundTime( '14:46:13', time.TIME_FORMAT_HH_MM_SS ) )
32
+ .toEqual( '14:30:00' );
33
+ expect( time.roundTime( '01:23', time.TIME_FORMAT_HH_MM ) )
34
+ .toEqual( '01:00' );
35
+ expect( time.roundTime( '14:46', time.TIME_FORMAT_HH_MM ) )
36
+ .toEqual( '14:30' );
37
+ expect( time.roundTime( '23:54.423', time.TIME_FORMAT_MM_SS_SSS ) )
38
+ .toEqual( '00:00.000' );
39
+ expect( time.roundTime( '46:13.042', time.TIME_FORMAT_MM_SS_SSS ) )
40
+ .toEqual( '30:00.000' );
41
+ expect( time.roundTime( '23:54', time.TIME_FORMAT_MM_SS ) )
42
+ .toEqual( '00:00' );
43
+ expect( time.roundTime( '46:13', time.TIME_FORMAT_MM_SS ) )
44
+ .toEqual( '30:00' );
45
+ } );
46
+
47
+ test( 'START_OF_DAY', () => {
48
+ expect( time.START_OF_DAY ).toEqual( '00:00' );
49
+ } );
50
+
51
+ test( 'END_OF_DAY', () => {
52
+ expect( time.END_OF_DAY ).toEqual( '23:59' );
53
+ } );
54
+
55
+ test( 'TIME_FORMAT_HH_MM_SS_SSS', () => {
56
+ expect( time.TIME_FORMAT_HH_MM_SS_SSS ).toEqual( 'hh:mm:ss.sss' );
57
+ } );
58
+
59
+ test( 'TIME_FORMAT_HH_MM_SS', () => {
60
+ expect( time.TIME_FORMAT_HH_MM_SS ).toEqual( 'hh:mm:ss' );
61
+ } );
62
+
63
+ test( 'TIME_FORMAT_HH_MM', () => {
64
+ expect( time.TIME_FORMAT_HH_MM ).toEqual( 'hh:mm' );
65
+ } );
66
+
67
+ test( 'TIME_FORMAT_MM_SS_SSS', () => {
68
+ expect( time.TIME_FORMAT_MM_SS_SSS ).toEqual( 'mm:ss.sss' );
69
+ } );
70
+
71
+ test( 'TIME_FORMAT_MM_SS', () => {
72
+ expect( time.TIME_FORMAT_MM_SS ).toEqual( 'mm:ss' );
73
+ } );
74
+
75
+ test( 'HOUR_IN_MS', () => {
76
+ expect( time.HOUR_IN_MS ).toEqual( 3600000 );
77
+ } );
78
+
79
+ test( 'MINUTE_IN_MS', () => {
80
+ expect( time.MINUTE_IN_MS ).toEqual( 60000 );
81
+ } );
82
+
83
+ test( 'SECOND_IN_MS', () => {
84
+ expect( time.SECOND_IN_MS ).toEqual( 1000 );
85
+ } );
86
+
87
+ /**
88
+ * Below are tests copied from the hh-mm-ss library and adjusted to use
89
+ * Jest instead of Tape for testing.
90
+ * Link: https://github.com/Goldob/hh-mm-ss/blob/master/test/index.js
91
+ */
92
+ test( 'fromMilliseconds() test', () => {
93
+ // Basic functionality
94
+ expect( time.fromMilliseconds( 75000 ) ).toEqual( '01:15' );
95
+ expect( time.fromMilliseconds( 442800000 ) ).toEqual( '123:00:00' );
96
+ expect( time.fromMilliseconds( 90576 ) ).toEqual( '01:30.576' );
97
+ expect( time.fromMilliseconds( -157250 ) ).toEqual( '-02:37.250' );
98
+
99
+ // Output formatting
100
+ expect( time.fromMilliseconds( 38000, 'mm:ss.sss' ) ).toEqual( '00:38.000' );
101
+ expect( time.fromMilliseconds( 0, 'hh:mm:ss' ) ).toEqual( '00:00:00' );
102
+ expect( time.fromMilliseconds( 3600000, 'mm:ss' ) ).toEqual( '01:00:00' );
103
+ expect( time.fromMilliseconds( 4500000, 'hh:mm' ) ).toEqual( '01:15' );
104
+ expect( time.fromMilliseconds( -9900000, 'hh:mm' ) ).toEqual( '-02:45' );
105
+
106
+ // Input validation
107
+ expect( () => time.fromMilliseconds( null ) ).toThrowErrorMatchingSnapshot();
108
+ expect( () => time.fromMilliseconds('text') ).toThrowErrorMatchingSnapshot();
109
+ expect( () => time.fromMilliseconds(0, 'mm:hh:ss') ).toThrowErrorMatchingSnapshot();
110
+ } );
111
+
112
+ test( 'fromSeconds() test', () => {
113
+ // Basic functionality
114
+ expect( time.fromSeconds( 75 ) ).toEqual( '01:15' );
115
+ expect( time.fromSeconds( 442800 ) ).toEqual( '123:00:00' );
116
+ expect( time.fromSeconds( -442800 ) ).toEqual( '-123:00:00' );
117
+
118
+ // Output formatting
119
+ expect( time.fromSeconds( 38, 'mm:ss.sss' ) ).toEqual( '00:38.000' );
120
+ expect( time.fromSeconds( 0, 'hh:mm:ss' ) ).toEqual( '00:00:00' );
121
+ expect( time.fromSeconds( 3600, 'mm:ss' ) ).toEqual( '01:00:00' );
122
+ expect( time.fromSeconds( 4500, 'hh:mm' ) ).toEqual( '01:15' );
123
+ expect( time.fromSeconds( -9900, 'hh:mm' ) ).toEqual( '-02:45' );
124
+
125
+ // Input validation
126
+ expect( () => time.fromSeconds( null ) ).toThrowErrorMatchingSnapshot();
127
+ expect( () => time.fromSeconds( 'text' ) ).toThrowErrorMatchingSnapshot();
128
+ expect( () => time.fromSeconds( 0, 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
129
+ } );
130
+
131
+ test( 'toMilliseconds() test', () => {
132
+ // Basic functionality
133
+ expect( time.toMilliseconds( '01:05:17' ) ).toEqual( 3917000 );
134
+ expect( time.toMilliseconds( '137:00:00.0' ) ).toEqual( 493200000 );
135
+ expect( time.toMilliseconds( '00:10.230' ) ).toEqual( 10230 );
136
+ expect( time.toMilliseconds( '00:00:07.10845' ) ).toEqual( 7108 );
137
+ expect( time.toMilliseconds( '-02:07:12' ) ).toEqual( -7632000 );
138
+ expect( time.toMilliseconds( '02:00' ) ).toEqual( 120000 );
139
+ expect( time.toMilliseconds( '02:00', 'hh:mm' ) ).toEqual( 7200000 );
140
+ expect( time.toMilliseconds( '-04:35', 'hh:mm' ) ).toEqual( -16500000 );
141
+ expect( time.toMilliseconds( '00:00:07.10845', 'hh:mm' ) ).toEqual( 7108 );
142
+
143
+ // Input validation
144
+ expect( () => time.toMilliseconds( '13:05:02:11' ) ).toThrowErrorMatchingSnapshot();
145
+ expect( () => time.toMilliseconds( '153' ) ).toThrowErrorMatchingSnapshot();
146
+ expect( () => time.toMilliseconds( null ) ).toThrowErrorMatchingSnapshot();
147
+ expect( () => time.toMilliseconds( '00:62' ) ).toThrowErrorMatchingSnapshot();
148
+ expect( () => time.toMilliseconds( '01:30', 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
149
+ } );
150
+
151
+ test( 'toSeconds() test', () => {
152
+ // Basic functionality
153
+ expect( time.toSeconds( '01:05:17' ) ).toEqual( 3917 );
154
+ expect( time.toSeconds( '137:00:00.0' ) ).toEqual( 493200 );
155
+ expect( time.toSeconds( '00:10.230' ) ).toEqual( 10 );
156
+ expect( time.toSeconds( '00:00:07.10845' ) ).toEqual( 7 );
157
+ expect( time.toSeconds( '-02:07:12' ) ).toEqual( -7632 );
158
+ expect( time.toSeconds( '02:00' ) ).toEqual( 120 );
159
+ expect( time.toSeconds( '02:00', 'hh:mm' ) ).toEqual( 7200 );
160
+ expect( time.toSeconds( '-04:35', 'hh:mm' ) ).toEqual( -16500 );
161
+ expect( time.toSeconds( '00:00:07.10845', 'hh:mm' ) ).toEqual( 7 );
162
+
163
+ // Input validation
164
+ expect( () => time.toSeconds( '13:05:02:11' ) ).toThrowErrorMatchingSnapshot();
165
+ expect( () => time.toSeconds( '153' ) ).toThrowErrorMatchingSnapshot();
166
+ expect( () => time.toSeconds( null ) ).toThrowErrorMatchingSnapshot();
167
+ expect( () => time.toSeconds( '00:62' ) ).toThrowErrorMatchingSnapshot();
168
+ expect( () => time.toSeconds( '01:30', 'mm:hh:ss' ) ).toThrowErrorMatchingSnapshot();
169
+ } );
170
+
171
+ test( 'symmetrical conversion test', () => {
172
+ /*
173
+ * fromMilliseconds() and toMilliseconds() for all formats
174
+ */
175
+
176
+ // 90000ms = 1m 30s
177
+ expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'mm:ss' ), 'mm:ss' ) ).toEqual( 90000 );
178
+ expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( 90000 );
179
+ expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm' ), 'hh:mm' ) ).toEqual( 90000 );
180
+ expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( 90000 );
181
+ expect( time.toMilliseconds( time.fromMilliseconds( 90000, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( 90000 );
182
+
183
+ // 7517245ms = 2h 5m 17.245s
184
+ expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'mm:ss' ), 'mm:ss' ) ).toEqual( 7517245 );
185
+ expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( 7517245 );
186
+ expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm' ), 'hh:mm' ) ).toEqual( 7517245 );
187
+ expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( 7517245 );
188
+ expect( time.toMilliseconds( time.fromMilliseconds( 7517245, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( 7517245 );
189
+
190
+ // -10800000ms = -3h
191
+ expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'mm:ss' ), 'mm:ss' ) ).toEqual( -10800000 );
192
+ expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'mm:ss.sss' ), 'mm:ss.sss' ) ).toEqual( -10800000 );
193
+ expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm' ), 'hh:mm' ) ).toEqual( -10800000 );
194
+ expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm:ss' ), 'hh:mm:ss' ) ).toEqual( -10800000 );
195
+ expect( time.toMilliseconds( time.fromMilliseconds( -10800000, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss' ) ).toEqual( -10800000 );
196
+
197
+ /*
198
+ * fromSeconds() and toMilliseconds() for all formats
199
+ */
200
+
201
+ // 930s = 15m 30s
202
+ expect( time.toSeconds( time.fromSeconds( 930, 'mm:ss' ), 'mm:ss') ).toEqual( 930 );
203
+ expect( time.toSeconds( time.fromSeconds( 930, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( 930 );
204
+ expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm' ), 'hh:mm') ).toEqual( 930 );
205
+ expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( 930 );
206
+ expect( time.toSeconds( time.fromSeconds( 930, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( 930 );
207
+
208
+ // 4850s = 1h 20m 50s
209
+ expect( time.toSeconds( time.fromSeconds( 4850, 'mm:ss' ), 'mm:ss') ).toEqual( 4850 );
210
+ expect( time.toSeconds( time.fromSeconds( 4850, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( 4850 );
211
+ expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm' ), 'hh:mm') ).toEqual( 4850 );
212
+ expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( 4850 );
213
+ expect( time.toSeconds( time.fromSeconds( 4850, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( 4850 );
214
+
215
+ // -300s = -5m
216
+ expect( time.toSeconds( time.fromSeconds( -300, 'mm:ss' ), 'mm:ss') ).toEqual( -300 );
217
+ expect( time.toSeconds( time.fromSeconds( -300, 'mm:ss.sss' ), 'mm:ss.sss') ).toEqual( -300 );
218
+ expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm' ), 'hh:mm') ).toEqual( -300 );
219
+ expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm:ss' ), 'hh:mm:ss') ).toEqual( -300 );
220
+ expect( time.toSeconds( time.fromSeconds( -300, 'hh:mm:ss.sss' ), 'hh:mm:ss.sss') ).toEqual( -300 );
221
+ } );
222
+ } );
common/src/modules/utils/api.js ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { rest } from '@moderntribe/common/utils/globals';
2
+ import 'whatwg-fetch';
3
+
4
+ /**
5
+ * Send a request into a wp-json endpoint
6
+ *
7
+ * @param {Object} params An object with the following properties:
8
+ * - path: Path for the endpoint
9
+ * - headers: Array of extra headers for the request
10
+ * - initParams: Params send into the fetch along with headers and credentials
11
+ * - namespace: Endpoint namespace default to `wp/v2`
12
+ *
13
+ * @returns {Promise<Response>} return a fetch promise
14
+ */
15
+ export const wpREST = async ( params ) => {
16
+ const { url = '', nonce = {}, namespaces = {} } = rest();
17
+
18
+ /**
19
+ * @todo refactor this method as for more details look into:
20
+ * - https://github.com/moderntribe/events-gutenberg/pull/346#discussion_r222217138
21
+ */
22
+ const options = {
23
+ path: '',
24
+ headers: {},
25
+ initParams: {},
26
+ namespace: namespaces.core || 'wp/v2',
27
+ ...params,
28
+ };
29
+
30
+ const endpoint = `${ url }${ options.namespace }/${ options.path }`;
31
+
32
+ const headers = {
33
+ 'X-WP-Nonce': nonce.wp_rest || '',
34
+ ...options.headers,
35
+ };
36
+
37
+ try {
38
+ const response = await fetch( endpoint, {
39
+ ...options.initParams,
40
+ credentials: 'include',
41
+ headers,
42
+ } );
43
+
44
+ let data = {};
45
+
46
+ if ( response.ok ) {
47
+ data = await response.json();
48
+ }
49
+
50
+ return {
51
+ response,
52
+ data,
53
+ };
54
+ } catch ( e ) {
55
+ throw e;
56
+ }
57
+ };
common/src/modules/utils/date.js ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { identity } from 'lodash';
5
+ import chrono from 'chrono-node';
6
+
7
+ /**
8
+ * Wordpress dependencies
9
+ */
10
+ import { __ } from '@wordpress/i18n';
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+ import {
16
+ moment as momentUtil,
17
+ timezone as timezoneUtil,
18
+ } from '@moderntribe/common/utils';
19
+ import { dateSettings } from '@moderntribe/common/utils/globals';
20
+
21
+ const formats = dateSettings() && dateSettings().formats ? dateSettings().formats : {};
22
+ const timezone = dateSettings() && dateSettings().formats ? dateSettings().formats : {};
23
+
24
+ export const FORMATS = {
25
+ TIME: 'HH:mm:ss',
26
+ DATE_TIME: 'YYYY-MM-DD HH:mm:ss',
27
+ WP: {
28
+ time: 'g:i a',
29
+ time24Hr: 'H:i',
30
+ date: 'F j, Y',
31
+ datetime: 'F j, Y g:i a',
32
+ dateNoYear: 'F j',
33
+ ...formats,
34
+ },
35
+ TIMEZONE: {
36
+ string: 'UTC',
37
+ ...timezone,
38
+ },
39
+ DATABASE: {
40
+ date: 'Y-m-d',
41
+ datetime: 'Y-m-d H:i:s',
42
+ time: 'H:i:s',
43
+ },
44
+ };
45
+
46
+ export const TODAY = new Date();
47
+
48
+ export const timezonesAsSelectData = () => {
49
+ return timezones().map( ( tzone ) => ( {
50
+ value: tzone.key,
51
+ label: tzone.text,
52
+ } ) );
53
+ };
54
+
55
+ export const timezones = () => {
56
+ return timezoneUtil.getItems()
57
+ .map( ( group ) => group.options || [] )
58
+ .reduce( ( prev, current ) => [ ...prev, ...current ], [] );
59
+ };
60
+
61
+ export const toNaturalLanguage = ( params = {} ) => {
62
+ const options = {
63
+ date: null,
64
+ format: {
65
+ month: 'MMMM',
66
+ day: 'D',
67
+ year: 'YYYY',
68
+ time: momentUtil.toFormat( FORMATS.WP.time ),
69
+ },
70
+ separator: '',
71
+ ...params,
72
+ };
73
+
74
+ const parsed = {
75
+ text: '',
76
+ moment: options.date && momentUtil.toMoment( options.date ),
77
+ detail: {
78
+ day: '',
79
+ month: '',
80
+ year: '',
81
+ time: '',
82
+ },
83
+ isValid: false,
84
+ };
85
+
86
+ parsed.isValid = Boolean( parsed.moment && parsed.moment.isValid() );
87
+
88
+ if ( parsed.isValid ) {
89
+ parsed.detail = {
90
+ month: `${ parsed.moment.format( options.format.month ) }`,
91
+ day: `${ parsed.moment.format( options.format.day ) }`,
92
+ year: `${ parsed.moment.format( options.format.year ) }`,
93
+ time: `${ parsed.moment.format( options.format.time ) }`,
94
+ };
95
+ const { detail } = parsed;
96
+ parsed.text = `${ detail.month } ${ detail.day } ${ detail.year } ${ options.separator } ${ detail.time }`;
97
+ }
98
+ return parsed;
99
+ };
100
+
101
+ export const rangeToNaturalLanguage = ( start = '', end = '', separators = {} ) => {
102
+ const separatorOptions = {
103
+ time: __( 'at', 'tribe-common' ),
104
+ date: ' - ',
105
+ ...separators,
106
+ };
107
+ const from = toNaturalLanguage( { date: start, separator: separatorOptions.time } );
108
+ const to = toNaturalLanguage( { date: end, separator: separatorOptions.time } );
109
+ const parts = [ from.text ];
110
+
111
+ if ( from.isValid && to.isValid ) {
112
+ if ( momentUtil.isSameDay( from.moment, to.moment ) ) {
113
+ /**
114
+ * If both dates are happening on the same day the only relevant thing is the time on the second
115
+ * part of the string (to keep string cleaner).
116
+ *
117
+ * - Current behavior 'Oct 8 2018 at 12:00 pm - Oct 8 2018 at 12:30 pm'
118
+ * - New behavior: 'Oct 8 2018 at 12:00 pm - 12:30 pm'
119
+ */
120
+ parts.push( to.detail.time );
121
+ } else if ( momentUtil.isSameMonth( from.moment, to.moment ) ) {
122
+ /**
123
+ * If both dates are happening on the same month and not on the same day but during the same year
124
+ * we don't need to show the same year twice.
125
+ *
126
+ * - Current Behavior: 'Oct 8 2018 at 12:00 pm - Oct 24 2018 12:30 pm'
127
+ * - New Behavior: 'Oct 8 2018 at 12:00 pm - Oct 24 12:30 pm'
128
+ */
129
+ parts.push( `${ to.detail.month } ${ to.detail.day } ${ separatorOptions.time } ${ to.detail.time }` );
130
+ } else {
131
+ // Otherwise just use the full text
132
+ parts.push( to.text );
133
+ }
134
+ }
135
+
136
+ return parts.filter( identity ).join( separatorOptions.date );
137
+ };
138
+
139
+ export const labelToDate = ( label ) => {
140
+ const [ parsed ] = chrono.parse( label );
141
+ const dates = {
142
+ start: null,
143
+ end: null,
144
+ };
145
+ if ( parsed ) {
146
+ const { start, end } = parsed;
147
+ dates.start = start ? momentUtil.toDateTime( momentUtil.toMoment( start.date() ) ) : null;
148
+ dates.end = end ? momentUtil.toDateTime( momentUtil.toMoment( end.date() ) ) : null;
149
+ }
150
+ return dates;
151
+ };
common/src/modules/utils/dom.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { noop } from 'lodash';
5
+
6
+ /**
7
+ * Test if a node element has a class present on it
8
+ *
9
+ * @param {HTMLElement|Element} node The node where to look for the class names
10
+ * @param {array} classNames List of class names as an array of strings
11
+ * @returns {boolean} `true` if has any of the classes or false if does not have any
12
+ */
13
+ export const hasClass = ( node, classNames = [] ) => {
14
+ for ( let i = 0; i < classNames.length; i++ ) {
15
+ if ( node.classList.contains( classNames[ i ] ) ) {
16
+ return true;
17
+ }
18
+ }
19
+ return false;
20
+ };
21
+
22
+ /**
23
+ * Utility to search the parent of a node looking from the current node Up to the highest
24
+ * node on the DOM Tree
25
+ *
26
+ * @param {(DOMElement|object)} node - The DOM node where the search starts
27
+ * @param {function} callback - Is executed on every iteration, it should return a boolean
28
+ * @returns {boolean} Returns tre if the callback returns true with any of the parents.
29
+ */
30
+ export const searchParent = ( node = {}, callback = noop ) => {
31
+ let found = false;
32
+ let testNode = node;
33
+ do {
34
+ if ( testNode ) {
35
+ found = callback( testNode );
36
+ }
37
+ const nextNode = testNode && testNode.parentNode ? testNode.parentNode : null;
38
+ testNode = isRootNode( nextNode ) ? null : nextNode;
39
+ } while ( ! found && testNode !== null );
40
+
41
+ return found;
42
+ };
43
+
44
+ /**
45
+ * Test if a node is the same as the root element or the base node of the document.
46
+ *
47
+ * @param {Element} node A Document Node
48
+ * @returns {boolean} true if node is the root Node Document
49
+ */
50
+ export const isRootNode = ( node ) => node === window.top.document;
common/src/modules/utils/get-hidden-height.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @function getHiddenHeight
3
+ * @desc gets the height of hidden objects.
4
+ */
5
+
6
+ const getHiddenHeight = ( el ) => {
7
+ const width = el.clientWidth;
8
+ const element = el;
9
+
10
+ element.style.visibility = 'hidden';
11
+ element.style.height = 'auto';
12
+ element.style.maxHeight = 'none';
13
+ element.style.position = 'fixed';
14
+ element.style.width = `${width}px`;
15
+
16
+ const tHeight = element.offsetHeight;
17
+
18
+ element.style.visibility = '';
19
+ element.style.height = '';
20
+ element.style.maxHeight = '';
21
+ element.style.width = '';
22
+ element.style.position = '';
23
+ element.style.zIndex = '';
24
+
25
+ return tHeight;
26
+ };
27
+
28
+ export default getHiddenHeight;
common/src/modules/utils/globals.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @todo: handle globals in a better way
3
+ */
4
+ export const get = ( key, defaultValue ) => window[ key ] || defaultValue;
5
+ export const google = () => get( 'google' );
6
+
7
+ // Localized Config
8
+ export const config = () => get( 'tribe_editor_config', {} );
9
+
10
+ // Common
11
+ export const common = () => config().common || {};
12
+ export const adminUrl = () => common().adminUrl || '';
13
+ export const rest = () => common().rest || {};
14
+ export const restNonce = () => rest().nonce || {};
15
+ export const dateSettings = () => common().dateSettings || {};
16
+ export const editorConstants = () => common().constants || {};
17
+ export const list = () => ( {
18
+ countries: common().countries || {},
19
+ us_states: common().usStates || {},
20
+ } );
21
+
22
+ // TEC
23
+ export const tec = () => config().events || {};
24
+ export const editor = () => tec().editor || {};
25
+ export const settings = () => tec().settings || {};
26
+ export const mapsAPI = () => tec().googleMap || {};
27
+ export const priceSettings = () => tec().priceSettings || {};
28
+ export const tecDateSettings = () => tec().dateSettings || {};
29
+ export const timezoneHtml = () => tec().timezoneHTML || '';
30
+ export const defaultTimes = () => tec().defaultTimes || {};
31
+
32
+ // PRO
33
+ export const pro = () => config().eventsPRO || {};
34
+ export const editorDefaults = () => pro().defaults || {};
35
+
36
+ // Tickets
37
+ export const tickets = () => config().tickets || {};
common/src/modules/utils/index.js ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import * as date from './date';
2
+ import * as dom from './dom';
3
+ import * as globals from './globals';
4
+ import * as input from './input';
5
+ import * as moment from './moment';
6
+ import * as range from './range';
7
+ import * as slide from './slide';
8
+ import * as string from './string';
9
+ import * as time from './time';
10
+ import * as timezone from './timezone';
11
+ import * as number from './number';
12
+ import * as api from './api';
13
+
14
+ export { date };
15
+ export { dom };
16
+ export { default as getHiddenHeight } from './get-hidden-height';
17
+ export { globals };
18
+ export { input };
19
+ export { moment };
20
+ export { range };
21
+ export { slide };
22
+ export { string };
23
+ export { time };
24
+ export { timezone };
25
+ export { number };
26
+ export { api };
27
+ export { default as TribePropTypes } from './proptypes';
common/src/modules/utils/input.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Allow to set a function (callback) as the parameter of onChange which will send the value of the
3
+ * event into the callback to avoid arrow functions around props of components.
4
+ *
5
+ * @param {Function} callback executed once the event is fired.
6
+ * @return {Function} Function executed by the event to extract the value
7
+ */
8
+ export const sendValue = ( callback ) => ( event ) => {
9
+ const { target = {} } = event;
10
+ const { value = '' } = target;
11
+ callback( value );
12
+ };
common/src/modules/utils/moment.js ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { isString } from 'lodash';
5
+ import moment, { isMoment } from 'moment';
6
+
7
+ /**
8
+ * Internal dependencies
9
+ */
10
+ import {
11
+ date as dateUtil,
12
+ time,
13
+ string,
14
+ } from '@moderntribe/common/utils';
15
+
16
+ export const TIME_FORMAT = 'h:mm a';
17
+
18
+ /**
19
+ * Make sure the format provided matches the spec used by moment.js
20
+ *
21
+ * @param {string} format The format to be converted to a moment format
22
+ * @returns {string} return a moment.js valid format
23
+ */
24
+ export const toFormat = ( format ) => {
25
+ const replacements = {
26
+ d: 'DD',
27
+ D: 'ddd',
28
+ j: 'D',
29
+ l: 'dddd',
30
+ N: 'E',
31
+ S: 'o',
32
+ w: 'e',
33
+ z: 'DDD',
34
+ W: 'W',
35
+ F: 'MMMM',
36
+ m: 'MM',
37
+ M: 'MMM',
38
+ n: 'M',
39
+ t: '', // no equivalent
40
+ L: '', // no equivalent
41
+ o: 'YYYY',
42
+ Y: 'YYYY',
43
+ y: 'YY',
44
+ a: 'a',
45
+ A: 'A',
46
+ B: '', // no equivalent
47
+ g: 'h',
48
+ G: 'H',
49
+ h: 'hh',
50
+ H: 'HH',
51
+ i: 'mm',
52
+ s: 'ss',
53
+ u: 'SSS',
54
+ e: 'zz', // deprecated since version 1.6.0 of moment.js
55
+ I: '', // no equivalent
56
+ O: '', // no equivalent
57
+ P: '', // no equivalent
58
+ T: '', // no equivalent
59
+ Z: '', // no equivalent
60
+ c: '', // no equivalent
61
+ r: '', // no equivalent
62
+ U: 'X',
63
+ };
64
+
65
+ return string.replaceWithObject( format, replacements );
66
+ };
67
+
68
+ /**
69
+ * Round the time of a moment object if the minutes on the date is lower than 30 will set to 0 if
70
+ * is greater will se 30 so is either 30 or 0.
71
+ *
72
+ * @param {moment} date Make sure the date is rounded between 0 or 30 minutes
73
+ * @returns {moment} A moment object
74
+ */
75
+ export const roundTime = ( date ) => {
76
+ if ( ! isMoment( date ) ) {
77
+ return date;
78
+ }
79
+
80
+ let minutes = date.minute();
81
+ if ( minutes >= 30 ) {
82
+ minutes = ( minutes % 30 );
83
+ }
84
+
85
+ return date
86
+ .clone()
87
+ .subtract( minutes, 'm' )
88
+ .seconds( 0 );
89
+ };
90
+
91
+ /**
92
+ * Parse multiple formats in a date to ensure the generated dates are valid
93
+ *
94
+ * @param {string} date The date to be converted
95
+ * @param {array} formats The list of formats used to format
96
+ * @returns {moment} moment Object with the date or current date if is non valid
97
+ */
98
+ export const parseFormats = ( date, formats = [ dateUtil.FORMATS.DATABASE.datetime, dateUtil.FORMATS.WP.datetime ] ) => {
99
+ for ( let i = 0; i < formats.length; i ++ ) {
100
+ const format = formats[ i ];
101
+ const result = toMoment( date, format );
102
+ if ( result.isValid() ) {
103
+ return result;
104
+ }
105
+ }
106
+
107
+ const noFormat = moment( date );
108
+ return noFormat.isValid() ? noFormat : moment();
109
+ };
110
+
111
+ /**
112
+ * Convert a Date() object into a Moment.js object avoiding warnings of different formats
113
+ * used by Date
114
+ *
115
+ * @param {(Date|moment|string)} date The date to be converted.
116
+ * @param {string} format The format of the data to be used
117
+ * @param {bool} Force the parse of the format default to true
118
+ * @returns {moment} A moment object
119
+ */
120
+ export const toMoment = ( date, format = dateUtil.FORMATS.DATABASE.datetime, parseFormat = true ) => {
121
+ if ( isMoment( date ) || date instanceof Date ) {
122
+ return moment( date );
123
+ } else if ( isString( date ) ) {
124
+ return moment( date, parseFormat ? toFormat( format ) : format );
125
+ }
126
+
127
+ return moment();
128
+ };
129
+
130
+ export const toMomentFromDate = ( date ) => {
131
+ if ( ! ( date instanceof Date ) ) {
132
+ throw new Error( 'Make sure your date is an instance of Date' );
133
+ }
134
+
135
+ const year = date.getFullYear();
136
+ const month = date.getMonth();
137
+ const day = date.getDate();
138
+
139
+ return moment()
140
+ .year( year )
141
+ .month( month )
142
+ .date( day )
143
+ .startOf( 'day' );
144
+ };
145
+
146
+ /**
147
+ * Convert a Date() object or date string and time into a moment object
148
+ *
149
+ * @param {(Date|moment|string)} date The date to be converted.
150
+ * @param {string} time The time string in HH:mm format..
151
+ * @returns {moment} A moment object
152
+ */
153
+ export const toMomentFromDateTime = ( date, time ) => {
154
+ const [ hours, minutes ] = time.split( ':' );
155
+ return moment( date ).hours( hours ).minutes( minutes );
156
+ };
157
+
158
+ /**
159
+ * Replace the date of a moment object with another date from another moment object
160
+ *
161
+ * @param {moment} original The moment object where the date is going to be replaced
162
+ * @param {moment} replaced The moment object where the date to be used to replace is located
163
+ * @returns {moment} A moment object where the date is replaced
164
+ */
165
+ export const replaceDate = ( original, replaced ) => {
166
+ if ( ! isMoment( original ) || ! isMoment( replaced ) ) {
167
+ throw new Error( 'Make sure your values are instances of moment' );
168
+ }
169
+
170
+ return original
171
+ .year( replaced.year() )
172
+ .month( replaced.month() )
173
+ .date( replaced.date() );
174
+ };
175
+
176
+ /**
177
+ * Set time in seconds to a moment object
178
+ *
179
+ * @param {moment} original The original moment where the date is going to be set
180
+ * @param {number} seconds Amount of seconds to be set to the moment object.
181
+ * @returns {moment} A moment object with the new date
182
+ */
183
+ export const setTimeInSeconds = ( original, seconds = 0 ) => {
184
+ if ( ! isMoment( original ) ) {
185
+ throw new Error( 'Make sure your values are instances of moment' );
186
+ }
187
+
188
+ if ( seconds < 0 ) {
189
+ return original;
190
+ }
191
+
192
+ return original
193
+ .startOf( 'day' )
194
+ .seconds( seconds || original.seconds() );
195
+ };
196
+
197
+ /**
198
+ * Total seconds of a current date from moment
199
+ *
200
+ * @param {moment} date The date to compare on the current day
201
+ * @returns {int} Total of seconds from start of the day to the current moment,
202
+ */
203
+ export const totalSeconds = ( date ) => {
204
+ if ( ! date || ! isMoment( date ) ) {
205
+ return 0;
206
+ }
207
+ return date.diff( moment( date ).startOf( 'day' ), 'seconds' );
208
+ };
209
+
210
+ /**
211
+ * Convert a moment object into a WP date time format
212
+ *
213
+ * @param {moment} date A moment date object
214
+ * @param {string} format Format used to output the date
215
+ * @returns {string} A date time format
216
+ */
217
+ export const toDateTime = ( date, format = dateUtil.FORMATS.DATABASE.datetime ) => (
218
+ date.format( toFormat( format ) )
219
+ );
220
+
221
+ export const toDate = ( date, format = dateUtil.FORMATS.WP.date ) => (
222
+ date.format( toFormat( format ) )
223
+ );
224
+
225
+ export const toDateNoYear = ( date, format = dateUtil.FORMATS.WP.dateNoYear ) => (
226
+ date.format( toFormat( format ) )
227
+ );
228
+
229
+ export const toTime = ( date, format = dateUtil.FORMATS.WP.time ) => (
230
+ date.format( toFormat( format ) )
231
+ );
232
+
233
+ export const toTime24Hr = ( date, format = dateUtil.FORMATS.WP.time24Hr ) => (
234
+ date.format( toFormat( format ) )
235
+ );
236
+
237
+ export const toDatabaseDate = ( date, format = dateUtil.FORMATS.DATABASE.date ) => (
238
+ date.format( toFormat( format ) )
239
+ );
240
+
241
+ export const toDatabaseTime = ( date, format = dateUtil.FORMATS.DATABASE.time ) => (
242
+ date.format( toFormat( format ) )
243
+ );
244
+
245
+ export const toDatePicker = ( date = moment(), format = 'YYYY-MM-DDTHH:mm:ss' ) => (
246
+ date.format( format )
247
+ );
248
+
249
+ /**
250
+ * Test if the start and end dates are the same day.
251
+ *
252
+ * @param {moment} start The start date
253
+ * @param {(moment|String)} end The end date
254
+ * @returns {boolean} if the start and end dates are the same day
255
+ */
256
+ export const isSameDay = ( start, end ) => {
257
+
258
+ if ( ! start || ! end ) {
259
+ return false;
260
+ }
261
+
262
+ return moment( start ).isSame( end, 'day' );
263
+ };
264
+
265
+ /**
266
+ * Test if two moment objects are in the same month
267
+ *
268
+ * @param {moment} start The start moment
269
+ * @param {moment} end The end moment
270
+ * @returns {boolean} true if start and end are on the same month
271
+ */
272
+ export const isSameMonth = ( start, end ) => {
273
+
274
+ if ( ! start || ! end ) {
275
+ return false;
276
+ }
277
+
278
+ return moment( start ).isSame( end, 'month' );
279
+ };
280
+
281
+ /**
282
+ * Test if the start and end dates have the same year.
283
+ *
284
+ * @param {moment} start The start date
285
+ * @param {(moment|String)} end The end date
286
+ * @returns {boolean} if the start and end dates have the same year
287
+ */
288
+ export const isSameYear = ( start, end ) => (
289
+ toMoment( start ).isSame( toMoment( end ), 'year' )
290
+ );
291
+
292
+ /**
293
+ * Reset the time of an event by creating an object with start and end ensuring the end event is
294
+ * after the start date and both are on the same day if the start is one hour before the end of the
295
+ * day it will remove an hour of the start to ensure both start / end happen on the same day
296
+ *
297
+ * @param {moment} start The start date
298
+ * @returns {{start: {moment}, end: {moment}}} Object with two keys: start, end
299
+ */
300
+ export const resetTimes = ( start ) => {
301
+ const testMoment = start.clone().add( time.HOUR_IN_SECONDS, 'seconds' );
302
+
303
+ // Rollback an hour before adding half an hour as we are on the edge of the day
304
+ if ( ! isSameDay( start, testMoment ) ) {
305
+ start.subtract( time.HOUR_IN_SECONDS, 'seconds' );
306
+ }
307
+
308
+ const end = start.clone().add( time.HOUR_IN_SECONDS, 'seconds' );
309
+
310
+ return {
311
+ start,
312
+ end,
313
+ };
314
+ };
315
+
316
+ /**
317
+ * Make sure the start time is always before the end time
318
+ *
319
+ * @param {moment} start The start date
320
+ * @param {moment} end The end date
321
+ * @returns {{start: {moment}, end: {moment}}} Object with two keys: start, end
322
+ */
323
+ export const adjustStart = ( start, end ) => {
324
+ if ( end.isSameOrBefore( start ) ) {
325
+ return resetTimes( start );
326
+ }
327
+
328
+ return {
329
+ start,
330
+ end,
331
+ };
332
+ };
common/src/modules/utils/number.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Calculate the percentage of two numbers
3
+ *
4
+ * @param {number} value Initial value from where to take the percentage
5
+ * @param {number} total Total value to get the percentage relative to this value
6
+ * @returns {number} total percentage value
7
+ */
8
+ export const percentage = ( value = 0, total = 0 ) => {
9
+ if ( total === 0 ) {
10
+ return 0;
11
+ }
12
+
13
+ const result = Number.parseFloat( ( value / total ) * 100 );
14
+
15
+ if ( isNaN( result ) ) {
16
+ throw new RangeError(
17
+ `Make sure ${value} and ${total} are valid numbers, operation result in NaN value`
18
+ );
19
+ }
20
+
21
+ return result;
22
+ };
common/src/modules/utils/proptypes.js ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Create chainable validator with isRequired check
3
+ * @param {function} validator
4
+ */
5
+ export const createChainableValidator = ( validator ) => {
6
+ const createChainedValidator = (
7
+ isRequired,
8
+ props,
9
+ propName,
10
+ componentName,
11
+ ) => {
12
+ const propValue = props[ propName ];
13
+
14
+ if ( propValue == null ) {
15
+ if ( isRequired ) {
16
+ if ( propValue === null ) {
17
+ /* eslint-disable-next-line max-len */
18
+ return new Error( `The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is \`null\`.` );
19
+ }
20
+ /* eslint-disable-next-line max-len */
21
+ return new Error( `The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is \`undefined\`.` );
22
+ }
23
+ return null;
24
+ } else {
25
+ return validator( props, propName, componentName );
26
+ }
27
+ };
28
+
29
+ const chainedValidator = createChainedValidator.bind( null, false );
30
+ chainedValidator.isRequired = createChainedValidator.bind( null, true );
31
+
32
+ return chainedValidator;
33
+ }
34
+
35
+ export const timeRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/;
36
+
37
+ /**
38
+ * PropTypes check for type string and time format using 24h clock in hh:mm format
39
+ * e.g. 00:24, 03:57, 21:12
40
+ *
41
+ * @param {object} props
42
+ * @param {string} propName
43
+ * @param {string} componentName
44
+ */
45
+ export const timeFormat = ( props, propName, componentName ) => {
46
+ const propValue = props[ propName ];
47
+
48
+ if ( typeof propValue !== 'string' ) {
49
+ const type = typeof propValue;
50
+ /* eslint-disable-next-line max-len */
51
+ return new Error( `Invalid prop \`${propName}\` of type \`${type}\` supplied to \`${componentName}\`, expected \`string\`.` );
52
+ }
53
+
54
+ if ( ! timeRegex.test( propValue ) ) {
55
+ /* eslint-disable-next-line max-len */
56
+ return new Error( `Invalid prop \`${propName}\` format supplied to \`${componentName}\`, expected \`hh:mm\`.` );
57
+ }
58
+
59
+ return null;
60
+ };
61
+
62
+ export const nullType = ( props, propName, componentName ) => {
63
+ if ( null !== props[ propName ] ) {
64
+ return new Error(
65
+ `Invalid prop: \`${propName}\` supplied to \`${ componentName }\`, expect null.`
66
+ );
67
+ }
68
+ }
69
+
70
+ export default {
71
+ timeFormat: createChainableValidator( timeFormat ),
72
+ nullType: createChainableValidator( nullType ),
73
+ };
common/src/modules/utils/range.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { trim, isEmpty, split } from 'lodash';
5
+
6
+ /**
7
+ * Parse a string into a range type of string {a} - {b} where a and b are numbers
8
+ *
9
+ * @param {string} input The original string
10
+ * @returns {string} A formatted range string.
11
+ */
12
+ export const parser = ( input ) => {
13
+ const range = trim( input );
14
+
15
+ if ( isEmpty( range ) ) {
16
+ return range;
17
+ }
18
+
19
+ const chars = parseChars( input );
20
+
21
+ if ( isEmpty( chars ) ) {
22
+ return chars;
23
+ }
24
+
25
+ const [ a, b ] = extractParts( chars );
26
+ const [ num_a, num_b ] = [ parseFloat( a ), parseFloat( b ) ];
27
+
28
+ if ( ! num_b || num_b === num_a ) {
29
+ return num_a === 0 ? '' : trim( a );
30
+ }
31
+
32
+ return num_a >= num_b ? `${ trim( b ) } - ${ trim( a ) }` : `${ trim( a ) } - ${ trim( b ) }`;
33
+ };
34
+
35
+ /**
36
+ * Remove any char that is not a: number, dash, dot or comma.
37
+ *
38
+ * @param {string} input The string from where to extract the chars
39
+ * @returns {string} A string with only valid chars
40
+ */
41
+ export const parseChars = ( input = '' ) => (
42
+ split( input, ' ' )
43
+ .map( ( part ) => {
44
+ // Remove anything that is not a number a period or a dash
45
+ return part.replace( /[^0-9.,-]/g, '' );
46
+ } )
47
+ .join( ' ' )
48
+ .trim()
49
+ );
50
+
51
+ /**
52
+ * Extract only valid numbers from the string
53
+ *
54
+ * @param {string} chars The chars to be split into parts.
55
+ * @returns {array} An array with the parts
56
+ */
57
+ export const extractParts = ( chars ) => (
58
+ split( chars.replace( /,/g, '.' ), '-' )
59
+ // Convert , into . so we can parse into numbers
60
+ .map( ( item ) => {
61
+ const re = /([0-9]+(.[0-9]+)?)/g;
62
+ const result = re.exec( item.trim() );
63
+ return null === result ? '' : result[ 1 ];
64
+ } )
65
+ .filter( ( item ) => ! isEmpty( item ) )
66
+ .map( ( item ) => {
67
+ // If the user input the price with decimals (even .00) we want to keep them
68
+ const decimals = 0 < item.indexOf( '.' ) ? 2 : 0;
69
+ return parseFloat( item ).toFixed( decimals );
70
+ } )
71
+ .filter( ( item ) => ! isNaN( item ) )
72
+ .slice( 0, 2 )
73
+ );
74
+
75
+ /**
76
+ * Test to see if an input range is free of cost
77
+ *
78
+ * @param {string} input Range input
79
+ * @returns {boolean} true if the event has 0 on all parts of the range, false otherwise
80
+ */
81
+ export const isFree = ( input ) => {
82
+ const parts = split( input, '-' );
83
+ const test = parts
84
+ .map( ( item ) => parseFloat( item ) )
85
+ .filter( ( item ) => ! isNaN( item ) )
86
+ .filter( ( item ) => item === 0 );
87
+
88
+ return parts.length === test.length;
89
+ };
common/src/modules/utils/slide.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Element to slide gets the following CSS:
3
+ * max-height: 0;
4
+ * overflow: hidden;
5
+ */
6
+ import BezierEasing from 'bezier-easing';
7
+ import getHiddenHeight from './get-hidden-height';
8
+
9
+ const ease = BezierEasing( 0.25, 0.1, 0.25, 1 );
10
+
11
+ const requestIds = {};
12
+
13
+ /**
14
+ * Check that request id exists, if not create an entry
15
+ * @param {string} id Unique ID of animation
16
+ */
17
+ export const checkRequestIds = ( id ) => {
18
+ if ( ! requestIds[ id ] ) {
19
+ requestIds[ id ] = {
20
+ up: null,
21
+ down: null,
22
+ };
23
+ }
24
+
25
+ return requestIds[ id ];
26
+ };
27
+
28
+ /**
29
+ * Cancel animations with request id
30
+ * @param {string} id Unique ID of animation
31
+ */
32
+ const cancelAnimations = ( id ) => {
33
+ if ( requestIds[ id ].up ) {
34
+ window.cancelAnimationFrame( requestIds[ id ].up );
35
+ requestIds[ id ].up = null;
36
+ }
37
+ if ( requestIds[ id ].down ) {
38
+ window.cancelAnimationFrame( requestIds[ id ].down );
39
+ requestIds[ id ].down = null;
40
+ }
41
+ };
42
+
43
+ /**
44
+ * Like jQuery's slideDown function
45
+ * @param {Node} elem Element to show and hide
46
+ * @param {string} id Unique ID of animation
47
+ * @param {int} time Length of animation in ms
48
+ * @param {function} callback Callback function
49
+ */
50
+ export const down = ( elem, id, time = 400, callback = null ) => {
51
+ const startHeight = elem.offsetHeight;
52
+ const endHeight = getHiddenHeight( elem );
53
+ let startTime = null;
54
+ elem.style.maxHeight = '0';
55
+
56
+ checkRequestIds( id );
57
+ cancelAnimations( id );
58
+
59
+ const step = ( timestamp ) => {
60
+ if ( ! startTime ) {
61
+ startTime = timestamp;
62
+ }
63
+ const timeDiff = timestamp - startTime;
64
+ const progress = ease( timeDiff / time );
65
+ const height = ( progress * ( endHeight - startHeight ) ) + startHeight;
66
+ elem.style.maxHeight = `${height}px`;
67
+
68
+ if ( timeDiff < time ) {
69
+ requestIds[ id ].down = window.requestAnimationFrame( step );
70
+ } else {
71
+ requestIds[ id ].down = null;
72
+ elem.style.maxHeight = 'none';
73
+ if ( callback ) {
74
+ callback();
75
+ }
76
+ }
77
+ };
78
+
79
+ requestIds[ id ].down = window.requestAnimationFrame( step );
80
+ };
81
+
82
+ /**
83
+ * Slide element up
84
+ * @param {Node} elem Element to show and hide
85
+ * @param {string} id Unique ID of animation
86
+ * @param {int} time Length of animation in ms
87
+ * @param {function} callback Callback function
88
+ */
89
+ export const up = ( elem, id, time = 400, callback = null ) => {
90
+ const startHeight = elem.offsetHeight;
91
+ const endHeight = 0;
92
+ let startTime = null;
93
+ elem.style.maxHeight = `${startHeight}px`;
94
+
95
+ checkRequestIds( id );
96
+ cancelAnimations( id );
97
+
98
+ const step = ( timestamp ) => {
99
+ if ( ! startTime ) {
100
+ startTime = timestamp;
101
+ }
102
+ const timeDiff = timestamp - startTime;
103
+ const progress = ease( timeDiff / time );
104
+ const height = ( progress * ( endHeight - startHeight ) ) + startHeight;
105
+ elem.style.maxHeight = `${height}px`;
106
+
107
+ if ( timeDiff < time ) {
108
+ requestIds[ id ].up = window.requestAnimationFrame( step );
109
+ } else {
110
+ requestIds[ id ].up = null;
111
+ elem.style.maxHeight = '0';
112
+ if ( callback ) {
113
+ callback();
114
+ }
115
+ }
116
+ };
117
+
118
+ requestIds[ id ].up = window.requestAnimationFrame( step );
119
+ };
common/src/modules/utils/string.js ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { escapeRegExp, isUndefined, isString, identity } from 'lodash';
5
+
6
+ /**
7
+ * Test if a string is equivalent to a true value
8
+ *
9
+ * @param {string} value The value to be tested
10
+ * @returns {boolean} true if the value is a valid "true" value.
11
+ */
12
+ export const isTruthy = ( value ) => {
13
+ const validValues = [
14
+ 'true',
15
+ 'yes',
16
+ '1',
17
+ ];
18
+ return validValues.indexOf( value ) !== -1;
19
+ };
20
+
21
+ /**
22
+ * Test if a string is equivalent to a false value
23
+ *
24
+ * @param {string} value The value to be tested
25
+ * @returns {boolean} true if the value is a valid "false" value.
26
+ */
27
+ export const isFalsy = ( value ) => {
28
+ const validValues = [
29
+ 'false',
30
+ 'no',
31
+ '0',
32
+ '',
33
+ ];
34
+ return validValues.indexOf( value ) !== -1;
35
+ };
36
+
37
+ export const replaceWithObject = ( str = '', pairs = {} ) => {
38
+ const substrs = Object.keys( pairs ).map( escapeRegExp );
39
+ return str.split( RegExp( `(${ substrs.join( '|' ) })` ) )
40
+ .map( part => isUndefined( pairs[ part ] ) ? part : pairs[ part ] )
41
+ .join( '' );
42
+ };
43
+
44
+ /**
45
+ * Extract the words from a string into an array of words removing all the empty spaces.
46
+ *
47
+ * @param {string} text The initial text
48
+ * @returns {array} Return an array with the words
49
+ */
50
+ export const getWords = ( text = '' ) => {
51
+ if ( ! isString( text ) ) {
52
+ return [];
53
+ }
54
+ return text.split( /\s/ ).filter( identity );
55
+ };
56
+
57
+ /**
58
+ * Apply separators specifically for check box style list where if there are more than 2 words the first
59
+ * separators except the last is different from the rest, and if there are only 2 words it only uses
60
+ * the last separator instead
61
+ *
62
+ * @param {array} words The list of words to join
63
+ * @param {string} startSeparator the separator applied if there are more than 2 words between all the words except the last one
64
+ * @param {string} endSeparator separator applied between the last words
65
+ * @returns {string} return a string with custom separators between words
66
+ */
67
+ export const wordsAsList = ( words, startSeparator = ', ', endSeparator = ' & ' ) => {
68
+ if ( words.length <= 1 ) {
69
+ return words.join( '' );
70
+ } else {
71
+ const start = words.slice( 0, words.length - 1 ).join( startSeparator );
72
+ const last = words[ words.length - 1 ];
73
+ return `${ start }${ endSeparator }${ last }`;
74
+ }
75
+ };
76
+
77
+ /**
78
+ * Creates a string that only contains a-z characters, useful specially for keys
79
+ *
80
+ * @param {string} text Then ame to be normalized
81
+ * @returns {string} A formatted string with no spacing and only a-z chars
82
+ */
83
+ export const normalize = ( text = '' ) => {
84
+ if ( ! isString( text ) ) {
85
+ return '';
86
+ }
87
+ return text.toLowerCase()
88
+ // Remove any non word or space
89
+ .replace( /[^a-z\s]/g, '' )
90
+ .trim()
91
+ .replace( /\s+/g, '-' );
92
+ };
93
+
94
+ /**
95
+ * Remove invalid characters from a string that aren't consider as valid for a block name.
96
+ *
97
+ * @since 4.8
98
+ *
99
+ * @param {string} text The text to be formatted as block name
100
+ * @returns {string} The formatted text
101
+ */
102
+ export const toBlockName = ( text = '' ) => {
103
+ if ( ! isString( text ) ) {
104
+ return '';
105
+ }
106
+
107
+ // Remove any non numeric, a-z or - value
108
+ return text.replace(/[^a-zA-Z0-9-]/g, '' );
109
+ }
common/src/modules/utils/time.js ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import zeroFill from 'zero-fill';
5
+
6
+ export const MINUTE_IN_SECONDS = 60;
7
+ export const HALF_HOUR_IN_SECONDS = MINUTE_IN_SECONDS * 30;
8
+ export const HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS;
9
+ export const DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS;
10
+
11
+ export const START_OF_DAY = '00:00';
12
+ export const END_OF_DAY = '23:59';
13
+
14
+ /**
15
+ * Round the time of a time string
16
+ * If the minutes is lower than 30, it will round the minutes to 0
17
+ * If the minutes is greater than or equal to 30, it will round the minutes to 30
18
+ *
19
+ * @param {string} time
20
+ * @returns {moment} A moment object
21
+ */
22
+ export const roundTime = ( time, format = TIME_FORMAT_MM_SS ) => {
23
+ const seconds = toSeconds( time, format );
24
+ const overage = seconds % ( MINUTE_IN_SECONDS * 30 );
25
+ const roundedSeconds = seconds - overage;
26
+ return fromSeconds( roundedSeconds, format );
27
+ }
28
+
29
+ /**
30
+ * The code below is copied from the library hh-mm-ss
31
+ * Link: https://www.npmjs.com/package/hh-mm-ss
32
+ * The code has been copied so that Modern Tribe can maintain this library
33
+ * internally and adjust as needed.
34
+ */
35
+ export const TIME_FORMAT_HH_MM_SS_SSS = 'hh:mm:ss.sss';
36
+ export const TIME_FORMAT_HH_MM_SS = 'hh:mm:ss';
37
+ export const TIME_FORMAT_HH_MM = 'hh:mm';
38
+ export const TIME_FORMAT_MM_SS_SSS = 'mm:ss.sss';
39
+ export const TIME_FORMAT_MM_SS = 'mm:ss';
40
+
41
+ export const SECOND_IN_MS = 1000;
42
+ export const MINUTE_IN_MS = MINUTE_IN_SECONDS * SECOND_IN_MS;
43
+ export const HOUR_IN_MS = HOUR_IN_SECONDS * SECOND_IN_MS;
44
+
45
+ /**
46
+ * Converts milliseconds to time in the format provided
47
+ *
48
+ * @param {int} ms Milliseconds to convert from
49
+ * @param {string} format Format of time to convert to
50
+ * @returns {string} Time string equivalent of milliseconds in format provided
51
+ */
52
+ export const fromMilliseconds = ( ms, format = TIME_FORMAT_MM_SS ) => {
53
+ if ( typeof ms !== 'number' || Number.isNaN( ms ) ) {
54
+ /* eslint-disable-next-line max-len */
55
+ throw new Error( 'Argument `ms` provided to `fromMilliseconds` is not a number or is NaN.' );
56
+ }
57
+
58
+ const absMs = Math.abs( ms );
59
+
60
+ const negative = ( ms < 0 );
61
+ const hours = Math.floor( absMs / HOUR_IN_MS );
62
+ const minutes = Math.floor( absMs % HOUR_IN_MS / MINUTE_IN_MS );
63
+ const seconds = Math.floor( absMs % MINUTE_IN_MS / SECOND_IN_MS );
64
+ const miliseconds = Math.floor( absMs % SECOND_IN_MS );
65
+
66
+ return formatTime( {
67
+ negative,
68
+ hours,
69
+ minutes,
70
+ seconds,
71
+ miliseconds,
72
+ }, format );
73
+ };
74
+
75
+ /**
76
+ * Converts seconds to time in the format provided
77
+ *
78
+ * @param {int} s Seconds to convert from
79
+ * @param {string} format Format of time to convert to
80
+ * @returns {string} Time string equivalent of seconds in format provided
81
+ */
82
+ export const fromSeconds = ( s, format = TIME_FORMAT_MM_SS ) => {
83
+ if ( typeof s !== 'number' || Number.isNaN( s ) ) {
84
+ /* eslint-disable-next-line max-len */
85
+ throw new Error( 'Argument `s` provided to `fromSeconds` is not a number or is NaN.' );
86
+ }
87
+
88
+ const ms = s * SECOND_IN_MS;
89
+
90
+ return fromMilliseconds( ms, format );
91
+ };
92
+
93
+ /**
94
+ * Converts time in the format provided to milliseconds
95
+ *
96
+ * @param {string} time Time string to convert from
97
+ * @param {string} format Format of time to convert from
98
+ * @returns {int} Milliseconds equivalent of time string in format provided
99
+ */
100
+ export const toMilliseconds = ( time, format = TIME_FORMAT_MM_SS ) => {
101
+ let re;
102
+
103
+ if ( [
104
+ TIME_FORMAT_HH_MM_SS_SSS,
105
+ TIME_FORMAT_HH_MM_SS,
106
+ TIME_FORMAT_MM_SS_SSS,
107
+ TIME_FORMAT_MM_SS,
108
+ ].includes( format ) ) {
109
+ re = /^(-)?(?:(\d\d+):)?(\d\d):(\d\d)(\.\d+)?$/;
110
+ } else if ( format === TIME_FORMAT_HH_MM ) {
111
+ re = /^(-)?(\d\d):(\d\d)(?::(\d\d)(?:(\.\d+))?)?$/;
112
+ } else {
113
+ /* eslint-disable-next-line max-len */
114
+ throw new Error( 'Argument `format` provided to `toMilliseconds` is not a recognized format.' );
115
+ }
116
+
117
+ const result = re.exec( time );
118
+ if ( ! result ) {
119
+ /* eslint-disable-next-line max-len */
120
+ throw new Error( 'Argument `time` provided to `toMilliseconds` is not a recognized format.' );
121
+ }
122
+
123
+ const negative = result[ 1 ] === '-';
124
+ const hours = result[ 2 ] | 0;
125
+ const minutes = result[ 3 ] | 0;
126
+ const seconds = result[ 4 ] | 0;
127
+ const miliseconds = Math.floor( 1000 * result[ 5 ] | 0 );
128
+
129
+ if ( minutes >= 60 || seconds >= 60 ) {
130
+ /* eslint-disable-next-line max-len */
131
+ throw new Error( 'Argument `time` provided to `toMilliseconds` contains minutes or seconds greater than 59.' );
132
+ }
133
+
134
+ return ( negative ? -1 : 1 ) * (
135
+ hours * HOUR_IN_MS
136
+ + minutes * MINUTE_IN_MS
137
+ + seconds * SECOND_IN_MS
138
+ + miliseconds
139
+ );
140
+ };
141
+
142
+ /**
143
+ * Converts time in the format provided to seconds
144
+ *
145
+ * @param {string} time Time string to convert from
146
+ * @param {string} format Format of time to convert from
147
+ * @returns {int} Seconds equivalent of time string in format provided
148
+ */
149
+ export const toSeconds = ( time, format = TIME_FORMAT_MM_SS ) => {
150
+ const ms = toMilliseconds( time, format );
151
+ return Math.floor( ms / SECOND_IN_MS );
152
+ };
153
+
154
+ /**
155
+ * Formats time object to time string in the format provided
156
+ *
157
+ * @param {object} time Time object to format from
158
+ * @param {string} format Format of time to format to
159
+ * @returns {string} Time string in format provided
160
+ */
161
+ export const formatTime = ( time, format ) => {
162
+ let showMs;
163
+ let showSc;
164
+ let showHr;
165
+
166
+ switch ( format ) {
167
+ case TIME_FORMAT_HH_MM_SS_SSS:
168
+ showMs = true;
169
+ showSc = true;
170
+ showHr = true;
171
+ break;
172
+ case TIME_FORMAT_HH_MM_SS:
173
+ showMs = ! ! time.miliseconds;
174
+ showSc = true;
175
+ showHr = true;
176
+ break;
177
+ case TIME_FORMAT_HH_MM:
178
+ showMs = ! ! time.miliseconds;
179
+ showSc = showMs || ! ! time.seconds;
180
+ showHr = true;
181
+ break;
182
+ case TIME_FORMAT_MM_SS_SSS:
183
+ showMs = true;
184
+ showSc = true;
185
+ showHr = ! ! time.hours;
186
+ break;
187
+ case TIME_FORMAT_MM_SS:
188
+ showMs = ! ! time.miliseconds;
189
+ showSc = true;
190
+ showHr = ! ! time.hours;
191
+ break;
192
+ default:
193
+ /* eslint-disable-next-line max-len */
194
+ throw new Error( 'Argument `format` provided to `formatTime` is not a recognized format.' );
195
+ }
196
+
197
+ const hh = zeroFill( 2, time.hours );
198
+ const mm = zeroFill( 2, time.minutes );
199
+ const ss = zeroFill( 2, time.seconds );
200
+ const sss = zeroFill( 3, time.miliseconds );
201
+
202
+ return ( time.negative ? '-' : '' ) + ( showHr ? (
203
+ showMs ? `${hh}:${mm}:${ss}.${sss}` : showSc ? `${hh}:${mm}:${ss}` : `${hh}:${mm}`
204
+ ) : (
205
+ showMs ? `${mm}:${ss}.${sss}` : `${mm}:${ss}`
206
+ ) );
207
+ };
common/src/modules/utils/timezone.js ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { find, flatten, map, get } from 'lodash';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { timezoneHtml } from '@moderntribe/common/utils/globals';
10
+
11
+ /**
12
+ * Module Code
13
+ */
14
+
15
+ let timezoneOpts;
16
+
17
+ export const getTimezoneOpts = () => {
18
+ // Verify if we have it in cache solved
19
+ if ( timezoneOpts ) {
20
+ return timezoneOpts;
21
+ }
22
+
23
+ const $timezoneOpts = jQuery( timezoneHtml() );
24
+ const groups = [];
25
+ let number = 0;
26
+
27
+ $timezoneOpts.each( ( index, item ) => {
28
+ const $group = jQuery( item );
29
+
30
+ if ( ! $group.is( 'optgroup' ) ) {
31
+ return;
32
+ }
33
+
34
+ number++;
35
+
36
+ const label = $group.attr( 'label' );
37
+ const group = {
38
+ key: label,
39
+ text: label,
40
+ options: [],
41
+ };
42
+
43
+ $group.find( 'option' ).each( ( optIndex, optionEl ) => {
44
+ number++;
45
+
46
+ const $option = jQuery( optionEl );
47
+ group.options.push( {
48
+ key: $option.val(),
49
+ text: $option.text(),
50
+ index: number,
51
+ } );
52
+ } );
53
+
54
+ groups.push( group );
55
+ } );
56
+
57
+ // Save it in a cache
58
+ timezoneOpts = groups;
59
+
60
+ return groups;
61
+ }
62
+
63
+ export const getItems = ( searchFor ) => {
64
+ const groups = getTimezoneOpts();
65
+
66
+ if ( searchFor ) {
67
+ const opts = flatten( map( groups, 'options' ) );
68
+ return find( opts, searchFor );
69
+ }
70
+
71
+ return groups;
72
+ }
common/src/resources/css/accessibility.css ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+
12
+ /**
13
+ * Following rules set in this article about accessibility elements
14
+ *
15
+ * @link https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
16
+ */
17
+ .tribe-js .tribe-accessible-js-hidden {
18
+ clip: rect( 1px 1px 1px 1px ); /* IE 6/7 */
19
+ clip: rect( 1px, 1px, 1px, 1px );
20
+ height: 1px;
21
+ overflow: hidden;
22
+ position: absolute;
23
+ white-space: nowrap; /* added line */
24
+ width: 1px;
25
+ }
26
+ .tribe-accessible-hidden {
27
+ clip: rect( 1px 1px 1px 1px ); /* IE 6/7 */
28
+ clip: rect( 1px, 1px, 1px, 1px );
29
+ height: 1px;
30
+ overflow: hidden;
31
+ position: absolute;
32
+ white-space: nowrap; /* added line */
33
+ width: 1px;
34
+ }
common/src/resources/css/app-shop.css ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ #tribe-app-shop {
12
+ max-width: 960px;
13
+ }
14
+
15
+ #tribe-app-shop .addon-grid {
16
+ width: 100%;
17
+ }
18
+
19
+ #tribe-app-shop .header h1 {
20
+ display: inline-block;
21
+ }
22
+
23
+ #tribe-app-shop .header .button {
24
+ margin-top: 10px;
25
+ }
26
+
27
+ #tribe-app-shop .tribe-addon {
28
+ background-color: #fff;
29
+ border-bottom: 1px solid #dfdfdf;
30
+ display: inline-block;
31
+ margin: 0 15px 15px 0;
32
+ overflow: hidden;
33
+ padding: 0;
34
+ position: relative;
35
+ vertical-align: top;
36
+ width: 300px;
37
+ border-radius: 3px 3px 3px 3px;
38
+ box-sizing: border-box;
39
+ }
40
+
41
+ #tribe-app-shop .tribe-addon h4 {
42
+ font-size: 1.17em;
43
+ margin: 15px 0;
44
+ }
45
+
46
+ #tribe-app-shop .tribe-addon h4 a {
47
+ text-decoration: none;
48
+ }
49
+
50
+ #tribe-app-shop .tribe-addon .button {
51
+ bottom: 15px;
52
+ display: block;
53
+ position: absolute;
54
+ }
55
+
56
+ #tribe-app-shop .tribe-addon .button-disabled {
57
+ padding-left: 3px;
58
+ }
59
+
60
+ #tribe-app-shop .tribe-addon .button-disabled .dashicons {
61
+ font-size: 28px;
62
+ padding-right: 9px;
63
+ }
64
+
65
+ #tribe-app-shop .tribe-addon .caption {
66
+ padding: 0 15px 45px 15px;
67
+ }
68
+
69
+ #tribe-app-shop .tribe-addon .thumb img {
70
+ height: 228px;
71
+ max-width: 100%;
72
+ width: 300px;
73
+ }
74
+
75
+ #tribe-app-shop .tribe-addon.first {
76
+ margin: 20px 0;
77
+ overflow: hidden;
78
+ padding: 0;
79
+ width: 937px;
80
+ }
81
+
82
+ #tribe-app-shop .tribe-addon.first h4 {
83
+ font-size: 20px;
84
+ line-height: 1.4;
85
+ margin: 15px 0 0 0;
86
+ }
87
+
88
+ #tribe-app-shop .tribe-addon.first .caption {
89
+ display: inline-block;
90
+ padding-left: 20px;
91
+ width: 600px;
92
+ }
93
+
94
+ #tribe-app-shop .tribe-addon.first .thumb {
95
+ float: left;
96
+ height: 228px;
97
+ width: 300px;
98
+ }
99
+
100
+ #tribe-app-shop .tribe-installed-headline {
101
+ margin-bottom: 20px;
102
+ }
common/src/resources/css/app/components.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ .tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
2
+ .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
common/src/resources/css/app/components.min.css CHANGED
@@ -1,2 +1,2 @@
1
- .tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
2
  .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
1
+ .tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
2
  .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
common/src/resources/css/app/elements.css ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .tribe-editor__btn--label{background-color:transparent;border:none;padding:0;margin:0;text-align:left}.editor-styles-wrapper .tribe-editor__button,.tribe-editor__button{background-color:transparent;border:none;padding:0;margin:0;font-family:Helvetica,"sans-serif";cursor:pointer}.editor-styles-wrapper .tribe-editor__button[disabled],.tribe-editor__button[disabled]{cursor:default}.editor-styles-wrapper .tribe-editor__button--sm,.tribe-editor__button--sm{background-color:#009fd4;color:#fff;padding:11px 16px 9px;font-size:15px;font-weight:700;line-height:18px;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.editor-styles-wrapper .tribe-editor__button--sm:focus,.editor-styles-wrapper .tribe-editor__button--sm:hover,.tribe-editor__button--sm:focus,.tribe-editor__button--sm:hover{background-color:#007bb4}.editor-styles-wrapper .tribe-editor__button--sm[disabled],.editor-styles-wrapper .tribe-editor__button--sm[disabled]:focus,.editor-styles-wrapper .tribe-editor__button--sm[disabled]:hover,.tribe-editor__button--sm[disabled],.tribe-editor__button--sm[disabled]:focus,.tribe-editor__button--sm[disabled]:hover{background-color:#f3f4f5;color:#8d949b}
2
+ .tribe-editor__accordion__row-content{max-height:0;overflow:hidden}.tribe-editor__accordion__row-content.active{max-height:none}
3
+ .editor-block-inspector__card .tribe-editor__icons__container{padding:4px;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.editor-block-inspector__card .tribe-editor__icons__container svg{width:28px;height:28px}.editor-block-inspector__card .tribe-editor__icons--tec{background-color:#199fd1}button[class*=" editor-block-list-item-tribe-"] svg,button[class^=editor-block-list-item-tribe-] svg{color:#16a0d6}
4
+ .tribe-editor__counter{display:-webkit-box;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-align:center;align-items:center}.tribe-editor__counter__count{-webkit-box-flex:0;flex:none;color:#aeb4bb;font-size:32px;font-weight:700;line-height:40px;margin-bottom:10px}.tribe-editor__counter__label{-webkit-box-flex:0;flex:none;color:#aeb4bb;font-size:12px;line-height:14px;letter-spacing:.04px}
5
+ .edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:center;align-items:center}.tribe-editor__image-upload--has-image .tribe-editor__image-upload__content{-webkit-box-align:start;align-items:flex-start}.tribe-editor__image-upload__content p.tribe-editor__image-upload__description{-webkit-box-flex:0;flex:none;width:52%;font-family:Helvetica,sans-serif;font-size:14px;color:#545d66;line-height:18px;margin:0}.tribe-editor__image-upload__upload-button{-webkit-box-flex:0;flex:none;margin-right:10px}.tribe-editor__image-upload__image-wrapper{-webkit-box-flex:0;flex:none;width:42%;max-width:325px;padding-left:25px;position:relative}.tribe-editor__image-upload__remove-button{position:absolute;top:10px;right:10px;width:32px;height:32px;padding:8px;border-radius:50%;background-color:#f8f9fb}.tribe-editor__image-upload__remove-button>svg,.tribe-editor__image-upload__remove-button>svg path{fill:#545d66}.tribe-editor__image-upload__remove-button:focus>svg,.tribe-editor__image-upload__remove-button:focus>svg path,.tribe-editor__image-upload__remove-button:hover>svg,.tribe-editor__image-upload__remove-button:hover>svg path{fill:#009fd4}.tribe-editor__image-upload__remove-button:disabled:focus>svg,.tribe-editor__image-upload__remove-button:disabled:focus>svg path,.tribe-editor__image-upload__remove-button:disabled:hover>svg,.tribe-editor__image-upload__remove-button:disabled:hover>svg path,.tribe-editor__image-upload__remove-button:disabled>svg,.tribe-editor__image-upload__remove-button:disabled>svg path{fill:#aeb4bb}.tribe-editor__image-upload__remove-button-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
6
+ .tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:10px 17px;border:1px solid #e1e3e6}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__labeled-item__label,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;padding-right:10px}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link{-webkit-box-flex:0;flex:none;color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;text-decoration:none;box-shadow:none;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover{color:#007bb4}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled{color:#aeb4bb}
7
+ .tribe-editor__label-with-modal{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:11px 17px;border:1px solid #e1e3e6;height:40px}.tribe-editor__label-with-modal .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px}.tribe-editor__label-with-modal .tribe-editor__label-with-modal__modal-button{-webkit-box-flex:0;flex:none}.tribe-editor__label-with-modal .tribe-editor__modal-button__button{color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:hover{color:#007bb4}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:hover{color:#aeb4bb}
8
+ .tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
9
+ .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
10
+ input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
11
+ .tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__toggle input.tribe-editor__timepicker__input[type=text]{font-family:Helvetica,sans-serif;font-size:14px;line-height:1.5;padding:6px 0 6px 10px;border:none;width:80px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn{padding:10px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn:disabled>svg.dashicon{fill:#aeb4bb}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__all-day-btn{color:#545d66;line-height:20px;padding:6px 10px;text-decoration:none;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__content.components-popover .components-popover__content{min-width:110px}.tribe-editor__timepicker__content .tribe-editor__timepicker__items{height:250px;overflow:auto}.tribe-editor__timepicker__content .tribe-editor__timepicker__items .components-placeholder{height:inherit}.tribe-editor__timepicker__content .tribe-editor__timepicker__item{display:block;width:100%;color:#555d66;padding:5px 12px;cursor:pointer;border-bottom:1px solid #e2e4e7;line-height:20px;background:transparent;text-align:left}.tribe-editor__timepicker__content .tribe-editor__timepicker__item:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item:hover{background-color:#e7f5fa}.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:hover{color:#fff;background-color:#009fd4}
12
+ .DayPicker{display:inline-block;font-size:1rem}.DayPicker-wrapper{position:relative;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-direction:row;padding-bottom:1em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-Months{display:-webkit-box;display:flex;flex-wrap:wrap;-webkit-box-pack:center;justify-content:center}.DayPicker-Month{display:table;margin:0 1em;margin-top:1em;border-spacing:0;border-collapse:collapse;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DayPicker-NavButton{position:absolute;top:1em;right:1.5em;left:auto;display:inline-block;margin-top:2px;width:1.25em;height:1.25em;background-position:50%;background-size:50%;background-repeat:no-repeat;color:#8b9898;cursor:pointer}.DayPicker-NavButton:hover{opacity:.8}.DayPicker-NavButton--prev{margin-right:1.5em;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAVVJREFUWAnN2G0KgjAYwPHpGfRkaZeqvgQaK+hY3SUHrk1YzNLay/OiEFp92I+/Mp2F2Mh2lLISWnflFjzH263RQjzMZ19wgs73ez0o1WmtW+dgA01VxrE3p6l2GLsnBy1VYQOtVSEH/atCCgqpQgKKqYIOiq2CBkqtggLKqQIKgqgCBjpJ2Y5CdJ+zrT9A7HHSTA1dxUdHgzCqJIEwq0SDsKsEg6iqBIEoq/wEcVRZBXFV+QJxV5mBtlDFB5VjYTaGZ2sf4R9PM7U9ZU+lLuaetPP/5Die3ToO1+u+MKtHs06qODB2zBnI/jBd4MPQm1VkY79Tb18gB+C62FdBFsZR6yeIo1YQiLJWMIiqVjQIu1YSCLNWFgijVjYIuhYYCKoWKAiiFgoopxYaKLUWOii2FgkophYp6F3r42W5A9s9OcgNvva8xQaysKXlFytoqdYmQH6tF3toSUo0INq9AAAAAElFTkSuQmCC")}.DayPicker-NavButton--next{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAwCAYAAAB5R9gVAAAABGdBTUEAALGPC/xhBQAAAXRJREFUWAnN119ugjAcwPHWzJ1gnmxzB/BBE0n24m4xfNkTaOL7wOtsl3AXMMb+Vjaa1BG00N8fSEibPpAP3xAKKs2yjzTPH9RAjhEo9WzPr/Vm8zgE0+gXATAxxuxtqeJ9t5tIwv5AtQAApsfT6TPdbp+kUBcgVwvO51KqVhMkXKsVJFXrOkigVhCIs1Y4iKlWZxB1rX4gwlpRIIpa8SDkWmggrFq4IIRaJKCYWnSgnrXIQV1r8YD+1Vrn+bReagysIFfLABRt31v8oBu1xEBttfRbltmfjgEcWh9snUS2kNdBK6WN1vrOWxObWsz+fjxevsxmB1GQDfINWiev83nhaoiB/CoOU438oPrhXS0WpQ9xc1ZQWxWHqUYe0I0qrKCQKjygDlXIQV2r0IF6ViEBxVTBBSFUQQNhVYkHIVeJAtkNsbQ7c1LtzP6FsObhb2rCKv7NBIGoq4SDmKoEgTirXAcJVGkFSVVpgoSrXICGUMUH/QBZNSUy5XWUhwAAAABJRU5ErkJggg==")}.DayPicker-NavButton--interactionDisabled{display:none}.DayPicker-Caption{display:table-caption;margin-bottom:.5em;padding:0 .5em;text-align:left}.DayPicker-Caption>div{font-weight:500;font-size:1.15em}.DayPicker-Weekdays{display:table-header-group;margin-top:1em}.DayPicker-WeekdaysRow{display:table-row}.DayPicker-Weekday{display:table-cell;padding:.5em;color:#8b9898;text-align:center;font-size:.875em}.DayPicker-Weekday abbr[title]{border-bottom:none;text-decoration:none}.DayPicker-Body{display:table-row-group}.DayPicker-Week{display:table-row}.DayPicker-Day{border-radius:50%;text-align:center}.DayPicker-Day,.DayPicker-WeekNumber{display:table-cell;padding:.5em;vertical-align:middle;cursor:pointer}.DayPicker-WeekNumber{min-width:1em;border-right:1px solid #eaecec;color:#8b9898;text-align:right;font-size:.75em}.DayPicker--interactionDisabled .DayPicker-Day{cursor:default}.DayPicker-Footer{padding-top:.5em}.DayPicker-TodayButton{border:none;background-color:transparent;background-image:none;box-shadow:none;color:#4a90e2;font-size:.875em;cursor:pointer}.DayPicker-Day--today{color:#d0021b;font-weight:700}.DayPicker-Day--outside{color:#8b9898;cursor:default}.DayPicker-Day--disabled{color:#dce0e0;cursor:default}.DayPicker-Day--sunday{background-color:#f7f8f8}.DayPicker-Day--sunday:not(.DayPicker-Day--today){color:#dce0e0}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside){position:relative;background-color:#4a90e2;color:#f0f8ff}.DayPicker-Day--selected:not(.DayPicker-Day--disabled):not(.DayPicker-Day--outside):hover{background-color:#51a0fa}.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#f0f8ff}.DayPickerInput{display:inline-block}.DayPickerInput-OverlayWrapper{position:relative}.DayPickerInput-Overlay{position:absolute;left:0;z-index:1;background:#fff;box-shadow:0 2px 5px rgba(0,0,0,.15)}
13
+ .tribe-editor__day-picker-input.DayPickerInput>input{border:1px solid #e1e3e6;color:#545d66;font-size:16px;line-height:24px;padding:7px 15px;width:100%;height:40px}.tribe-editor__day-picker-input.DayPickerInput>input:disabled{color:#aeb4bb}.tribe-editor__day-picker-input .DayPickerInput-Overlay{padding:20px;z-index:10}.tribe-editor__day-picker-input .DayPicker{width:100%}.tribe-editor__day-picker-input .DayPicker-Month{margin:0}.tribe-editor__day-picker-input .DayPicker-Caption>div,.tribe-editor__day-picker-input .DayPicker-Day,.tribe-editor__day-picker-input .DayPicker-Weekday{color:#545d66;font-family:Helvetica,"sans-serif";font-weight:400}.tribe-editor__day-picker-input .DayPicker-Caption>div{font-size:16px;margin-bottom:12px;text-align:center}.tribe-editor__day-picker-input .DayPicker-Weekday{font-size:12px}.tribe-editor__day-picker-input .DayPicker-Day{font-size:14px}.tribe-editor__day-picker-input .DayPicker-Day:hover{color:#007bb4;background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--today{color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--disabled{pointer-events:none;color:#ccc}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside){border-radius:0;background-color:#009fd4;color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--outside):hover{background-color:#007bb4;color:#fff}.tribe-editor__day-picker-input .DayPicker-NavButton--prev{left:0;top:0}.tribe-editor__day-picker-input .DayPicker-NavButton--next{right:0;top:0}.tribe-editor__day-picker-input .DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover{background-color:#fff}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside){background-color:#e7f5fa;color:#545d66}.tribe-editor__day-picker-input .DayPicker-Day--selected:not(.DayPicker-Day--start):not(.DayPicker-Day--end):not(.DayPicker-Day--outside):hover{color:#007bb4}
14
+ .tribe-editor__creatable-select .tribe-editor__creatable-select__control{height:40px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__creatable-select .tribe-editor__creatable-select__control:hover{border:1px solid #e1e3e6}.tribe-editor__creatable-select .tribe-editor__creatable-select__control--is-focused{box-shadow:none}.tribe-editor__creatable-select .tribe-editor__creatable-select__value-container{padding:2px 5px 2px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input{font-size:16px}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input{margin:0;line-height:1.5}.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input,.tribe-editor__creatable-select .tribe-editor__creatable-select__input>input:focus{box-shadow:none}.tribe-editor__creatable-select svg.tribe-editor__creatable-select__dropdown-indicator{fill:#555d66}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px)}.tribe-editor__creatable-select .tribe-editor__creatable-select__menu-list{padding:0}.tribe-editor__creatable-select .tribe-editor__creatable-select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-focused{background-color:#e7f5fa}.tribe-editor__creatable-select .tribe-editor__creatable-select__option--is-selected{background-color:#11a0d2}
15
+ .tribe-editor__placeholder{border:2px dashed #e1e3e6;padding:12px 15px 14px;text-align:center;font-family:Helvetica,Arial,"sans-serif";font-size:1rem;line-height:1.5;font-weight:700;color:#8d949b;min-width:260px;display:inline-block}
16
+ .tribe-editor__heading{font-family:Helvetica,Arial,"sans-serif";color:#000}.tribe-editor__heading--h1{font-size:2.375rem}.tribe-editor__heading--h2{font-size:1.3125rem}.tribe-editor__heading--h3{font-size:1rem}
17
+ .tribe-editor__paragraph{font-family:Helvetica,Arial,"sans-serif";line-height:1.5;font-weight:400}.tribe-editor__paragraph--medium{font-size:1rem}.tribe-editor__paragraph--small{font-size:.875rem}.tribe-editor__paragraph a{color:#11a0d2}.tribe-editor__paragraph a:hover{text-decoration:none;color:#007bb4}
18
+ input[type=checkbox].tribe-editor__input--checkbox{background-color:#fff;border:1px solid #e0e5e9;border-radius:0}input[type=checkbox].tribe-editor__input--checkbox:focus{border:1px solid #e0e5e9;box-shadow:0 0 0 1px #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked{background-color:#fff;border:1px solid #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked:focus{border:1px solid #e0e5e9;box-shadow:0 0 0 1px #e0e5e9}input[type=checkbox].tribe-editor__input--checkbox:checked:before{color:#11a0d2}
19
+ .tribe-editor__select .tribe-editor__select__control{height:46px;border:1px solid #e1e3e6;border-radius:3px;background-color:#fff}.tribe-editor__select .tribe-editor__select__control:hover{border:1px solid #e1e3e6}.tribe-editor__select .tribe-editor__select__control--is-focused{box-shadow:none}.tribe-editor__select .tribe-editor__select__value-container{padding:2px 10px 2px 15px}.tribe-editor__select .tribe-editor__select__single-value{margin:0;max-width:calc(100% - 15px);font-size:16px;line-height:1.5}.tribe-editor__select .tribe-editor__select__input{font-size:16px}.tribe-editor__select .tribe-editor__select__input>input{margin:0;line-height:1.5}.tribe-editor__select svg.tribe-editor__select__dropdown-indicator{fill:#555d66}.tribe-editor__select .tribe-editor__select__menu{margin:0;border:1px solid #e1e3e6;border-top:none;border-radius:0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;box-shadow:none;-webkit-transform:translateY(-7px);transform:translateY(-7px);z-index:10}.tribe-editor__select .tribe-editor__select__menu-list{padding:0}.tribe-editor__select .tribe-editor__select__option{font-size:16px;line-height:1.5;padding:3px 15px}.tribe-editor__select .tribe-editor__select__option--is-focused{background-color:#e7f5fa}.tribe-editor__select .tribe-editor__select__option--is-selected{background-color:#11a0d2}.tribe-editor__select--is-disabled svg.tribe-editor__select__dropdown-indicator{fill:#aeb4bb}
20
+ .post-type-tribe_events .editor-styles-wrapper{max-width:none!important}
common/src/resources/css/app/elements.min.css CHANGED
@@ -5,7 +5,7 @@
5
  .edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:center;align-items:center}.tribe-editor__image-upload--has-image .tribe-editor__image-upload__content{-webkit-box-align:start;align-items:flex-start}.tribe-editor__image-upload__content p.tribe-editor__image-upload__description{-webkit-box-flex:0;flex:none;width:52%;font-family:Helvetica,sans-serif;font-size:14px;color:#545d66;line-height:18px;margin:0}.tribe-editor__image-upload__upload-button{-webkit-box-flex:0;flex:none;margin-right:10px}.tribe-editor__image-upload__image-wrapper{-webkit-box-flex:0;flex:none;width:42%;max-width:325px;padding-left:25px;position:relative}.tribe-editor__image-upload__remove-button{position:absolute;top:10px;right:10px;width:32px;height:32px;padding:8px;border-radius:50%;background-color:#f8f9fb}.tribe-editor__image-upload__remove-button>svg,.tribe-editor__image-upload__remove-button>svg path{fill:#545d66}.tribe-editor__image-upload__remove-button:focus>svg,.tribe-editor__image-upload__remove-button:focus>svg path,.tribe-editor__image-upload__remove-button:hover>svg,.tribe-editor__image-upload__remove-button:hover>svg path{fill:#009fd4}.tribe-editor__image-upload__remove-button:disabled:focus>svg,.tribe-editor__image-upload__remove-button:disabled:focus>svg path,.tribe-editor__image-upload__remove-button:disabled:hover>svg,.tribe-editor__image-upload__remove-button:disabled:hover>svg path,.tribe-editor__image-upload__remove-button:disabled>svg,.tribe-editor__image-upload__remove-button:disabled>svg path{fill:#aeb4bb}.tribe-editor__image-upload__remove-button-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
6
  .tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:10px 17px;border:1px solid #e1e3e6}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__labeled-item__label,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;padding-right:10px}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link{-webkit-box-flex:0;flex:none;color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;text-decoration:none;box-shadow:none;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover{color:#007bb4}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled{color:#aeb4bb}
7
  .tribe-editor__label-with-modal{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:11px 17px;border:1px solid #e1e3e6;height:40px}.tribe-editor__label-with-modal .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px}.tribe-editor__label-with-modal .tribe-editor__label-with-modal__modal-button{-webkit-box-flex:0;flex:none}.tribe-editor__label-with-modal .tribe-editor__modal-button__button{color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:hover{color:#007bb4}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:hover{color:#aeb4bb}
8
- .tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .block-editor-inner-blocks .editor-block-list__layout .editor-block-list__block,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
9
  .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
10
  input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
11
  .tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__toggle input.tribe-editor__timepicker__input[type=text]{font-family:Helvetica,sans-serif;font-size:14px;line-height:1.5;padding:6px 0 6px 10px;border:none;width:80px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn{padding:10px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn:disabled>svg.dashicon{fill:#aeb4bb}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__all-day-btn{color:#545d66;line-height:20px;padding:6px 10px;text-decoration:none;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__content.components-popover .components-popover__content{min-width:110px}.tribe-editor__timepicker__content .tribe-editor__timepicker__items{height:250px;overflow:auto}.tribe-editor__timepicker__content .tribe-editor__timepicker__items .components-placeholder{height:inherit}.tribe-editor__timepicker__content .tribe-editor__timepicker__item{display:block;width:100%;color:#555d66;padding:5px 12px;cursor:pointer;border-bottom:1px solid #e2e4e7;line-height:20px;background:transparent;text-align:left}.tribe-editor__timepicker__content .tribe-editor__timepicker__item:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item:hover{background-color:#e7f5fa}.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:hover{color:#fff;background-color:#009fd4}
5
  .edit-post-visual-editor .editor-block-list__block .tribe-editor__image-upload__title{padding:0;margin:0 0 12px;color:#000;font-size:15px;font-weight:700;line-height:18px}.tribe-editor__image-upload__content{display:-webkit-box;display:flex;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:center;align-items:center}.tribe-editor__image-upload--has-image .tribe-editor__image-upload__content{-webkit-box-align:start;align-items:flex-start}.tribe-editor__image-upload__content p.tribe-editor__image-upload__description{-webkit-box-flex:0;flex:none;width:52%;font-family:Helvetica,sans-serif;font-size:14px;color:#545d66;line-height:18px;margin:0}.tribe-editor__image-upload__upload-button{-webkit-box-flex:0;flex:none;margin-right:10px}.tribe-editor__image-upload__image-wrapper{-webkit-box-flex:0;flex:none;width:42%;max-width:325px;padding-left:25px;position:relative}.tribe-editor__image-upload__remove-button{position:absolute;top:10px;right:10px;width:32px;height:32px;padding:8px;border-radius:50%;background-color:#f8f9fb}.tribe-editor__image-upload__remove-button>svg,.tribe-editor__image-upload__remove-button>svg path{fill:#545d66}.tribe-editor__image-upload__remove-button:focus>svg,.tribe-editor__image-upload__remove-button:focus>svg path,.tribe-editor__image-upload__remove-button:hover>svg,.tribe-editor__image-upload__remove-button:hover>svg path{fill:#009fd4}.tribe-editor__image-upload__remove-button:disabled:focus>svg,.tribe-editor__image-upload__remove-button:disabled:focus>svg path,.tribe-editor__image-upload__remove-button:disabled:hover>svg,.tribe-editor__image-upload__remove-button:disabled:hover>svg path,.tribe-editor__image-upload__remove-button:disabled>svg,.tribe-editor__image-upload__remove-button:disabled>svg path{fill:#aeb4bb}.tribe-editor__image-upload__remove-button-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}
6
  .tribe-editor__rsvp .tribe-editor__label-with-link,.tribe-editor__ticket .tribe-editor__label-with-link{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:10px 17px;border:1px solid #e1e3e6}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__labeled-item__label,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;padding-right:10px}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link{-webkit-box-flex:0;flex:none;color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;text-decoration:none;box-shadow:none;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:focus,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link:hover{color:#007bb4}.tribe-editor__rsvp .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled,.tribe-editor__ticket .tribe-editor__label-with-link .tribe-editor__label-with-link__link.tribe-editor__label-with-link__link--disabled{color:#aeb4bb}
7
  .tribe-editor__label-with-modal{display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;background-color:#fff;padding:11px 17px;border:1px solid #e1e3e6;height:40px}.tribe-editor__label-with-modal .tribe-editor__labeled-item__label{-webkit-box-flex:1;flex:auto;color:#545d66;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px}.tribe-editor__label-with-modal .tribe-editor__label-with-modal__modal-button{-webkit-box-flex:0;flex:none}.tribe-editor__label-with-modal .tribe-editor__modal-button__button{color:#009fd4;font-size:15px;font-weight:700;line-height:18px;letter-spacing:.38px;-webkit-transition:color .2s ease;transition:color .2s ease}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:hover{color:#007bb4}.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:focus,.tribe-editor__label-with-modal .tribe-editor__modal-button__button:disabled:hover{color:#aeb4bb}
8
+ .tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{margin:0;max-width:100%!important;padding:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-hovered>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected-parent>.editor-block-list__block-edit:before,.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block.is-selected>.editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit{margin:0}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit:before{outline:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block .editor-block-list__block-edit .editor-block-contextual-toolbar{display:none}.tribe-common__plugin-block-hook .editor-inner-blocks .editor-block-list__layout .editor-block-list__block{outline:none}
9
  .tribe-common-form-select{display:-webkit-box;display:flex}.tribe-common-form-select>div{-webkit-box-flex:0;flex:0 0 auto;min-width:193px}.tribe-common-form-select__toggle{background-color:#fff;border-radius:2px;border:2px solid #eaebec}.tribe-common-form-select__toggle button{-webkit-box-align:center;align-items:center;background-color:#fefffe;border:none;color:#545d66;display:-webkit-box;display:flex;font-family:Helvetica,sans-serif;font-size:16px;font-weight:400;-webkit-box-pack:center;justify-content:center;line-height:1.5;padding:6px 10px;text-align:left;text-decoration:none;width:100%}.tribe-common-form-select__toggle button>span{-webkit-box-flex:1;flex:1}.tribe-common-form-select__options__option{background:transparent;border:0;color:#555d66;cursor:pointer;display:block;line-height:20px;padding:5px 12px;text-align:left;width:100%}.tribe-common-form-select__options__option:hover{background-color:#009fd4;color:#fff}
10
  input.tribe-editor__input[type=number],input.tribe-editor__input[type=text]{color:#000;font-size:16px;line-height:24px;border:1px solid #e1e3e6;padding:7px 15px;margin:0;height:40px}input.tribe-editor__input[type=number]:focus,input.tribe-editor__input[type=text]:focus{color:#000;box-shadow:none;outline:none}input.tribe-editor__input[type=number]:disabled,input.tribe-editor__input[type=text]:disabled{color:#aeb4bb}
11
  .tribe-editor__timepicker{display:inline-block}.tribe-editor__timepicker__toggle{background-color:#fff;border:1px solid #e1e3e6;border-radius:2px;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__toggle input.tribe-editor__timepicker__input[type=text]{font-family:Helvetica,sans-serif;font-size:14px;line-height:1.5;padding:6px 0 6px 10px;border:none;width:80px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn{padding:10px}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__toggle-btn:disabled>svg.dashicon{fill:#aeb4bb}.tribe-editor__timepicker__toggle button.tribe-editor__timepicker__all-day-btn{color:#545d66;line-height:20px;padding:6px 10px;text-decoration:none;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center}.tribe-editor__timepicker__content.components-popover .components-popover__content{min-width:110px}.tribe-editor__timepicker__content .tribe-editor__timepicker__items{height:250px;overflow:auto}.tribe-editor__timepicker__content .tribe-editor__timepicker__items .components-placeholder{height:inherit}.tribe-editor__timepicker__content .tribe-editor__timepicker__item{display:block;width:100%;color:#555d66;padding:5px 12px;cursor:pointer;border-bottom:1px solid #e2e4e7;line-height:20px;background:transparent;text-align:left}.tribe-editor__timepicker__content .tribe-editor__timepicker__item:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item:hover{background-color:#e7f5fa}.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:focus,.tribe-editor__timepicker__content .tribe-editor__timepicker__item--current:hover{color:#fff;background-color:#009fd4}
common/src/resources/css/bumpdown.css ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* = Bumpdown CSS
12
+ =============================================*/
13
+ .wrap .tribe-bumpdown,
14
+ .tribe-bumpdown,
15
+ .tribe-bumpdown-cell.tribe-bumpdown {
16
+ display: none;
17
+ margin: 1rem 0;
18
+ }
19
+ .wrap .tribe-bumpdown .tribe-bumpdown-content, .tribe-bumpdown .tribe-bumpdown-content, .tribe-bumpdown-cell.tribe-bumpdown .tribe-bumpdown-content {
20
+ background: #f1f1f1;
21
+ padding: 10px 35px 10px 10px;
22
+ font-size: 12px;
23
+ position: relative;
24
+ }
25
+ .tribe-bumpdown-cell.tribe-bumpdown {
26
+ padding: 0;
27
+ }
28
+ #poststuff .tribe-bumpdown h1,
29
+ #poststuff .tribe-bumpdown h2,
30
+ #poststuff .tribe-bumpdown h3,
31
+ #poststuff .tribe-bumpdown h4,
32
+ .tribe-bumpdown h1,
33
+ .tribe-bumpdown h2,
34
+ .tribe-bumpdown h3,
35
+ .tribe-bumpdown h4 {
36
+ padding-left: 0;
37
+ padding-top: 0;
38
+ }
39
+ .tribe-bumpdown-arrow {
40
+ position: absolute;
41
+ width: 0;
42
+ height: 0;
43
+ top: -11px;
44
+ margin-left: -18px;
45
+ border-left: 8px solid transparent;
46
+ border-right: 8px solid transparent;
47
+
48
+ border-bottom: 11px solid #f1f1f1;
49
+ }
50
+ .tribe-bumpdown-close {
51
+ color: #686868;
52
+ cursor: pointer;
53
+ position: absolute;
54
+ right: .5rem;
55
+ top: .5rem;
56
+ z-index: 2;
57
+ }
58
+ .tribe-bumpdown-trigger .target {
59
+ color: #0074a2;
60
+ }
61
+ @media screen and (max-width: 782px) {
62
+ .wrap td.tribe-bumpdown {
63
+ padding-right: 35px;
64
+ }
65
+
66
+ .tribe-bumpdown-arrow {
67
+ margin-left: -15px;
68
+ }
69
+ }
common/src/resources/css/buttonset.css ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ .tribe-buttonset .tribe-button-field {
12
+ background-color: #f7f7f7;
13
+ }
14
+
15
+ .tribe-button-field {
16
+ color: #444;
17
+ cursor: pointer;
18
+ display: inline-block;
19
+ text-decoration: none;
20
+ font-size: 13px;
21
+ line-height: 26px;
22
+ height: 28px;
23
+ margin: 0 0 3px;
24
+ padding: 0 10px 1px;
25
+ background-color: #fff;
26
+ border-width: 1px;
27
+ border-style: solid;
28
+ border-color: #ddd;
29
+ -webkit-appearance: none;
30
+ border-radius: 3px;
31
+ white-space: nowrap;
32
+ box-sizing: border-box;
33
+ }
34
+
35
+ .tribe-button-field.tribe-active {
36
+ color: #fff;
37
+ background-color: #585858;
38
+ border-color: #585858;
39
+ }
common/src/resources/css/common-full.css ADDED
@@ -0,0 +1,2300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /*
12
+ * Common Full CSS
13
+ *
14
+ * DO NOT EDIT THIS CSS FILE DIRECTLY.
15
+ * -------------------------------------------------------------
16
+ * This file is just a clearing-house, see the pcss directory
17
+ * and edit the source files found there.
18
+ */
19
+
20
+ /* Reset */
21
+
22
+ /* -----------------------------------------------------------------------------
23
+ *
24
+ * Resets Full
25
+ *
26
+ * This file is just a clearing-house.
27
+ * Make partials (start with an underscore) for any actual css code.
28
+ *
29
+ * ----------------------------------------------------------------------------- */
30
+
31
+ /* Reset */
32
+
33
+ /* -----------------------------------------------------------------------------
34
+ *
35
+ * Normalize "Light"
36
+ *
37
+ * ----------------------------------------------------------------------------- */
38
+
39
+ .tribe-common figure {
40
+ line-height: 0;
41
+ }
42
+
43
+ .tribe-common figcaption {
44
+ line-height: normal;
45
+ }
46
+
47
+ .tribe-common a {
48
+ background-color: transparent;
49
+ -webkit-text-decoration-skip: objects;
50
+ }
51
+
52
+ .tribe-common abbr[title] {
53
+ border-bottom: none;
54
+ text-decoration: underline;
55
+ -webkit-text-decoration: underline dotted;
56
+ text-decoration: underline dotted;
57
+ }
58
+
59
+ .tribe-common code,
60
+ .tribe-common kbd,
61
+ .tribe-common pre,
62
+ .tribe-common samp {
63
+ font-family: monospace;
64
+ font-size: 1em;
65
+ }
66
+
67
+ .tribe-common b,
68
+ .tribe-common strong {
69
+ font-weight: inherit;
70
+ font-weight: bolder;
71
+ }
72
+
73
+ .tribe-common dfn {
74
+ font-style: italic;
75
+ }
76
+
77
+ .tribe-common mark {
78
+ background-color: #ff0;
79
+ color: #000;
80
+ }
81
+
82
+ .tribe-common small {
83
+ font-size: 80%;
84
+ }
85
+
86
+ .tribe-common sub,
87
+ .tribe-common sup {
88
+ font-size: 75%;
89
+ line-height: 0;
90
+ }
91
+
92
+ .tribe-common hr {
93
+ border: 0;
94
+ height: 0;
95
+ }
96
+
97
+ /* Input: Kill browser input chrome */
98
+
99
+ .tribe-common input[type="text"],
100
+ .tribe-common input[type="email"],
101
+ .tribe-common input[type="url"],
102
+ .tribe-common input[type="search"],
103
+ .tribe-common input[type="submit"],
104
+ .tribe-common input[type="password"],
105
+ .tribe-common input[type="reset"],
106
+ .tribe-common input[type="button"],
107
+ .tribe-common button,
108
+ .tribe-common textarea {
109
+ -webkit-appearance: none;
110
+ -moz-appearance: none;
111
+ appearance: none;
112
+ }
113
+
114
+ .tribe-common input,
115
+ .tribe-common button,
116
+ .tribe-common select,
117
+ .tribe-common textarea,
118
+ .tribe-common optgroup {
119
+ color: inherit;
120
+ font: inherit;
121
+ line-height: normal;
122
+ -webkit-font-smoothing: antialiased;
123
+ }
124
+
125
+ .tribe-common input,
126
+ .tribe-common button,
127
+ .tribe-common select,
128
+ .tribe-common textarea {
129
+ outline: 0;
130
+ border-radius: 0;
131
+ }
132
+
133
+ .tribe-common select:-moz-focusring {
134
+ color: transparent;
135
+ text-shadow: 0 0 0 #000;
136
+ }
137
+
138
+ .tribe-common optgroup {
139
+ font-weight: bold;
140
+ }
141
+
142
+ /* -----------------------------------------------------------------------------
143
+ *
144
+ * Reset "Light"
145
+ *
146
+ * ----------------------------------------------------------------------------- */
147
+
148
+ .tribe-common h1,
149
+ .tribe-common h2,
150
+ .tribe-common h3,
151
+ .tribe-common h4,
152
+ .tribe-common h5,
153
+ .tribe-common h6,
154
+ .tribe-common p {
155
+ font-weight: normal;
156
+ text-rendering: optimizeLegibility;
157
+ }
158
+
159
+ /* Theme Overrides */
160
+
161
+ /* .tribe-theme-avada { */
162
+
163
+ /* -------------------------------------------------------------------------
164
+ * Reset Full Theme Overrides - Avada
165
+ * ------------------------------------------------------------------------- */
166
+
167
+ /* } */
168
+
169
+ /* .tribe-theme-divi { */
170
+
171
+ /* -------------------------------------------------------------------------
172
+ * Reset Full Theme Overrides - Divi
173
+ * ------------------------------------------------------------------------- */
174
+
175
+ /* } */
176
+
177
+ /* #top.tribe-theme-enfold .tribe-common { */
178
+
179
+ /* -------------------------------------------------------------------------
180
+ * Reset Full Theme Overrides - Enfold
181
+ * ------------------------------------------------------------------------- */
182
+
183
+ /* } */
184
+
185
+ /* .tribe-theme-genesis { */
186
+
187
+ /* -------------------------------------------------------------------------
188
+ * Reset Full Theme Overrides - Genesis
189
+ * ------------------------------------------------------------------------- */
190
+
191
+ /* } */
192
+
193
+ /* -------------------------------------------------------------------------
194
+ * Reset Full Theme Overrides - Twenty Nineteen
195
+ * ------------------------------------------------------------------------- */
196
+
197
+ .tribe-theme-twentynineteen .tribe-common h1:before, .tribe-theme-twentynineteen .tribe-common h2:before {
198
+ content: none;
199
+ }
200
+
201
+ .tribe-theme-twentynineteen .tribe-common button,
202
+ .tribe-theme-twentynineteen .tribe-common input[type="button"],
203
+ .tribe-theme-twentynineteen .tribe-common input[type="reset"],
204
+ .tribe-theme-twentynineteen .tribe-common input[type="submit"] {
205
+ outline: none;
206
+ }
207
+
208
+ .tribe-theme-twentynineteen .tribe-common th,
209
+ .tribe-theme-twentynineteen .tribe-common td {
210
+ word-break: normal;
211
+ }
212
+
213
+ /* -------------------------------------------------------------------------
214
+ * Reset Full Theme Overrides - Twenty Seventeen
215
+ * ------------------------------------------------------------------------- */
216
+
217
+ .tribe-theme-twentyseventeen .tribe-common h5 {
218
+ letter-spacing: normal;
219
+ text-transform: none;
220
+ }
221
+
222
+ .tribe-theme-twentyseventeen .tribe-common input[type="text"] {
223
+ border-radius: 0;
224
+ }
225
+
226
+ .tribe-theme-twentytwenty .tribe-common {
227
+
228
+ /* -------------------------------------------------------------------------
229
+ * Reset Full Theme Overrides - Twenty Twenty
230
+ * ------------------------------------------------------------------------- */
231
+ background-color: #FFFFFF;
232
+ letter-spacing: normal;
233
+ }
234
+
235
+ .tribe-theme-twentytwenty .tribe-common input,
236
+ .tribe-theme-twentytwenty .tribe-common textarea {
237
+ letter-spacing: normal;
238
+ }
239
+
240
+ .tribe-theme-twentytwenty .tribe-common * {
241
+ word-break: normal;
242
+ }
243
+
244
+ /* Utilities */
245
+
246
+ /* -----------------------------------------------------------------------------
247
+ *
248
+ * Utilities
249
+ *
250
+ * This file is just a clearing-house.
251
+ * Make partials (start with an underscore) for any actual css code.
252
+ *
253
+ * ----------------------------------------------------------------------------- */
254
+
255
+ /* Variables */
256
+
257
+ :root {
258
+ /* -----------------------------------------------------------------------------
259
+ * Borders - Radius
260
+ * ----------------------------------------------------------------------------- */
261
+
262
+ /* -----------------------------------------------------------------------------
263
+ * Borders - Width
264
+ * ----------------------------------------------------------------------------- */
265
+ }
266
+
267
+ :root {
268
+ /* -----------------------------------------------------------------------------
269
+ * Box Shadows
270
+ * ----------------------------------------------------------------------------- */
271
+ }
272
+
273
+ :root {
274
+ /* -----------------------------------------------------------------------------
275
+ * Layers of z-index
276
+ * ----------------------------------------------------------------------------- */
277
+ }
278
+
279
+ :root {
280
+ /* -----------------------------------------------------------------------------
281
+ * Colors - Typography
282
+ * ----------------------------------------------------------------------------- */
283
+
284
+ /* -----------------------------------------------------------------------------
285
+ * Colors - Iconography
286
+ * ----------------------------------------------------------------------------- */
287
+
288
+ /* -----------------------------------------------------------------------------
289
+ * Colors - UI
290
+ * ----------------------------------------------------------------------------- */
291
+
292
+ /* -----------------------------------------------------------------------------
293
+ * Colors - Borders & Misc
294
+ * ----------------------------------------------------------------------------- */
295
+
296
+ }
297
+
298
+ :root {
299
+ /* -----------------------------------------------------------------------------
300
+ * Forms - Colors
301
+ * ----------------------------------------------------------------------------- */
302
+
303
+ /* -----------------------------------------------------------------------------
304
+ * Forms - Box Shadows
305
+ * ----------------------------------------------------------------------------- */
306
+ }
307
+
308
+ :root {
309
+ /* -----------------------------------------------------------------------------
310
+ * Gutter - Default
311
+ * ----------------------------------------------------------------------------- */
312
+
313
+ /* -----------------------------------------------------------------------------
314
+ * Gutter - Page
315
+ * ----------------------------------------------------------------------------- */
316
+
317
+ /* -----------------------------------------------------------------------------
318
+ * Grid Width - Default
319
+ * ----------------------------------------------------------------------------- */
320
+
321
+ /* -----------------------------------------------------------------------------
322
+ * Grid Width - Relative
323
+ * ----------------------------------------------------------------------------- */
324
+ }
325
+
326
+ :root {
327
+ /* -----------------------------------------------------------------------------
328
+ * Opacities
329
+ * ----------------------------------------------------------------------------- */
330
+ }
331
+
332
+ :root {
333
+ /* -----------------------------------------------------------------------------
334
+ * Spacers
335
+ * ----------------------------------------------------------------------------- */
336
+ }
337
+
338
+ /* -----------------------------------------------------------------------------
339
+ * SVG - Arrow Right
340
+ * ----------------------------------------------------------------------------- */
341
+
342
+ /* -----------------------------------------------------------------------------
343
+ * SVG - Arrow (light, left)
344
+ * ----------------------------------------------------------------------------- */
345
+
346
+ /* -----------------------------------------------------------------------------
347
+ * SVG - Caret Down
348
+ * ----------------------------------------------------------------------------- */
349
+
350
+ /* -----------------------------------------------------------------------------
351
+ * SVG - Caret Left
352
+ * ----------------------------------------------------------------------------- */
353
+
354
+ /* -----------------------------------------------------------------------------
355
+ * SVG - Caret Right
356
+ * ----------------------------------------------------------------------------- */
357
+
358
+ /* -----------------------------------------------------------------------------
359
+ * SVG - Caret Up
360
+ * ----------------------------------------------------------------------------- */
361
+
362
+ /* -----------------------------------------------------------------------------
363
+ * SVG - Check
364
+ * ----------------------------------------------------------------------------- */
365
+
366
+ /* -----------------------------------------------------------------------------
367
+ * SVG - Close
368
+ * ----------------------------------------------------------------------------- */
369
+
370
+ /* -----------------------------------------------------------------------------
371
+ * SVG - Day
372
+ * ----------------------------------------------------------------------------- */
373
+
374
+ /* -----------------------------------------------------------------------------
375
+ * SVG - Dropdown
376
+ * ----------------------------------------------------------------------------- */
377
+
378
+ /* -----------------------------------------------------------------------------
379
+ * SVG - Error
380
+ * ----------------------------------------------------------------------------- */
381
+
382
+ /* -----------------------------------------------------------------------------
383
+ * SVG - Featured
384
+ * ----------------------------------------------------------------------------- */
385
+
386
+ /* -----------------------------------------------------------------------------
387
+ * SVG - Filters
388
+ * ----------------------------------------------------------------------------- */
389
+
390
+ /* -----------------------------------------------------------------------------
391
+ * SVG - List
392
+ * ----------------------------------------------------------------------------- */
393
+
394
+ /* -----------------------------------------------------------------------------
395
+ * SVG - Location
396
+ * ----------------------------------------------------------------------------- */
397
+
398
+ /* -----------------------------------------------------------------------------
399
+ * SVG - Map
400
+ * ----------------------------------------------------------------------------- */
401
+
402
+ /* -----------------------------------------------------------------------------
403
+ * SVG - Month
404
+ * ----------------------------------------------------------------------------- */
405
+
406
+ /* -----------------------------------------------------------------------------
407
+ * SVG - Photo
408
+ * ----------------------------------------------------------------------------- */
409
+
410
+ /* -----------------------------------------------------------------------------
411
+ * SVG - Recurring
412
+ * ----------------------------------------------------------------------------- */
413
+
414
+ /* -----------------------------------------------------------------------------
415
+ * SVG - Remove
416
+ * ----------------------------------------------------------------------------- */
417
+
418
+ /* -----------------------------------------------------------------------------
419
+ * SVG - Reset
420
+ * ----------------------------------------------------------------------------- */
421
+
422
+ /* -----------------------------------------------------------------------------
423
+ * SVG - Search
424
+ * ----------------------------------------------------------------------------- */
425
+
426
+ /* -----------------------------------------------------------------------------
427
+ * SVG - Search Filter
428
+ * ----------------------------------------------------------------------------- */
429
+
430
+ /* -----------------------------------------------------------------------------
431
+ * SVG - Week
432
+ * ----------------------------------------------------------------------------- */
433
+
434
+ :root {
435
+ /* -----------------------------------------------------------------------------
436
+ * Transitions
437
+ * ----------------------------------------------------------------------------- */
438
+ }
439
+
440
+ :root {
441
+ /* -----------------------------------------------------------------------------
442
+ * Font Stacks
443
+ * ----------------------------------------------------------------------------- */
444
+
445
+ /* -----------------------------------------------------------------------------
446
+ * Font Weights
447
+ * ----------------------------------------------------------------------------- */
448
+
449
+ /* -----------------------------------------------------------------------------
450
+ * Font Sizing
451
+ * ----------------------------------------------------------------------------- */
452
+
453
+ /* -----------------------------------------------------------------------------
454
+ * Line Height
455
+ * ----------------------------------------------------------------------------- */
456
+ }
457
+
458
+ /* Mixins */
459
+
460
+ /* -----------------------------------------------------------------------------
461
+ * Body
462
+ * ----------------------------------------------------------------------------- */
463
+
464
+ /* -----------------------------------------------------------------------------
465
+ * Desktop Body 1
466
+ * ----------------------------------------------------------------------------- */
467
+
468
+ /* -----------------------------------------------------------------------------
469
+ * Desktop Body 2
470
+ * ----------------------------------------------------------------------------- */
471
+
472
+ /* -----------------------------------------------------------------------------
473
+ * Desktop Body 3
474
+ * ----------------------------------------------------------------------------- */
475
+
476
+ /* -----------------------------------------------------------------------------
477
+ * Mobile Body 1
478
+ * ----------------------------------------------------------------------------- */
479
+
480
+ /* -----------------------------------------------------------------------------
481
+ * Mobile Body 2
482
+ * ----------------------------------------------------------------------------- */
483
+
484
+ /* -----------------------------------------------------------------------------
485
+ * Mobile Body 3
486
+ * ----------------------------------------------------------------------------- */
487
+
488
+ /* -----------------------------------------------------------------------------
489
+ * Heading
490
+ * ----------------------------------------------------------------------------- */
491
+
492
+ /* -----------------------------------------------------------------------------
493
+ * Heading 1
494
+ * ----------------------------------------------------------------------------- */
495
+
496
+ /* -----------------------------------------------------------------------------
497
+ * Heading 2
498
+ * ----------------------------------------------------------------------------- */
499
+
500
+ /* -----------------------------------------------------------------------------
501
+ * Heading 3
502
+ * ----------------------------------------------------------------------------- */
503
+
504
+ /* -----------------------------------------------------------------------------
505
+ * Heading 4
506
+ * ----------------------------------------------------------------------------- */
507
+
508
+ /* -----------------------------------------------------------------------------
509
+ * Heading 5
510
+ * ----------------------------------------------------------------------------- */
511
+
512
+ /* -----------------------------------------------------------------------------
513
+ * Heading 6
514
+ * ----------------------------------------------------------------------------- */
515
+
516
+ /* -----------------------------------------------------------------------------
517
+ * Heading 7
518
+ * ----------------------------------------------------------------------------- */
519
+
520
+ /* -----------------------------------------------------------------------------
521
+ * Heading 8
522
+ * ----------------------------------------------------------------------------- */
523
+
524
+ /* -----------------------------------------------------------------------------
525
+ * Anchor - Default
526
+ * ----------------------------------------------------------------------------- */
527
+
528
+ /* -----------------------------------------------------------------------------
529
+ * Anchor - Alt
530
+ * ----------------------------------------------------------------------------- */
531
+
532
+ /* -----------------------------------------------------------------------------
533
+ * Anchor - Thin
534
+ * ----------------------------------------------------------------------------- */
535
+
536
+ /* -----------------------------------------------------------------------------
537
+ * Anchor - Thin
538
+ * ----------------------------------------------------------------------------- */
539
+
540
+ /* -----------------------------------------------------------------------------
541
+ * Button - Global
542
+ * ----------------------------------------------------------------------------- */
543
+
544
+ /* -----------------------------------------------------------------------------
545
+ * Button - Solid
546
+ * ----------------------------------------------------------------------------- */
547
+
548
+ /* -----------------------------------------------------------------------------
549
+ * Button - Link
550
+ * ----------------------------------------------------------------------------- */
551
+
552
+ /* -----------------------------------------------------------------------------
553
+ * Button - Border
554
+ * ----------------------------------------------------------------------------- */
555
+
556
+ /* -----------------------------------------------------------------------------
557
+ * Button - Icon Border
558
+ * ----------------------------------------------------------------------------- */
559
+
560
+ /* -----------------------------------------------------------------------------
561
+ * Sliders & Toggles
562
+ * ----------------------------------------------------------------------------- */
563
+
564
+ /* -----------------------------------------------------------------------------
565
+ * Sliders
566
+ * ----------------------------------------------------------------------------- */
567
+
568
+ /* -----------------------------------------------------------------------------
569
+ * Hidden: Hide from both screenreaders and browsers
570
+ * @author: h5bp.com/u
571
+ * ----------------------------------------------------------------------------- */
572
+
573
+ /* -----------------------------------------------------------------------------
574
+ * Visually Hide: Hide only visually, but have it available for screenreaders
575
+ * @author: h5bp.com/v
576
+ * ----------------------------------------------------------------------------- */
577
+
578
+ /* -----------------------------------------------------------------------------
579
+ * Visually Show: Show element after has been hidden with %visually-hide
580
+ * ----------------------------------------------------------------------------- */
581
+
582
+ /* Base */
583
+
584
+ /* -----------------------------------------------------------------------------
585
+ *
586
+ * Base Full
587
+ *
588
+ * This file is just a clearing-house.
589
+ * Make partials (start with an underscore) for any actual css code.
590
+ *
591
+ * ----------------------------------------------------------------------------- */
592
+
593
+ /* Forms */
594
+
595
+ .tribe-common {
596
+
597
+ /* -----------------------------------------------------------------------------
598
+ *
599
+ * Form Control: Checkboxes & Radios Theme Overrides
600
+ *
601
+ * ----------------------------------------------------------------------------- */
602
+
603
+ /* -----------------------------------------------------------------------------
604
+ * Form Control: Checkboxes Theme Overrides
605
+ * ----------------------------------------------------------------------------- */
606
+
607
+ /* -----------------------------------------------------------------------------
608
+ * Form Control: Radios Theme Overrides
609
+ * ----------------------------------------------------------------------------- */
610
+ }
611
+
612
+ /* -----------------------------------------------------------------------------
613
+ *
614
+ * Form Control: Checkboxes & Radios
615
+ *
616
+ * Example (Checkboxes):
617
+ * <fieldset>
618
+ * <legend>Legend for Checkboxes</legend>
619
+ * <div class="tribe-common-form-control-checkbox-radio-group">
620
+ * <div class="tribe-common-form-control-checkbox">
621
+ * <input
622
+ * class="tribe-common-form-control-checkbox__input"
623
+ * id="checkboxOne"
624
+ * name="checkboxGroup"
625
+ * type="checkbox"
626
+ * value="checkboxOne"
627
+ * checked="checked"
628
+ * />
629
+ * <label
630
+ * class="tribe-common-form-control-checkbox__label"
631
+ * for="checkboxOne"
632
+ * >
633
+ * Checkbox One
634
+ * </label>
635
+ * </div>
636
+ * <div class="tribe-common-form-control-checkbox">
637
+ * <input
638
+ * class="tribe-common-form-control-checkbox__input"
639
+ * id="checkboxTwo"
640
+ * name="checkboxGroup"
641
+ * type="checkbox"
642
+ * value="checkboxTwo"
643
+ * />
644
+ * <label
645
+ * class="tribe-common-form-control-checkbox__label"
646
+ * for="checkboxTwo"
647
+ * >
648
+ * Checkbox Two
649
+ * </label>
650
+ * </div>
651
+ * </div>
652
+ * </fieldset>
653
+ *
654
+ * Example (Radios):
655
+ * <div class="tribe-common-form-control-checkbox-radio-group">
656
+ * <div class="tribe-common-form-control-radio">
657
+ * <input
658
+ * class="tribe-common-form-control-radio__input"
659
+ * id="radioExample"
660
+ * name="radioExample"
661
+ * type="radio"
662
+ * value="RadioExample"
663
+ * checked="checked"
664
+ * />
665
+ * <label
666
+ * class="tribe-common-form-control-radio__label"
667
+ * for="radioExample"
668
+ * >
669
+ * Radio Example
670
+ * </label>
671
+ * </div>
672
+ * </div>
673
+ *
674
+ * ----------------------------------------------------------------------------- */
675
+
676
+ .tribe-common .tribe-common-form-control-checkbox,
677
+ .tribe-common .tribe-common-form-control-radio {
678
+ line-height: 0;
679
+ }
680
+
681
+ .tribe-common .tribe-common-form-control-checkbox__label,
682
+ .tribe-common .tribe-common-form-control-radio__label {
683
+ color: #141827;
684
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
685
+ font-size: 14px;
686
+ line-height: 1.62;
687
+ font-weight: 400;
688
+
689
+ color: #727272;
690
+ }
691
+
692
+ .tribe-common .tribe-common-form-control-checkbox__input,
693
+ .tribe-common .tribe-common-form-control-radio__input {
694
+ -webkit-appearance: none;
695
+ -moz-appearance: none;
696
+ appearance: none;
697
+ background-color: #FFFFFF;
698
+ border: 1px solid #141827;
699
+ height: 20px;
700
+ position: relative;
701
+ width: 20px;
702
+ }
703
+
704
+ .tribe-common .tribe-common-form-control-checkbox__input:active,
705
+ .tribe-common .tribe-common-form-control-checkbox__input:focus,
706
+ .tribe-common .tribe-common-form-control-checkbox__input:hover,
707
+ .tribe-common .tribe-common-form-control-radio__input:active,
708
+ .tribe-common .tribe-common-form-control-radio__input:focus,
709
+ .tribe-common .tribe-common-form-control-radio__input:hover {
710
+ border: 1px solid #141827;
711
+ }
712
+
713
+ .tribe-common .tribe-common-form-control-checkbox__input:checked, .tribe-common .tribe-common-form-control-radio__input:checked {
714
+ background-color: #141827;
715
+ }
716
+
717
+ /* -----------------------------------------------------------------------------
718
+ * Form Control: Checkboxes
719
+ * ----------------------------------------------------------------------------- */
720
+
721
+ .tribe-common .tribe-common-form-control-checkbox__input:checked:before {
722
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFFFFF'/%3E%3C/svg%3E");
723
+ background-repeat: no-repeat;
724
+ background-size: contain;
725
+ content: '';
726
+ display: block;
727
+ height: 9px;
728
+ left: 50%;
729
+ position: absolute;
730
+ top: 50%;
731
+ -webkit-transform: translate(-50%, -50%);
732
+ transform: translate(-50%, -50%);
733
+ width: 12px;
734
+ }
735
+
736
+ /* -----------------------------------------------------------------------------
737
+ * Form Control: Radios
738
+ * ----------------------------------------------------------------------------- */
739
+
740
+ .tribe-common .tribe-common-form-control-radio__input {
741
+ border-radius: 50%;
742
+ }
743
+
744
+ .tribe-common .tribe-common-form-control-radio__input:checked:before {
745
+ background-color: #FFFFFF;
746
+ border-radius: 50%;
747
+ content: '';
748
+ display: block;
749
+ height: 8px;
750
+ left: 50%;
751
+ position: absolute;
752
+ top: 50%;
753
+ -webkit-transform: translate(-50%, -50%);
754
+ transform: translate(-50%, -50%);
755
+ width: 8px;
756
+ }
757
+
758
+ /* -----------------------------------------------------------------------------
759
+ * Theme Overrides - Enfold
760
+ * ----------------------------------------------------------------------------- */
761
+
762
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label {
763
+ font-weight: 400;
764
+ font-size: 14px;
765
+ }
766
+
767
+ /* -----------------------------------------------------------------------------
768
+ * Theme Overrides - Enfold
769
+ * ----------------------------------------------------------------------------- */
770
+
771
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label {
772
+ font-weight: 400;
773
+ font-size: 14px;
774
+ }
775
+
776
+ /* .tribe-common { */
777
+
778
+ /* -----------------------------------------------------------------------------
779
+ *
780
+ * Form Control: Groups (Checkbox & Radio)
781
+ *
782
+ * Example:
783
+ * <div class="tribe-common-form-control-checkbox-radio-group">
784
+ * <div class="tribe-common-form-control-checkbox">
785
+ * <input id="checkboxOne" name="checkboxGroup" type="checkbox" value="checkboxOne" checked="checked" />
786
+ * <label for="checkboxOne">Checkbox One</label>
787
+ * </div>
788
+ * <div class="tribe-common-form-control-checkbox">
789
+ * <input id="checkboxTwo" name="checkboxGroup" type="checkbox" value="checkboxTwo" />
790
+ * <label for="checkboxTwo">Checkbox two</label>
791
+ * </div>
792
+ * </div>
793
+ *
794
+ * ----------------------------------------------------------------------------- */
795
+
796
+ /* .tribe-common-form-control-checkbox-radio-group {} */
797
+
798
+ /* } */
799
+
800
+ .tribe-common {
801
+
802
+ /* -----------------------------------------------------------------------------
803
+ *
804
+ * Form Control: Sliders Theme Overrides
805
+ *
806
+ * ----------------------------------------------------------------------------- */
807
+ }
808
+
809
+ /* -----------------------------------------------------------------------------
810
+ *
811
+ * Form Control: Sliders
812
+ *
813
+ * Example (Horizontal):
814
+ * <div class="tribe-common-form-control-slider">
815
+ * <input
816
+ * class="tribe-common-form-control-slider__input"
817
+ * id="sliderOne"
818
+ * type="range"
819
+ * min="0"
820
+ * max="100"
821
+ * value="50"
822
+ * />
823
+ * <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
824
+ * </div>
825
+ *
826
+ * Example (Vertical):
827
+ * <div class="tribe-common-form-control-slider tribe-common-form-control-slider--vertical">
828
+ * <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
829
+ * <input
830
+ * class="tribe-common-form-control-slider__input"
831
+ * id="sliderOne"
832
+ * type="range"
833
+ * min="0"
834
+ * max="100"
835
+ * value="50"
836
+ * />
837
+ * </div>
838
+ *
839
+ * ----------------------------------------------------------------------------- */
840
+
841
+ .tribe-common .tribe-common-form-control-slider {
842
+ line-height: 0;
843
+ }
844
+
845
+ .tribe-common .tribe-common-form-control-slider__input {
846
+ -webkit-appearance: none;
847
+ -moz-appearance: none;
848
+ appearance: none;
849
+ background-color: transparent;
850
+ border: 0;
851
+ }
852
+
853
+ /* -----------------------------------------------------------------------------
854
+ * Track styles
855
+ * ----------------------------------------------------------------------------- */
856
+
857
+ .tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track {
858
+ border: none;
859
+ border-radius: 5px;
860
+ height: 10px;
861
+ margin: 5px 0;
862
+ padding: 0;
863
+ position: relative;
864
+ -webkit-transition: background-color 0.2s ease;
865
+ transition: background-color 0.2s ease;
866
+ background-color: #334AFF;
867
+ }
868
+
869
+ .tribe-common .tribe-common-form-control-slider__input::-moz-range-track {
870
+ border: none;
871
+ border-radius: 5px;
872
+ height: 10px;
873
+ margin: 5px 0;
874
+ padding: 0;
875
+ position: relative;
876
+ -moz-transition: background-color 0.2s ease;
877
+ transition: background-color 0.2s ease;
878
+ background-color: #334AFF;
879
+ }
880
+
881
+ .tribe-common .tribe-common-form-control-slider__input::-ms-track {
882
+ background-color: transparent;
883
+ border-color: transparent;
884
+ border-width: 5px 0;
885
+ color: transparent;
886
+ height: 10px;
887
+ }
888
+
889
+ .tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,
890
+ .tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper {
891
+ background-color: #334AFF;
892
+ border-radius: 10px;
893
+ }
894
+
895
+ /* -----------------------------------------------------------------------------
896
+ * Thumb styles
897
+ * ----------------------------------------------------------------------------- */
898
+
899
+ .tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb {
900
+ background-color: #FFFFFF;
901
+ border: 1px solid #D5D5D5;
902
+ border-radius: 50%;
903
+ box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
904
+ height: 20px;
905
+ width: 20px;
906
+ margin-top: -5px;
907
+
908
+ -webkit-appearance: none;
909
+
910
+ appearance: none;
911
+ }
912
+
913
+ .tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb {
914
+ background-color: #FFFFFF;
915
+ border: 1px solid #D5D5D5;
916
+ border-radius: 50%;
917
+ box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
918
+ height: 20px;
919
+ width: 20px;
920
+ margin-top: -5px;
921
+ }
922
+
923
+ .tribe-common .tribe-common-form-control-slider__input::-ms-thumb {
924
+ background-color: #FFFFFF;
925
+ border: 1px solid #D5D5D5;
926
+ border-radius: 50%;
927
+ box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
928
+ height: 20px;
929
+ width: 20px;
930
+ margin-top: -5px;
931
+
932
+ box-shadow: none;
933
+ margin-top: -1px;
934
+ }
935
+
936
+ .tribe-common .tribe-common-form-control-slider__label {
937
+ color: #141827;
938
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
939
+ font-size: 12px;
940
+ line-height: 1.38;
941
+ font-weight: 400;
942
+
943
+ color: #727272;
944
+ }
945
+
946
+ /* -----------------------------------------------------------------------------
947
+ * Theme Overrides - Enfold
948
+ * ----------------------------------------------------------------------------- */
949
+
950
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label {
951
+ font-weight: 400;
952
+ font-size: 12px;
953
+ }
954
+
955
+ .tribe-common {
956
+
957
+ /* -----------------------------------------------------------------------------
958
+ *
959
+ * Form Control: Text Theme Overrides
960
+ *
961
+ * ----------------------------------------------------------------------------- */
962
+ }
963
+
964
+ /* -----------------------------------------------------------------------------
965
+ *
966
+ * Form Control: Text
967
+ *
968
+ * Example:
969
+ * <div class="tribe-common-form-control-text">
970
+ * <label class="tribe-common-form-control-text__label" for="textInput">Text Input</label>
971
+ * <input
972
+ * class="tribe-common-form-control-text__input"
973
+ * id="textInput"
974
+ * name="textInput"
975
+ * type="text"
976
+ * placeholder="Text Input"
977
+ * />
978
+ * </div>
979
+ *
980
+ * ----------------------------------------------------------------------------- */
981
+
982
+ .tribe-common .tribe-common-form-control-text__input {
983
+ color: #141827;
984
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
985
+ font-size: 16px;
986
+ line-height: 1.62;
987
+ font-weight: 400;
988
+
989
+ border: 0;
990
+ border-bottom: 1px solid #D5D5D5;
991
+ }
992
+
993
+ .tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder {
994
+ color: #727272;
995
+ font-style: normal;
996
+ }
997
+
998
+ .tribe-common .tribe-common-form-control-text__input::-moz-placeholder {
999
+ color: #727272;
1000
+ font-style: normal;
1001
+ }
1002
+
1003
+ .tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder {
1004
+ color: #727272;
1005
+ font-style: normal;
1006
+ }
1007
+
1008
+ .tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder {
1009
+ color: #727272;
1010
+ font-style: normal;
1011
+ }
1012
+
1013
+ .tribe-common .tribe-common-form-control-text__input::placeholder {
1014
+ color: #727272;
1015
+ font-style: normal;
1016
+ }
1017
+
1018
+ .tribe-common .tribe-common-form-control-text__input:focus {
1019
+ border-bottom-color: #141827;
1020
+ outline: 0;
1021
+ }
1022
+
1023
+ /* -------------------------------------------------------------------------
1024
+ * Theme Overrides - Twenty Seventeen
1025
+ * ------------------------------------------------------------------------- */
1026
+
1027
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input {
1028
+ color: #141827;
1029
+ }
1030
+
1031
+ /* -------------------------------------------------------------------------
1032
+ * Theme Overrides - Twenty Twenty
1033
+ * ------------------------------------------------------------------------- */
1034
+
1035
+ .tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input {
1036
+ line-height: inherit;
1037
+ }
1038
+
1039
+ /* -------------------------------------------------------------------------
1040
+ * Theme Overrides - Enfold
1041
+ * ------------------------------------------------------------------------- */
1042
+
1043
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
1044
+ color: #141827;
1045
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1046
+ font-size: 16px;
1047
+ line-height: 1.62;
1048
+ font-weight: 400;
1049
+
1050
+ border: 0;
1051
+ border-bottom: 1px solid #D5D5D5;
1052
+ }
1053
+
1054
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus {
1055
+ border-bottom-color: #141827;
1056
+ box-shadow: none;
1057
+ }
1058
+
1059
+ .tribe-common {
1060
+
1061
+ /* -----------------------------------------------------------------------------
1062
+ *
1063
+ * Form Control: Toggles Theme Overrides
1064
+ *
1065
+ * ----------------------------------------------------------------------------- */
1066
+ }
1067
+
1068
+ /* -----------------------------------------------------------------------------
1069
+ *
1070
+ * Form Control: Toggles
1071
+ *
1072
+ * Example (Horizontal):
1073
+ * <div class="tribe-common-form-control-toggle">
1074
+ * <input
1075
+ * class="tribe-common-form-control-toggle__input"
1076
+ * id="toggleOne"
1077
+ * name="toggleGroup"
1078
+ * type="checkbox"
1079
+ * value="toggleOne"
1080
+ * />
1081
+ * <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
1082
+ * </div>
1083
+ *
1084
+ * Example (Vertical):
1085
+ * <div class="tribe-common-form-control-toggle tribe-common-form-control-toggle--vertical">
1086
+ * <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
1087
+ * <input
1088
+ * class="tribe-common-form-control-toggle__input"
1089
+ * id="toggleOne"
1090
+ * name="toggleGroup"
1091
+ * type="checkbox"
1092
+ * value="toggleOne"
1093
+ * />
1094
+ * </div>
1095
+ *
1096
+ * ----------------------------------------------------------------------------- */
1097
+
1098
+ .tribe-common .tribe-common-form-control-toggle {
1099
+ line-height: 0;
1100
+ }
1101
+
1102
+ .tribe-common .tribe-common-form-control-toggle__input {
1103
+ border: none;
1104
+ border-radius: 5px;
1105
+ height: 10px;
1106
+ margin: 5px 0;
1107
+ padding: 0;
1108
+ position: relative;
1109
+ -webkit-transition: background-color 0.2s ease;
1110
+ transition: background-color 0.2s ease;
1111
+
1112
+ -webkit-appearance: none;
1113
+
1114
+ -moz-appearance: none;
1115
+
1116
+ appearance: none;
1117
+ background-color: #D5D5D5;
1118
+ width: 40px;
1119
+ }
1120
+
1121
+ .tribe-common .tribe-common-form-control-toggle__input:after {
1122
+ background-color: #FFFFFF;
1123
+ border: 1px solid #D5D5D5;
1124
+ border-radius: 50%;
1125
+ box-shadow: 0 2px 5px 0 rgba(0,0,0, 0.14);
1126
+ height: 20px;
1127
+ width: 20px;
1128
+
1129
+ content: '';
1130
+ left: 0;
1131
+ position: absolute;
1132
+ top: -5px;
1133
+ -webkit-transition: -webkit-transform 0.2s ease;
1134
+ transition: -webkit-transform 0.2s ease;
1135
+ transition: transform 0.2s ease;
1136
+ transition: transform 0.2s ease, -webkit-transform 0.2s ease;
1137
+ }
1138
+
1139
+ .tribe-common .tribe-common-form-control-toggle__input:checked {
1140
+ background-color: #334AFF;
1141
+ }
1142
+
1143
+ .tribe-common .tribe-common-form-control-toggle__input:checked:after {
1144
+ -webkit-transform: translateX(20px);
1145
+ transform: translateX(20px);
1146
+ }
1147
+
1148
+ .tribe-common .tribe-common-form-control-toggle__label {
1149
+ color: #141827;
1150
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1151
+ font-size: 12px;
1152
+ line-height: 1.38;
1153
+ font-weight: 400;
1154
+
1155
+ color: #727272;
1156
+ }
1157
+
1158
+ /* -----------------------------------------------------------------------------
1159
+ * Theme Overrides - Enfold
1160
+ * ----------------------------------------------------------------------------- */
1161
+
1162
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label {
1163
+ font-weight: 400;
1164
+ font-size: 12px;
1165
+ }
1166
+
1167
+ /* Grid */
1168
+
1169
+ /* .tribe-common { */
1170
+
1171
+ /* -----------------------------------------------------------------------------
1172
+ * Grid: Columns
1173
+ * ----------------------------------------------------------------------------- */
1174
+
1175
+ /* } */
1176
+
1177
+ /* .tribe-common { */
1178
+
1179
+ /* -----------------------------------------------------------------------------
1180
+ *
1181
+ * Grid: Rows
1182
+ *
1183
+ * Example:
1184
+ * <div class="g-row">
1185
+ * <div class="g-col">
1186
+ * <p>Component or another grid layout, perhaps?</p>
1187
+ * </div>
1188
+ * </div>
1189
+ *
1190
+ * ----------------------------------------------------------------------------- */
1191
+
1192
+ /* } */
1193
+
1194
+ /* Typography */
1195
+
1196
+ .tribe-common {
1197
+
1198
+ /* -------------------------------------------------------------------------
1199
+ *
1200
+ * Anchor: Theme Overrides
1201
+ *
1202
+ * ------------------------------------------------------------------------- */
1203
+ }
1204
+
1205
+ .tribe-common a {
1206
+ color: #141827;
1207
+ outline: 0;
1208
+ text-decoration: none;
1209
+ }
1210
+
1211
+ .tribe-common a:hover,
1212
+ .tribe-common a:focus,
1213
+ .tribe-common a:active,
1214
+ .tribe-common a:visited {
1215
+ color: #141827;
1216
+ outline: 0;
1217
+ text-decoration: none;
1218
+ }
1219
+
1220
+ /* -------------------------------------------------------------------------
1221
+ *
1222
+ * Anchor: Theme Overrides
1223
+ *
1224
+ * ------------------------------------------------------------------------- */
1225
+
1226
+ /* -------------------------------------------------------------------------
1227
+ * Theme Overrides - Twenty Seventeen
1228
+ * ------------------------------------------------------------------------- */
1229
+
1230
+ .tribe-theme-twentyseventeen .tribe-common a {
1231
+ box-shadow: none;
1232
+ }
1233
+
1234
+ .tribe-theme-twentyseventeen .tribe-common a:hover,
1235
+ .tribe-theme-twentyseventeen .tribe-common a:focus {
1236
+ box-shadow: none;
1237
+ color: #141827;
1238
+ }
1239
+
1240
+ /* -------------------------------------------------------------------------
1241
+ * Theme Overrides - Twenty Nineteen
1242
+ * ------------------------------------------------------------------------- */
1243
+
1244
+ .tribe-theme-twentynineteen .tribe-common a,
1245
+ .tribe-theme-twentynineteen .entry .tribe-common a {
1246
+ text-decoration: none;
1247
+ }
1248
+
1249
+ /* -------------------------------------------------------------------------
1250
+ *
1251
+ * Anchor
1252
+ *
1253
+ * Example:
1254
+ * <a class="tribe-common-anchor">Anchor Text</a>
1255
+ * <a class="tribe-common-anchor-alt">Anchor Alt Text</a>
1256
+ * <a class="tribe-common-anchor-thin">Anchor Thin Text</a>
1257
+ *
1258
+ * ------------------------------------------------------------------------- */
1259
+
1260
+ .tribe-common .tribe-common-anchor {
1261
+ border-bottom: 2px solid transparent;
1262
+ -webkit-transition: border-color 0.2s ease;
1263
+ transition: border-color 0.2s ease;
1264
+ }
1265
+
1266
+ .tribe-common .tribe-common-anchor:active,
1267
+ .tribe-common .tribe-common-anchor:focus,
1268
+ .tribe-common .tribe-common-anchor:hover {
1269
+ border-bottom: 2px solid #141827;
1270
+ }
1271
+
1272
+ .tribe-common .tribe-common-anchor-alt {
1273
+ border-bottom: 2px solid #334AFF;
1274
+ color: #141827;
1275
+ -webkit-transition: color 0.2s ease;
1276
+ transition: color 0.2s ease;
1277
+ }
1278
+
1279
+ .tribe-common .tribe-common-anchor-alt:active,
1280
+ .tribe-common .tribe-common-anchor-alt:focus,
1281
+ .tribe-common .tribe-common-anchor-alt:hover {
1282
+ border-bottom: 2px solid #334AFF;
1283
+ color: #334AFF;
1284
+ }
1285
+
1286
+ .tribe-common .tribe-common-anchor-thin {
1287
+ border-bottom: 1px solid transparent;
1288
+ -webkit-transition: border-color 0.2s ease;
1289
+ transition: border-color 0.2s ease;
1290
+ }
1291
+
1292
+ .tribe-common .tribe-common-anchor-thin:active,
1293
+ .tribe-common .tribe-common-anchor-thin:focus,
1294
+ .tribe-common .tribe-common-anchor-thin:hover {
1295
+ border-bottom: 1px solid #141827;
1296
+ }
1297
+
1298
+ /* -------------------------------------------------------------------------
1299
+ * Theme Overrides - Twenty Seventeen
1300
+ * ------------------------------------------------------------------------- */
1301
+
1302
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,
1303
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus {
1304
+ color: #334AFF;
1305
+ }
1306
+
1307
+ /* -------------------------------------------------------------------------
1308
+ * Body 1
1309
+ * ------------------------------------------------------------------------- */
1310
+
1311
+ .tribe-common .tribe-common-b1 {
1312
+ color: #141827;
1313
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1314
+ font-size: 14px;
1315
+ font-weight: 400;
1316
+ line-height: 1.62;
1317
+ }
1318
+
1319
+ /* -------------------------------------------------------------------------
1320
+ *
1321
+ * Body
1322
+ *
1323
+ * Example:
1324
+ * <p class="tribe-common-b1">Text here</p>
1325
+ *
1326
+ * ------------------------------------------------------------------------- */
1327
+
1328
+ .tribe-common .tribe-common-b1--bold {
1329
+ font-weight: 700;
1330
+ }
1331
+
1332
+ /* -------------------------------------------------------------------------
1333
+ * Body 2
1334
+ * ------------------------------------------------------------------------- */
1335
+
1336
+ .tribe-common .tribe-common-b2 {
1337
+ color: #141827;
1338
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1339
+ font-size: 12px;
1340
+ font-weight: 400;
1341
+ line-height: 1.38;
1342
+ }
1343
+
1344
+ .tribe-common .tribe-common-b2--bold {
1345
+ font-weight: 700;
1346
+ }
1347
+
1348
+ /* -------------------------------------------------------------------------
1349
+ * Body 3
1350
+ * ------------------------------------------------------------------------- */
1351
+
1352
+ .tribe-common .tribe-common-b3 {
1353
+ color: #141827;
1354
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1355
+ font-size: 11px;
1356
+ font-weight: 400;
1357
+ line-height: 1.5;
1358
+ }
1359
+
1360
+ .tribe-common .tribe-common-b3--bold {
1361
+ font-weight: 700;
1362
+ }
1363
+
1364
+ /* -------------------------------------------------------------------------
1365
+ * Body 1 for --viewport-medium
1366
+ * ------------------------------------------------------------------------- */
1367
+
1368
+ /* -------------------------------------------------------------------------
1369
+ * Body 2 for --viewport-medium
1370
+ * ------------------------------------------------------------------------- */
1371
+
1372
+ /* -------------------------------------------------------------------------
1373
+ * Body 3 for --viewport-medium
1374
+ * ------------------------------------------------------------------------- */
1375
+
1376
+ .tribe-common {
1377
+
1378
+ /* -------------------------------------------------------------------------
1379
+ *
1380
+ * CTA: Theme Overrides
1381
+ *
1382
+ * ------------------------------------------------------------------------- */
1383
+ }
1384
+
1385
+ /* -------------------------------------------------------------------------
1386
+ *
1387
+ * CTA
1388
+ *
1389
+ * Example:
1390
+ * <a class="tribe-common-cta">Link Text</a>
1391
+ * <a class="tribe-common-cta tribe-common-cta--alt">Link Text Alt</a>
1392
+ *
1393
+ * ------------------------------------------------------------------------- */
1394
+
1395
+ .tribe-common .tribe-common-cta {
1396
+ color: #141827;
1397
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1398
+ font-size: 12px;
1399
+ line-height: 1.38;
1400
+ font-weight: 400;
1401
+ font-weight: 700;
1402
+ border-bottom: 2px solid transparent;
1403
+ -webkit-transition: border-color 0.2s ease;
1404
+ transition: border-color 0.2s ease;
1405
+ }
1406
+
1407
+ .tribe-common .tribe-common-cta:active,
1408
+ .tribe-common .tribe-common-cta:focus,
1409
+ .tribe-common .tribe-common-cta:hover {
1410
+ border-bottom: 2px solid #141827;
1411
+ }
1412
+
1413
+ .tribe-common .tribe-common-cta--alt {
1414
+ border-bottom: 2px solid #334AFF;
1415
+ color: #141827;
1416
+ -webkit-transition: color 0.2s ease;
1417
+ transition: color 0.2s ease;
1418
+ }
1419
+
1420
+ .tribe-common .tribe-common-cta--alt:active,
1421
+ .tribe-common .tribe-common-cta--alt:focus,
1422
+ .tribe-common .tribe-common-cta--alt:hover {
1423
+ border-bottom: 2px solid #334AFF;
1424
+ color: #334AFF;
1425
+ }
1426
+
1427
+ .tribe-common .tribe-common-cta--thin-alt {
1428
+ border-bottom: 1px solid #334AFF;
1429
+ color: #141827;
1430
+ -webkit-transition: color 0.2s ease;
1431
+ transition: color 0.2s ease;
1432
+ }
1433
+
1434
+ .tribe-common .tribe-common-cta--thin-alt:active,
1435
+ .tribe-common .tribe-common-cta--thin-alt:focus,
1436
+ .tribe-common .tribe-common-cta--thin-alt:hover {
1437
+ border-bottom: 1px solid #334AFF;
1438
+ color: #334AFF;
1439
+ }
1440
+
1441
+ /* -------------------------------------------------------------------------
1442
+ * Theme Overrides - Twenty Seventeen
1443
+ * ------------------------------------------------------------------------- */
1444
+
1445
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,
1446
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,
1447
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover,
1448
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus {
1449
+ color: #334AFF;
1450
+ }
1451
+
1452
+ .tribe-common {
1453
+ /* -------------------------------------------------------------------------
1454
+ *
1455
+ * Heading
1456
+ *
1457
+ * Example:
1458
+ * <h1 class="tribe-common-h1">Heading Text</h1>
1459
+ *
1460
+ * ------------------------------------------------------------------------- */
1461
+
1462
+ /* -------------------------------------------------------------------------
1463
+ *
1464
+ * Heading: Theme Overrides
1465
+ *
1466
+ * ------------------------------------------------------------------------- */
1467
+ }
1468
+
1469
+ /* -------------------------------------------------------------------------
1470
+ * Heading: h1
1471
+ * ------------------------------------------------------------------------- */
1472
+
1473
+ .tribe-common .tribe-common-h1 {
1474
+ color: #141827;
1475
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1476
+ font-weight: 700;
1477
+ font-size: 28px;
1478
+ line-height: 1.42;
1479
+ }
1480
+
1481
+ /* -------------------------------------------------------------------------
1482
+ * Heading: h2
1483
+ * ------------------------------------------------------------------------- */
1484
+
1485
+ .tribe-common .tribe-common-h2 {
1486
+ color: #141827;
1487
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1488
+ font-weight: 700;
1489
+ font-size: 24px;
1490
+ line-height: 1.42;
1491
+ }
1492
+
1493
+ /* -------------------------------------------------------------------------
1494
+ * Heading: h3
1495
+ * ------------------------------------------------------------------------- */
1496
+
1497
+ .tribe-common .tribe-common-h3 {
1498
+ color: #141827;
1499
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1500
+ font-weight: 700;
1501
+ font-size: 22px;
1502
+ line-height: 1.5;
1503
+ }
1504
+
1505
+ /* -------------------------------------------------------------------------
1506
+ * Heading: h4
1507
+ * ------------------------------------------------------------------------- */
1508
+
1509
+ .tribe-common .tribe-common-h4 {
1510
+ color: #141827;
1511
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1512
+ font-weight: 700;
1513
+ font-size: 20px;
1514
+ line-height: 1.42;
1515
+ }
1516
+
1517
+ /* -------------------------------------------------------------------------
1518
+ * Heading: h5
1519
+ * ------------------------------------------------------------------------- */
1520
+
1521
+ .tribe-common .tribe-common-h5 {
1522
+ color: #141827;
1523
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1524
+ font-weight: 700;
1525
+ font-size: 18px;
1526
+ line-height: 1.5;
1527
+ }
1528
+
1529
+ /* -------------------------------------------------------------------------
1530
+ * Heading: h6
1531
+ * ------------------------------------------------------------------------- */
1532
+
1533
+ .tribe-common .tribe-common-h6 {
1534
+ color: #141827;
1535
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1536
+ font-weight: 700;
1537
+ font-size: 16px;
1538
+ line-height: 1.5;
1539
+ }
1540
+
1541
+ /* -------------------------------------------------------------------------
1542
+ * Heading: h7
1543
+ * ------------------------------------------------------------------------- */
1544
+
1545
+ .tribe-common .tribe-common-h7 {
1546
+ color: #141827;
1547
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1548
+ font-weight: 700;
1549
+ font-size: 14px;
1550
+ line-height: 1.62;
1551
+ }
1552
+
1553
+ /* -------------------------------------------------------------------------
1554
+ * Heading: h8
1555
+ * ------------------------------------------------------------------------- */
1556
+
1557
+ .tribe-common .tribe-common-h8 {
1558
+ color: #141827;
1559
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1560
+ font-weight: 700;
1561
+ font-size: 12px;
1562
+ line-height: 1.38;
1563
+ }
1564
+
1565
+ /* -------------------------------------------------------------------------
1566
+ * Heading: h3 for --viewport-medium
1567
+ * ------------------------------------------------------------------------- */
1568
+
1569
+ /* -------------------------------------------------------------------------
1570
+ * Heading: h4 for --viewport-medium
1571
+ * ------------------------------------------------------------------------- */
1572
+
1573
+ /* -------------------------------------------------------------------------
1574
+ * Heading: h5 for --viewport-medium
1575
+ * ------------------------------------------------------------------------- */
1576
+
1577
+ /* -------------------------------------------------------------------------
1578
+ * Heading: h6 for --viewport-medium
1579
+ * ------------------------------------------------------------------------- */
1580
+
1581
+ /* -------------------------------------------------------------------------
1582
+ * Heading: h7 for --viewport-medium
1583
+ * ------------------------------------------------------------------------- */
1584
+
1585
+ /* -------------------------------------------------------------------------
1586
+ * Heading: alt style
1587
+ * ------------------------------------------------------------------------- */
1588
+
1589
+ .tribe-common .tribe-common-h--alt {
1590
+ font-weight: 400;
1591
+ }
1592
+
1593
+ /* -------------------------------------------------------------------------
1594
+ * Theme Overrides - Avada
1595
+ * ------------------------------------------------------------------------- */
1596
+
1597
+ /* -------------------------------------------------------------------------
1598
+ * Heading: h1
1599
+ * ------------------------------------------------------------------------- */
1600
+
1601
+ .tribe-theme-avada #main .tribe-common .tribe-common-h1 {
1602
+ color: #141827;
1603
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1604
+ font-weight: 700;
1605
+ font-size: 28px;
1606
+ line-height: 1.42;
1607
+ }
1608
+
1609
+ /* -------------------------------------------------------------------------
1610
+ * Heading: h2
1611
+ * ------------------------------------------------------------------------- */
1612
+
1613
+ .tribe-theme-avada #main .tribe-common .tribe-common-h2 {
1614
+ color: #141827;
1615
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1616
+ font-weight: 700;
1617
+ font-size: 24px;
1618
+ line-height: 1.42;
1619
+ }
1620
+
1621
+ /* -------------------------------------------------------------------------
1622
+ * Heading: h3
1623
+ * ------------------------------------------------------------------------- */
1624
+
1625
+ .tribe-theme-avada #main .tribe-common .tribe-common-h3 {
1626
+ color: #141827;
1627
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1628
+ font-weight: 700;
1629
+ font-size: 22px;
1630
+ line-height: 1.5;
1631
+ }
1632
+
1633
+ /* -------------------------------------------------------------------------
1634
+ * Heading: h4
1635
+ * ------------------------------------------------------------------------- */
1636
+
1637
+ .tribe-theme-avada #main .tribe-common .tribe-common-h4 {
1638
+ color: #141827;
1639
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1640
+ font-weight: 700;
1641
+ font-size: 20px;
1642
+ line-height: 1.42;
1643
+ }
1644
+
1645
+ /* -------------------------------------------------------------------------
1646
+ * Heading: h5
1647
+ * ------------------------------------------------------------------------- */
1648
+
1649
+ .tribe-theme-avada #main .tribe-common .tribe-common-h5 {
1650
+ color: #141827;
1651
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1652
+ font-weight: 700;
1653
+ font-size: 18px;
1654
+ line-height: 1.5;
1655
+ }
1656
+
1657
+ /* -------------------------------------------------------------------------
1658
+ * Heading: h6
1659
+ * ------------------------------------------------------------------------- */
1660
+
1661
+ .tribe-theme-avada #main .tribe-common .tribe-common-h6 {
1662
+ color: #141827;
1663
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1664
+ font-weight: 700;
1665
+ font-size: 16px;
1666
+ line-height: 1.5;
1667
+ }
1668
+
1669
+ /* -------------------------------------------------------------------------
1670
+ * Heading: h7
1671
+ * ------------------------------------------------------------------------- */
1672
+
1673
+ .tribe-theme-avada #main .tribe-common .tribe-common-h7 {
1674
+ color: #141827;
1675
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1676
+ font-weight: 700;
1677
+ font-size: 14px;
1678
+ line-height: 1.62;
1679
+ }
1680
+
1681
+ /* -------------------------------------------------------------------------
1682
+ * Heading: h8
1683
+ * ------------------------------------------------------------------------- */
1684
+
1685
+ .tribe-theme-avada #main .tribe-common .tribe-common-h8 {
1686
+ color: #141827;
1687
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1688
+ font-weight: 700;
1689
+ font-size: 12px;
1690
+ line-height: 1.38;
1691
+ }
1692
+
1693
+ /* -------------------------------------------------------------------------
1694
+ * Heading: h3 for --viewport-medium
1695
+ * ------------------------------------------------------------------------- */
1696
+
1697
+ /* -------------------------------------------------------------------------
1698
+ * Heading: h4 for --viewport-medium
1699
+ * ------------------------------------------------------------------------- */
1700
+
1701
+ /* -------------------------------------------------------------------------
1702
+ * Heading: h5 for --viewport-medium
1703
+ * ------------------------------------------------------------------------- */
1704
+
1705
+ /* -------------------------------------------------------------------------
1706
+ * Heading: h6 for --viewport-medium
1707
+ * ------------------------------------------------------------------------- */
1708
+
1709
+ /* -------------------------------------------------------------------------
1710
+ * Heading: h7 for --viewport-medium
1711
+ * ------------------------------------------------------------------------- */
1712
+
1713
+ /* -------------------------------------------------------------------------
1714
+ * Heading: alt style
1715
+ * ------------------------------------------------------------------------- */
1716
+
1717
+ .tribe-theme-avada #main .tribe-common .tribe-common-h--alt {
1718
+ font-weight: 400;
1719
+ }
1720
+
1721
+ .tribe-common {
1722
+ /* -------------------------------------------------------------------------
1723
+ * Lists
1724
+ * ------------------------------------------------------------------------- */
1725
+
1726
+ /* -----------------------------------------------------------------------------
1727
+ *
1728
+ * Lists: Theme Overrides
1729
+ *
1730
+ * ----------------------------------------------------------------------------- */
1731
+ }
1732
+
1733
+ /* -------------------------------------------------------------------------
1734
+ * Button
1735
+ * ------------------------------------------------------------------------- */
1736
+
1737
+ .tribe-common button {
1738
+ background-color: transparent;
1739
+ border: none;
1740
+ }
1741
+
1742
+ .tribe-common button:hover,
1743
+ .tribe-common button:focus {
1744
+ background-color: transparent;
1745
+ }
1746
+
1747
+ /* -------------------------------------------------------------------------
1748
+ * Theme Overrides - Twenty Seventeen
1749
+ * ------------------------------------------------------------------------- */
1750
+
1751
+ .tribe-theme-twentyseventeen .tribe-common button:hover,
1752
+ .tribe-theme-twentyseventeen .tribe-common button:focus {
1753
+ background-color: transparent;
1754
+ }
1755
+
1756
+ /* -------------------------------------------------------------------------
1757
+ *
1758
+ * Button: Theme Overrides
1759
+ *
1760
+ * ------------------------------------------------------------------------- */
1761
+
1762
+ .tribe-theme-twentytwenty .tribe-common button {
1763
+ background-color: transparent;
1764
+ text-transform: inherit;
1765
+ }
1766
+
1767
+ .tribe-theme-twentytwenty .tribe-common button:hover,
1768
+ .tribe-theme-twentytwenty .tribe-common button:focus {
1769
+ text-decoration: none;
1770
+ }
1771
+
1772
+ /* .tribe-common { */
1773
+
1774
+ /* -----------------------------------------------------------------------------
1775
+ *
1776
+ * Layout: Global Content Container
1777
+ *
1778
+ * ----------------------------------------------------------------------------- */
1779
+
1780
+ /* } */
1781
+
1782
+ /* -------------------------------------------------------------------------
1783
+ * SVG Icons
1784
+ * ------------------------------------------------------------------------- */
1785
+
1786
+ .tribe-common .tribe-common-svgicon--featured {
1787
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E");
1788
+ }
1789
+
1790
+ .tribe-common {
1791
+ /* -----------------------------------------------------------------------------
1792
+ *
1793
+ * Tables
1794
+ *
1795
+ * ----------------------------------------------------------------------------- */
1796
+
1797
+ /* -----------------------------------------------------------------------------
1798
+ * Tables: Theme Overrides
1799
+ * ----------------------------------------------------------------------------- */
1800
+ }
1801
+
1802
+ /* -----------------------------------------------------------------------------
1803
+ * Theme Overrides - Enfold
1804
+ * ----------------------------------------------------------------------------- */
1805
+
1806
+ .tribe-theme-enfold .tribe-common th {
1807
+ letter-spacing: 0;
1808
+ text-transform: none;
1809
+ }
1810
+
1811
+ /* Components */
1812
+
1813
+ /* -----------------------------------------------------------------------------
1814
+ *
1815
+ * Components Full
1816
+ *
1817
+ * This file is just a clearing-house.
1818
+ * Make partials (start with an underscore) for any actual css code.
1819
+ *
1820
+ * ----------------------------------------------------------------------------- */
1821
+
1822
+ /* Buttons */
1823
+
1824
+ .tribe-common {
1825
+
1826
+ /* -------------------------------------------------------------------------
1827
+ *
1828
+ * Button: Border - Theme Overrides
1829
+ *
1830
+ * ------------------------------------------------------------------------- */
1831
+ }
1832
+
1833
+ /* -----------------------------------------------------------------------------
1834
+ *
1835
+ * Button: Border
1836
+ *
1837
+ * Example:
1838
+ * <button class="tribe-common-c-btn-border">...</button>
1839
+ * <a href="#" class="tribe-common-c-btn-border">...</a>
1840
+ *
1841
+ * ----------------------------------------------------------------------------- */
1842
+
1843
+ .tribe-common .tribe-common-c-btn-border,
1844
+ .tribe-common a.tribe-common-c-btn-border {
1845
+ color: #141827;
1846
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
1847
+ font-size: 12px;
1848
+ line-height: 1.38;
1849
+ font-weight: 400;
1850
+ border: 0;
1851
+ cursor: pointer;
1852
+ display: inline-block;
1853
+ height: auto;
1854
+ padding: 0;
1855
+ text-decoration: none;
1856
+ width: auto;
1857
+ background-color: #FFFFFF;
1858
+ border: 1px solid #D5D5D5;
1859
+ border-radius: 4px;
1860
+ text-align: center;
1861
+ -webkit-transition: color 0.2s ease, border-color 0.2s ease;
1862
+ transition: color 0.2s ease, border-color 0.2s ease;
1863
+
1864
+ color: #727272;
1865
+ padding: 14px 20px 14px;
1866
+ }
1867
+
1868
+ .tribe-common .tribe-common-c-btn-border:hover,
1869
+ .tribe-common .tribe-common-c-btn-border:focus,
1870
+ .tribe-common a.tribe-common-c-btn-border:hover,
1871
+ .tribe-common a.tribe-common-c-btn-border:focus {
1872
+ background-color: #FFFFFF;
1873
+ }
1874
+
1875
+ .tribe-common .tribe-common-c-btn-border:active, .tribe-common a.tribe-common-c-btn-border:active {
1876
+ border-color: #141827;
1877
+ }
1878
+
1879
+ .tribe-common .tribe-common-c-btn-border:active,
1880
+ .tribe-common .tribe-common-c-btn-border:focus,
1881
+ .tribe-common .tribe-common-c-btn-border:hover,
1882
+ .tribe-common a.tribe-common-c-btn-border:active,
1883
+ .tribe-common a.tribe-common-c-btn-border:focus,
1884
+ .tribe-common a.tribe-common-c-btn-border:hover {
1885
+ color: #141827;
1886
+ }
1887
+
1888
+ .tribe-common .tribe-common-c-btn-border:disabled, .tribe-common a.tribe-common-c-btn-border:disabled {
1889
+ color: #D5D5D5
1890
+ }
1891
+
1892
+ /* -------------------------------------------------------------------------
1893
+ * Theme Overrides - Twenty Seventeen
1894
+ * ------------------------------------------------------------------------- */
1895
+
1896
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover {
1897
+ background-color: #FFFFFF;
1898
+ }
1899
+
1900
+ .tribe-common {
1901
+
1902
+ /* -----------------------------------------------------------------------------
1903
+ * Button: Icon Caret Left
1904
+ * ----------------------------------------------------------------------------- */
1905
+
1906
+ /* -----------------------------------------------------------------------------
1907
+ * Button: Icon Caret Right
1908
+ * ----------------------------------------------------------------------------- */
1909
+
1910
+ /* -----------------------------------------------------------------------------
1911
+ * Button: Icon Filters
1912
+ * ----------------------------------------------------------------------------- */
1913
+
1914
+ /* -----------------------------------------------------------------------------
1915
+ * Button: Icon Search
1916
+ * ----------------------------------------------------------------------------- */
1917
+
1918
+ /* -------------------------------------------------------------------------
1919
+ *
1920
+ * Button: Icon Border - Theme Overrides
1921
+ *
1922
+ * ------------------------------------------------------------------------- */
1923
+ }
1924
+
1925
+ /* -----------------------------------------------------------------------------
1926
+ *
1927
+ * Button: Icon
1928
+ *
1929
+ * Example:
1930
+ * <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</button>
1931
+ * <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</a>
1932
+ *
1933
+ * ----------------------------------------------------------------------------- */
1934
+
1935
+ .tribe-common .tribe-common-c-btn-icon {
1936
+ border: 0;
1937
+ cursor: pointer;
1938
+ display: inline-block;
1939
+ height: auto;
1940
+ padding: 0;
1941
+ text-decoration: none;
1942
+ width: auto;
1943
+ }
1944
+
1945
+ /* -----------------------------------------------------------------------------
1946
+ *
1947
+ * Button: Icon Border
1948
+ *
1949
+ * Example:
1950
+ * <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</button>
1951
+ * <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</a>
1952
+ *
1953
+ * ----------------------------------------------------------------------------- */
1954
+
1955
+ .tribe-common .tribe-common-c-btn-icon--border {
1956
+ background-color: #FFFFFF;
1957
+ border: 1px solid #D5D5D5;
1958
+ -webkit-box-align: center;
1959
+ align-items: center;
1960
+ display: -webkit-inline-box;
1961
+ display: inline-flex;
1962
+ height: 56px;
1963
+ -webkit-box-pack: center;
1964
+ justify-content: center;
1965
+ -webkit-transition: none;
1966
+ transition: none;
1967
+ width: 56px;
1968
+ }
1969
+
1970
+ .tribe-common .tribe-common-c-btn-icon--border:hover,
1971
+ .tribe-common .tribe-common-c-btn-icon--border:focus {
1972
+ background-color: #FFFFFF;
1973
+ }
1974
+
1975
+ .tribe-common .tribe-common-c-btn-icon--border:active {
1976
+ border-color: #141827;
1977
+ }
1978
+
1979
+ /* -------------------------------------------------------------------------
1980
+ * Theme Overrides - Twenty Seventeen
1981
+ * ------------------------------------------------------------------------- */
1982
+
1983
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover {
1984
+ background-color: #FFFFFF;
1985
+ }
1986
+
1987
+ .tribe-common {
1988
+
1989
+ /* -------------------------------------------------------------------------
1990
+ *
1991
+ * Button: Solid - Theme Overrides
1992
+ *
1993
+ * ------------------------------------------------------------------------- */
1994
+ }
1995
+
1996
+ /* -----------------------------------------------------------------------------
1997
+ *
1998
+ * Button: Solid
1999
+ *
2000
+ * Example:
2001
+ * <button class="tribe-common-c-btn">...</button>
2002
+ * <a href="#" class="tribe-common-c-btn">...</a>
2003
+ *
2004
+ * ----------------------------------------------------------------------------- */
2005
+
2006
+ .tribe-common .tribe-common-c-btn,
2007
+ .tribe-common a.tribe-common-c-btn {
2008
+ color: #141827;
2009
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
2010
+ font-size: 14px;
2011
+ line-height: 1.62;
2012
+ font-weight: 400;
2013
+ font-weight: 700;
2014
+ border: 0;
2015
+ cursor: pointer;
2016
+ display: inline-block;
2017
+ height: auto;
2018
+ padding: 0;
2019
+ text-decoration: none;
2020
+ width: auto;
2021
+ border-radius: 4px;
2022
+ color: #FFFFFF;
2023
+ text-align: center;
2024
+ -webkit-transition: background-color 0.2s ease;
2025
+ transition: background-color 0.2s ease;
2026
+
2027
+ padding: 11px 20px 11px;
2028
+ background-color: #334AFF;
2029
+ }
2030
+
2031
+ .tribe-common .tribe-common-c-btn:focus,
2032
+ .tribe-common .tribe-common-c-btn:hover,
2033
+ .tribe-common a.tribe-common-c-btn:focus,
2034
+ .tribe-common a.tribe-common-c-btn:hover {
2035
+ background-color: rgba(51,74,255, 0.8);
2036
+ }
2037
+
2038
+ .tribe-common .tribe-common-c-btn:active, .tribe-common a.tribe-common-c-btn:active {
2039
+ background-color: rgba(51,74,255, 0.9);
2040
+ }
2041
+
2042
+ .tribe-common .tribe-common-c-btn:disabled, .tribe-common a.tribe-common-c-btn:disabled {
2043
+ background-color: rgba(51,74,255, 0.07);
2044
+ }
2045
+
2046
+ /* -------------------------------------------------------------------------
2047
+ * Theme Overrides - Twenty Seventeen
2048
+ * ------------------------------------------------------------------------- */
2049
+
2050
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover,
2051
+ .tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus {
2052
+ background-color: rgba(51,74,255, 0.8);
2053
+ color: #FFFFFF;
2054
+ }
2055
+
2056
+ /* -------------------------------------------------------------------------
2057
+ * Theme Overrides - Twenty Twenty
2058
+ * ------------------------------------------------------------------------- */
2059
+
2060
+ .tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn {
2061
+ background-color: #334AFF;
2062
+ }
2063
+
2064
+ .tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover,
2065
+ .tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus {
2066
+ background-color: rgba(51,74,255, 0.8);
2067
+ color: #FFFFFF;
2068
+ }
2069
+
2070
+ /* .tribe-common { */
2071
+
2072
+ /* -----------------------------------------------------------------------------
2073
+ *
2074
+ * Component: Image
2075
+ *
2076
+ * Example (Regular):
2077
+ * <img src="#" alt="" class="tribe-common-c-image" />
2078
+ *
2079
+ * Example (Background):
2080
+ * <div class="tribe-common-c-image tribe-common-c-image--bg">
2081
+ * <div class="tribe-common-c-image__bg"></div>
2082
+ * </div>
2083
+ *
2084
+ * ----------------------------------------------------------------------------- */
2085
+
2086
+ /* } */
2087
+
2088
+ /* -----------------------------------------------------------------------------
2089
+ *
2090
+ * Component: Loader
2091
+ *
2092
+ *
2093
+ * Example:
2094
+ * <div class="tribe-events-view-loader__dots tribe-common-c-loader">
2095
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--first"></div>
2096
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--second"></div>
2097
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--third"></div>
2098
+ * </div>
2099
+ *
2100
+ * ----------------------------------------------------------------------------- */
2101
+
2102
+ .tribe-common .tribe-common-c-loader__dot {
2103
+ -webkit-animation-name: tribe-common-c-loader-bounce;
2104
+ animation-name: tribe-common-c-loader-bounce;
2105
+ -webkit-animation-duration: 2.24s;
2106
+ animation-duration: 2.24s;
2107
+ -webkit-animation-iteration-count: infinite;
2108
+ animation-iteration-count: infinite;
2109
+ -webkit-animation-direction: normal;
2110
+ animation-direction: normal;
2111
+ }
2112
+
2113
+ .tribe-common .tribe-common-c-loader__dot--first {
2114
+ -webkit-animation-delay: 0.45s;
2115
+ animation-delay: 0.45s;
2116
+ }
2117
+
2118
+ .tribe-common .tribe-common-c-loader__dot--second {
2119
+ -webkit-animation-delay: 1.05s;
2120
+ animation-delay: 1.05s;
2121
+ }
2122
+
2123
+ .tribe-common .tribe-common-c-loader__dot--third {
2124
+ -webkit-animation-delay: 1.35s;
2125
+ animation-delay: 1.35s;
2126
+ }
2127
+
2128
+ @-webkit-keyframes tribe-common-c-loader-bounce {
2129
+ 0% {}
2130
+
2131
+ 50% { background-color: #334AFF; }
2132
+
2133
+ 100% {}
2134
+ }
2135
+
2136
+ @keyframes tribe-common-c-loader-bounce {
2137
+ 0% {}
2138
+
2139
+ 50% { background-color: #334AFF; }
2140
+
2141
+ 100% {}
2142
+ }
2143
+
2144
+ @media (min-width: 768px) {
2145
+
2146
+ .tribe-common .tribe-common-form-control-text__input {
2147
+ color: #141827;
2148
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
2149
+ font-size: 14px;
2150
+ line-height: 1.62;
2151
+ font-weight: 400;
2152
+
2153
+ border: 0
2154
+ }
2155
+
2156
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
2157
+ color: #141827;
2158
+ font-family: "Helvetica Neue", Helvetica, -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
2159
+ font-size: 14px;
2160
+ line-height: 1.62;
2161
+ font-weight: 400;
2162
+
2163
+ border: 0
2164
+ }
2165
+
2166
+ .tribe-common .tribe-common-b1 {
2167
+ font-size: 16px;
2168
+ line-height: 1.62
2169
+ }
2170
+
2171
+ .tribe-common .tribe-common-b2 {
2172
+ font-size: 14px;
2173
+ line-height: 1.62
2174
+ }
2175
+
2176
+ .tribe-common .tribe-common-b3 {
2177
+ font-size: 12px;
2178
+ line-height: 1.38
2179
+ }
2180
+
2181
+ .tribe-common .tribe-common-b1--min-medium {
2182
+ font-size: 16px;
2183
+ line-height: 1.62
2184
+ }
2185
+
2186
+ .tribe-common .tribe-common-b2--min-medium {
2187
+ font-size: 14px;
2188
+ line-height: 1.62
2189
+ }
2190
+
2191
+ .tribe-common .tribe-common-b3--min-medium {
2192
+ font-size: 12px;
2193
+ line-height: 1.38
2194
+ }
2195
+
2196
+ .tribe-common .tribe-common-h1 {
2197
+ font-size: 42px;
2198
+ line-height: 1.38
2199
+ }
2200
+
2201
+ .tribe-common .tribe-common-h2 {
2202
+ font-size: 32px;
2203
+ line-height: 1.38
2204
+ }
2205
+
2206
+ .tribe-common .tribe-common-h3 {
2207
+ font-size: 28px;
2208
+ line-height: 1.42
2209
+ }
2210
+
2211
+ .tribe-common .tribe-common-h4 {
2212
+ font-size: 24px;
2213
+ line-height: 1.42
2214
+ }
2215
+
2216
+ .tribe-common .tribe-common-h6 {
2217
+ font-size: 16px;
2218
+ line-height: 1.62
2219
+ }
2220
+
2221
+ .tribe-common .tribe-common-h3--min-medium {
2222
+ font-size: 28px;
2223
+ line-height: 1.42
2224
+ }
2225
+
2226
+ .tribe-common .tribe-common-h4--min-medium {
2227
+ font-size: 24px;
2228
+ line-height: 1.42
2229
+ }
2230
+
2231
+ .tribe-common .tribe-common-h5--min-medium {
2232
+ font-size: 18px;
2233
+ line-height: 1.5
2234
+ }
2235
+
2236
+ .tribe-common .tribe-common-h6--min-medium {
2237
+ font-size: 16px;
2238
+ line-height: 1.62
2239
+ }
2240
+
2241
+ .tribe-common .tribe-common-h7--min-medium {
2242
+ font-size: 14px;
2243
+ line-height: 1.62
2244
+ }
2245
+
2246
+ .tribe-theme-avada #main .tribe-common .tribe-common-h1 {
2247
+ font-size: 42px;
2248
+ line-height: 1.38
2249
+ }
2250
+
2251
+ .tribe-theme-avada #main .tribe-common .tribe-common-h2 {
2252
+ font-size: 32px;
2253
+ line-height: 1.38
2254
+ }
2255
+
2256
+ .tribe-theme-avada #main .tribe-common .tribe-common-h3 {
2257
+ font-size: 28px;
2258
+ line-height: 1.42
2259
+ }
2260
+
2261
+ .tribe-theme-avada #main .tribe-common .tribe-common-h4 {
2262
+ font-size: 24px;
2263
+ line-height: 1.42
2264
+ }
2265
+
2266
+ .tribe-theme-avada #main .tribe-common .tribe-common-h6 {
2267
+ font-size: 16px;
2268
+ line-height: 1.62
2269
+ }
2270
+
2271
+ .tribe-theme-avada #main .tribe-common .tribe-common-h3--min-medium {
2272
+ font-size: 28px;
2273
+ line-height: 1.42
2274
+ }
2275
+
2276
+ .tribe-theme-avada #main .tribe-common .tribe-common-h4--min-medium {
2277
+ font-size: 24px;
2278
+ line-height: 1.42
2279
+ }
2280
+
2281
+ .tribe-theme-avada #main .tribe-common .tribe-common-h5--min-medium {
2282
+ font-size: 18px;
2283
+ line-height: 1.5
2284
+ }
2285
+
2286
+ .tribe-theme-avada #main .tribe-common .tribe-common-h6--min-medium {
2287
+ font-size: 16px;
2288
+ line-height: 1.62
2289
+ }
2290
+
2291
+ .tribe-theme-avada #main .tribe-common .tribe-common-h7--min-medium {
2292
+ font-size: 14px;
2293
+ line-height: 1.62
2294
+ }
2295
+
2296
+ .tribe-common .tribe-common-c-btn-border,
2297
+ .tribe-common a.tribe-common-c-btn-border {
2298
+ padding: 6px 15px
2299
+ }
2300
+ }
common/src/resources/css/common-full.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;line-height:normal;-webkit-font-smoothing:antialiased}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{outline:0;border-radius:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{opacity:1}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:#fff;letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;color:#5d5d5d}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #141827;height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border:1px solid #141827}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:#141827}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFF'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:#fff;border-radius:50%;content:"";display:block;height:8px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}#top .main_color .tribe-common .tribe-common-form-control-checkbox__label,#top .main_color .tribe-common .tribe-common-form-control-radio__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-weight:400;font-size:14px}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:#334aff;border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#5d5d5d}#top .main_color .tribe-common .tribe-common-form-control-slider__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label{font-weight:400;font-size:12px}.tribe-common .tribe-common-form-control-text__input{font-size:16px;border:0;border-bottom:1px solid #d5d5d5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;line-height:1.62;font-weight:400}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{font-size:14px;border:0}.tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input::-moz-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder,.tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input::placeholder{color:#5d5d5d;font-style:normal;opacity:1}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:#141827}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;background:#fff;border:0;border-bottom:1px solid #d5d5d5}#top .main_color .tribe-common .tribe-common-form-control-text__input:focus,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;box-shadow:none}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;border:0}.tribe-common .tribe-common-form-control-toggle{line-height:0}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#d5d5d5;width:40px}.tribe-common .tribe-common-form-control-toggle__input:after{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;content:"";left:0;position:absolute;top:-5px;transition:transform .2s ease}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:#334aff}.tribe-common .tribe-common-form-control-toggle__input:checked:after{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#5d5d5d}#top .main_color .tribe-common .tribe-common-form-control-toggle__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label{font-weight:400;font-size:12px}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:#141827;outline:0;text-decoration:none}.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:#141827}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a{text-decoration:none}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid #141827}.tribe-common .tribe-common-anchor-thin-alt{border-bottom:1px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-thin-alt:active,.tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-common .tribe-common-anchor-thin-alt:hover{border-bottom:1px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-thin-alt:hover{color:#334aff}.tribe-common .tribe-common-b1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1{font-size:16px;line-height:1.62}.tribe-common .tribe-common-b1--bold{font-weight:700}.tribe-common .tribe-common-b2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.38}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2{font-size:14px;line-height:1.62}.tribe-common .tribe-common-b2--bold{font-weight:700}.tribe-common .tribe-common-b3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:11px;font-weight:400;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3{font-size:12px;line-height:1.38}.tribe-common .tribe-common-b3--bold{font-weight:700}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b1--min-medium{font-size:16px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b2--min-medium{font-size:14px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-b3--min-medium{font-size:12px;line-height:1.38}.tribe-common .tribe-common-cta{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;font-weight:700;border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-cta--thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta--thin:active,.tribe-common .tribe-common-cta--thin:focus,.tribe-common .tribe-common-cta--thin:hover{border-bottom:1px solid #141827}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:#334aff}.tribe-common .tribe-common-h1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:28px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:24px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-common .tribe-common-h3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:22px;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:20px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h5{font-size:18px}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-common .tribe-common-h6{font-size:16px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-common--breakpoint-medium.tribe-common .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h--alt{font-weight:400}.tribe-theme-avada #main .tribe-common .tribe-common-h1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:22px;line-height:1.5}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;font-size:20px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:18px}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common.tribe-common--breakpoint-medium .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:400}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E")}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:#fff;border:1px solid #d5d5d5;border-radius:4px;text-align:center;transition:color .2s ease,border-color .2s ease;color:#5d5d5d;padding:14px 20px}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{border-color:#141827}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{padding:6px 15px}.tribe-common .tribe-common-c-btn-border:active,.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{color:#141827}.tribe-common .tribe-common-c-btn-border:disabled,.tribe-common a.tribe-common-c-btn-border:disabled{color:#d5d5d5}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--border{background-color:#fff;border:1px solid #d5d5d5;align-items:center;display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:#141827}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;font-weight:700;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:4px;color:#fff;text-align:center;transition:background-color .2s ease;background-color:#334aff;padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:rgba(51,74,255,.9)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:rgba(51,74,255,.07)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:#334aff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-common .tribe-common-c-loader__dot{animation-name:a;animation-duration:2.24s;animation-iteration-count:infinite;animation-direction:normal}.tribe-common .tribe-common-c-loader__dot--first{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third{animation-delay:1.35s}@keyframes a{50%{background-color:#334aff}}
1
+ .tribe-common figure{line-height:0}.tribe-common figcaption{line-height:normal}.tribe-common a{background-color:transparent;-webkit-text-decoration-skip:objects}.tribe-common abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.tribe-common code,.tribe-common kbd,.tribe-common pre,.tribe-common samp{font-family:monospace;font-size:1em}.tribe-common b,.tribe-common strong{font-weight:inherit;font-weight:bolder}.tribe-common dfn{font-style:italic}.tribe-common mark{background-color:#ff0;color:#000}.tribe-common small{font-size:80%}.tribe-common sub,.tribe-common sup{font-size:75%;line-height:0}.tribe-common hr{border:0;height:0}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=email],.tribe-common input[type=password],.tribe-common input[type=reset],.tribe-common input[type=search],.tribe-common input[type=submit],.tribe-common input[type=text],.tribe-common input[type=url],.tribe-common textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none}.tribe-common button,.tribe-common input,.tribe-common optgroup,.tribe-common select,.tribe-common textarea{color:inherit;font:inherit;line-height:normal;-webkit-font-smoothing:antialiased}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{outline:0;border-radius:0}.tribe-common select:-moz-focusring{color:transparent;text-shadow:0 0 0 #000}.tribe-common optgroup{font-weight:700}.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common p{font-weight:400;text-rendering:optimizeLegibility}.tribe-theme-twentynineteen .tribe-common h1:before,.tribe-theme-twentynineteen .tribe-common h2:before{content:none}.tribe-theme-twentynineteen .tribe-common button,.tribe-theme-twentynineteen .tribe-common input[type=button],.tribe-theme-twentynineteen .tribe-common input[type=reset],.tribe-theme-twentynineteen .tribe-common input[type=submit]{outline:none}.tribe-theme-twentynineteen .tribe-common td,.tribe-theme-twentynineteen .tribe-common th{word-break:normal}.tribe-theme-twentyseventeen .tribe-common h5{letter-spacing:normal;text-transform:none}.tribe-theme-twentyseventeen .tribe-common input[type=text]{border-radius:0}.tribe-theme-twentytwenty .tribe-common{background-color:#fff;letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common input,.tribe-theme-twentytwenty .tribe-common textarea{letter-spacing:normal}.tribe-theme-twentytwenty .tribe-common *{word-break:normal}.tribe-common .tribe-common-form-control-checkbox,.tribe-common .tribe-common-form-control-radio{line-height:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;color:#727272}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border:1px solid #141827;height:20px;position:relative;width:20px}.tribe-common .tribe-common-form-control-checkbox__input:active,.tribe-common .tribe-common-form-control-checkbox__input:focus,.tribe-common .tribe-common-form-control-checkbox__input:hover,.tribe-common .tribe-common-form-control-radio__input:active,.tribe-common .tribe-common-form-control-radio__input:focus,.tribe-common .tribe-common-form-control-radio__input:hover{border:1px solid #141827}.tribe-common .tribe-common-form-control-checkbox__input:checked,.tribe-common .tribe-common-form-control-radio__input:checked{background-color:#141827}.tribe-common .tribe-common-form-control-checkbox__input:checked:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='9' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.6.1L3.9 6.8 1.4 4.3c-.1-.1-.3-.1-.4 0l-.8.8c-.1.1-.1.3 0 .4l3.4 3.4c.2.1.4.1.5 0l7.7-7.7c.1-.1.1-.3 0-.4L11 .1c-.1-.1-.3-.1-.4 0z' fill='%23FFF'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;content:"";display:block;height:9px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:12px}.tribe-common .tribe-common-form-control-radio__input{border-radius:50%}.tribe-common .tribe-common-form-control-radio__input:checked:before{background-color:#fff;border-radius:50%;content:"";display:block;height:8px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:8px}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__label,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-radio__label{font-weight:400;font-size:14px}.tribe-common .tribe-common-form-control-slider{line-height:0}.tribe-common .tribe-common-form-control-slider__input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-runnable-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-moz-range-track{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;background-color:#334aff}.tribe-common .tribe-common-form-control-slider__input::-ms-track{background-color:transparent;border-color:transparent;border-width:5px 0;color:transparent;height:10px}.tribe-common .tribe-common-form-control-slider__input::-ms-fill-lower,.tribe-common .tribe-common-form-control-slider__input::-ms-fill-upper{background-color:#334aff;border-radius:10px}.tribe-common .tribe-common-form-control-slider__input::-webkit-slider-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;-webkit-appearance:none;appearance:none}.tribe-common .tribe-common-form-control-slider__input::-moz-range-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px}.tribe-common .tribe-common-form-control-slider__input::-ms-thumb{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;margin-top:-5px;box-shadow:none;margin-top:-1px}.tribe-common .tribe-common-form-control-slider__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#727272}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-slider__label{font-weight:400;font-size:12px}.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;border:0;border-bottom:1px solid #d5d5d5}.tribe-common .tribe-common-form-control-text__input::-webkit-input-placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input::-moz-placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input:-ms-input-placeholder,.tribe-common .tribe-common-form-control-text__input::-ms-input-placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input::placeholder{color:#727272;font-style:normal}.tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;outline:0}.tribe-theme-twentyseventeen .tribe-common .tribe-common-form-control-text__input{color:#141827}.tribe-theme-twentytwenty .tribe-common .tribe-common-form-control-text__input{line-height:inherit}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:16px;line-height:1.62;font-weight:400;border:0;border-bottom:1px solid #d5d5d5}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input:focus{border-bottom-color:#141827;box-shadow:none}.tribe-common .tribe-common-form-control-toggle{line-height:0}.tribe-common .tribe-common-form-control-toggle__input{border:none;border-radius:5px;height:10px;margin:5px 0;padding:0;position:relative;transition:background-color .2s ease;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#d5d5d5;width:40px}.tribe-common .tribe-common-form-control-toggle__input:after{background-color:#fff;border:1px solid #d5d5d5;border-radius:50%;box-shadow:0 2px 5px 0 rgba(0,0,0,.14);height:20px;width:20px;content:"";left:0;position:absolute;top:-5px;transition:transform .2s ease}.tribe-common .tribe-common-form-control-toggle__input:checked{background-color:#334aff}.tribe-common .tribe-common-form-control-toggle__input:checked:after{transform:translateX(20px)}.tribe-common .tribe-common-form-control-toggle__label{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;color:#727272}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__label{font-weight:400;font-size:12px}.tribe-common a,.tribe-common a:active,.tribe-common a:focus,.tribe-common a:hover,.tribe-common a:visited{color:#141827;outline:0;text-decoration:none}.tribe-theme-twentyseventeen .tribe-common a{box-shadow:none}.tribe-theme-twentyseventeen .tribe-common a:focus,.tribe-theme-twentyseventeen .tribe-common a:hover{box-shadow:none;color:#141827}.tribe-theme-twentynineteen .entry .tribe-common a,.tribe-theme-twentynineteen .tribe-common a{text-decoration:none}.tribe-common .tribe-common-anchor{border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor:active,.tribe-common .tribe-common-anchor:focus,.tribe-common .tribe-common-anchor:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-anchor-alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-anchor-alt:active,.tribe-common .tribe-common-anchor-alt:focus,.tribe-common .tribe-common-anchor-alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-anchor-thin{border-bottom:1px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-anchor-thin:active,.tribe-common .tribe-common-anchor-thin:focus,.tribe-common .tribe-common-anchor-thin:hover{border-bottom:1px solid #141827}.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-anchor-alt:hover{color:#334aff}.tribe-common .tribe-common-b1{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.62}.tribe-common .tribe-common-b1--bold{font-weight:700}.tribe-common .tribe-common-b2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.38}.tribe-common .tribe-common-b2--bold{font-weight:700}.tribe-common .tribe-common-b3{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:11px;font-weight:400;line-height:1.5}.tribe-common .tribe-common-b3--bold{font-weight:700}.tribe-common .tribe-common-cta{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;font-weight:700;border-bottom:2px solid transparent;transition:border-color .2s ease}.tribe-common .tribe-common-cta:active,.tribe-common .tribe-common-cta:focus,.tribe-common .tribe-common-cta:hover{border-bottom:2px solid #141827}.tribe-common .tribe-common-cta--alt{border-bottom:2px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--alt:active,.tribe-common .tribe-common-cta--alt:focus,.tribe-common .tribe-common-cta--alt:hover{border-bottom:2px solid #334aff;color:#334aff}.tribe-common .tribe-common-cta--thin-alt{border-bottom:1px solid #334aff;color:#141827;transition:color .2s ease}.tribe-common .tribe-common-cta--thin-alt:active,.tribe-common .tribe-common-cta--thin-alt:focus,.tribe-common .tribe-common-cta--thin-alt:hover{border-bottom:1px solid #334aff;color:#334aff}.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--alt:hover,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-cta--thin-alt:hover{color:#334aff}.tribe-common .tribe-common-h1{font-size:28px}.tribe-common .tribe-common-h1,.tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.42}.tribe-common .tribe-common-h2{font-size:24px}.tribe-common .tribe-common-h3{font-size:22px;line-height:1.5}.tribe-common .tribe-common-h3,.tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h4{font-size:20px;line-height:1.42}.tribe-common .tribe-common-h5{font-size:18px}.tribe-common .tribe-common-h5,.tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-common .tribe-common-h6{font-size:16px}.tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-common .tribe-common-h7,.tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-common .tribe-common-h--alt{font-weight:400}.tribe-theme-avada #main .tribe-common .tribe-common-h1{font-size:28px}.tribe-theme-avada #main .tribe-common .tribe-common-h1,.tribe-theme-avada #main .tribe-common .tribe-common-h2{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h2{font-size:24px}.tribe-theme-avada #main .tribe-common .tribe-common-h3{font-size:22px;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h3,.tribe-theme-avada #main .tribe-common .tribe-common-h4{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h4{font-size:20px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h5{font-size:18px}.tribe-theme-avada #main .tribe-common .tribe-common-h5,.tribe-theme-avada #main .tribe-common .tribe-common-h6{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px}.tribe-theme-avada #main .tribe-common .tribe-common-h7{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7,.tribe-theme-avada #main .tribe-common .tribe-common-h8{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-weight:700}.tribe-theme-avada #main .tribe-common .tribe-common-h8{font-size:12px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h--alt{font-weight:400}.tribe-common button{border:none}.tribe-common button,.tribe-common button:focus,.tribe-common button:hover,.tribe-theme-twentyseventeen .tribe-common button:focus,.tribe-theme-twentyseventeen .tribe-common button:hover{background-color:transparent}.tribe-theme-twentytwenty .tribe-common button{background-color:transparent;text-transform:inherit}.tribe-theme-twentytwenty .tribe-common button:focus,.tribe-theme-twentytwenty .tribe-common button:hover{text-decoration:none}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23334AFF'/%3E%3C/svg%3E")}.tribe-theme-enfold .tribe-common th{letter-spacing:0;text-transform:none}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:12px;line-height:1.38;font-weight:400;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;background-color:#fff;border:1px solid #d5d5d5;border-radius:4px;text-align:center;transition:color .2s ease,border-color .2s ease;color:#727272;padding:14px 20px}.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:active{border-color:#141827}.tribe-common .tribe-common-c-btn-border:active,.tribe-common .tribe-common-c-btn-border:focus,.tribe-common .tribe-common-c-btn-border:hover,.tribe-common a.tribe-common-c-btn-border:active,.tribe-common a.tribe-common-c-btn-border:focus,.tribe-common a.tribe-common-c-btn-border:hover{color:#141827}.tribe-common .tribe-common-c-btn-border:disabled,.tribe-common a.tribe-common-c-btn-border:disabled{color:#d5d5d5}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon{border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto}.tribe-common .tribe-common-c-btn-icon--border{background-color:#fff;border:1px solid #d5d5d5;align-items:center;display:inline-flex;height:56px;justify-content:center;transition:none;width:56px}.tribe-common .tribe-common-c-btn-icon--border:focus,.tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn-icon--border:active{border-color:#141827}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn-icon--border:hover{background-color:#fff}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;font-weight:700;border:0;cursor:pointer;display:inline-block;height:auto;padding:0;text-decoration:none;width:auto;border-radius:4px;color:#fff;text-align:center;transition:background-color .2s ease;padding:11px 20px;background-color:#334aff}.tribe-common .tribe-common-c-btn:focus,.tribe-common .tribe-common-c-btn:hover,.tribe-common a.tribe-common-c-btn:focus,.tribe-common a.tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8)}.tribe-common .tribe-common-c-btn:active,.tribe-common a.tribe-common-c-btn:active{background-color:rgba(51,74,255,.9)}.tribe-common .tribe-common-c-btn:disabled,.tribe-common a.tribe-common-c-btn:disabled{background-color:rgba(51,74,255,.07)}.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentyseventeen .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn{background-color:#334aff}.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:focus,.tribe-theme-twentytwenty .tribe-common .tribe-common-c-btn:hover{background-color:rgba(51,74,255,.8);color:#fff}.tribe-common .tribe-common-c-loader__dot{animation-name:a;animation-duration:2.24s;animation-iteration-count:infinite;animation-direction:normal}.tribe-common .tribe-common-c-loader__dot--first{animation-delay:.45s}.tribe-common .tribe-common-c-loader__dot--second{animation-delay:1.05s}.tribe-common .tribe-common-c-loader__dot--third{animation-delay:1.35s}@keyframes a{50%{background-color:#334aff}}@media (min-width:768px){#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{color:#141827;font-family:Helvetica Neue,Helvetica,-apple-system,BlinkMacSystemFont,Roboto,Arial,sans-serif;font-size:14px;line-height:1.62;font-weight:400;border:0}.tribe-common .tribe-common-b1{font-size:16px;line-height:1.62}.tribe-common .tribe-common-b2{font-size:14px;line-height:1.62}.tribe-common .tribe-common-b3{font-size:12px;line-height:1.38}.tribe-common .tribe-common-b1--min-medium{font-size:16px;line-height:1.62}.tribe-common .tribe-common-b2--min-medium{font-size:14px;line-height:1.62}.tribe-common .tribe-common-b3--min-medium{font-size:12px;line-height:1.38}.tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-common .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-common .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-common .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-common .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h1{font-size:42px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h2{font-size:32px;line-height:1.38}.tribe-theme-avada #main .tribe-common .tribe-common-h3{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h4{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h6{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h3--min-medium{font-size:28px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h4--min-medium{font-size:24px;line-height:1.42}.tribe-theme-avada #main .tribe-common .tribe-common-h5--min-medium{font-size:18px;line-height:1.5}.tribe-theme-avada #main .tribe-common .tribe-common-h6--min-medium{font-size:16px;line-height:1.62}.tribe-theme-avada #main .tribe-common .tribe-common-h7--min-medium{font-size:14px;line-height:1.62}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:6px 15px}}
common/src/resources/css/common-skeleton.css ADDED
@@ -0,0 +1,1740 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /*
12
+ * Common Skeleton CSS
13
+ *
14
+ * DO NOT EDIT THIS CSS FILE DIRECTLY.
15
+ * -------------------------------------------------------------
16
+ * This file is just a clearing-house, see the pcss directory
17
+ * and edit the source files found there.
18
+ */
19
+
20
+ /* Reset */
21
+
22
+ /* -----------------------------------------------------------------------------
23
+ *
24
+ * Resets Skeleton
25
+ *
26
+ * This file is just a clearing-house.
27
+ * Make partials (start with an underscore) for any actual css code.
28
+ *
29
+ * ----------------------------------------------------------------------------- */
30
+
31
+ /* Reset */
32
+
33
+ .tribe-common {
34
+ -webkit-font-smoothing: antialiased;
35
+ -moz-osx-font-smoothing: grayscale;
36
+ font-smoothing: antialiased;
37
+ }
38
+
39
+ /* -----------------------------------------------------------------------------
40
+ *
41
+ * Global "Resets"
42
+ *
43
+ * ----------------------------------------------------------------------------- */
44
+
45
+ .tribe-common * {
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ /* -----------------------------------------------------------------------------
50
+ *
51
+ * HTML5 Elements
52
+ *
53
+ * ----------------------------------------------------------------------------- */
54
+
55
+ .tribe-common article,
56
+ .tribe-common aside,
57
+ .tribe-common details,
58
+ .tribe-common figcaption,
59
+ .tribe-common figure,
60
+ .tribe-common footer,
61
+ .tribe-common header,
62
+ .tribe-common main,
63
+ .tribe-common menu,
64
+ .tribe-common nav,
65
+ .tribe-common section,
66
+ .tribe-common summary {
67
+ display: block;
68
+ }
69
+
70
+ /* -----------------------------------------------------------------------------
71
+ *
72
+ * Normalize "Light"
73
+ *
74
+ * ----------------------------------------------------------------------------- */
75
+
76
+ .tribe-common svg:not(:root) {
77
+ overflow: hidden;
78
+ }
79
+
80
+ .tribe-common audio,
81
+ .tribe-common canvas,
82
+ .tribe-common progress,
83
+ .tribe-common video {
84
+ display: inline-block;
85
+ }
86
+
87
+ .tribe-common audio:not([controls]) {
88
+ display: none;
89
+ height: 0;
90
+ }
91
+
92
+ .tribe-common progress {
93
+ vertical-align: baseline;
94
+ }
95
+
96
+ .tribe-common template,
97
+ .tribe-common [hidden] {
98
+ display: none;
99
+ }
100
+
101
+ .tribe-common pre {
102
+ overflow: auto;
103
+ }
104
+
105
+ .tribe-common sub,
106
+ .tribe-common sup {
107
+ position: relative;
108
+ vertical-align: baseline;
109
+ }
110
+
111
+ .tribe-common sup {
112
+ top: -0.5em;
113
+ }
114
+
115
+ .tribe-common sub {
116
+ bottom: -0.25em;
117
+ }
118
+
119
+ .tribe-common input,
120
+ .tribe-common button,
121
+ .tribe-common select,
122
+ .tribe-common textarea {
123
+ box-sizing: border-box;
124
+ margin: 0;
125
+ }
126
+
127
+ .tribe-common input[type="number"]::-webkit-inner-spin-button,
128
+ .tribe-common input[type="number"]::-webkit-outer-spin-button {
129
+ height: auto;
130
+ }
131
+
132
+ .tribe-common legend {
133
+ color: inherit;
134
+ display: table;
135
+ max-width: 100%;
136
+ white-space: normal;
137
+ }
138
+
139
+ .tribe-common textarea {
140
+ resize: none;
141
+ overflow: auto;
142
+ }
143
+
144
+ .tribe-common button,
145
+ .tribe-common input[type="button"],
146
+ .tribe-common input[type="reset"],
147
+ .tribe-common input[type="submit"] {
148
+ cursor: pointer;
149
+ overflow: visible;
150
+ }
151
+
152
+ .tribe-common button[disabled],
153
+ .tribe-common input[disabled] {
154
+ cursor: default;
155
+ }
156
+
157
+ .tribe-common button::-moz-focus-inner,
158
+ .tribe-common input::-moz-focus-inner {
159
+ border: 0;
160
+ padding: 0;
161
+ }
162
+
163
+ /* -----------------------------------------------------------------------------
164
+ *
165
+ * Reset "Light"
166
+ *
167
+ * ----------------------------------------------------------------------------- */
168
+
169
+ .tribe-common div,
170
+ .tribe-common span,
171
+ .tribe-common applet,
172
+ .tribe-common object,
173
+ .tribe-common iframe,
174
+ .tribe-common h1,
175
+ .tribe-common h2,
176
+ .tribe-common h3,
177
+ .tribe-common h4,
178
+ .tribe-common h5,
179
+ .tribe-common h6,
180
+ .tribe-common p,
181
+ .tribe-common blockquote,
182
+ .tribe-common pre,
183
+ .tribe-common a,
184
+ .tribe-common abbr,
185
+ .tribe-common acronym,
186
+ .tribe-common address,
187
+ .tribe-common big,
188
+ .tribe-common cite,
189
+ .tribe-common code,
190
+ .tribe-common del,
191
+ .tribe-common dfn,
192
+ .tribe-common em,
193
+ .tribe-common img,
194
+ .tribe-common ins,
195
+ .tribe-common kbd,
196
+ .tribe-common q,
197
+ .tribe-common s,
198
+ .tribe-common samp,
199
+ .tribe-common small,
200
+ .tribe-common strike,
201
+ .tribe-common strong,
202
+ .tribe-common sub,
203
+ .tribe-common sup,
204
+ .tribe-common tt,
205
+ .tribe-common var,
206
+ .tribe-common b,
207
+ .tribe-common u,
208
+ .tribe-common i,
209
+ .tribe-common center,
210
+ .tribe-common dl,
211
+ .tribe-common dt,
212
+ .tribe-common dd,
213
+ .tribe-common ol,
214
+ .tribe-common ul,
215
+ .tribe-common li,
216
+ .tribe-common fieldset,
217
+ .tribe-common form,
218
+ .tribe-common label,
219
+ .tribe-common legend,
220
+ .tribe-common table,
221
+ .tribe-common caption,
222
+ .tribe-common tbody,
223
+ .tribe-common tfoot,
224
+ .tribe-common thead,
225
+ .tribe-common tr,
226
+ .tribe-common th,
227
+ .tribe-common td,
228
+ .tribe-common article,
229
+ .tribe-common aside,
230
+ .tribe-common canvas,
231
+ .tribe-common details,
232
+ .tribe-common embed,
233
+ .tribe-common figure,
234
+ .tribe-common figcaption,
235
+ .tribe-common footer,
236
+ .tribe-common header,
237
+ .tribe-common main,
238
+ .tribe-common menu,
239
+ .tribe-common nav,
240
+ .tribe-common output,
241
+ .tribe-common ruby,
242
+ .tribe-common section,
243
+ .tribe-common summary,
244
+ .tribe-common time,
245
+ .tribe-common mark,
246
+ .tribe-common audio,
247
+ .tribe-common video {
248
+ margin: 0;
249
+ padding: 0;
250
+ border: 0;
251
+ }
252
+
253
+ .tribe-common ol,
254
+ .tribe-common ul {
255
+ list-style: none;
256
+ }
257
+
258
+ .tribe-common img {
259
+ -ms-interpolation-mode: bicubic;
260
+ height: auto;
261
+ max-width: 100%;
262
+ border-style: none;
263
+ }
264
+
265
+ .tribe-common iframe,
266
+ .tribe-common video,
267
+ .tribe-common embed {
268
+ max-width: 100%;
269
+ max-height: 100%;
270
+ }
271
+
272
+ /* Theme Overrides */
273
+
274
+ /* -------------------------------------------------------------------------
275
+ * Reset Skeleton Theme Overrides - Avada
276
+ * ------------------------------------------------------------------------- */
277
+
278
+ .tribe-theme-avada input[type="text"] {
279
+ margin: 0;
280
+ }
281
+
282
+ /* -------------------------------------------------------------------------
283
+ * Reset Skeleton Theme Overrides - Divi
284
+ * ------------------------------------------------------------------------- */
285
+
286
+ .tribe-theme-divi .entry-content .tribe-common table, .tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table {
287
+ border: 0;
288
+ margin: 0;
289
+ }
290
+
291
+ .tribe-theme-divi .entry-content .tribe-common td, .tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td {
292
+ border: 0;
293
+ }
294
+
295
+ .tribe-theme-divi #content-area .tribe-common td,
296
+ .tribe-theme-divi #content-area .tribe-common th,
297
+ .tribe-theme-divi #content-area .tribe-common tr {
298
+ padding: 0;
299
+ }
300
+
301
+ /* -------------------------------------------------------------------------
302
+ * Reset Skeleton Theme Overrides - Enfold
303
+ * ------------------------------------------------------------------------- */
304
+
305
+ #top.tribe-theme-enfold .tribe-common form {
306
+ margin: 0;
307
+ }
308
+
309
+ #top.tribe-theme-enfold .tribe-common input {
310
+ margin: 0;
311
+ }
312
+
313
+ /* .tribe-theme-genesis { */
314
+
315
+ /* -------------------------------------------------------------------------
316
+ * Reset Skeleton Theme Overrides - Genesis
317
+ * ------------------------------------------------------------------------- */
318
+
319
+ /* } */
320
+
321
+ /* .tribe-theme-twentynineteen .tribe-common { */
322
+
323
+ /* -------------------------------------------------------------------------
324
+ * Reset Skeleton Theme Overrides - Twenty Nineteen
325
+ * ------------------------------------------------------------------------- */
326
+
327
+ /* } */
328
+
329
+ /* .tribe-theme-twentyseventeen .tribe-common { */
330
+
331
+ /* -------------------------------------------------------------------------
332
+ * Reset Skeleton Theme Overrides - Twenty Seventeen
333
+ * ------------------------------------------------------------------------- */
334
+
335
+ /* } */
336
+
337
+ /* .tribe-theme-twentytwenty .tribe-common { */
338
+
339
+ /* -------------------------------------------------------------------------
340
+ * Reset Skeleton Theme Overrides - Twenty Twenty
341
+ * ------------------------------------------------------------------------- */
342
+
343
+ /* } */
344
+
345
+ /* Utilities */
346
+
347
+ /* -----------------------------------------------------------------------------
348
+ *
349
+ * Utilities
350
+ *
351
+ * This file is just a clearing-house.
352
+ * Make partials (start with an underscore) for any actual css code.
353
+ *
354
+ * ----------------------------------------------------------------------------- */
355
+
356
+ /* Variables */
357
+
358
+ :root {
359
+ /* -----------------------------------------------------------------------------
360
+ * Borders - Radius
361
+ * ----------------------------------------------------------------------------- */
362
+
363
+ /* -----------------------------------------------------------------------------
364
+ * Borders - Width
365
+ * ----------------------------------------------------------------------------- */
366
+ }
367
+
368
+ :root {
369
+ /* -----------------------------------------------------------------------------
370
+ * Box Shadows
371
+ * ----------------------------------------------------------------------------- */
372
+ }
373
+
374
+ :root {
375
+ /* -----------------------------------------------------------------------------
376
+ * Layers of z-index
377
+ * ----------------------------------------------------------------------------- */
378
+ }
379
+
380
+ :root {
381
+ /* -----------------------------------------------------------------------------
382
+ * Colors - Typography
383
+ * ----------------------------------------------------------------------------- */
384
+
385
+ /* -----------------------------------------------------------------------------
386
+ * Colors - Iconography
387
+ * ----------------------------------------------------------------------------- */
388
+
389
+ /* -----------------------------------------------------------------------------
390
+ * Colors - UI
391
+ * ----------------------------------------------------------------------------- */
392
+
393
+ /* -----------------------------------------------------------------------------
394
+ * Colors - Borders & Misc
395
+ * ----------------------------------------------------------------------------- */
396
+
397
+ }
398
+
399
+ :root {
400
+ /* -----------------------------------------------------------------------------
401
+ * Forms - Colors
402
+ * ----------------------------------------------------------------------------- */
403
+
404
+ /* -----------------------------------------------------------------------------
405
+ * Forms - Box Shadows
406
+ * ----------------------------------------------------------------------------- */
407
+ }
408
+
409
+ :root {
410
+ /* -----------------------------------------------------------------------------
411
+ * Gutter - Default
412
+ * ----------------------------------------------------------------------------- */
413
+
414
+ /* -----------------------------------------------------------------------------
415
+ * Gutter - Page
416
+ * ----------------------------------------------------------------------------- */
417
+
418
+ /* -----------------------------------------------------------------------------
419
+ * Grid Width - Default
420
+ * ----------------------------------------------------------------------------- */
421
+
422
+ /* -----------------------------------------------------------------------------
423
+ * Grid Width - Relative
424
+ * ----------------------------------------------------------------------------- */
425
+ }
426
+
427
+ :root {
428
+ /* -----------------------------------------------------------------------------
429
+ * Opacities
430
+ * ----------------------------------------------------------------------------- */
431
+ }
432
+
433
+ :root {
434
+ /* -----------------------------------------------------------------------------
435
+ * Spacers
436
+ * ----------------------------------------------------------------------------- */
437
+ }
438
+
439
+ /* -----------------------------------------------------------------------------
440
+ * SVG - Arrow Right
441
+ * ----------------------------------------------------------------------------- */
442
+
443
+ /* -----------------------------------------------------------------------------
444
+ * SVG - Arrow (light, left)
445
+ * ----------------------------------------------------------------------------- */
446
+
447
+ /* -----------------------------------------------------------------------------
448
+ * SVG - Caret Down
449
+ * ----------------------------------------------------------------------------- */
450
+
451
+ /* -----------------------------------------------------------------------------
452
+ * SVG - Caret Left
453
+ * ----------------------------------------------------------------------------- */
454
+
455
+ /* -----------------------------------------------------------------------------
456
+ * SVG - Caret Right
457
+ * ----------------------------------------------------------------------------- */
458
+
459
+ /* -----------------------------------------------------------------------------
460
+ * SVG - Caret Up
461
+ * ----------------------------------------------------------------------------- */
462
+
463
+ /* -----------------------------------------------------------------------------
464
+ * SVG - Check
465
+ * ----------------------------------------------------------------------------- */
466
+
467
+ /* -----------------------------------------------------------------------------
468
+ * SVG - Close
469
+ * ----------------------------------------------------------------------------- */
470
+
471
+ /* -----------------------------------------------------------------------------
472
+ * SVG - Day
473
+ * ----------------------------------------------------------------------------- */
474
+
475
+ /* -----------------------------------------------------------------------------
476
+ * SVG - Dropdown
477
+ * ----------------------------------------------------------------------------- */
478
+
479
+ /* -----------------------------------------------------------------------------
480
+ * SVG - Error
481
+ * ----------------------------------------------------------------------------- */
482
+
483
+ /* -----------------------------------------------------------------------------
484
+ * SVG - Featured
485
+ * ----------------------------------------------------------------------------- */
486
+
487
+ /* -----------------------------------------------------------------------------
488
+ * SVG - Filters
489
+ * ----------------------------------------------------------------------------- */
490
+
491
+ /* -----------------------------------------------------------------------------
492
+ * SVG - List
493
+ * ----------------------------------------------------------------------------- */
494
+
495
+ /* -----------------------------------------------------------------------------
496
+ * SVG - Location
497
+ * ----------------------------------------------------------------------------- */
498
+
499
+ /* -----------------------------------------------------------------------------
500
+ * SVG - Map
501
+ * ----------------------------------------------------------------------------- */
502
+
503
+ /* -----------------------------------------------------------------------------
504
+ * SVG - Month
505
+ * ----------------------------------------------------------------------------- */
506
+
507
+ /* -----------------------------------------------------------------------------
508
+ * SVG - Photo
509
+ * ----------------------------------------------------------------------------- */
510
+
511
+ /* -----------------------------------------------------------------------------
512
+ * SVG - Recurring
513
+ * ----------------------------------------------------------------------------- */
514
+
515
+ /* -----------------------------------------------------------------------------
516
+ * SVG - Remove
517
+ * ----------------------------------------------------------------------------- */
518
+
519
+ /* -----------------------------------------------------------------------------
520
+ * SVG - Reset
521
+ * ----------------------------------------------------------------------------- */
522
+
523
+ /* -----------------------------------------------------------------------------
524
+ * SVG - Search
525
+ * ----------------------------------------------------------------------------- */
526
+
527
+ /* -----------------------------------------------------------------------------
528
+ * SVG - Search Filter
529
+ * ----------------------------------------------------------------------------- */
530
+
531
+ /* -----------------------------------------------------------------------------
532
+ * SVG - Week
533
+ * ----------------------------------------------------------------------------- */
534
+
535
+ :root {
536
+ /* -----------------------------------------------------------------------------
537
+ * Transitions
538
+ * ----------------------------------------------------------------------------- */
539
+ }
540
+
541
+ :root {
542
+ /* -----------------------------------------------------------------------------
543
+ * Font Stacks
544
+ * ----------------------------------------------------------------------------- */
545
+
546
+ /* -----------------------------------------------------------------------------
547
+ * Font Weights
548
+ * ----------------------------------------------------------------------------- */
549
+
550
+ /* -----------------------------------------------------------------------------
551
+ * Font Sizing
552
+ * ----------------------------------------------------------------------------- */
553
+
554
+ /* -----------------------------------------------------------------------------
555
+ * Line Height
556
+ * ----------------------------------------------------------------------------- */
557
+ }
558
+
559
+ /* Mixins */
560
+
561
+ /* -----------------------------------------------------------------------------
562
+ * Body
563
+ * ----------------------------------------------------------------------------- */
564
+
565
+ /* -----------------------------------------------------------------------------
566
+ * Desktop Body 1
567
+ * ----------------------------------------------------------------------------- */
568
+
569
+ /* -----------------------------------------------------------------------------
570
+ * Desktop Body 2
571
+ * ----------------------------------------------------------------------------- */
572
+
573
+ /* -----------------------------------------------------------------------------
574
+ * Desktop Body 3
575
+ * ----------------------------------------------------------------------------- */
576
+
577
+ /* -----------------------------------------------------------------------------
578
+ * Mobile Body 1
579
+ * ----------------------------------------------------------------------------- */
580
+
581
+ /* -----------------------------------------------------------------------------
582
+ * Mobile Body 2
583
+ * ----------------------------------------------------------------------------- */
584
+
585
+ /* -----------------------------------------------------------------------------
586
+ * Mobile Body 3
587
+ * ----------------------------------------------------------------------------- */
588
+
589
+ /* -----------------------------------------------------------------------------
590
+ * Heading
591
+ * ----------------------------------------------------------------------------- */
592
+
593
+ /* -----------------------------------------------------------------------------
594
+ * Heading 1
595
+ * ----------------------------------------------------------------------------- */
596
+
597
+ /* -----------------------------------------------------------------------------
598
+ * Heading 2
599
+ * ----------------------------------------------------------------------------- */
600
+
601
+ /* -----------------------------------------------------------------------------
602
+ * Heading 3
603
+ * ----------------------------------------------------------------------------- */
604
+
605
+ /* -----------------------------------------------------------------------------
606
+ * Heading 4
607
+ * ----------------------------------------------------------------------------- */
608
+
609
+ /* -----------------------------------------------------------------------------
610
+ * Heading 5
611
+ * ----------------------------------------------------------------------------- */
612
+
613
+ /* -----------------------------------------------------------------------------
614
+ * Heading 6
615
+ * ----------------------------------------------------------------------------- */
616
+
617
+ /* -----------------------------------------------------------------------------
618
+ * Heading 7
619
+ * ----------------------------------------------------------------------------- */
620
+
621
+ /* -----------------------------------------------------------------------------
622
+ * Heading 8
623
+ * ----------------------------------------------------------------------------- */
624
+
625
+ /* -----------------------------------------------------------------------------
626
+ * Anchor - Default
627
+ * ----------------------------------------------------------------------------- */
628
+
629
+ /* -----------------------------------------------------------------------------
630
+ * Anchor - Alt
631
+ * ----------------------------------------------------------------------------- */
632
+
633
+ /* -----------------------------------------------------------------------------
634
+ * Anchor - Thin
635
+ * ----------------------------------------------------------------------------- */
636
+
637
+ /* -----------------------------------------------------------------------------
638
+ * Anchor - Thin
639
+ * ----------------------------------------------------------------------------- */
640
+
641
+ /* -----------------------------------------------------------------------------
642
+ * Button - Global
643
+ * ----------------------------------------------------------------------------- */
644
+
645
+ /* -----------------------------------------------------------------------------
646
+ * Button - Solid
647
+ * ----------------------------------------------------------------------------- */
648
+
649
+ /* -----------------------------------------------------------------------------
650
+ * Button - Link
651
+ * ----------------------------------------------------------------------------- */
652
+
653
+ /* -----------------------------------------------------------------------------
654
+ * Button - Border
655
+ * ----------------------------------------------------------------------------- */
656
+
657
+ /* -----------------------------------------------------------------------------
658
+ * Button - Icon Border
659
+ * ----------------------------------------------------------------------------- */
660
+
661
+ /* -----------------------------------------------------------------------------
662
+ * Sliders & Toggles
663
+ * ----------------------------------------------------------------------------- */
664
+
665
+ /* -----------------------------------------------------------------------------
666
+ * Sliders
667
+ * ----------------------------------------------------------------------------- */
668
+
669
+ /* -----------------------------------------------------------------------------
670
+ * Hidden: Hide from both screenreaders and browsers
671
+ * @author: h5bp.com/u
672
+ * ----------------------------------------------------------------------------- */
673
+
674
+ /* -----------------------------------------------------------------------------
675
+ * Visually Hide: Hide only visually, but have it available for screenreaders
676
+ * @author: h5bp.com/v
677
+ * ----------------------------------------------------------------------------- */
678
+
679
+ /* -----------------------------------------------------------------------------
680
+ * Visually Show: Show element after has been hidden with %visually-hide
681
+ * ----------------------------------------------------------------------------- */
682
+
683
+ /* Base */
684
+
685
+ /* -----------------------------------------------------------------------------
686
+ *
687
+ * Base Skeleton
688
+ *
689
+ * This file is just a clearing-house.
690
+ * Make partials (start with an underscore) for any actual css code.
691
+ *
692
+ * ----------------------------------------------------------------------------- */
693
+
694
+ /* Forms */
695
+
696
+ .tribe-common {
697
+
698
+
699
+ /* -----------------------------------------------------------------------------
700
+ * Form Control: Checkboxes
701
+ * ----------------------------------------------------------------------------- */
702
+
703
+ /* -----------------------------------------------------------------------------
704
+ * Form Control: Radios
705
+ * ----------------------------------------------------------------------------- */
706
+
707
+ /* -----------------------------------------------------------------------------
708
+ *
709
+ * Form Control: Checkboxes & Radios Theme Overrides
710
+ *
711
+ * ----------------------------------------------------------------------------- */
712
+
713
+ /* -----------------------------------------------------------------------------
714
+ * Form Control: Checkboxes Theme Overrides
715
+ * ----------------------------------------------------------------------------- */
716
+
717
+ /* -----------------------------------------------------------------------------
718
+ * Form Control: Radios Theme Overrides
719
+ * ----------------------------------------------------------------------------- */
720
+ }
721
+
722
+ /* -----------------------------------------------------------------------------
723
+ *
724
+ * Form Control: Checkboxes & Radios
725
+ *
726
+ * Example (Checkboxes):
727
+ * <fieldset>
728
+ * <legend>Legend for Checkboxes</legend>
729
+ * <div class="tribe-common-form-control-checkbox-radio-group">
730
+ * <div class="tribe-common-form-control-checkbox">
731
+ * <input
732
+ * class="tribe-common-form-control-checkbox__input"
733
+ * id="checkboxOne"
734
+ * name="checkboxGroup"
735
+ * type="checkbox"
736
+ * value="checkboxOne"
737
+ * checked="checked"
738
+ * />
739
+ * <label
740
+ * class="tribe-common-form-control-checkbox__label"
741
+ * for="checkboxOne"
742
+ * >
743
+ * Checkbox One
744
+ * </label>
745
+ * </div>
746
+ * <div class="tribe-common-form-control-checkbox">
747
+ * <input
748
+ * class="tribe-common-form-control-checkbox__input"
749
+ * id="checkboxTwo"
750
+ * name="checkboxGroup"
751
+ * type="checkbox"
752
+ * value="checkboxTwo"
753
+ * />
754
+ * <label
755
+ * class="tribe-common-form-control-checkbox__label"
756
+ * for="checkboxTwo"
757
+ * >
758
+ * Checkbox Two
759
+ * </label>
760
+ * </div>
761
+ * </div>
762
+ * </fieldset>
763
+ *
764
+ * Example (Radios):
765
+ * <div class="tribe-common-form-control-checkbox-radio-group">
766
+ * <div class="tribe-common-form-control-radio">
767
+ * <input
768
+ * class="tribe-common-form-control-radio__input"
769
+ * id="radioExample"
770
+ * name="radioExample"
771
+ * type="radio"
772
+ * value="RadioExample"
773
+ * checked="checked"
774
+ * />
775
+ * <label
776
+ * class="tribe-common-form-control-radio__label"
777
+ * for="radioExample"
778
+ * >
779
+ * Radio Example
780
+ * </label>
781
+ * </div>
782
+ * </div>
783
+ *
784
+ * ----------------------------------------------------------------------------- */
785
+
786
+ .tribe-common .tribe-common-form-control-checkbox__label,
787
+ .tribe-common .tribe-common-form-control-radio__label {
788
+ cursor: pointer;
789
+ display: inline-block;
790
+ margin-left: 11px;
791
+ vertical-align: middle;
792
+ }
793
+
794
+ .tribe-common .tribe-common-form-control-checkbox__input,
795
+ .tribe-common .tribe-common-form-control-radio__input {
796
+ cursor: pointer;
797
+ display: inline-block;
798
+ margin: 0;
799
+ vertical-align: middle;
800
+ }
801
+
802
+ /* -----------------------------------------------------------------------------
803
+ * Theme Overrides - Enfold
804
+ * ----------------------------------------------------------------------------- */
805
+
806
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input {
807
+ display: inline-block;
808
+ }
809
+
810
+ /* -----------------------------------------------------------------------------
811
+ *
812
+ * Form Control: Groups (Checkbox & Radio)
813
+ *
814
+ * Example:
815
+ * <div class="tribe-common-form-control-checkbox-radio-group">
816
+ * <div class="tribe-common-form-control-checkbox">
817
+ * <input id="checkboxOne" name="checkboxGroup" type="checkbox" value="checkboxOne" checked="checked" />
818
+ * <label for="checkboxOne">Checkbox One</label>
819
+ * </div>
820
+ * <div class="tribe-common-form-control-checkbox">
821
+ * <input id="checkboxTwo" name="checkboxGroup" type="checkbox" value="checkboxTwo" />
822
+ * <label for="checkboxTwo">Checkbox two</label>
823
+ * </div>
824
+ * </div>
825
+ *
826
+ * ----------------------------------------------------------------------------- */
827
+
828
+ .tribe-common .tribe-common-form-control-checkbox-radio-group > * {
829
+ margin-bottom: 15px;
830
+ }
831
+
832
+ .tribe-common .tribe-common-form-control-checkbox-radio-group > *:last-child {
833
+ margin-bottom: 0;
834
+ }
835
+
836
+ .tribe-common {
837
+
838
+ /* -----------------------------------------------------------------------------
839
+ *
840
+ * Form Control: Sliders Theme Overrides
841
+ *
842
+ * ----------------------------------------------------------------------------- */
843
+ }
844
+
845
+ /* -----------------------------------------------------------------------------
846
+ *
847
+ * Form Control: Sliders
848
+ *
849
+ * Example (Horizontal):
850
+ * <div class="tribe-common-form-control-slider">
851
+ * <input
852
+ * class="tribe-common-form-control-slider__input"
853
+ * id="sliderOne"
854
+ * type="range"
855
+ * min="0"
856
+ * max="100"
857
+ * value="50"
858
+ * />
859
+ * <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
860
+ * </div>
861
+ *
862
+ * Example (Vertical):
863
+ * <div class="tribe-common-form-control-slider tribe-common-form-control-slider--vertical">
864
+ * <label class="tribe-common-form-control-slider__label" for="sliderOne">Slider One</label>
865
+ * <input
866
+ * class="tribe-common-form-control-slider__input"
867
+ * id="sliderOne"
868
+ * type="range"
869
+ * min="0"
870
+ * max="100"
871
+ * value="50"
872
+ * />
873
+ * </div>
874
+ *
875
+ * ----------------------------------------------------------------------------- */
876
+
877
+ .tribe-common .tribe-common-form-control-slider__input {
878
+ cursor: pointer;
879
+ display: inline-block;
880
+ margin: 0;
881
+ padding: 0;
882
+ width: 120px;
883
+ vertical-align: middle;
884
+
885
+ /* -----------------------------------------------------------------------------
886
+ * Track styles
887
+ * ----------------------------------------------------------------------------- */
888
+
889
+ /* -----------------------------------------------------------------------------
890
+ * Thumb styles
891
+ * ----------------------------------------------------------------------------- */
892
+ }
893
+
894
+ .tribe-common .tribe-common-form-control-slider__label {
895
+ cursor: pointer;
896
+ display: inline-block;
897
+ margin-left: 11px;
898
+ vertical-align: middle;
899
+ }
900
+
901
+ .tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label {
902
+ display: block;
903
+ margin: 0 0 6px;
904
+ }
905
+
906
+ .tribe-common {
907
+
908
+ /* -----------------------------------------------------------------------------
909
+ *
910
+ * Form Control: Text Theme Overrides
911
+ *
912
+ * ----------------------------------------------------------------------------- */
913
+ }
914
+
915
+ /* -----------------------------------------------------------------------------
916
+ *
917
+ * Form Control: Text
918
+ *
919
+ * Example:
920
+ * <div class="tribe-common-form-control-text">
921
+ * <label class="tribe-common-form-control-text__label" for="textInput">Text Input</label>
922
+ * <input
923
+ * class="tribe-common-form-control-text__input"
924
+ * id="textInput"
925
+ * name="textInput"
926
+ * type="text"
927
+ * placeholder="Text Input"
928
+ * />
929
+ * </div>
930
+ *
931
+ * ----------------------------------------------------------------------------- */
932
+
933
+ .tribe-common .tribe-common-form-control-text__label {
934
+ border: 0;
935
+ clip: rect(0 0 0 0);
936
+ height: 1px;
937
+ margin: -1px;
938
+ overflow: hidden;
939
+ padding: 0;
940
+ position: absolute;
941
+ width: 1px;
942
+ }
943
+
944
+ .tribe-common .tribe-common-form-control-text__input {
945
+ height: auto;
946
+ padding: 12px 28px 12px 0;
947
+ width: 100%;
948
+ }
949
+
950
+ /* -------------------------------------------------------------------------
951
+ * Theme Overrides - Enfold
952
+ * ------------------------------------------------------------------------- */
953
+
954
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
955
+ padding: 12px 28px 12px 0;
956
+ width: 100%;
957
+ }
958
+
959
+ .tribe-common {
960
+
961
+ /* -----------------------------------------------------------------------------
962
+ *
963
+ * Form Control: Toggles Theme Overrides
964
+ *
965
+ * ----------------------------------------------------------------------------- */
966
+ }
967
+
968
+ /* -----------------------------------------------------------------------------
969
+ *
970
+ * Form Control: Toggles
971
+ *
972
+ * Example (Horizontal):
973
+ * <div class="tribe-common-form-control-toggle">
974
+ * <input
975
+ * class="tribe-common-form-control-toggle__input"
976
+ * id="toggleOne"
977
+ * name="toggleGroup"
978
+ * type="checkbox"
979
+ * value="toggleOne"
980
+ * />
981
+ * <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
982
+ * </div>
983
+ *
984
+ * Example (Vertical):
985
+ * <div class="tribe-common-form-control-toggle tribe-common-form-control-toggle--vertical">
986
+ * <label class="tribe-common-form-control-toggle__label" for="toggleOne">Toggle One</label>
987
+ * <input
988
+ * class="tribe-common-form-control-toggle__input"
989
+ * id="toggleOne"
990
+ * name="toggleGroup"
991
+ * type="checkbox"
992
+ * value="toggleOne"
993
+ * />
994
+ * </div>
995
+ *
996
+ * ----------------------------------------------------------------------------- */
997
+
998
+ .tribe-common .tribe-common-form-control-toggle__input {
999
+ cursor: pointer;
1000
+ display: inline-block;
1001
+ vertical-align: middle;
1002
+ }
1003
+
1004
+ .tribe-common .tribe-common-form-control-toggle__label {
1005
+ cursor: pointer;
1006
+ display: inline-block;
1007
+ margin-left: 11px;
1008
+ vertical-align: middle;
1009
+ }
1010
+
1011
+ .tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label {
1012
+ display: block;
1013
+ margin: 0 0 6px;
1014
+ }
1015
+
1016
+ /* -----------------------------------------------------------------------------
1017
+ * Theme Overrides - Enfold
1018
+ * ----------------------------------------------------------------------------- */
1019
+
1020
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input {
1021
+ display: inline-block;
1022
+ margin: 5px 0;
1023
+ }
1024
+
1025
+ /* Grid */
1026
+
1027
+ /* -----------------------------------------------------------------------------
1028
+ * Grid: Columns
1029
+ * ----------------------------------------------------------------------------- */
1030
+
1031
+ .tribe-common .tribe-common-g-col {
1032
+ min-width: 0;
1033
+ width: 100%;
1034
+ }
1035
+
1036
+ .tribe-common {
1037
+
1038
+ /* -------------------------------------------------------------------------
1039
+ *
1040
+ * Grid Rows: Theme Overrides
1041
+ *
1042
+ * ------------------------------------------------------------------------- */
1043
+ }
1044
+
1045
+ /* -----------------------------------------------------------------------------
1046
+ *
1047
+ * Grid: Rows
1048
+ *
1049
+ * Example:
1050
+ * <div class="g-row">
1051
+ * <div class="g-col">
1052
+ * <p>Component or another grid layout, perhaps?</p>
1053
+ * </div>
1054
+ * </div>
1055
+ *
1056
+ * ----------------------------------------------------------------------------- */
1057
+
1058
+ .tribe-common .tribe-common-g-row {
1059
+ display: -webkit-box;
1060
+ display: flex;
1061
+ flex-wrap: wrap;
1062
+ }
1063
+
1064
+ .tribe-common .tribe-common-g-row--gutters {
1065
+ margin-left: -21px;
1066
+ margin-right: -21px;
1067
+ }
1068
+
1069
+ .tribe-common .tribe-common-g-row--gutters > .tribe-common-g-col {
1070
+ padding-left: 21px;
1071
+ padding-right: 21px;
1072
+ }
1073
+
1074
+ /* -----------------------------------------------------------------------------
1075
+ * Theme Overrides - Twenty Nineteen
1076
+ * ----------------------------------------------------------------------------- */
1077
+
1078
+ .tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters {
1079
+ margin-left: -21px;
1080
+ margin-right: -21px;
1081
+ padding: 0;
1082
+ }
1083
+
1084
+ .tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters > .entry.tribe-common-g-col {
1085
+ margin: 0;
1086
+ padding-left: 21px;
1087
+ padding-right: 21px;
1088
+ }
1089
+
1090
+ /* Typography */
1091
+
1092
+ .tribe-common {
1093
+
1094
+ /* -------------------------------------------------------------------------
1095
+ *
1096
+ * Anchor: Theme Overrides
1097
+ *
1098
+ * ------------------------------------------------------------------------- */
1099
+
1100
+ /* -------------------------------------------------------------------------
1101
+ *
1102
+ * Anchor
1103
+ *
1104
+ * Example:
1105
+ * <a class="tribe-common-anchor">Anchor Text</a>
1106
+ * <a class="tribe-common-anchor-alt">Anchor Alt Text</a>
1107
+ * <a class="tribe-common-anchor-thin">Anchor Thin Text</a>
1108
+ *
1109
+ * ------------------------------------------------------------------------- */
1110
+
1111
+ /* -------------------------------------------------------------------------
1112
+ *
1113
+ * Anchor: Theme Overrides
1114
+ *
1115
+ * ------------------------------------------------------------------------- */
1116
+ }
1117
+
1118
+ .tribe-common a {
1119
+ cursor: pointer;
1120
+ }
1121
+
1122
+ /* .tribe-common { */
1123
+
1124
+ /* -------------------------------------------------------------------------
1125
+ *
1126
+ * Body
1127
+ *
1128
+ * Example:
1129
+ * <p class="tribe-common-b1">Text here</p>
1130
+ *
1131
+ * ------------------------------------------------------------------------- */
1132
+
1133
+ /* -------------------------------------------------------------------------
1134
+ * Body 1
1135
+ * ------------------------------------------------------------------------- */
1136
+
1137
+ /* -------------------------------------------------------------------------
1138
+ * Body 2
1139
+ * ------------------------------------------------------------------------- */
1140
+
1141
+ /* -------------------------------------------------------------------------
1142
+ * Body 3
1143
+ * ------------------------------------------------------------------------- */
1144
+
1145
+ /* -------------------------------------------------------------------------
1146
+ * Body 1 for --viewport-medium
1147
+ * ------------------------------------------------------------------------- */
1148
+
1149
+ /* -------------------------------------------------------------------------
1150
+ * Body 2 for --viewport-medium
1151
+ * ------------------------------------------------------------------------- */
1152
+
1153
+ /* -------------------------------------------------------------------------
1154
+ * Body 3 for --viewport-medium
1155
+ * ------------------------------------------------------------------------- */
1156
+
1157
+ /* } */
1158
+
1159
+ /* .tribe-common { */
1160
+
1161
+ /* -------------------------------------------------------------------------
1162
+ *
1163
+ * CTA
1164
+ *
1165
+ * Example:
1166
+ * <a class="tribe-common-cta">Link Text</a>
1167
+ * <a class="tribe-common-cta tribe-common-cta--alt">Link Text Alt</a>
1168
+ *
1169
+ * ------------------------------------------------------------------------- */
1170
+
1171
+ /* -------------------------------------------------------------------------
1172
+ *
1173
+ * CTA: Theme Overrides
1174
+ *
1175
+ * ------------------------------------------------------------------------- */
1176
+
1177
+ /* } */
1178
+
1179
+ /* .tribe-common { */
1180
+
1181
+ /* -------------------------------------------------------------------------
1182
+ *
1183
+ * Heading
1184
+ *
1185
+ * Example:
1186
+ * <h1 class="tribe-common-h1">Heading Text</h1>
1187
+ *
1188
+ * ------------------------------------------------------------------------- */
1189
+
1190
+ /* -------------------------------------------------------------------------
1191
+ * Heading: h1
1192
+ * ------------------------------------------------------------------------- */
1193
+
1194
+ /* -------------------------------------------------------------------------
1195
+ * Heading: h2
1196
+ * ------------------------------------------------------------------------- */
1197
+
1198
+ /* -------------------------------------------------------------------------
1199
+ * Heading: h3
1200
+ * ------------------------------------------------------------------------- */
1201
+
1202
+ /* -------------------------------------------------------------------------
1203
+ * Heading: h4
1204
+ * ------------------------------------------------------------------------- */
1205
+
1206
+ /* -------------------------------------------------------------------------
1207
+ * Heading: h5
1208
+ * ------------------------------------------------------------------------- */
1209
+
1210
+ /* -------------------------------------------------------------------------
1211
+ * Heading: h6
1212
+ * ------------------------------------------------------------------------- */
1213
+
1214
+ /* -------------------------------------------------------------------------
1215
+ * Heading: h7
1216
+ * ------------------------------------------------------------------------- */
1217
+
1218
+ /* -------------------------------------------------------------------------
1219
+ * Heading: h8
1220
+ * ------------------------------------------------------------------------- */
1221
+
1222
+ /* -------------------------------------------------------------------------
1223
+ * Heading: h3 for --viewport-medium
1224
+ * ------------------------------------------------------------------------- */
1225
+
1226
+ /* -------------------------------------------------------------------------
1227
+ * Heading: h4 for --viewport-medium
1228
+ * ------------------------------------------------------------------------- */
1229
+
1230
+ /* -------------------------------------------------------------------------
1231
+ * Heading: h5 for --viewport-medium
1232
+ * ------------------------------------------------------------------------- */
1233
+
1234
+ /* -------------------------------------------------------------------------
1235
+ * Heading: h6 for --viewport-medium
1236
+ * ------------------------------------------------------------------------- */
1237
+
1238
+ /* -------------------------------------------------------------------------
1239
+ * Heading: h7 for --viewport-medium
1240
+ * ------------------------------------------------------------------------- */
1241
+
1242
+ /* -------------------------------------------------------------------------
1243
+ * Heading: alt style
1244
+ * ------------------------------------------------------------------------- */
1245
+
1246
+ /* -------------------------------------------------------------------------
1247
+ *
1248
+ * Heading: Theme Overrides
1249
+ *
1250
+ * ------------------------------------------------------------------------- */
1251
+
1252
+ /* } */
1253
+
1254
+ .tribe-common {
1255
+ /* -------------------------------------------------------------------------
1256
+ * Lists
1257
+ * ------------------------------------------------------------------------- */
1258
+
1259
+ /* -----------------------------------------------------------------------------
1260
+ *
1261
+ * Lists: Theme Overrides
1262
+ *
1263
+ * ----------------------------------------------------------------------------- */
1264
+ }
1265
+
1266
+ /* -------------------------------------------------------------------------
1267
+ * Theme Overrides - Divi
1268
+ * ------------------------------------------------------------------------- */
1269
+
1270
+ .tribe-theme-divi #left-area .tribe-common ul,
1271
+ .tribe-theme-divi .entry-content .tribe-common ul,
1272
+ body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul {
1273
+ list-style-type: none;
1274
+ padding: 0;
1275
+ }
1276
+
1277
+ .tribe-common {
1278
+
1279
+ /* -------------------------------------------------------------------------
1280
+ *
1281
+ * Button: Theme Overrides
1282
+ *
1283
+ * ------------------------------------------------------------------------- */
1284
+
1285
+ }
1286
+
1287
+ /* -------------------------------------------------------------------------
1288
+ * Button
1289
+ * ------------------------------------------------------------------------- */
1290
+
1291
+ .tribe-common button {
1292
+ padding: 0;
1293
+ }
1294
+
1295
+ /* -----------------------------------------------------------------------------
1296
+ *
1297
+ * Layout: Global Content Container
1298
+ *
1299
+ * ----------------------------------------------------------------------------- */
1300
+
1301
+ .tribe-common .tribe-common-l-container {
1302
+ max-width: 1260px;
1303
+ margin-left: auto;
1304
+ margin-right: auto;
1305
+ padding-left: 19.5px;
1306
+ padding-right: 19.5px;
1307
+ width: 100%;
1308
+ }
1309
+
1310
+ /* -------------------------------------------------------------------------
1311
+ * SVG Icons
1312
+ * ------------------------------------------------------------------------- */
1313
+
1314
+ .tribe-common .tribe-common-svgicon {
1315
+ background-repeat: no-repeat;
1316
+ background-size: contain;
1317
+ }
1318
+
1319
+ .tribe-common .tribe-common-svgicon--close {
1320
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'%3E%3Cpath d='M16 2L2 16M16 16L2 2' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
1321
+ }
1322
+
1323
+ .tribe-common .tribe-common-svgicon--close-secondary {
1324
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'%3E%3Cpath d='M16 2L2 16M16 16L2 2' stroke='%23BABABA'/%3E%3C/g%3E%3C/svg%3E");
1325
+ }
1326
+
1327
+ .tribe-common .tribe-common-svgicon--day {
1328
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874h1.747a.873.873 0 0 0 .873-.874v-1.747a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
1329
+ }
1330
+
1331
+ .tribe-common .tribe-common-svgicon--filters {
1332
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23727272'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23727272'/%3E%3Cpath d='M12 9v6' stroke='%23727272'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
1333
+ }
1334
+
1335
+ .tribe-common .tribe-common-svgicon--list {
1336
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='18' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cpath d='M19.883 3.272c.342 0 .622-.21.622-.467v-.464c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.464c0 .257.28.467.622.467h12.756zM1.838 4.207a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 9.98c.342 0 .622-.21.622-.466v-.465c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.465c0 .256.28.466.622.466h12.756zM1.838 10.916a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z' fill='%23141827'/%3E%3Cg%3E%3Cpath d='M19.883 16.689c.342 0 .622-.21.622-.467v-.465c0-.256-.28-.466-.622-.466H7.127c-.342 0-.622.21-.622.466v.465c0 .257.28.467.622.467h12.756zM1.838 17.624a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z' fill='%23141827'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
1337
+ }
1338
+
1339
+ .tribe-common .tribe-common-svgicon--map {
1340
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath stroke='%23141827' stroke-linejoin='round' d='M13.921 11.632H17.5l3.588 8.421H1l3.488-8.421h4.016'/%3E%3Cpath d='M11.32 15.506c.2-.248 4.93-6.108 4.93-9.04 0-3.015-2.305-5.468-5.138-5.468-2.833 0-5.138 2.453-5.138 5.467 0 2.933 4.729 8.793 4.93 9.041a.268.268 0 0 0 .208.101c.08 0 .155-.037.207-.101zm-4.797-9.04c0-2.693 2.058-4.883 4.589-4.883 2.53 0 4.588 2.19 4.588 4.882 0 2.387-3.667 7.22-4.588 8.397-.922-1.177-4.589-6.009-4.589-8.397z' stroke='%23141827' stroke-width='.4' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath d='M12.85 6.477c0-1.007-.78-1.826-1.738-1.826-.96 0-1.74.819-1.74 1.826 0 1.007.78 1.826 1.74 1.826.959 0 1.739-.82 1.739-1.826zm-3.15 0c0-.817.633-1.482 1.412-1.482.778 0 1.41.665 1.41 1.482s-.632 1.482-1.41 1.482c-.779 0-1.412-.665-1.412-1.482z' stroke='%23141827' stroke-width='.7' fill='%23000' fill-rule='nonzero'/%3E%3C/g%3E%3C/svg%3E");
1341
+ }
1342
+
1343
+ .tribe-common .tribe-common-svgicon--month {
1344
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
1345
+ }
1346
+
1347
+ .tribe-common .tribe-common-svgicon--no-map {
1348
+ background-image: svg-inline(no-map);
1349
+ }
1350
+
1351
+ .tribe-common .tribe-common-svgicon--photo {
1352
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='17' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cpath d='M19.348.11H.634a.509.509 0 0 0-.52.508v15.017c0 .284.23.508.52.508h18.714c.29 0 .52-.224.52-.508V.618a.509.509 0 0 0-.52-.508zm-.54 1.035v10.837l-2.87-3.084c-.583-.61-1.664-.61-2.246 0l-1.393 1.481-4.034-4.525a1.625 1.625 0 0 0-1.227-.528 1.6 1.6 0 0 0-1.206.548l-4.657 5.175V1.145h17.632zM1.174 15.108v-2.496l5.448-6.089a.529.529 0 0 1 .415-.182c.146 0 .333.06.437.182l4.429 4.972c.104.102.25.183.395.183.166.02.291-.06.395-.162l1.788-1.908c.167-.183.5-.183.686 0l3.66 3.917v1.603H1.175v-.02z' fill='%23141827'/%3E%3Cpath d='M14.19 5.757c1.044 0 1.91-.872 1.91-1.968s-.846-1.969-1.91-1.969c-1.062 0-1.909.873-1.909 1.969s.866 1.968 1.91 1.968zm0-2.902c.493 0 .907.427.907.934 0 .507-.414.933-.906.933-.492 0-.906-.426-.906-.933 0-.507.414-.934.906-.934z' fill='%23141827'/%3E%3C/g%3E%3C/svg%3E");
1353
+ }
1354
+
1355
+ .tribe-common .tribe-common-svgicon--search {
1356
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");
1357
+ }
1358
+
1359
+ .tribe-common .tribe-common-svgicon--week {
1360
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827' fill-rule='nonzero'/%3E%3C/svg%3E");
1361
+ }
1362
+
1363
+ .tribe-common .tribe-common-svgicon--featured {
1364
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23141827'/%3E%3C/svg%3E");
1365
+ height: 10px;
1366
+ width: 8px;
1367
+ }
1368
+
1369
+ .tribe-common .tribe-common-svgicon--recurring {
1370
+ background-image: svg-inline(recurring-active);
1371
+ height: 10px;
1372
+ width: 10px;
1373
+ }
1374
+
1375
+ .tribe-common .tribe-common-svgicon--search {
1376
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");
1377
+ }
1378
+
1379
+ .tribe-common .tribe-common-svgicon--filters {
1380
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23727272'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23727272'/%3E%3Cpath d='M12 9v6' stroke='%23727272'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
1381
+ }
1382
+
1383
+ .tribe-common .tribe-common-svgicon--close {
1384
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'%3E%3Cpath d='M16 2L2 16M16 16L2 2' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
1385
+ }
1386
+
1387
+ /* .tribe-common { */
1388
+
1389
+ /* -----------------------------------------------------------------------------
1390
+ *
1391
+ * Tables
1392
+ *
1393
+ * ----------------------------------------------------------------------------- */
1394
+
1395
+ /* -----------------------------------------------------------------------------
1396
+ * Tables: Theme Overrides
1397
+ * ----------------------------------------------------------------------------- */
1398
+
1399
+ /* } */
1400
+
1401
+ /* A11y */
1402
+
1403
+ /* -----------------------------------------------------------------------------
1404
+ *
1405
+ * A11y
1406
+ *
1407
+ * This file is just a clearing-house.
1408
+ * Make partials (start with an underscore) for any actual css code.
1409
+ *
1410
+ * ----------------------------------------------------------------------------- */
1411
+
1412
+ /* -----------------------------------------------------------------------------
1413
+ * Hide from screenreaders & browsers
1414
+ * ----------------------------------------------------------------------------- */
1415
+
1416
+ .tribe-common .tribe-common-a11y-hidden {
1417
+ display: none !important;
1418
+ visibility: hidden;
1419
+ }
1420
+
1421
+ /* -----------------------------------------------------------------------------
1422
+ * Hide from browsers & show for screenreaders
1423
+ * ----------------------------------------------------------------------------- */
1424
+
1425
+ .tribe-common .tribe-common-a11y-visual-hide {
1426
+ border: 0;
1427
+ clip: rect(0 0 0 0);
1428
+ height: 1px;
1429
+ margin: -1px;
1430
+ overflow: hidden;
1431
+ padding: 0;
1432
+ position: absolute;
1433
+ width: 1px;
1434
+ }
1435
+
1436
+ /* -----------------------------------------------------------------------------
1437
+ * Show for browsers & screenreaders
1438
+ * ----------------------------------------------------------------------------- */
1439
+
1440
+ .tribe-common .tribe-common-a11y-visual-show {
1441
+ border: 0;
1442
+ clip: rect(0 0 0 0);
1443
+ height: 1px;
1444
+ margin: -1px;
1445
+ overflow: hidden;
1446
+ padding: 0;
1447
+ position: absolute;
1448
+ width: 1px;
1449
+ }
1450
+
1451
+ /* Components */
1452
+
1453
+ /* -----------------------------------------------------------------------------
1454
+ *
1455
+ * Components Skeleton
1456
+ *
1457
+ * This file is just a clearing-house.
1458
+ * Make partials (start with an underscore) for any actual css code.
1459
+ *
1460
+ * ----------------------------------------------------------------------------- */
1461
+
1462
+ /* Buttons */
1463
+
1464
+ .tribe-common {
1465
+
1466
+ /* -------------------------------------------------------------------------
1467
+ *
1468
+ * Button: Border - Theme Overrides
1469
+ *
1470
+ * ------------------------------------------------------------------------- */
1471
+ }
1472
+
1473
+ /* -----------------------------------------------------------------------------
1474
+ *
1475
+ * Button: Border
1476
+ *
1477
+ * Example:
1478
+ * <button class="tribe-common-c-btn-border">...</button>
1479
+ * <a href="#" class="tribe-common-c-btn-border">...</a>
1480
+ *
1481
+ * ----------------------------------------------------------------------------- */
1482
+
1483
+ .tribe-common .tribe-common-c-btn-border,
1484
+ .tribe-common a.tribe-common-c-btn-border {
1485
+ padding: 14px 20px 14px;
1486
+ width: 100%;
1487
+ }
1488
+
1489
+ .tribe-common {
1490
+
1491
+ /* -----------------------------------------------------------------------------
1492
+ *
1493
+ * Button: Icon Border
1494
+ *
1495
+ * Example:
1496
+ * <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</button>
1497
+ * <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--border tribe-common-c-btn-icon--filter">...</a>
1498
+ *
1499
+ * ----------------------------------------------------------------------------- */
1500
+
1501
+ /* -------------------------------------------------------------------------
1502
+ *
1503
+ * Button: Icon Border - Theme Overrides
1504
+ *
1505
+ * ------------------------------------------------------------------------- */
1506
+ }
1507
+
1508
+ /* -----------------------------------------------------------------------------
1509
+ *
1510
+ * Button: Icon
1511
+ *
1512
+ * Example:
1513
+ * <button class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</button>
1514
+ * <a href="#" class="tribe-common-c-btn-icon tribe-common-c-btn-icon--filter">...</a>
1515
+ *
1516
+ * ----------------------------------------------------------------------------- */
1517
+
1518
+ .tribe-common .tribe-common-c-btn-icon:before {
1519
+ background-repeat: no-repeat;
1520
+ background-size: contain;
1521
+ content: '';
1522
+ display: block;
1523
+ }
1524
+
1525
+ /* -----------------------------------------------------------------------------
1526
+ * Button: Icon Caret Left
1527
+ * ----------------------------------------------------------------------------- */
1528
+
1529
+ .tribe-common .tribe-common-c-btn-icon--caret-left:before {
1530
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");
1531
+ height: 20px;
1532
+ width: 12px;
1533
+ }
1534
+
1535
+ .tribe-common .tribe-common-c-btn-icon--caret-left:active:before, .tribe-common .tribe-common-c-btn-icon--caret-left:hover:before, .tribe-common .tribe-common-c-btn-icon--caret-left:focus:before {
1536
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23727272'/%3E%3C/svg%3E");
1537
+ }
1538
+
1539
+ .tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before {
1540
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E");
1541
+ }
1542
+
1543
+ /* -----------------------------------------------------------------------------
1544
+ * Button: Icon Caret Right
1545
+ * ----------------------------------------------------------------------------- */
1546
+
1547
+ .tribe-common .tribe-common-c-btn-icon--caret-right:before {
1548
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");
1549
+ height: 20px;
1550
+ width: 12px;
1551
+ }
1552
+
1553
+ .tribe-common .tribe-common-c-btn-icon--caret-right:active:before, .tribe-common .tribe-common-c-btn-icon--caret-right:hover:before, .tribe-common .tribe-common-c-btn-icon--caret-right:focus:before {
1554
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23727272'/%3E%3C/svg%3E");
1555
+ }
1556
+
1557
+ .tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before {
1558
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E");
1559
+ }
1560
+
1561
+ /* -----------------------------------------------------------------------------
1562
+ * Button: Icon Filters
1563
+ * ----------------------------------------------------------------------------- */
1564
+
1565
+ .tribe-common .tribe-common-c-btn-icon--filters:before {
1566
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23727272'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23727272'/%3E%3Cpath d='M12 9v6' stroke='%23727272'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23727272'/%3E%3C/g%3E%3C/svg%3E");
1567
+ height: 20px;
1568
+ width: 24px;
1569
+ }
1570
+
1571
+ .tribe-common .tribe-common-c-btn-icon--filters:active:before, .tribe-common .tribe-common-c-btn-icon--filters:hover:before, .tribe-common .tribe-common-c-btn-icon--filters:focus:before {
1572
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23141827'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23141827'/%3E%3Cpath d='M12 9v6' stroke='%23141827'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23141827'/%3E%3C/g%3E%3C/svg%3E");
1573
+ }
1574
+
1575
+ .tribe-common .tribe-common-c-btn-icon--filters:disabled:before {
1576
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0M3 15v-2' stroke='%23D5D5D5'/%3E%3Ccircle cx='3' cy='9' r='3' stroke='%23D5D5D5'/%3E%3Cpath d='M12 9v6' stroke='%23D5D5D5'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)' stroke='%23D5D5D5'/%3E%3C/g%3E%3C/svg%3E");
1577
+ }
1578
+
1579
+ /* -----------------------------------------------------------------------------
1580
+ * Button: Icon Search
1581
+ * ----------------------------------------------------------------------------- */
1582
+
1583
+ .tribe-common .tribe-common-c-btn-icon--search:before {
1584
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");
1585
+ height: 20px;
1586
+ width: 20px;
1587
+ }
1588
+
1589
+ .tribe-common .tribe-common-c-btn-icon--search:active:before, .tribe-common .tribe-common-c-btn-icon--search:hover:before, .tribe-common .tribe-common-c-btn-icon--search:focus:before {
1590
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E");
1591
+ }
1592
+
1593
+ .tribe-common .tribe-common-c-btn-icon--search:disabled:before {
1594
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E");
1595
+ }
1596
+
1597
+ .tribe-common {
1598
+
1599
+ /* -------------------------------------------------------------------------
1600
+ *
1601
+ * Button: Solid - Theme Overrides
1602
+ *
1603
+ * ------------------------------------------------------------------------- */
1604
+ }
1605
+
1606
+ /* -----------------------------------------------------------------------------
1607
+ *
1608
+ * Button: Solid
1609
+ *
1610
+ * Example:
1611
+ * <button class="tribe-common-c-btn">...</button>
1612
+ * <a href="#" class="tribe-common-c-btn">...</a>
1613
+ *
1614
+ * ----------------------------------------------------------------------------- */
1615
+
1616
+ .tribe-common .tribe-common-c-btn,
1617
+ .tribe-common a.tribe-common-c-btn {
1618
+ padding: 11px 20px 11px;
1619
+ width: 100%;
1620
+ }
1621
+
1622
+ /* -----------------------------------------------------------------------------
1623
+ *
1624
+ * Component: Image
1625
+ *
1626
+ * Example (Regular):
1627
+ * <img src="#" alt="" class="tribe-common-c-image" />
1628
+ *
1629
+ * Example (Background):
1630
+ * <div class="tribe-common-c-image tribe-common-c-image--bg">
1631
+ * <div class="tribe-common-c-image__bg"></div>
1632
+ * </div>
1633
+ *
1634
+ * ----------------------------------------------------------------------------- */
1635
+
1636
+ .tribe-common .tribe-common-c-image {
1637
+ display: block;
1638
+ height: auto;
1639
+ margin-left: auto;
1640
+ margin-right: auto;
1641
+ width: 100%;
1642
+ }
1643
+
1644
+ .tribe-common .tribe-common-c-image--bg {
1645
+ position: relative;
1646
+ }
1647
+
1648
+ .tribe-common .tribe-common-c-image__bg {
1649
+ background: center center no-repeat;
1650
+ background-size: cover;
1651
+ bottom: 0;
1652
+ height: 100%;
1653
+ left: 0;
1654
+ position: absolute;
1655
+ right: 0;
1656
+ top: 0;
1657
+ width: 100%;
1658
+ }
1659
+
1660
+ /* -----------------------------------------------------------------------------
1661
+ *
1662
+ * Component: Loader
1663
+ *
1664
+ *
1665
+ * Example:
1666
+ * <div class="tribe-events-view-loader__dots tribe-common-c-loader">
1667
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--first"></div>
1668
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--second"></div>
1669
+ * <div class="tribe-common-c-loader__dot tribe-common-c-loader__dot--third"></div>
1670
+ * </div>
1671
+ *
1672
+ * ----------------------------------------------------------------------------- */
1673
+
1674
+ .tribe-common .tribe-common-c-loader {
1675
+ display: -webkit-box;
1676
+ display: flex;
1677
+ padding-top: 192px;
1678
+ }
1679
+
1680
+ .tribe-common .tribe-common-c-loader__dot {
1681
+ background-color: rgba(51,74,255, 0.07);
1682
+ height: 15px;
1683
+ width: 15px;
1684
+ border-radius: 50%;
1685
+ }
1686
+
1687
+ .tribe-common .tribe-common-c-loader__dot:not(:first-of-type) {
1688
+ margin-left: 8px;
1689
+ }
1690
+
1691
+ @media (min-width: 768px) {
1692
+
1693
+ .tribe-common .tribe-common-form-control-text__input {
1694
+ padding: 20px 20px 20px 40px
1695
+ }
1696
+
1697
+ #top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input {
1698
+ padding: 20px 20px 20px 40px
1699
+ }
1700
+
1701
+ .tribe-common .tribe-common-g-row--gutters {
1702
+ margin-left: -24px;
1703
+ margin-right: -24px
1704
+ }
1705
+
1706
+ .tribe-common .tribe-common-g-row--gutters > .tribe-common-g-col {
1707
+ padding-left: 24px;
1708
+ padding-right: 24px
1709
+ }
1710
+
1711
+ .tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters {
1712
+ margin-left: -24px;
1713
+ margin-right: -24px
1714
+ }
1715
+
1716
+ .tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters > .entry.tribe-common-g-col {
1717
+ padding-left: 24px;
1718
+ padding-right: 24px
1719
+ }
1720
+
1721
+ .tribe-common .tribe-common-l-container {
1722
+ padding-left: 42px;
1723
+ padding-right: 42px
1724
+ }
1725
+
1726
+ .tribe-common .tribe-common-c-btn-border,
1727
+ .tribe-common a.tribe-common-c-btn-border {
1728
+ padding: 6px 15px;
1729
+ width: auto
1730
+ }
1731
+
1732
+ .tribe-common .tribe-common-c-btn,
1733
+ .tribe-common a.tribe-common-c-btn {
1734
+ width: auto
1735
+ }
1736
+
1737
+ .tribe-common .tribe-common-c-loader {
1738
+ padding-top: 288px
1739
+ }
1740
+ }
common/src/resources/css/common-skeleton.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-common{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}.tribe-common *{box-sizing:border-box}.tribe-common article,.tribe-common aside,.tribe-common details,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common header,.tribe-common main,.tribe-common menu,.tribe-common nav,.tribe-common section,.tribe-common summary{display:block}.tribe-common svg:not(:root){overflow:hidden}.tribe-common audio,.tribe-common canvas,.tribe-common progress,.tribe-common video{display:inline-block}.tribe-common audio:not([controls]){display:none;height:0}.tribe-common progress{vertical-align:baseline}.tribe-common [hidden],.tribe-common template{display:none}.tribe-common pre{overflow:auto}.tribe-common sub,.tribe-common sup{position:relative;vertical-align:baseline}.tribe-common sup{top:-.5em}.tribe-common sub{bottom:-.25em}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{box-sizing:border-box;margin:0}.tribe-common input[type=number]::-webkit-inner-spin-button,.tribe-common input[type=number]::-webkit-outer-spin-button{height:auto}.tribe-common legend{color:inherit;display:table;max-width:100%;white-space:normal}.tribe-common textarea{resize:none;overflow:auto}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=reset],.tribe-common input[type=submit]{cursor:pointer;overflow:visible}.tribe-common button[disabled],.tribe-common input[disabled]{cursor:default}.tribe-common button::-moz-focus-inner,.tribe-common input::-moz-focus-inner{border:0;padding:0}.tribe-common a,.tribe-common abbr,.tribe-common acronym,.tribe-common address,.tribe-common applet,.tribe-common article,.tribe-common aside,.tribe-common audio,.tribe-common b,.tribe-common big,.tribe-common blockquote,.tribe-common canvas,.tribe-common caption,.tribe-common center,.tribe-common cite,.tribe-common code,.tribe-common dd,.tribe-common del,.tribe-common details,.tribe-common dfn,.tribe-common div,.tribe-common dl,.tribe-common dt,.tribe-common em,.tribe-common embed,.tribe-common fieldset,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common form,.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common header,.tribe-common i,.tribe-common iframe,.tribe-common img,.tribe-common ins,.tribe-common kbd,.tribe-common label,.tribe-common legend,.tribe-common li,.tribe-common main,.tribe-common mark,.tribe-common menu,.tribe-common nav,.tribe-common object,.tribe-common ol,.tribe-common output,.tribe-common p,.tribe-common pre,.tribe-common q,.tribe-common ruby,.tribe-common s,.tribe-common samp,.tribe-common section,.tribe-common small,.tribe-common span,.tribe-common strike,.tribe-common strong,.tribe-common sub,.tribe-common summary,.tribe-common sup,.tribe-common table,.tribe-common tbody,.tribe-common td,.tribe-common tfoot,.tribe-common th,.tribe-common thead,.tribe-common time,.tribe-common tr,.tribe-common tt,.tribe-common u,.tribe-common ul,.tribe-common var,.tribe-common video{margin:0;padding:0;border:0}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common img{-ms-interpolation-mode:bicubic;height:auto;max-width:100%;border-style:none}.tribe-common embed,.tribe-common iframe,.tribe-common video{max-width:100%;max-height:100%}.tribe-theme-avada input[type=text]{margin:0}.tribe-theme-divi .entry-content .tribe-common table,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table{border:0;margin:0}.tribe-theme-divi .entry-content .tribe-common td,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td{border:0}.tribe-theme-divi #content-area .tribe-common td,.tribe-theme-divi #content-area .tribe-common th,.tribe-theme-divi #content-area .tribe-common tr,.tribe-theme-divi #left-area .tribe-common ul{padding:0}#top .main_color .tribe-common button[disabled],#top.tribe-theme-enfold .tribe-common button[disabled]{cursor:default}#top .main_color .tribe-common form,#top .main_color .tribe-common input,#top.tribe-theme-enfold .tribe-common form,#top.tribe-theme-enfold .tribe-common input{margin:0}.entry-content-wrapper .tribe-common li,.entry-content .tribe-common ol,.entry-content .tribe-common ul,.tribe-theme-genesis .tribe-common ol,.tribe-theme-genesis .tribe-common ul{margin:0;padding:0}.tribe-theme-twentyseventeen .tribe-common div.tribe-dialog{z-index:5!important}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{cursor:pointer;display:inline-block;margin:0;vertical-align:middle}#top .main_color .tribe-common .tribe-common-form-control-checkbox__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{display:inline-block}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider__input{cursor:pointer;display:inline-block;margin:0;padding:0;width:120px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{height:auto;padding:12px 28px 12px 0;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-form-control-text__input{padding:20px 20px 20px 40px}#top .main_color .tribe-common .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{padding:12px 28px 12px 0;width:100%}#top .main_color .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input,#top.tribe-theme-enfold .tribe-common.tribe-common--breakpoint-medium .tribe-common-form-control-text__input{padding:20px 20px 20px 40px}.tribe-common .tribe-common-form-control-toggle__input,.tribe-common .tribe-common-form-control-toggle__label{cursor:pointer;display:inline-block;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle__label{margin-left:11px}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top .main_color .tribe-common .tribe-common-form-control-toggle__input,#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:21px;padding-right:21px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px;padding:0}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .entry.tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{margin:0;padding-left:21px;padding-right:21px}.tribe-theme-twentynineteen .tribe-common.tribe-common--breakpoint-medium .tribe-common-g-row--gutters>.entry.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-common a{cursor:pointer}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.entry-content .tribe-common ol>li,.entry-content .tribe-common ul>li{list-style-type:none}.tribe-common button{padding:0}.tribe-common .tribe-common-l-container{max-width:1260px;margin-left:auto;margin-right:auto;padding-left:19.5px;padding-right:19.5px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-l-container{padding-left:42px;padding-right:42px}.tribe-common .tribe-common-svgicon{background-repeat:no-repeat;background-size:contain}.tribe-common .tribe-common-svgicon--close-secondary{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23BABABA' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--day{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874H16.8a.873.873 0 0 0 .873-.874V14.53a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--list{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'%3E%3Cg fill='%23141827' fill-rule='evenodd'%3E%3Cpath fill-rule='nonzero' d='M0 .504v20.03c0 .278.19.503.425.503h20.188c.235 0 .425-.225.425-.504V.503c0-.277-.19-.503-.425-.503H.425C.19 0 0 .226 0 .504zm1.158.944h18.695v2.705H1.158V1.448zm0 2.705h18.695v15.432H1.158V4.153z'/%3E%3Cpath d='M13.39 5.731v2.13a1.07 1.07 0 0 0 1.076 1.064h2.154a1.07 1.07 0 0 0 1.077-1.065V5.731a1.07 1.07 0 0 0-1.077-1.064h-2.154A1.07 1.07 0 0 0 13.39 5.73z'/%3E%3Cpath fill-rule='nonzero' d='M8.84 8.937c.286 0 .52-.236.52-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.52.522v.425c0 .287.234.523.52.523h4.82zm2.064-2.8c.287 0 .521-.236.521-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.521.522v.425c0 .287.234.523.52.523h6.884z'/%3E%3Cpath d='M13.39 12.731v2.13a1.07 1.07 0 0 0 1.076 1.064h2.154a1.07 1.07 0 0 0 1.077-1.065v-2.129a1.07 1.07 0 0 0-1.077-1.064h-2.154a1.07 1.07 0 0 0-1.077 1.064z'/%3E%3Cpath fill-rule='nonzero' d='M8.84 15.937c.286 0 .52-.236.52-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.52.522v.425c0 .287.234.523.52.523h4.82zm2.064-2.8c.287 0 .521-.236.521-.523v-.425a.523.523 0 0 0-.52-.522H4.02a.523.523 0 0 0-.521.522v.425c0 .287.234.523.52.523h6.884z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'%3E%3Cg fill='%23141827' fill-rule='nonzero'%3E%3Cg stroke-width='.7'%3E%3Cpath stroke='%23141827' d='M10.67 17.21c.182-.225 4.46-5.527 4.46-8.18 0-2.728-2.085-4.947-4.648-4.947-2.563 0-4.649 2.22-4.649 4.946 0 2.654 4.279 7.956 4.46 8.18a.243.243 0 0 0 .189.092c.072 0 .14-.034.188-.092zM6.33 9.03c0-2.436 1.863-4.418 4.152-4.418 2.29 0 4.152 1.982 4.152 4.417 0 2.16-3.318 6.533-4.152 7.597C9.648 15.562 6.33 11.19 6.33 9.03z'/%3E%3Cpath stroke='%23000' d='M12.055 9.04c0-.911-.706-1.652-1.573-1.652-.868 0-1.574.74-1.574 1.652 0 .91.706 1.652 1.574 1.652.867 0 1.573-.741 1.573-1.652zm-2.85 0c0-.74.573-1.34 1.277-1.34s1.277.6 1.277 1.34c0 .74-.573 1.34-1.277 1.34s-1.277-.6-1.277-1.34z'/%3E%3C/g%3E%3Cpath d='M0 .504v20.03c0 .278.19.503.425.503h20.188c.235 0 .425-.225.425-.504V.503c0-.277-.19-.503-.425-.503H.425C.19 0 0 .226 0 .504zm1.158.944h18.695v2.705H1.158V1.448zm0 2.705h18.695v15.432H1.158V4.153z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--month{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--no-map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='92' height='92' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none'%3E%3Cg stroke='%23141827' stroke-width='2.5' transform='translate(2 2)'%3E%3Cpath d='M32.219 88S0 58.674 0 32.281C-.011 15.598 12.685 1.66 29.278.136c16.593-1.523 31.608 9.873 34.627 26.28M32.733 88s2.96-2.693 7.083-7.181' stroke-linecap='round'/%3E%3Ccircle cx='33' cy='33' r='8.905'/%3E%3Ccircle cx='65.127' cy='59.016' r='23.571'/%3E%3C/g%3E%3Cg transform='translate(64.857 47.048)'%3E%3Ccircle fill='%23111' cx='2.839' cy='26.495' r='2.839'/%3E%3Cpath d='M2.642 0v18.925' stroke='%23141827' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--photo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 21 21'%3E%3Cg fill='%23141827'%3E%3Cpath d='M20.407 0H.577A.565.565 0 0 0 0 .564v19.872c0 .316.254.564.578.564h19.83a.565.565 0 0 0 .577-.564V.564A.565.565 0 0 0 20.407 0zm-.6 1.15v14.868l-2.226-3.427c-.646-.677-1.848-.677-2.495 0l-1.548 1.646-4.482-5.029a1.806 1.806 0 0 0-1.363-.586c-.508 0-1.016.225-1.34.609l-5.175 5.75V1.15h18.628zM1.177 19.85v-3.133l6.053-6.765a.588.588 0 0 1 .462-.203c.162 0 .37.068.485.203l4.921 5.525c.116.113.278.203.44.203.184.022.323-.068.438-.18l1.987-2.12c.185-.203.555-.203.763 0l3.103 4.352v2.14H1.178v-.022z'/%3E%3Cpath d='M14.955 9.041c1.16 0 2.122-.97 2.122-2.187 0-1.218-.94-2.187-2.122-2.187-1.181 0-2.122.97-2.122 2.187 0 1.218.963 2.187 2.122 2.187zm0-3.224c.547 0 1.006.473 1.006 1.037s-.459 1.037-1.006 1.037c-.547 0-1.006-.473-1.006-1.037s.46-1.037 1.006-1.037z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--week{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23141827'/%3E%3C/svg%3E");height:10px;width:8px}.tribe-common .tribe-common-svgicon--recurring{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.333 3.826c0 .065 0 .13-.02.174 0 .022-.02.065-.02.087a.9.9 0 0 1-.197.37L10.45 7.37a.797.797 0 0 1-.592.26.797.797 0 0 1-.593-.26c-.316-.348-.316-.935 0-1.305l1.225-1.348H6.3c-2.547 0-4.64 2.283-4.64 5.11 0 1.369.474 2.651 1.363 3.608.316.348.316.935 0 1.304A.797.797 0 0 1 2.43 15a.797.797 0 0 1-.593-.26C.652 13.434 0 11.695 0 9.847c0-3.826 2.825-6.935 6.301-6.935h4.208L9.284 1.565c-.316-.348-.316-.935 0-1.304.316-.348.85-.348 1.185 0l2.647 2.913a.952.952 0 0 1 .198.37c0 .021.02.065.02.086v.196zM20 10.152c0 3.826-2.825 6.935-6.301 6.935H9.49l1.225 1.348c.336.348.336.935 0 1.304a.797.797 0 0 1-.593.261.83.83 0 0 1-.592-.26l-2.627-2.936a.948.948 0 0 1-.198-.37c0-.021-.02-.064-.02-.086-.02-.065-.02-.109-.02-.174 0-.065 0-.13.02-.174 0-.022.02-.065.02-.087a.9.9 0 0 1 .198-.37L9.55 12.63c.316-.347.849-.347 1.185 0 .336.348.336.935 0 1.305L9.51 15.283h4.208c2.548 0 4.641-2.283 4.641-5.11 0-1.369-.474-2.651-1.362-3.608a.97.97 0 0 1 0-1.304c.316-.348.849-.348 1.185 0C19.348 6.543 20 8.283 20 10.152z' fill='%23141827'/%3E%3C/svg%3E");height:10px;width:10px}.tribe-common .tribe-common-svgicon--search{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--filters{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%235D5D5D' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--close{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%235D5D5D' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide,.tribe-common .tribe-common-a11y-visual-show{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:14px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn-border,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn-border{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--caret-left:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-left:active:before,.tribe-common .tribe-common-c-btn-icon--caret-left:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-left:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-right:active:before,.tribe-common .tribe-common-c-btn-icon--caret-right:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-right:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%235D5D5D'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%235D5D5D' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E");height:20px;width:24px}.tribe-common .tribe-common-c-btn-icon--filters:active:before,.tribe-common .tribe-common-c-btn-icon--filters:focus:before,.tribe-common .tribe-common-c-btn-icon--filters:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23D5D5D5' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%235D5D5D'/%3E%3C/svg%3E");height:20px;width:20px}.tribe-common .tribe-common-c-btn-icon--search:active:before,.tribe-common .tribe-common-c-btn-icon--search:focus:before,.tribe-common .tribe-common-c-btn-icon--search:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{padding:11px 20px;width:100%}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-btn,.tribe-common--breakpoint-medium.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.tribe-common .tribe-common-c-loader{display:flex;padding-top:192px}.tribe-common--breakpoint-medium.tribe-common .tribe-common-c-loader{padding-top:288px}.tribe-common .tribe-common-c-loader__dot{background-color:rgba(51,74,255,.07);height:15px;width:15px;border-radius:50%}.tribe-common .tribe-common-c-loader__dot:not(:first-of-type){margin-left:8px}
1
+ .tribe-common{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased}.tribe-common *{box-sizing:border-box}.tribe-common article,.tribe-common aside,.tribe-common details,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common header,.tribe-common main,.tribe-common menu,.tribe-common nav,.tribe-common section,.tribe-common summary{display:block}.tribe-common svg:not(:root){overflow:hidden}.tribe-common audio,.tribe-common canvas,.tribe-common progress,.tribe-common video{display:inline-block}.tribe-common audio:not([controls]){display:none;height:0}.tribe-common progress{vertical-align:baseline}.tribe-common [hidden],.tribe-common template{display:none}.tribe-common pre{overflow:auto}.tribe-common sub,.tribe-common sup{position:relative;vertical-align:baseline}.tribe-common sup{top:-.5em}.tribe-common sub{bottom:-.25em}.tribe-common button,.tribe-common input,.tribe-common select,.tribe-common textarea{box-sizing:border-box;margin:0}.tribe-common input[type=number]::-webkit-inner-spin-button,.tribe-common input[type=number]::-webkit-outer-spin-button{height:auto}.tribe-common legend{color:inherit;display:table;max-width:100%;white-space:normal}.tribe-common textarea{resize:none;overflow:auto}.tribe-common button,.tribe-common input[type=button],.tribe-common input[type=reset],.tribe-common input[type=submit]{cursor:pointer;overflow:visible}.tribe-common button[disabled],.tribe-common input[disabled]{cursor:default}.tribe-common button::-moz-focus-inner,.tribe-common input::-moz-focus-inner{border:0;padding:0}.tribe-common a,.tribe-common abbr,.tribe-common acronym,.tribe-common address,.tribe-common applet,.tribe-common article,.tribe-common aside,.tribe-common audio,.tribe-common b,.tribe-common big,.tribe-common blockquote,.tribe-common canvas,.tribe-common caption,.tribe-common center,.tribe-common cite,.tribe-common code,.tribe-common dd,.tribe-common del,.tribe-common details,.tribe-common dfn,.tribe-common div,.tribe-common dl,.tribe-common dt,.tribe-common em,.tribe-common embed,.tribe-common fieldset,.tribe-common figcaption,.tribe-common figure,.tribe-common footer,.tribe-common form,.tribe-common h1,.tribe-common h2,.tribe-common h3,.tribe-common h4,.tribe-common h5,.tribe-common h6,.tribe-common header,.tribe-common i,.tribe-common iframe,.tribe-common img,.tribe-common ins,.tribe-common kbd,.tribe-common label,.tribe-common legend,.tribe-common li,.tribe-common main,.tribe-common mark,.tribe-common menu,.tribe-common nav,.tribe-common object,.tribe-common ol,.tribe-common output,.tribe-common p,.tribe-common pre,.tribe-common q,.tribe-common ruby,.tribe-common s,.tribe-common samp,.tribe-common section,.tribe-common small,.tribe-common span,.tribe-common strike,.tribe-common strong,.tribe-common sub,.tribe-common summary,.tribe-common sup,.tribe-common table,.tribe-common tbody,.tribe-common td,.tribe-common tfoot,.tribe-common th,.tribe-common thead,.tribe-common time,.tribe-common tr,.tribe-common tt,.tribe-common u,.tribe-common ul,.tribe-common var,.tribe-common video{margin:0;padding:0;border:0}.tribe-common ol,.tribe-common ul{list-style:none}.tribe-common img{-ms-interpolation-mode:bicubic;height:auto;max-width:100%;border-style:none}.tribe-common embed,.tribe-common iframe,.tribe-common video{max-width:100%;max-height:100%}.tribe-theme-avada input[type=text]{margin:0}.tribe-theme-divi .entry-content .tribe-common table,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common table{border:0;margin:0}.tribe-theme-divi .entry-content .tribe-common td,.tribe-theme-divibody.et-pb-preview #main-content .container .tribe-common td{border:0}.tribe-theme-divi #content-area .tribe-common td,.tribe-theme-divi #content-area .tribe-common th,.tribe-theme-divi #content-area .tribe-common tr{padding:0}#top.tribe-theme-enfold .tribe-common form,#top.tribe-theme-enfold .tribe-common input{margin:0}.tribe-common .tribe-common-form-control-checkbox__label,.tribe-common .tribe-common-form-control-radio__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-checkbox__input,.tribe-common .tribe-common-form-control-radio__input{cursor:pointer;display:inline-block;margin:0;vertical-align:middle}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-checkbox__input{display:inline-block}.tribe-common .tribe-common-form-control-checkbox-radio-group>*{margin-bottom:15px}.tribe-common .tribe-common-form-control-checkbox-radio-group>:last-child{margin-bottom:0}.tribe-common .tribe-common-form-control-slider__input{cursor:pointer;display:inline-block;margin:0;padding:0;width:120px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider__label{cursor:pointer;display:inline-block;margin-left:11px;vertical-align:middle}.tribe-common .tribe-common-form-control-slider--vertical .tribe-common-form-control-slider__label{display:block;margin:0 0 6px}.tribe-common .tribe-common-form-control-text__label{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-form-control-text__input{height:auto;padding:12px 28px 12px 0;width:100%}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input{padding:12px 28px 12px 0;width:100%}.tribe-common .tribe-common-form-control-toggle__input,.tribe-common .tribe-common-form-control-toggle__label{cursor:pointer;display:inline-block;vertical-align:middle}.tribe-common .tribe-common-form-control-toggle__label{margin-left:11px}.tribe-common .tribe-common-form-control-toggle--vertical .tribe-common-form-control-toggle__label{display:block;margin:0 0 6px}#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-toggle__input{display:inline-block;margin:5px 0}.tribe-common .tribe-common-g-col{min-width:0;width:100%}.tribe-common .tribe-common-g-row{display:flex;flex-wrap:wrap}.tribe-common .tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:21px;padding-right:21px}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:-21px;margin-right:-21px;padding:0}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{margin:0;padding-left:21px;padding-right:21px}.tribe-common a{cursor:pointer}.tribe-theme-divi #left-area .tribe-common ul,.tribe-theme-divi .entry-content .tribe-common ul,body.et-pb-preview.tribe-theme-divi #main-content .container .tribe-common ul{list-style-type:none;padding:0}.tribe-common button{padding:0}.tribe-common .tribe-common-l-container{max-width:1260px;margin-left:auto;margin-right:auto;padding-left:19.5px;padding-right:19.5px;width:100%}.tribe-common .tribe-common-svgicon{background-repeat:no-repeat;background-size:contain}.tribe-common .tribe-common-svgicon--close-secondary{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23BABABA' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--day{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zM14.18 14.53v1.747c0 .482.39.874.873.874H16.8a.873.873 0 0 0 .873-.874V14.53a.873.873 0 0 0-.873-.873h-1.747a.873.873 0 0 0-.873.873z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--list{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='18' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827'%3E%3Cpath d='M19.883 3.272c.342 0 .622-.21.622-.467v-.464c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.464c0 .257.28.467.622.467h12.756zm-18.045.935a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 9.98c.342 0 .622-.21.622-.466v-.465c0-.257-.28-.467-.622-.467H7.127c-.342 0-.622.21-.622.467v.465c0 .256.28.466.622.466h12.756zm-18.045.936a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5zM19.883 16.689c.342 0 .622-.21.622-.467v-.465c0-.256-.28-.466-.622-.466H7.127c-.342 0-.622.21-.622.466v.465c0 .257.28.467.622.467h12.756zm-18.045.935a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--map{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827'%3E%3Cpath stroke-linejoin='round' d='M13.921 11.632H17.5l3.588 8.421H1l3.488-8.421h4.016'/%3E%3Cpath d='M11.32 15.506c.2-.248 4.93-6.108 4.93-9.04 0-3.015-2.305-5.468-5.138-5.468-2.833 0-5.138 2.453-5.138 5.467 0 2.933 4.729 8.793 4.93 9.041a.268.268 0 0 0 .208.101c.08 0 .155-.037.207-.101zm-4.797-9.04c0-2.693 2.058-4.883 4.589-4.883 2.53 0 4.588 2.19 4.588 4.882 0 2.387-3.667 7.22-4.588 8.397-.922-1.177-4.589-6.009-4.589-8.397z' stroke-width='.4' fill='%23141827' fill-rule='nonzero'/%3E%3Cpath d='M12.85 6.477c0-1.007-.78-1.826-1.738-1.826-.96 0-1.74.819-1.74 1.826 0 1.007.78 1.826 1.74 1.826.959 0 1.739-.82 1.739-1.826zm-3.15 0c0-.817.633-1.482 1.412-1.482.778 0 1.41.665 1.41 1.482s-.632 1.482-1.41 1.482c-.779 0-1.412-.665-1.412-1.482z' stroke-width='.7' fill='%23000' fill-rule='nonzero'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--month{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='22' height='22' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.637 1.063v19.879c0 .276.189.5.422.5h20.037c.232 0 .421-.224.421-.5V1.062c0-.275-.189-.5-.421-.5H1.059c-.233 0-.422.225-.422.5zM1.787 2H20.34v2.685H1.787V2zm0 4H20.34v14H1.787V6zM8 8.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-8 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm-12 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm0 4v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5zm4 0v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--no-map{background-image:svg-inline(no-map)}.tribe-common .tribe-common-svgicon--photo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='17' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23141827'%3E%3Cpath d='M19.348.11H.634a.509.509 0 0 0-.52.508v15.017c0 .284.23.508.52.508h18.714a.51.51 0 0 0 .52-.508V.618a.509.509 0 0 0-.52-.508zm-.54 1.035v10.837l-2.87-3.084c-.583-.61-1.664-.61-2.246 0l-1.393 1.481-4.034-4.525a1.625 1.625 0 0 0-1.227-.528 1.6 1.6 0 0 0-1.206.548l-4.657 5.175V1.145h17.632zM1.174 15.108v-2.496l5.448-6.089a.529.529 0 0 1 .415-.182c.146 0 .333.06.437.182l4.429 4.972c.104.102.25.183.395.183.166.02.291-.06.395-.162l1.788-1.908c.167-.183.5-.183.686 0l3.66 3.917v1.603H1.175v-.02z'/%3E%3Cpath d='M14.19 5.757c1.044 0 1.91-.872 1.91-1.968s-.846-1.969-1.91-1.969c-1.062 0-1.909.873-1.909 1.969s.866 1.968 1.91 1.968zm0-2.902c.493 0 .907.427.907.934 0 .507-.414.933-.906.933-.492 0-.906-.426-.906-.933 0-.507.414-.934.906-.934z'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--week{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='21' height='21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 .503v19.994c0 .278.19.503.424.503h20.152c.234 0 .424-.225.424-.503V.503C21 .225 20.81 0 20.576 0H.424C.19 0 0 .225 0 .503zm1.156.943h18.66v2.7H1.157v-2.7zm0 4.023h18.66V19.55H1.157V5.469zm6.25 6.537v1.006c0 .278.224.503.502.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H7.908a.503.503 0 0 0-.503.502zm4.022 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H11.93a.503.503 0 0 0-.503.502zm4.023 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502h-1.006a.503.503 0 0 0-.503.502zm-12.069 0v1.006c0 .278.225.503.503.503h1.006a.503.503 0 0 0 .503-.503v-1.006a.503.503 0 0 0-.503-.502H3.885a.503.503 0 0 0-.503.502z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--featured{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='16' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h16v20l-7.902-5.122L0 20z' fill='%23141827'/%3E%3C/svg%3E");height:10px;width:8px}.tribe-common .tribe-common-svgicon--recurring{background-image:svg-inline(recurring-active);height:10px;width:10px}.tribe-common .tribe-common-svgicon--search{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--filters{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-svgicon--close{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23727272' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E")}.tribe-common .tribe-common-a11y-hidden{display:none!important;visibility:hidden}.tribe-common .tribe-common-a11y-visual-hide,.tribe-common .tribe-common-a11y-visual-show{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:14px 20px;width:100%}.tribe-common .tribe-common-c-btn-icon:before{background-repeat:no-repeat;background-size:contain;content:"";display:block}.tribe-common .tribe-common-c-btn-icon--caret-left:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-left:active:before,.tribe-common .tribe-common-c-btn-icon--caret-left:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-left:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-left:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11.916 17.841L10 19.757l-9.9-9.9L10-.041l1.916 1.916-7.983 7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23BABABA'/%3E%3C/svg%3E");height:20px;width:12px}.tribe-common .tribe-common-c-btn-icon--caret-right:active:before,.tribe-common .tribe-common-c-btn-icon--caret-right:focus:before,.tribe-common .tribe-common-c-btn-icon--caret-right:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23727272'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--caret-right:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.084 2.159L2 .243l9.9 9.9L2 20.041.084 18.126l7.983-7.984z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23727272' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E");height:20px;width:24px}.tribe-common .tribe-common-c-btn-icon--filters:active:before,.tribe-common .tribe-common-c-btn-icon--filters:focus:before,.tribe-common .tribe-common-c-btn-icon--filters:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23141827' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--filters:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='17'%3E%3Cg fill='none' fill-rule='evenodd' stroke='%23D5D5D5' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' transform='translate(1 1)'%3E%3Cpath d='M3 3V0m0 15v-2'/%3E%3Ccircle cx='3' cy='9' r='3'/%3E%3Cpath d='M12 9v6'/%3E%3Ccircle cx='12' cy='3' r='3' transform='matrix(1 0 0 -1 0 6)'/%3E%3C/g%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23727272'/%3E%3C/svg%3E");height:20px;width:20px}.tribe-common .tribe-common-c-btn-icon--search:active:before,.tribe-common .tribe-common-c-btn-icon--search:focus:before,.tribe-common .tribe-common-c-btn-icon--search:hover:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23141827'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn-icon--search:disabled:before{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='20' height='20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20 18.711l-6.044-6.044a7.782 7.782 0 0 0 1.688-4.845c0-2.089-.822-4.044-2.288-5.533C11.866.822 9.91 0 7.822 0S3.778.822 2.29 2.289A7.801 7.801 0 0 0 0 7.822c0 2.09.822 4.045 2.289 5.534a7.801 7.801 0 0 0 5.533 2.288c1.778 0 3.467-.6 4.845-1.688L18.71 20 20 18.711zM3.578 12.067c-2.334-2.334-2.334-6.156 0-8.49a5.968 5.968 0 0 1 4.244-1.755c1.6 0 3.111.622 4.245 1.756 2.333 2.333 2.333 6.155 0 8.489a5.968 5.968 0 0 1-4.245 1.755c-1.6 0-3.11-.622-4.244-1.755z' fill='%23D5D5D5'/%3E%3C/svg%3E")}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{padding:11px 20px;width:100%}.tribe-common .tribe-common-c-image{display:block;height:auto;margin-left:auto;margin-right:auto;width:100%}.tribe-common .tribe-common-c-image--bg{position:relative}.tribe-common .tribe-common-c-image__bg{background:50% no-repeat;background-size:cover;bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%}.tribe-common .tribe-common-c-loader{display:flex;padding-top:192px}.tribe-common .tribe-common-c-loader__dot{background-color:rgba(51,74,255,.07);height:15px;width:15px;border-radius:50%}.tribe-common .tribe-common-c-loader__dot:not(:first-of-type){margin-left:8px}@media (min-width:768px){#top.tribe-theme-enfold .tribe-common .tribe-common-form-control-text__input,.tribe-common .tribe-common-form-control-text__input{padding:20px 20px 20px 40px}.tribe-common .tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-common .tribe-common-g-row--gutters>.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-theme-twentynineteen .tribe-common .entry.tribe-common-g-row--gutters{margin-left:-24px;margin-right:-24px}.tribe-theme-twentynineteen .tribe-common .tribe-common-g-row--gutters>.entry.tribe-common-g-col{padding-left:24px;padding-right:24px}.tribe-common .tribe-common-l-container{padding-left:42px;padding-right:42px}.tribe-common .tribe-common-c-btn-border,.tribe-common a.tribe-common-c-btn-border{padding:6px 15px;width:auto}.tribe-common .tribe-common-c-btn,.tribe-common a.tribe-common-c-btn{width:auto}.tribe-common .tribe-common-c-loader{padding-top:288px}}
common/src/resources/css/datatables.css ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /*
12
+ * Table styles
13
+ */
14
+ table.dataTable {
15
+ border-collapse: separate;
16
+ border-spacing: 0;
17
+ clear: both;
18
+ margin: 0 auto;
19
+ width: 100%;
20
+ }
21
+ table.dataTable thead th:active,
22
+ table.dataTable thead td:active {
23
+ outline: none;
24
+ }
25
+ table.dataTable thead .sorting,
26
+ table.dataTable thead .sorting_asc,
27
+ table.dataTable thead .sorting_desc {
28
+ cursor: pointer;
29
+ *cursor: hand;
30
+ }
31
+ table.dataTable thead .sorting,
32
+ table.dataTable thead .sorting_asc,
33
+ table.dataTable thead .sorting_desc,
34
+ table.dataTable thead .sorting_asc_disabled,
35
+ table.dataTable thead .sorting_desc_disabled {
36
+ background-position: center right;
37
+ background-repeat: no-repeat;
38
+ }
39
+ table.dataTable thead .sorting {
40
+ background-image: url("../../../vendor/datatables/DataTables/images/sort_both.png");
41
+ }
42
+ table.dataTable thead .sorting_asc {
43
+ background-image: url("../../../vendor/datatables/DataTables/images/sort_asc.png");
44
+ }
45
+ table.dataTable thead .sorting_desc {
46
+ background-image: url("../../../vendor/datatables/DataTables/images/sort_desc.png");
47
+ }
48
+ table.dataTable thead .sorting_asc_disabled {
49
+ background-image: url("../../../vendor/datatables/DataTables/images/sort_asc_disabled.png");
50
+ }
51
+ table.dataTable thead .sorting_desc_disabled {
52
+ background-image: url("../../../vendor/datatables/DataTables/images/sort_desc_disabled.png");
53
+ }
54
+ table.dataTable.widefat thead th input, table.dataTable.widefat thead td input, table.dataTable.widefat tfoot th input, table.dataTable.widefat tfoot td input {
55
+ margin: 0 0 0 8px;
56
+ vertical-align: text-top;
57
+ }
58
+ table.dataTable.widefat thead td.check-column, table.dataTable.widefat tfoot td.check-column {
59
+ padding-top: 4px;
60
+ vertical-align: middle;
61
+ }
62
+ table.dataTable.widefat thead th.check-column, table.dataTable.widefat tfoot th.check-column, table.dataTable.widefat tbody th.check-column {
63
+ padding: 11px 0 0 3px;
64
+ }
65
+ table.dataTable .check-column {
66
+ width: 2.2em;
67
+ }
68
+ table.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {
69
+ border-top: 1px solid #ddd;
70
+ }
71
+ table.dataTable.row-border tbody tr:first-child th,
72
+ table.dataTable.row-border tbody tr:first-child td,
73
+ table.dataTable.display tbody tr:first-child th,
74
+ table.dataTable.display tbody tr:first-child td {
75
+ border-top: none;
76
+ }
77
+ table.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {
78
+ border-top: 1px solid #ddd;
79
+ border-right: 1px solid #ddd;
80
+ }
81
+ table.dataTable.cell-border tbody tr th:first-child,
82
+ table.dataTable.cell-border tbody tr td:first-child {
83
+ border-left: 1px solid #ddd;
84
+ }
85
+ table.dataTable.cell-border tbody tr:first-child th,
86
+ table.dataTable.cell-border tbody tr:first-child td {
87
+ border-top: none;
88
+ }
89
+ table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
90
+ background-color: #f9f9f9;
91
+ }
92
+ table.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {
93
+ background-color: #f6f6f6;
94
+ }
95
+ table.dataTable.order-column tbody tr > .sorting_1,
96
+ table.dataTable.order-column tbody tr > .sorting_2,
97
+ table.dataTable.order-column tbody tr > .sorting_3,
98
+ table.dataTable.display tbody tr > .sorting_1,
99
+ table.dataTable.display tbody tr > .sorting_2,
100
+ table.dataTable.display tbody tr > .sorting_3 {
101
+ background-color: #fafafa;
102
+ }
103
+ table.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
104
+ background-color: #f1f1f1;
105
+ }
106
+ table.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {
107
+ background-color: #f3f3f3;
108
+ }
109
+ table.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {
110
+ background-color: whitesmoke;
111
+ }
112
+ table.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {
113
+ background-color: #fafafa;
114
+ }
115
+ table.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {
116
+ background-color: #fcfcfc;
117
+ }
118
+ table.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {
119
+ background-color: #fefefe;
120
+ }
121
+ table.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {
122
+ background-color: #eaeaea;
123
+ }
124
+ table.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {
125
+ background-color: #ececec;
126
+ }
127
+ table.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {
128
+ background-color: #efefef;
129
+ }
130
+ table.dataTable.no-footer {
131
+ border-bottom: 1px solid #111;
132
+ }
133
+ table.dataTable.nowrap th, table.dataTable.nowrap td {
134
+ white-space: nowrap;
135
+ }
136
+ table.dataTable.compact thead th,
137
+ table.dataTable.compact thead td {
138
+ padding: 4px 17px 4px 4px;
139
+ }
140
+ table.dataTable.compact tfoot th,
141
+ table.dataTable.compact tfoot td {
142
+ padding: 4px;
143
+ }
144
+ table.dataTable.compact tbody th,
145
+ table.dataTable.compact tbody td {
146
+ padding: 4px;
147
+ }
148
+ table.dataTable th.dt-left,
149
+ table.dataTable td.dt-left {
150
+ text-align: left;
151
+ }
152
+ table.dataTable th.dt-center,
153
+ table.dataTable td.dt-center,
154
+ table.dataTable td.dataTables_empty {
155
+ text-align: center;
156
+ }
157
+ table.dataTable th.dt-right,
158
+ table.dataTable td.dt-right {
159
+ text-align: right;
160
+ }
161
+ table.dataTable th.dt-justify,
162
+ table.dataTable td.dt-justify {
163
+ text-align: justify;
164
+ }
165
+ table.dataTable th.dt-nowrap,
166
+ table.dataTable td.dt-nowrap {
167
+ white-space: nowrap;
168
+ }
169
+ table.dataTable thead th.dt-head-left,
170
+ table.dataTable thead td.dt-head-left,
171
+ table.dataTable tfoot th.dt-head-left,
172
+ table.dataTable tfoot td.dt-head-left {
173
+ text-align: left;
174
+ }
175
+ table.dataTable thead th.dt-head-center,
176
+ table.dataTable thead td.dt-head-center,
177
+ table.dataTable tfoot th.dt-head-center,
178
+ table.dataTable tfoot td.dt-head-center {
179
+ text-align: center;
180
+ }
181
+ table.dataTable thead th.dt-head-right,
182
+ table.dataTable thead td.dt-head-right,
183
+ table.dataTable tfoot th.dt-head-right,
184
+ table.dataTable tfoot td.dt-head-right {
185
+ text-align: right;
186
+ }
187
+ table.dataTable thead th.dt-head-justify,
188
+ table.dataTable thead td.dt-head-justify,
189
+ table.dataTable tfoot th.dt-head-justify,
190
+ table.dataTable tfoot td.dt-head-justify {
191
+ text-align: justify;
192
+ }
193
+ table.dataTable thead th.dt-head-nowrap,
194
+ table.dataTable thead td.dt-head-nowrap,
195
+ table.dataTable tfoot th.dt-head-nowrap,
196
+ table.dataTable tfoot td.dt-head-nowrap {
197
+ white-space: nowrap;
198
+ }
199
+ table.dataTable tbody th.dt-body-left,
200
+ table.dataTable tbody td.dt-body-left {
201
+ text-align: left;
202
+ }
203
+ table.dataTable tbody th.dt-body-center,
204
+ table.dataTable tbody td.dt-body-center {
205
+ text-align: center;
206
+ }
207
+ table.dataTable tbody th.dt-body-right,
208
+ table.dataTable tbody td.dt-body-right {
209
+ text-align: right;
210
+ }
211
+ table.dataTable tbody th.dt-body-justify,
212
+ table.dataTable tbody td.dt-body-justify {
213
+ text-align: justify;
214
+ }
215
+ table.dataTable tbody th.dt-body-nowrap,
216
+ table.dataTable tbody td.dt-body-nowrap {
217
+ white-space: nowrap;
218
+ }
219
+ table.dataTable,
220
+ table.dataTable th,
221
+ table.dataTable td {
222
+ box-sizing: content-box;
223
+ }
224
+ /*
225
+ * Control feature layout
226
+ */
227
+ .dataTables_wrapper {
228
+ clear: both;
229
+ position: relative;
230
+ zoom: 1;
231
+ }
232
+ .dataTables_wrapper .dataTables_length {
233
+ float: left;
234
+ }
235
+ .dataTables_wrapper .dataTables_filter {
236
+ float: right;
237
+ text-align: right;
238
+ }
239
+ .dataTables_wrapper .dataTables_filter input {
240
+ margin-left: 0.5em;
241
+ }
242
+ .dataTables_wrapper .dataTables_info {
243
+ clear: both;
244
+ float: left;
245
+ padding-top: 0.755em;
246
+ }
247
+ .dataTables_wrapper .dataTables_paginate {
248
+ float: right;
249
+ padding-top: 0.25em;
250
+ text-align: right;
251
+ }
252
+ .dataTables_wrapper .dataTables_paginate .paginate_button {
253
+ border-color: transparent;
254
+ border-radius: 3px;
255
+ border-style: solid;
256
+ border-width: 1px;
257
+ box-shadow: none;
258
+ box-sizing: border-box;
259
+ color: #555;
260
+ cursor: pointer;
261
+ display: inline-block;
262
+ font-size: 13px;
263
+ height: 28px;
264
+ line-height: 26px;
265
+ margin: 0 0 0 2px;
266
+ padding: 0 10px 1px;
267
+ text-decoration: none;
268
+ vertical-align: top;
269
+ white-space: nowrap;
270
+ }
271
+ .dataTables_wrapper .dataTables_paginate .paginate_button:hover,
272
+ .dataTables_wrapper .dataTables_paginate .paginate_button:active {
273
+ background: #fafafa;
274
+ border-color: #999;
275
+ color: #23282d;
276
+ }
277
+ .dataTables_wrapper .dataTables_paginate .paginate_button.next,
278
+ .dataTables_wrapper .dataTables_paginate .paginate_button.previous {
279
+ background: transparent;
280
+ border-color: transparent;
281
+ box-shadow: none;
282
+ color: #23282d;
283
+ }
284
+ .dataTables_wrapper .dataTables_paginate .paginate_button.next.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.previous.disabled {
285
+ background: transparent;
286
+ border-color: transparent;
287
+ box-shadow: none;
288
+ }
289
+ .dataTables_wrapper .dataTables_paginate .paginate_button.next.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.previous.disabled:hover {
290
+ background: transparent;
291
+ border-color: transparent;
292
+ box-shadow: none;
293
+ text-decoration: none;
294
+ }
295
+ .dataTables_wrapper .dataTables_paginate .paginate_button.next:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.previous:hover {
296
+ color: #222;
297
+ text-decoration: underline;
298
+ }
299
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current,
300
+ .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
301
+ background: #fcfcfc;
302
+ border-color: #999;
303
+ box-shadow: 0 1px 0 #cccccc;
304
+ color: #23282d;
305
+ text-decoration: none;
306
+ }
307
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,
308
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,
309
+ .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {
310
+ background: #f7f7f7;
311
+ border-color: #ddd;
312
+ box-shadow: none;
313
+ color: #a0a5aa;
314
+ cursor: default;
315
+ text-shadow: 0 1px 0 #fff;
316
+ -webkit-transform: none;
317
+ transform: none;
318
+ }
319
+ .dataTables_wrapper .dataTables_paginate .ellipsis {
320
+ padding: 0 1em;
321
+ }
322
+ .dataTables_wrapper .dataTables_processing {
323
+ position: absolute;
324
+ top: 50%;
325
+ left: 50%;
326
+ width: 100%;
327
+ height: 40px;
328
+ margin-left: -50%;
329
+ margin-top: -25px;
330
+ padding-top: 20px;
331
+ text-align: center;
332
+ font-size: 1.2em;
333
+ background-color: white;
334
+ background: -webkit-gradient(linear, left top, right top, from(rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), to(rgba(255, 255, 255, 0)));
335
+ 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%);
336
+ }
337
+ .dataTables_wrapper .dataTables_length,
338
+ .dataTables_wrapper .dataTables_filter,
339
+ .dataTables_wrapper .dataTables_info,
340
+ .dataTables_wrapper .dataTables_processing,
341
+ .dataTables_wrapper .dataTables_paginate {
342
+ color: #333;
343
+ }
344
+ .dataTables_wrapper .dataTables_scroll {
345
+ clear: both;
346
+ }
347
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {
348
+ *margin-top: -1px;
349
+ -webkit-overflow-scrolling: touch;
350
+ }
351
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th, .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td {
352
+ vertical-align: middle;
353
+ }
354
+ .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,
355
+ .dataTables_wrapper .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {
356
+ height: 0;
357
+ overflow: hidden;
358
+ margin: 0 !important;
359
+ padding: 0 !important;
360
+ }
361
+ .dataTables_wrapper.no-footer .dataTables_scrollBody {
362
+ border-bottom: 1px solid #111;
363
+ }
364
+ .dataTables_wrapper.no-footer div.dataTables_scrollHead table,
365
+ .dataTables_wrapper.no-footer div.dataTables_scrollBody table {
366
+ border-bottom: none;
367
+ }
368
+ .dataTables_wrapper:after {
369
+ visibility: hidden;
370
+ display: block;
371
+ content: "";
372
+ clear: both;
373
+ height: 0;
374
+ }
375
+ @media screen and (max-width: 767px) {
376
+ .dataTables_wrapper .dataTables_info,
377
+ .dataTables_wrapper .dataTables_paginate {
378
+ float: none;
379
+ text-align: center;
380
+ }
381
+
382
+ .dataTables_wrapper .dataTables_paginate {
383
+ margin-top: 0.5em;
384
+ }
385
+ }
386
+ @media screen and (max-width: 640px) {
387
+ .dataTables_wrapper .dataTables_length,
388
+ .dataTables_wrapper .dataTables_filter {
389
+ float: none;
390
+ text-align: center;
391
+ }
392
+
393
+ .dataTables_wrapper .dataTables_filter {
394
+ margin-top: 0.5em;
395
+ }
396
+ }
common/src/resources/css/datepicker.css ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ .tribe-ui-datepicker.ui-datepicker body,
12
+ .tribe-ui-datepicker.ui-datepicker button,
13
+ .tribe-ui-datepicker.ui-datepicker input,
14
+ .tribe-ui-datepicker.ui-datepicker select,
15
+ .tribe-ui-datepicker.ui-datepicker textarea {
16
+ font-family: "Verdana", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
17
+ }
18
+ .tribe-ui-datepicker.ui-datepicker table {
19
+ border: none;
20
+ }
21
+
22
+ .tribe-ui-datepicker .ui-datepicker-month {
23
+ font-weight: bold;
24
+ }
25
+
26
+ /* Interaction Cues
27
+ ----------------------------------*/
28
+
29
+ .tribe-ui-datepicker .ui-state-disabled {
30
+ cursor: default !important;
31
+ pointer-events: none;
32
+ }
33
+
34
+ /* Icons
35
+ ----------------------------------*/
36
+
37
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-group span.ui-icon {
38
+ display: inline-block;
39
+ vertical-align: middle;
40
+ margin-top: -.25rem;
41
+ position: relative;
42
+ text-indent: -99999px;
43
+ overflow: hidden;
44
+ background-repeat: no-repeat;
45
+ background-image: none;
46
+ }
47
+
48
+ .tribe-ui-datepicker .ui-widget-icon-block {
49
+ left: 50%;
50
+ margin-left: -8px;
51
+ display: block;
52
+ }
53
+
54
+ /* Misc visuals
55
+ ----------------------------------*/
56
+
57
+ /* Overlays */
58
+
59
+ .ui-widget-overlay {
60
+ position: fixed;
61
+ top: 0;
62
+ left: 0;
63
+ width: 100%;
64
+ height: 100%;
65
+ }
66
+
67
+ .tribe-ui-datepicker.ui-datepicker {
68
+ background: #fff;
69
+ box-shadow: 1px 1px 5px rgba(0,0,0,.5);
70
+ width: 17em;
71
+ padding: 1em;
72
+ display: none;
73
+ }
74
+
75
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-header {
76
+ margin-bottom: 1rem;
77
+ position: relative;
78
+ padding: 0;
79
+ border: 0;
80
+ background-color: transparent;
81
+ background-image: none;
82
+ }
83
+
84
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-prev,
85
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-next {
86
+ position: absolute;
87
+ top: 50%;
88
+ -webkit-transform: translateY(-50%);
89
+ transform: translateY(-50%);
90
+ line-height: 1.8em;
91
+ text-align: center;
92
+ }
93
+
94
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-prev:before {
95
+ color: #b1b1b1;
96
+ content: '\2190';
97
+ cursor: pointer;
98
+ }
99
+
100
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-prev:hover:before {
101
+ color: #000;
102
+ }
103
+
104
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-next:before {
105
+ color: #b1b1b1;
106
+ content: '\2192';
107
+ cursor: pointer;
108
+ }
109
+
110
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-next:hover:before {
111
+ color: #000;
112
+ }
113
+
114
+ .tribe-ui-datepicker .ui-datepicker-prev-hover,
115
+ .tribe-ui-datepicker .ui-datepicker-next-hover {
116
+ color: darken(#b1b1b1, 10%);
117
+ border: 0;
118
+ background: none;
119
+ }
120
+
121
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-prev {
122
+ left: 1px;
123
+ }
124
+
125
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-next {
126
+ right: 1px;
127
+ }
128
+
129
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-prev-hover {
130
+ left: 1px;
131
+ }
132
+
133
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-next-hover {
134
+ right: 1px;
135
+ }
136
+
137
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-title {
138
+ margin: 0 2.3em;
139
+ line-height: 1.8;
140
+ text-align: center;
141
+ }
142
+
143
+ .tribe-ui-datepicker select.ui-datepicker-month,
144
+ .tribe-ui-datepicker select.ui-datepicker-year {
145
+ border: none;
146
+ box-shadow: 0 1px 0 rgba(0,0,0,0.1);
147
+ margin-right: 1px;
148
+ width: 4.5rem;
149
+ }
150
+
151
+ .tribe-ui-datepicker.ui-datepicker table {
152
+ width: 100%;
153
+ font-size: .9rem;
154
+ border-collapse: collapse;
155
+ margin: 0 0 .4rem;
156
+ }
157
+
158
+ .tribe-ui-datepicker.ui-datepicker th {
159
+ color: #b1b1b1;
160
+ padding: .7rem .3rem;
161
+ text-align: center;
162
+ border: 0;
163
+ }
164
+
165
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-calendar td {
166
+ border: 1px solid #ddd;
167
+ padding: 1px;
168
+ }
169
+
170
+ .tribe-ui-datepicker.ui-datepicker td.ui-datepicker-unselectable {
171
+ border: none;
172
+ }
173
+
174
+ .tribe-ui-datepicker.ui-datepicker a.ui-state-active {
175
+ background: #0085ba;
176
+ color: #fff;
177
+ }
178
+
179
+ .tribe-ui-datepicker.ui-datepicker td span,
180
+ .tribe-ui-datepicker.ui-datepicker td a {
181
+ display: block;
182
+ padding: .5rem .2rem;
183
+ text-align: center;
184
+ text-decoration: none;
185
+ }
186
+
187
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-buttonpane {
188
+ background-image: none;
189
+ margin: .7rem 0 0 0;
190
+ padding: 0 .2rem;
191
+ border-left: 0;
192
+ border-right: 0;
193
+ border-bottom: 0;
194
+ }
195
+
196
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-buttonpane button {
197
+ float: right;
198
+ margin: .5rem .2rem .4rem;
199
+ cursor: pointer;
200
+ padding: .2rem .6rem .3rem .6rem;
201
+ width: auto;
202
+ overflow: visible;
203
+ }
204
+
205
+ .tribe-ui-datepicker.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
206
+ float: left;
207
+ background: #fff;
208
+ border: 1px solid #b1b1b1;
209
+ }
210
+
211
+ .tribe-ui-datepicker.ui-datepicker button.ui-datepicker-close {
212
+ background: linear-gradient(354deg, rgba(10,85,160,1.00) 0%, rgba(18,136,235,1.00) 100%);
213
+ border: 1px solid #0085ba;
214
+ color: #fff !important;
215
+ font-weight: 400;
216
+ }
217
+
218
+ /* with multiple calendars */
219
+
220
+ .tribe-ui-datepicker.ui-datepicker.ui-datepicker-multi {
221
+ width: auto;
222
+ }
223
+
224
+ .tribe-ui-datepicker.ui-datepicker-multi .ui-datepicker-group {
225
+ float: left;
226
+ }
227
+
228
+ .tribe-ui-datepicker.ui-datepicker-multi .ui-datepicker-group table {
229
+ width: 95%;
230
+ margin: 0 auto .4rem;
231
+ }
232
+
233
+ .tribe-ui-datepicker.ui-datepicker-multi-2 .ui-datepicker-group {
234
+ width: 50%;
235
+ }
236
+
237
+ .tribe-ui-datepicker.ui-datepicker-multi-3 .ui-datepicker-group {
238
+ width: 33.3%;
239
+ }
240
+
241
+ .tribe-ui-datepicker.ui-datepicker-multi-4 .ui-datepicker-group {
242
+ width: 25%;
243
+ }
244
+
245
+ .tribe-ui-datepicker.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
246
+ .tribe-ui-datepicker.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
247
+ border-left-width: 0;
248
+ }
249
+
250
+ .tribe-ui-datepicker.ui-datepicker-multi .ui-datepicker-buttonpane {
251
+ clear: left;
252
+ }
253
+
254
+ .tribe-ui-datepicker .ui-datepicker-row-break {
255
+ clear: both;
256
+ width: 100%;
257
+ font-size: 0;
258
+ }
259
+
260
+ /* Component containers
261
+ ----------------------------------*/
262
+
263
+ .tribe-ui-datepicker.ui-widget {
264
+ font-size: 1.2rem;
265
+ font-family: inherit;
266
+ }
267
+
268
+ .tribe-ui-datepicker.ui-widget .ui-widget {
269
+ font-size: 1rem;
270
+ }
271
+
272
+ .tribe-ui-datepicker.ui-widget input,
273
+ .tribe-ui-datepicker.ui-widget select,
274
+ .tribe-ui-datepicker.ui-widget textarea,
275
+ .tribe-ui-datepicker.ui-widget button {
276
+ font-size: 1rem;
277
+ }
278
+
279
+ .tribe-ui-datepicker.ui-widget-content a,
280
+ .tribe-ui-datepicker .ui-widget-header a {
281
+ color: #23282d;
282
+ }
283
+
284
+ /* Interaction states
285
+ ----------------------------------*/
286
+
287
+ .tribe-ui-datepicker .ui-state-default,
288
+ .tribe-ui-datepicker.ui-widget-content .ui-state-default,
289
+ .tribe-ui-datepicker .ui-widget-header .ui-state-default,
290
+ .tribe-ui-datepicker .ui-button,
291
+
292
+ /* We use html here because we need a greater specificity to make sure disabled
293
+ works properly when clicked or hovered */
294
+ html .tribe-ui-datepicker .ui-button.ui-state-disabled:hover,
295
+ html .tribe-ui-datepicker .ui-button.ui-state-disabled:active {
296
+ color: #23282d;
297
+ border: 0;
298
+ background-color: transparent;
299
+ background-image: none;
300
+ }
301
+
302
+ .tribe-ui-datepicker .ui-state-default a,
303
+ .tribe-ui-datepicker .ui-state-default a:link,
304
+ .tribe-ui-datepicker .ui-state-default a:visited,
305
+ .tribe-ui-datepicker a.ui-button,
306
+ .tribe-ui-datepicker a:link.ui-button,
307
+ .tribe-ui-datepicker a:visited.ui-button,
308
+ .tribe-ui-datepicker .ui-button {
309
+ color: #23282d;
310
+ text-decoration: none;
311
+ }
312
+
313
+ .tribe-ui-datepicker .ui-state-hover,
314
+ .tribe-ui-datepicker .ui-widget-content .ui-state-hover,
315
+ .tribe-ui-datepicker .ui-widget-header .ui-state-hover,
316
+ .tribe-ui-datepicker .ui-state-focus,
317
+ .tribe-ui-datepicker .ui-widget-content .ui-state-focus,
318
+ .tribe-ui-datepicker .ui-widget-header .ui-state-focus,
319
+ .tribe-ui-datepicker .ui-button:hover,
320
+ .tribe-ui-datepicker .ui-button:focus {
321
+ color: #000;
322
+ border: 0;
323
+ background: none;
324
+ }
325
+
326
+ .tribe-ui-datepicker .ui-state-hover a,
327
+ .tribe-ui-datepicker .ui-state-hover a:hover,
328
+ .tribe-ui-datepicker .ui-state-hover a:link,
329
+ .tribe-ui-datepicker .ui-state-hover a:visited,
330
+ .tribe-ui-datepicker .ui-state-focus a,
331
+ .tribe-ui-datepicker .ui-state-focus a:hover,
332
+ .tribe-ui-datepicker .ui-state-focus a:link,
333
+ .tribe-ui-datepicker .ui-state-focus a:visited,
334
+ .tribe-ui-datepicker a.ui-button:hover,
335
+ .tribe-ui-datepicker a.ui-button:focus {
336
+ color: #b1b1b1;
337
+ text-decoration: none;
338
+ background-color: none;
339
+ background-image: none;
340
+ }
341
+
342
+ .tribe-ui-datepicker .ui-visual-focus {
343
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
344
+ }
345
+
346
+ .tribe-ui-datepicker .ui-state-active,
347
+ .tribe-ui-datepicker .ui-widget-content .ui-state-active,
348
+ .tribe-ui-datepicker .ui-widget-header .ui-state-active,
349
+ .tribe-ui-datepicker a.ui-button:active,
350
+ .tribe-ui-datepicker .ui-button:active,
351
+ .tribe-ui-datepicker .ui-button.ui-state-active:hover {
352
+ background: linear-gradient(354deg, rgba(10,85,160,1.00) 0%, rgba(18,136,235,1.00) 100%);
353
+ color: #fff;
354
+ }
355
+
356
+ .tribe-ui-datepicker .ui-icon-background,
357
+ .tribe-ui-datepicker .ui-state-active .ui-icon-background {
358
+ border: #dddddd;
359
+ background-color: #1c94c4;
360
+ }
361
+
362
+ .tribe-ui-datepicker .ui-state-active a,
363
+ .tribe-ui-datepicker .ui-state-active a:link,
364
+ .tribe-ui-datepicker .ui-state-active a:visited {
365
+ color: #23282d;
366
+ text-decoration: none;
367
+ }
368
+
369
+ /* Interaction Cues
370
+ ----------------------------------*/
371
+
372
+ .tribe-ui-datepicker .ui-state-highlight,
373
+ .tribe-ui-datepicker.ui-widget-content .ui-state-highlight,
374
+ .tribe-ui-datepicker .ui-widget-header .ui-state-highlight {
375
+ background: #ffffff;
376
+ color: #363636;
377
+ border: 0;
378
+ background-image: none;
379
+ }
380
+
381
+ .tribe-ui-datepicker .ui-state-checked {
382
+ background: #ffffff;
383
+ }
384
+
385
+ .tribe-ui-datepicker .ui-state-highlight a,
386
+ .tribe-ui-datepicker.ui-widget-content .ui-state-highlight a,
387
+ .tribe-ui-datepicker .ui-widget-header .ui-state-highlight a {
388
+ color: #363636;
389
+ }
390
+
391
+ .tribe-ui-datepicker .ui-state-error,
392
+ .tribe-ui-datepicker.ui-widget-content .ui-state-error,
393
+ .tribe-ui-datepicker .ui-widget-header .ui-state-error {
394
+ background: #b81900;
395
+ color: #ffffff;
396
+ }
397
+
398
+ .tribe-ui-datepicker .ui-state-error a,
399
+ .tribe-ui-datepicker.ui-widget-content .ui-state-error a,
400
+ .tribe-ui-datepicker .ui-widget-header .ui-state-error a {
401
+ color: #ffffff;
402
+ }
403
+
404
+ .tribe-ui-datepicker .ui-state-error-text,
405
+ .tribe-ui-datepicker.ui-widget-content .ui-state-error-text,
406
+ .tribe-ui-datepicker .ui-widget-header .ui-state-error-text {
407
+ color: #ffffff;
408
+ }
409
+
410
+ .tribe-ui-datepicker .ui-priority-secondary,
411
+ .tribe-ui-datepicker.ui-widget-content .ui-priority-secondary,
412
+ .tribe-ui-datepicker .ui-widget-header .ui-priority-secondary {
413
+ opacity: .7;
414
+ filter:Alpha(Opacity=70); /* support: IE8 */
415
+ font-weight: normal;
416
+ }
417
+
418
+ .tribe-ui-datepicker .ui-state-disabled,
419
+ .tribe-ui-datepicker.ui-widget-content .ui-state-disabled,
420
+ .tribe-ui-datepicker .ui-widget-header .ui-state-disabled {
421
+ opacity: .35;
422
+ filter:Alpha(Opacity=35); /* support: IE8 */
423
+ background-image: none;
424
+ }
425
+
426
+ .tribe-ui-datepicker .ui-state-disabled .ui-icon {
427
+ filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
428
+ }
429
+
430
+ /* Corner radius */
431
+
432
+ .tribe-ui-datepicker .ui-corner-all,
433
+ .tribe-ui-datepicker .ui-corner-top,
434
+ .tribe-ui-datepicker .ui-corner-left,
435
+ .tribe-ui-datepicker .ui-corner-tl {
436
+ border-top-left-radius: 4px;
437
+ }
438
+
439
+ .tribe-ui-datepicker .ui-corner-all,
440
+ .tribe-ui-datepicker .ui-corner-top,
441
+ .tribe-ui-datepicker .ui-corner-right,
442
+ .tribe-ui-datepicker .ui-corner-tr {
443
+ border-top-right-radius: 4px;
444
+ }
445
+
446
+ .tribe-ui-datepicker .ui-corner-all,
447
+ .tribe-ui-datepicker .ui-corner-bottom,
448
+ .tribe-ui-datepicker .ui-corner-left,
449
+ .tribe-ui-datepicker .ui-corner-bl {
450
+ border-bottom-left-radius: 4px;
451
+ }
452
+
453
+ .tribe-ui-datepicker .ui-corner-all,
454
+ .tribe-ui-datepicker .ui-corner-bottom,
455
+ .tribe-ui-datepicker .ui-corner-right,
456
+ .tribe-ui-datepicker .ui-corner-br {
457
+ border-bottom-right-radius: 4px;
458
+ }
459
+
460
+ /* Overlays */
461
+
462
+ .tribe-ui-datepicker .ui-widget-overlay {
463
+ background: #666666 url("images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;
464
+ opacity: .5;
465
+ filter: Alpha(Opacity=50); /* support: IE8 */
466
+ }
467
+
468
+ .tribe-ui-datepicker .ui-widget-shadow {
469
+ box-shadow: -5px -5px 5px #000000;
470
+ }
471
+
472
+ .tribe-ui-datepicker .ui-helper-hidden {
473
+ display: none;
474
+ }
475
+
476
+ .tribe-ui-datepicker .ui-helper-hidden-accessible {
477
+ border: 0;
478
+ clip: rect(0 0 0 0);
479
+ height: 1px;
480
+ margin: -1px;
481
+ overflow: hidden;
482
+ padding: 0;
483
+ position: absolute;
484
+ width: 1px;
485
+ }
486
+
487
+ .tribe-ui-datepicker .ui-helper-reset {
488
+ margin: 0;
489
+ padding: 0;
490
+ border: 0;
491
+ outline: 0;
492
+ line-height: 1.3;
493
+ text-decoration: none;
494
+ font-size: 100%;
495
+ list-style: none;
496
+ }
497
+
498
+ .tribe-ui-datepicker .ui-helper-clearfix:before,
499
+ .tribe-ui-datepicker .ui-helper-clearfix:after {
500
+ content: "";
501
+ display: table;
502
+ border-collapse: collapse;
503
+ }
504
+
505
+ .tribe-ui-datepicker .ui-helper-clearfix:after {
506
+ clear: both;
507
+ }
508
+
509
+ .tribe-ui-datepicker .ui-helper-zfix {
510
+ width: 100%;
511
+ height: 100%;
512
+ top: 0;
513
+ left: 0;
514
+ position: absolute;
515
+ opacity: 0;
516
+ filter:Alpha(Opacity=0); /* support: IE8 */
517
+ }
518
+
519
+ .tribe-ui-datepicker .ui-front {
520
+ z-index: 100;
521
+ }
522
+
523
+ /* RTL support */
524
+
525
+ .tribe-ui-datepicker.ui-datepicker-rtl {
526
+ direction: rtl;
527
+ }
528
+
529
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-prev {
530
+ right: 2px;
531
+ left: auto;
532
+ }
533
+
534
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-next {
535
+ left: 2px;
536
+ right: auto;
537
+ }
538
+
539
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-prev:hover {
540
+ right: 1px;
541
+ left: auto;
542
+ }
543
+
544
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-next:hover {
545
+ left: 1px;
546
+ right: auto;
547
+ }
548
+
549
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-buttonpane {
550
+ clear: right;
551
+ }
552
+
553
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-buttonpane button {
554
+ float: left;
555
+ }
556
+
557
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
558
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-group {
559
+ float: right;
560
+ }
561
+
562
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
563
+ .tribe-ui-datepicker.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
564
+ border-right-width: 0;
565
+ border-left-width: 1px;
566
+ }
common/src/resources/css/dependency.css ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* Dependency CSS */
12
+ .tribe-dependent {
13
+ display: none;
14
+ }
15
+ .tribe-dependent.tribe-active {
16
+ display: inline-block;
17
+ }
18
+ div.tribe-dependent.tribe-active {
19
+ display: block;
20
+ }
21
+ div.tribe-dependent.tribe-active.select2-container {
22
+ display: inline-block;
23
+ }
24
+ td.tribe-dependent.tribe-active,
25
+ th.tribe-dependent.tribe-active {
26
+ display: table-cell;
27
+ }
28
+ tr.tribe-dependent.tribe-active {
29
+ display: table-row;
30
+ }
common/src/resources/css/dialog.css ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* = Dialogs
12
+ This can include modals, toasters, confirms. alerts.
13
+ ============================ */
14
+
15
+ /*
16
+ Adding these here for now until common-styles are live
17
+ @TODO: remove when that happens.
18
+ */
19
+
20
+ /* vars */
21
+
22
+ .tribe-common .tribe-dialog {
23
+ --tribe-dialog-background-color: #FFF;
24
+ --tribe-dialog-close-background: #FFF;
25
+ --tribe-dialog-close-border-color: #BABABA;
26
+ --tribe-dialog-close-border-width: 1px;
27
+ --tribe-dialog-close-color: #BABABA;
28
+ --tribe-dialog-close-height: 12px;
29
+ --tribe-dialog-close-height-desktop: 16px;
30
+ --tribe-dialog-overlay-color: transparent;
31
+ --tribe-modal-overlay-color: rgba(20,24,39,0.9);
32
+ --tribe-dialog-border-radius: 4px;
33
+ --tribe-dialog-padding: 16px;
34
+ --tribe-dialog-padding-top: 24px;
35
+ --tribe-dialog-padding-side: 28px;
36
+ }
37
+
38
+ /* The dialog/popup/modal itself */
39
+
40
+ .tribe-common div.tribe-dialog {
41
+ -webkit-box-align: center;
42
+ align-items: center;
43
+ display: -webkit-box;
44
+ display: flex;
45
+ height: 100vh;
46
+ -webkit-box-pack: center;
47
+ justify-content: center;
48
+ left: 0;
49
+ position: fixed;
50
+ top: 0;
51
+ width: 100vw;
52
+ z-index: 1;
53
+ }
54
+
55
+ .tribe-common div.tribe-dialog[aria-hidden='true'] {
56
+ display: none;
57
+ }
58
+
59
+ /* The trigger button" */
60
+
61
+ .tribe-common .tribe-dialog__trigger {}
62
+
63
+ /* The overlay */
64
+
65
+ .tribe-common .tribe-dialog__overlay {
66
+ background-color: var(--tribe-dialog-overlay-color);
67
+ height: 100vh;
68
+ left: 0;
69
+ opacity: .9;
70
+ position: fixed;
71
+ top: 0;
72
+ width: 100vw;
73
+ z-index: 1;
74
+ }
75
+
76
+ /* Content wrapper - includes close button*/
77
+
78
+ .tribe-common .tribe-dialog__wrapper {
79
+ background-color: var(--tribe-dialog-background-color);
80
+ border-radius: var(--tribe-dialog-border-radius);
81
+ box-shadow: 0 2px 54px 0 var(--tribe-modal-overlay-color);
82
+ width: 800px;
83
+ overflow-y: scroll;
84
+ padding: var(--tribe-dialog-padding);
85
+ max-height: 100vh;
86
+ max-width: 100vw;
87
+ z-index: 2;
88
+ }
89
+
90
+ .tribe-common .tribe-dialog__wrapper div[role="document"] {
91
+ -webkit-box-align: end;
92
+ align-items: flex-end;
93
+ display: -webkit-box;
94
+ display: flex;
95
+ -webkit-box-orient: vertical;
96
+ -webkit-box-direction: normal;
97
+ flex-flow: column;
98
+ -webkit-box-pack: justify;
99
+ justify-content: space-between;
100
+ position: relative;
101
+ }
102
+
103
+ /* The "close" button */
104
+
105
+ .tribe-common .tribe-dialog__close-button {
106
+ background: var(--tribe-dialog-close-background);
107
+ background-image: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'%3E%3Cpath d='M16 2L2 16M16 16L2 2' stroke='var(--color-icon-secondary)'/%3E%3C/g%3E%3C/svg%3E" );
108
+ background-repeat: no-repeat;
109
+ background-size: contain;
110
+ cursor: pointer;
111
+ display: inline-block;
112
+ font-size: 14px;
113
+ height: var(--tribe-dialog-close-height);
114
+ line-height: var(--tribe-dialog-close-height);
115
+ padding: 0;
116
+ position: absolute;
117
+ width: var(--tribe-dialog-close-height);
118
+ z-index: 1;
119
+ }
120
+
121
+ .tribe-common .tribe-dialog__close-button:focus,
122
+ .tribe-common .tribe-dialog__close-button:hover {
123
+ background: var(--tribe-dialog-close-background);
124
+ background-image: url( "data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cg fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'%3E%3Cpath d='M16 2L2 16M16 16L2 2' stroke='var(--color-icon-primary)'/%3E%3C/g%3E%3C/svg%3E" );
125
+ background-size: contain;
126
+ outline: none;
127
+ }
128
+
129
+ .tribe-common .tribe-dialog__close-button--hidden {
130
+ display: none;
131
+ }
132
+
133
+ .tribe-common .tribe-dialog__close-button--round {
134
+ border-radius: 50%;
135
+ }
136
+
137
+ .tribe-common .tribe-dialog__close-button--border {
138
+ border: var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color);
139
+ }
140
+
141
+ .tribe-common h2.tribe-dialog__title {
142
+ align-self: flex-start;
143
+ margin: 0 0 22px;
144
+ padding-right: calc(var(--tribe-dialog-close-height) + 0.5em);
145
+ padding-top: 0;
146
+
147
+ }
148
+
149
+ /* The content container*/
150
+
151
+ .tribe-common .tribe-dialog__content {
152
+ color: #141827;
153
+ font-size: 14px;
154
+ line-height: 1.64em;
155
+ padding-right: calc(var(--tribe-dialog-close-height) + 0.5em);
156
+ padding-top: calc(var(--tribe-dialog-close-height) + 0.5em);
157
+ width: 100%;
158
+ }
159
+
160
+ .tribe-common .tribe-dialog__title + .tribe-dialog__content {
161
+ padding: 0;
162
+ }
163
+
164
+ /* Modal Styles */
165
+
166
+ .tribe-common .tribe-modal__overlay {
167
+ background-color: var(--tribe-modal-overlay-color);
168
+ }
169
+
170
+ /* Confirmation Styles */
171
+
172
+ .tribe-common .tribe-confirm__content {
173
+ padding-right: 0;
174
+ }
175
+
176
+ .tribe-common .tribe-dialog__button_wrap {
177
+ display: -webkit-box;
178
+ display: flex;
179
+ -webkit-box-orient: horizontal;
180
+ -webkit-box-direction: normal;
181
+ flex-flow: row wrap;
182
+ -webkit-box-pack: end;
183
+ justify-content: flex-end;
184
+ }
185
+
186
+ @media screen and (min-width:768px) {
187
+
188
+ .tribe-common .tribe-dialog__wrapper {
189
+ max-height: calc(100vh - 160px);
190
+ padding: var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)
191
+ }
192
+
193
+ .tribe-common .tribe-dialog__close-button {
194
+ height: var(--tribe-dialog-close-height-desktop);
195
+ line-height: var(--tribe-dialog-close-height-desktop);
196
+ width: var(--tribe-dialog-close-height-desktop)
197
+ }
198
+ }
199
+
200
+ @media screen and (max-width:768px) {
201
+ .tribe-common .tribe-dialog__content:last-of-type {
202
+ padding-bottom: 36px;
203
+ }
204
+ }
common/src/resources/css/dialog.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:1}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:1}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);width:800px;overflow-y:scroll;padding:var(--tribe-dialog-padding);max-height:100vh;max-width:100vw;z-index:2;-webkit-transform:translateZ(0);-webkit-perspective:1000}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%23BABABA' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='%235D5D5D' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end}#top .main_color .tribe-common div.tribe-dialog,#top.tribe-theme-enfold .tribe-common div.tribe-dialog,.tribe-theme-avada .tribe-common div.tribe-dialog,.tribe-theme-divi .tribe-common div.tribe-dialog{z-index:99999}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
1
+ .tribe-common .tribe-dialog{--tribe-dialog-background-color:#fff;--tribe-dialog-close-background:#fff;--tribe-dialog-close-border-color:#bababa;--tribe-dialog-close-border-width:1px;--tribe-dialog-close-color:#bababa;--tribe-dialog-close-height:12px;--tribe-dialog-close-height-desktop:16px;--tribe-dialog-overlay-color:transparent;--tribe-modal-overlay-color:rgba(20,24,39,.9);--tribe-dialog-border-radius:4px;--tribe-dialog-padding:16px;--tribe-dialog-padding-top:24px;--tribe-dialog-padding-side:28px}.tribe-common div.tribe-dialog{align-items:center;display:flex;height:100vh;justify-content:center;left:0;position:fixed;top:0;width:100vw;z-index:1}.tribe-common div.tribe-dialog[aria-hidden=true]{display:none}.tribe-common .tribe-dialog__overlay{background-color:var(--tribe-dialog-overlay-color);height:100vh;left:0;opacity:.9;position:fixed;top:0;width:100vw;z-index:1}.tribe-common .tribe-dialog__wrapper{background-color:var(--tribe-dialog-background-color);border-radius:var(--tribe-dialog-border-radius);box-shadow:0 2px 54px 0 var(--tribe-modal-overlay-color);width:800px;overflow-y:scroll;padding:var(--tribe-dialog-padding);max-height:100vh;max-width:100vw;z-index:2}.tribe-common .tribe-dialog__wrapper div[role=document]{align-items:flex-end;display:flex;flex-flow:column;justify-content:space-between;position:relative}.tribe-common .tribe-dialog__close-button{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--color-icon-secondary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:contain;cursor:pointer;display:inline-block;font-size:14px;height:var(--tribe-dialog-close-height);line-height:var(--tribe-dialog-close-height);padding:0;position:absolute;width:var(--tribe-dialog-close-height);z-index:1}.tribe-common .tribe-dialog__close-button:focus,.tribe-common .tribe-dialog__close-button:hover{background:var(--tribe-dialog-close-background);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18'%3E%3Cpath d='M16 2L2 16m14 0L2 2' stroke='var(--color-icon-primary)' fill='none' fill-rule='evenodd' stroke-linecap='square' stroke-width='2'/%3E%3C/svg%3E");background-size:contain;outline:none}.tribe-common .tribe-dialog__close-button--hidden{display:none}.tribe-common .tribe-dialog__close-button--round{border-radius:50%}.tribe-common .tribe-dialog__close-button--border{border:var(--tribe-dialog-close-border-width) solid var(--tribe-dialog-close-border-color)}.tribe-common h2.tribe-dialog__title{align-self:flex-start;margin:0 0 22px;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:0}.tribe-common .tribe-dialog__content{color:#141827;font-size:14px;line-height:1.64em;padding-right:calc(var(--tribe-dialog-close-height) + .5em);padding-top:calc(var(--tribe-dialog-close-height) + .5em);width:100%}.tribe-common .tribe-dialog__title+.tribe-dialog__content{padding:0}.tribe-common .tribe-modal__overlay{background-color:var(--tribe-modal-overlay-color)}.tribe-common .tribe-confirm__content{padding-right:0}.tribe-common .tribe-dialog__button_wrap{display:flex;flex-flow:row wrap;justify-content:flex-end}@media screen and (min-width:768px){.tribe-common .tribe-dialog__wrapper{max-height:calc(100vh - 160px);padding:var(--tribe-dialog-padding-top) var(--tribe-dialog-padding-side)}.tribe-common .tribe-dialog__close-button{height:var(--tribe-dialog-close-height-desktop);line-height:var(--tribe-dialog-close-height-desktop);width:var(--tribe-dialog-close-height-desktop)}}@media screen and (max-width:768px){.tribe-common .tribe-dialog__content:last-of-type{padding-bottom:36px}}
common/src/resources/css/promoter.css ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ #wp-admin-bar-promoter-admin-bar a.ab-item {
12
+ display: -webkit-box;
13
+ display: flex;
14
+ flex-wrap: wrap;
15
+ -webkit-box-align: center;
16
+ align-items: center;
17
+ }
18
+
19
+ #wp-admin-bar-promoter-admin-bar a.ab-item .promoter-admin-bar__icon {
20
+ margin-right: 5px;
21
+ width: 20px;
22
+ height: 20px;
23
+ -webkit-box-flex: 0;
24
+ flex: none;
25
+ }
26
+
27
+ #wp-admin-bar-promoter-admin-bar a.ab-item .promoter-admin-bar__text {
28
+ -webkit-box-flex: 0;
29
+ flex: none;
30
+ }
31
+ #wp-admin-bar-promoter-admin-bar:focus .promoter-admin-bar__icon svg path, #wp-admin-bar-promoter-admin-bar:hover .promoter-admin-bar__icon svg path {
32
+ fill: #00B9EB;
33
+ }
common/src/resources/css/tooltip.css ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* = Tooltips
12
+ ============================ */
13
+
14
+ .tribe-tooltip {
15
+ cursor: pointer;
16
+ display: inline-block;
17
+ margin: 0;
18
+ position: relative;
19
+ text-align: left;
20
+ }
21
+
22
+ .tribe-tooltip .dashicons-info {
23
+ color: #a9a9a9;
24
+ font-size: 16px;
25
+ line-height: 1em;
26
+ vertical-align: middle;
27
+ }
28
+
29
+ /* defaults */
30
+
31
+ .tribe-tooltip .down,
32
+ .tribe-tooltip .left,
33
+ .tribe-tooltip .right,
34
+ .tribe-tooltip .up {
35
+ background-color: #fff;
36
+ box-shadow: 0 0 3px 3px rgba(4, 5, 5, 0.05);
37
+ box-sizing: border-box;
38
+ color: #333333;
39
+ font-size: 16px;
40
+ font-weight: 400;
41
+ max-weight: 100vw;
42
+ opacity: 0;
43
+ padding: 15px;
44
+ position: absolute;
45
+ -webkit-transform: translate(-50%, 0);
46
+ transform: translate(-50%, 0);
47
+ -webkit-transition: opacity 0.8s;
48
+ transition: opacity 0.8s;
49
+ visibility: hidden;
50
+ width: 250px;
51
+ z-index: 99999999;
52
+ }
53
+
54
+ .tribe-tooltip .down i, .tribe-tooltip .left i, .tribe-tooltip .right i, .tribe-tooltip .up i {
55
+ height: 12px;
56
+ overflow: hidden;
57
+ position: absolute;
58
+ width: 24px;
59
+ }
60
+
61
+ .tribe-tooltip .down i::after, .tribe-tooltip .left i::after, .tribe-tooltip .right i::after, .tribe-tooltip .up i::after {
62
+ background-color: #fff;
63
+ content: '';
64
+ height: 12px;
65
+ position: absolute;
66
+ width: 24px;
67
+ }
68
+
69
+ .tribe-tooltip.large .down,
70
+ .tribe-tooltip.large .left,
71
+ .tribe-tooltip.large .right,
72
+ .tribe-tooltip.large .up {
73
+ width: 400px;
74
+ }
75
+
76
+ .tribe-tooltip .tooltip-list {
77
+ padding-left: 10px;
78
+ }
79
+
80
+ .tribe-tooltip .tooltip-list li {
81
+ list-style-type: disc;
82
+ }
83
+
84
+ .tribe-tooltip .down {
85
+ left: 50%;
86
+ top: 28px;
87
+ }
88
+
89
+ .tribe-tooltip .down i {
90
+ bottom: 100%;
91
+ left: 50%;
92
+ margin-left: -7px;
93
+ }
94
+
95
+ .tribe-tooltip .down i::after {
96
+ box-shadow: 0 0 3px 3px rgba(4, 5, 5, 0.05);
97
+ left: 50%;
98
+ top: 50%;
99
+ -webkit-transform: translate(-50%, 50%) rotate(45deg);
100
+ transform: translate(-50%, 50%) rotate(45deg);
101
+ }
102
+
103
+ /* active (open) styles */
104
+
105
+ .tribe-tooltip.active .down,
106
+ .tribe-tooltip.active .left,
107
+ .tribe-tooltip.active .right,
108
+ .tribe-tooltip.active .up {
109
+ opacity: 1;
110
+ visibility: visible;
111
+ }
112
+
113
+ @media screen and (max-width: 480px) {
114
+
115
+ .tribe-tooltip.large .down,
116
+ .tribe-tooltip.large .left,
117
+ .tribe-tooltip.large .right,
118
+ .tribe-tooltip.large .up {
119
+ width: 250px
120
+ }
121
+ }
common/src/resources/css/tooltip.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-tooltip{cursor:pointer;display:inline-block;margin:0;position:relative;text-align:left}.tribe-tooltip .dashicons-info{color:#a9a9a9;font-size:16px;line-height:1em;vertical-align:middle}.tribe-tooltip .down,.tribe-tooltip .left,.tribe-tooltip .right,.tribe-tooltip .up{background-color:#fff;box-shadow:0 0 3px 3px rgba(4,5,5,.05);box-sizing:border-box;color:#333;font-size:16px;font-weight:400;max-width:100vw;opacity:0;padding:15px;position:absolute;transform:translate(-50%);transition:opacity .8s;visibility:hidden;width:250px;z-index:99999999}.tribe-tooltip .down i,.tribe-tooltip .left i,.tribe-tooltip .right i,.tribe-tooltip .up i{height:12px;overflow:hidden;position:absolute;width:24px}.tribe-tooltip .down i:after,.tribe-tooltip .left i:after,.tribe-tooltip .right i:after,.tribe-tooltip .up i:after{background-color:#fff;content:"";height:12px;position:absolute;width:24px}.tribe-tooltip.large .down,.tribe-tooltip.large .left,.tribe-tooltip.large .right,.tribe-tooltip.large .up{width:400px}.tribe-tooltip .tooltip-list{padding-left:10px}.tribe-tooltip .tooltip-list li{list-style-type:disc}.tribe-tooltip .down{left:50%;top:28px}.tribe-tooltip .down i{bottom:100%;left:50%;margin-left:-7px}.tribe-tooltip .down i:after{box-shadow:0 0 3px 3px rgba(4,5,5,.05);left:50%;top:50%;transform:translate(-50%,50%) rotate(45deg)}.tribe-tooltip.active .down,.tribe-tooltip.active .left,.tribe-tooltip.active .right,.tribe-tooltip.active .up{opacity:1;visibility:visible}@media screen and (max-width:480px){.tribe-tooltip.large .down,.tribe-tooltip.large .left,.tribe-tooltip.large .right,.tribe-tooltip.large .up{width:250px}}
1
+ .tribe-tooltip{cursor:pointer;display:inline-block;margin:0;position:relative;text-align:left}.tribe-tooltip .dashicons-info{color:#a9a9a9;font-size:16px;line-height:1em;vertical-align:middle}.tribe-tooltip .down,.tribe-tooltip .left,.tribe-tooltip .right,.tribe-tooltip .up{background-color:#fff;box-shadow:0 0 3px 3px rgba(4,5,5,.05);box-sizing:border-box;color:#333;font-size:16px;font-weight:400;max-weight:100vw;opacity:0;padding:15px;position:absolute;transform:translate(-50%);transition:opacity .8s;visibility:hidden;width:250px;z-index:99999999}.tribe-tooltip .down i,.tribe-tooltip .left i,.tribe-tooltip .right i,.tribe-tooltip .up i{height:12px;overflow:hidden;position:absolute;width:24px}.tribe-tooltip .down i:after,.tribe-tooltip .left i:after,.tribe-tooltip .right i:after,.tribe-tooltip .up i:after{background-color:#fff;content:"";height:12px;position:absolute;width:24px}.tribe-tooltip.large .down,.tribe-tooltip.large .left,.tribe-tooltip.large .right,.tribe-tooltip.large .up{width:400px}.tribe-tooltip .tooltip-list{padding-left:10px}.tribe-tooltip .tooltip-list li{list-style-type:disc}.tribe-tooltip .down{left:50%;top:28px}.tribe-tooltip .down i{bottom:100%;left:50%;margin-left:-7px}.tribe-tooltip .down i:after{box-shadow:0 0 3px 3px rgba(4,5,5,.05);left:50%;top:50%;transform:translate(-50%,50%) rotate(45deg)}.tribe-tooltip.active .down,.tribe-tooltip.active .left,.tribe-tooltip.active .right,.tribe-tooltip.active .up{opacity:1;visibility:visible}@media screen and (max-width:480px){.tribe-tooltip.large .down,.tribe-tooltip.large .left,.tribe-tooltip.large .right,.tribe-tooltip.large .up{width:250px}}
common/src/resources/css/tribe-common-admin.css ADDED
@@ -0,0 +1,1387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ /* = Shared CSS Elements
12
+ =============================================*/
13
+ .invalid input {
14
+ border: 2px solid red !important;
15
+ }
16
+ .valid input {
17
+ border: 1px solid green;
18
+ }
19
+ .clearfix {
20
+ zoom: 1; /* For IE */
21
+ }
22
+ .placeholder {
23
+ color: #999;
24
+ cursor: text;
25
+ padding: 4px 4px 4px 4px;
26
+ }
27
+ input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
28
+ color: #999;
29
+ }
30
+ input::-moz-placeholder, textarea::-moz-placeholder {
31
+ color: #999;
32
+ }
33
+ input:-ms-input-placeholder, textarea:-ms-input-placeholder {
34
+ color: #999;
35
+ }
36
+ input::-ms-input-placeholder, textarea::-ms-input-placeholder {
37
+ color: #999;
38
+ }
39
+ input::placeholder,
40
+ textarea::placeholder {
41
+ color: #999;
42
+ }
43
+ input::-webkit-input-placeholder,
44
+ textarea::-webkit-input-placeholder {
45
+ color: #999;
46
+ }
47
+ .bubble {
48
+ background-color: #f9f9f9;
49
+ border-color: #dfdfdf;
50
+ border-radius: 3px;
51
+ border-spacing: 0;
52
+ border-style: solid;
53
+ border-width: 1px;
54
+ padding: 10px;
55
+ }
56
+ .tribe-sticky-tooltip {
57
+ color: #bbb;
58
+ }
59
+ td.tribe_message {
60
+ padding-bottom: 10px !important;
61
+ }
62
+ #tribe_thanks {
63
+ float: left;
64
+ margin: 5px 0 0 0;
65
+ width: 200px;
66
+ }
67
+ .tribe_brand {
68
+ font-family: Georgia, serif !important;
69
+ font-size: 17px !important;
70
+ font-weight: normal;
71
+ margin: 8px 0;
72
+ }
73
+ /* = Upgrade Screen
74
+ =============================================*/
75
+ #tribe-upgrade {
76
+ background: #f6f6f6;
77
+ border: 1px solid #ccc;
78
+ border-radius: 5px;
79
+ margin: 20px 0 30px;
80
+ padding: 0 20px 20px;
81
+ }
82
+ #tribe-upgrade .message {
83
+ background-color: #ffffe0;
84
+ border-color: #e6db55;
85
+ border-radius: 3px;
86
+ border-style: solid;
87
+ border-width: 1px;
88
+ padding: 6px 12px;
89
+ }
90
+ /* = Plugin Screen
91
+ =============================================*/
92
+ table.plugins .tribe-plugin-update-message {
93
+ background: #d54e21; /* taken from color scheme in list-tables.css */
94
+ color: white;
95
+ display: inline-table;
96
+ margin: 6px 0;
97
+ padding: 10px 12px;
98
+ }
99
+ table.plugins .tribe-plugin-update-message h4 {
100
+ display: inline;
101
+ font-weight: bold;
102
+ margin-right: 8px;
103
+ }
104
+ table.plugins .tribe-plugin-update-message h4:after {
105
+ content: ' \00BB ';
106
+ }
107
+ table.plugins .tribe-plugin-update-message a {
108
+ color: white;
109
+ text-decoration: underline;
110
+ }
111
+ /* = Settings Screen
112
+ =============================================*/
113
+ .tribe-settings-form {
114
+ max-width: 1000px;
115
+ }
116
+ .tribe-settings-form fieldset {
117
+ clear: both;
118
+ display: inline-block;
119
+ padding: 10px 0;
120
+ }
121
+ .tribe-settings-form fieldset.tribe-field-license_key legend {
122
+ width: auto;
123
+ }
124
+ .tribe-settings-form legend {
125
+ float: left;
126
+ font-weight: bold;
127
+ margin-right: 20px;
128
+ width: 220px;
129
+ }
130
+ .tribe-settings-form .tribe-field-wrap {
131
+ float: left;
132
+ max-width: 500px;
133
+ }
134
+ .tribe-settings-form .tribe-field-wrap *:first-child {
135
+ margin-top: 0;
136
+ }
137
+ .tribe-settings-form .tribe-field-radio label, .tribe-settings-form .tribe-field-checkbox_list label {
138
+ display: block;
139
+ margin: 5px 0 5px 20px;
140
+ text-indent: -20px;
141
+ }
142
+ .tribe-settings-form .tribe-field-radio label > p, .tribe-settings-form .tribe-field-checkbox_list label > p {
143
+ text-indent: 0;
144
+ margin-left: 1px;
145
+ }
146
+ .tribe-settings-form .tribe-field-radio label input, .tribe-settings-form .tribe-field-checkbox_list label input {
147
+ margin-right: 5px;
148
+ }
149
+ .tribe-settings-form .tribe-settings-form-wrap fieldset,
150
+ .tribe-settings-form .tribe-settings-form-wrap .description,
151
+ .tribe-settings-form fieldset[id^='tribe-field-geoloc_'] {
152
+ padding-left: 12px;
153
+ }
154
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .description {
155
+ margin-left: 0;
156
+ max-width: 450px;
157
+ padding-left: 0;
158
+ }
159
+ .tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection {
160
+ margin-bottom: 18px;
161
+ }
162
+ .tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description {
163
+ color: #999;
164
+ margin-left: 1px;
165
+ }
166
+ .tribe-settings-form .tribe-settings-form-wrap h3 {
167
+ background-color: #f9f9f9;
168
+ margin-bottom: 10px;
169
+ padding: 6px 0 6px 12px;
170
+ }
171
+ .tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,
172
+ .tribe-settings-form .tribe-settings-form-wrap .system-info,
173
+ .tribe-settings-form .tribe-settings-form-wrap h3 + p,
174
+ .tribe-settings-form .tribe-settings-form-wrap .contained {
175
+ margin: 0 0 10px;
176
+ padding-left: 12px;
177
+ }
178
+ .tribe_settings .tribe-field-indent {
179
+ margin-left: 245px;
180
+ }
181
+ .tribe_settings #pu_dashboard_message {
182
+ display: none;
183
+ }
184
+ .tribe_settings .tribe-errors-list {
185
+ margin-left: 15px;
186
+ }
187
+ .tribe_settings .expiring-license {
188
+ color: red;
189
+ }
190
+ .tribe_settings .tribe-error {
191
+ border: 1px solid #f00;
192
+ }
193
+ .tribe_settings .tribe-field-description {
194
+ margin-bottom: 0;
195
+ position: relative;
196
+ top: -12px;
197
+ }
198
+ .tribe_settings #ical-link {
199
+ top: -14px;
200
+ }
201
+ /* Modern Tribe box */
202
+ #modern-tribe-info {
203
+ background-color: #f9f9f9;
204
+ border: 1px solid #ccc;
205
+ border-radius: 4px;
206
+ margin: 20px 0;
207
+ padding: 8px 20px 12px;
208
+ }
209
+ #modern-tribe-info img {
210
+ height: 18px;
211
+ margin: 10px 0;
212
+ width: 250px;
213
+ }
214
+ #modern-tribe-info ul {
215
+ list-style: disc;
216
+ margin-left: 20px;
217
+ }
218
+ #modern-tribe-info ul ul {
219
+ list-style: circle;
220
+ }
221
+ /* sizes */
222
+ .tribe-field-inline-dropdown {
223
+ margin-left: 0;
224
+ margin-right: 0;
225
+ }
226
+ .tribe-field-inline-text {
227
+ line-height: 28px;
228
+ margin: 0 2px;
229
+ }
230
+ .tribe-field-textarea.tribe-size-small textarea {
231
+ height: 60px;
232
+ width: 180px;
233
+ }
234
+ .tribe-field-textarea.tribe-size-medium textarea {
235
+ height: 80px;
236
+ width: 300px;
237
+ }
238
+ .tribe-field-textarea.tribe-size-large textarea {
239
+ height: 120px;
240
+ width: 450px;
241
+ }
242
+ .tribe-field-text.tribe-size-small input,
243
+ .tribe-field-email.tribe-size-small input,
244
+ .tribe-field-license_key.tribe-size-small input {
245
+ width: 50px;
246
+ }
247
+ .tribe-field-text.tribe-size-medium input,
248
+ .tribe-field-email.tribe-size-medium input,
249
+ .tribe-field-license_key.tribe-size-medium input {
250
+ width: 225px;
251
+ }
252
+ .tribe-field-text.tribe-size-large input,
253
+ .tribe-field-email.tribe-size-large input,
254
+ .tribe-field-license_key.tribe-size-large input {
255
+ width: 450px;
256
+ }
257
+ .tribe-field-dropdown.tribe-size-small select {
258
+ width: 100px;
259
+ }
260
+ .tribe-field-dropdown.tribe-size-medium select {
261
+ width: 300px;
262
+ }
263
+ .tribe-field-dropdown.tribe-size-large select {
264
+ width: 450px;
265
+ }
266
+ .tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap {
267
+ max-width: 600px;
268
+ }
269
+ .tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{
270
+ max-width: 100%;
271
+ }
272
+ .tribe-field-dropdown_chosen.tribe-size-small select {
273
+ width: 100px;
274
+ }
275
+ .tribe-field-dropdown_chosen.tribe-size-medium select {
276
+ width: 200px;
277
+ }
278
+ .tribe-field-dropdown_chosen.tribe-size-large select {
279
+ width: 300px;
280
+ }
281
+ .tribe-field-wrap .tooltip:first-child {
282
+ font-style: normal;
283
+ }
284
+ .tribe-field.indent {
285
+ margin-left: 252px;
286
+ width: 75%;
287
+ }
288
+ .tribe-field.indent legend {
289
+ font-weight: normal;
290
+ width: auto;
291
+ }
292
+ .tribe-field.indent .tribe-field-wrap {
293
+ padding-right: 12px;
294
+ }
295
+ .tribe-field.indent.tribe-field-radio .tribe-field-wrap {
296
+ clear: left;
297
+ margin-top: 12px;
298
+ }
299
+ .tribe-field.light-bordered {
300
+ background-color: white;
301
+ border: solid lightgrey 1px;
302
+ }
303
+ /* license keys */
304
+ .ajax-loading-license,
305
+ .valid-key,
306
+ .invalid-key {
307
+ display: none;
308
+ margin: 0 5px;
309
+ }
310
+ .ajax-loading-license {
311
+ position: relative;
312
+ top: 5px;
313
+ }
314
+ .key-validity {
315
+ display: inline-block;
316
+ }
317
+ .optin-fail,
318
+ .invalid-key {
319
+ color: red;
320
+ }
321
+ .optin-success,
322
+ .valid-key {
323
+ color: green;
324
+ }
325
+ .valid-key.service-msg {
326
+ color: #b72;
327
+ }
328
+ /* additional fields */
329
+ #additional-field-table {
330
+ margin-bottom: 20px;
331
+ }
332
+ /* miscellaneous */
333
+ .tribe-admin-box-left {
334
+ background-color: #f9f9f9;
335
+ border: 1px solid #ccc;
336
+ border-radius: 4px;
337
+ float: left;
338
+ margin: 20px 0;
339
+ padding: 0 20px 15px;
340
+ width: 20%;
341
+ }
342
+ .tribe-admin-box-right {
343
+ background-color: #f9f9f9;
344
+ border: 1px solid #ccc;
345
+ border-radius: 4px;
346
+ float: right;
347
+ margin: 20px 0;
348
+ padding: 0 20px 15px;
349
+ width: 68%;
350
+ }
351
+ .ajax-loader {
352
+ float: right;
353
+ margin: 10px;
354
+ }
355
+ .tribe-arrangeable-item {
356
+ border: 1px solid lightGrey;
357
+ border-radius: 3px;
358
+ }
359
+ .tribe-arrangeable-item .ui-state-default {
360
+ border: none;
361
+ }
362
+ .tribe-arrangeable-item-top {
363
+ padding: 6px;
364
+ }
365
+ .tribe-arrangeable-item-top:hover {
366
+ cursor: move;
367
+ }
368
+ .tribe-arrangeable-action {
369
+ float: right;
370
+ }
371
+ .tribe-arrangeable-child {
372
+ background-color: #f9f9f9;
373
+ border-top: 1px solid lightGrey;
374
+ display: none;
375
+ padding: 25px;
376
+ }
377
+ .tribe-arrangeable-child label {
378
+ display: block;
379
+ margin: 0 0 7px 0;
380
+ }
381
+ .tribe_events_active_filter_type_options {
382
+ margin: 10px 0;
383
+ }
384
+ .tribe_events_active_filter_type_options label {
385
+ margin: 7px 0;
386
+ }
387
+ .OrganizerInfo td small,
388
+ #event_organizer td small {
389
+ display: block;
390
+ margin: 0;
391
+ max-width: 250px;
392
+ }
393
+ .OrganizerInfo .organizer-email,
394
+ #event_organizer .organizer-email {
395
+ vertical-align: top;
396
+ }
397
+ .tribe-table-field-label {
398
+ max-width: 100%;
399
+ width: 200px;
400
+ }
401
+ /* = Help Screen
402
+ =============================================*/
403
+ #tribe-help-general,
404
+ #tribe-help-sidebar {
405
+ float: left;
406
+ margin-top: 20px;
407
+ }
408
+ #tribe-help-general p {
409
+ margin-left: 15px;
410
+ }
411
+ #tribe-help-general ul {
412
+ list-style-type: square;
413
+ margin-bottom: 20px;
414
+ margin-left: 35px;
415
+ }
416
+ #tribe-help-general ol {
417
+ margin-bottom: 20px;
418
+ margin-left: 35px;
419
+ }
420
+ #tribe-help-general h3 {
421
+ background-color: #f9f9f9;
422
+ margin-bottom: 10px;
423
+ padding: 6px 0 6px 12px;
424
+ }
425
+ #tribe-help-general h3 ~ h3 {
426
+ margin-top: 2.25em;
427
+ }
428
+ #tribe-help-general h3 + p {
429
+ margin: 0 0 20px;
430
+ padding-left: 12px;
431
+ }
432
+ #tribe-help-general {
433
+ width: 65%;
434
+ }
435
+ .tribe-help-section {
436
+ padding-bottom: 10px;
437
+ }
438
+ .tribe-section-type-box {
439
+ background-color: #f9f9f9;
440
+ border: 1px solid #ccc;
441
+ border-radius: 4px;
442
+ padding: 8px 20px 12px;
443
+ }
444
+ .tribe-section-type-box img {
445
+ height: auto;
446
+ margin: 10px 0;
447
+ max-width: 300px;
448
+ }
449
+ .tribe-section-type-box ul {
450
+ list-style: disc;
451
+ margin-left: 20px;
452
+ }
453
+ .tribe-section-type-box ul ul {
454
+ list-style: circle;
455
+ }
456
+ #tribe-log-controls {
457
+ padding-bottom: 1rem;
458
+
459
+ /* For consistency with help screen h3 and p elements */
460
+ padding-left: 12px;
461
+ }
462
+ #tribe-log-controls > div {
463
+ display: inline-block;
464
+ padding-right: 1rem;
465
+ }
466
+ #tribe-log-controls .working {
467
+ opacity: 1;
468
+ -webkit-transition: opacity 0.2s;
469
+ transition: opacity 0.2s;
470
+ }
471
+ #tribe-log-controls .working.hidden {
472
+ opacity: 0;
473
+ -webkit-transition: opacity 0.2s;
474
+ transition: opacity 0.2s;
475
+ }
476
+ #tribe-system-info dl.support-stats,
477
+ #tribe-log-viewer,
478
+ .template-updates-wrapper {
479
+ background: #000;
480
+ border-radius: 2px;
481
+ color: #888;
482
+ max-height: 400px;
483
+ overflow: scroll;
484
+ padding: 10px;
485
+ }
486
+ #tribe-system-info dl.support-stats dt,
487
+ .template-updates-wrapper dt {
488
+ clear: both;
489
+ float: left;
490
+ font-weight: bold;
491
+ text-transform: uppercase;
492
+ width: 25%;
493
+ }
494
+ #tribe-system-info dl.support-stats dd,
495
+ .template-updates-wrapper dd {
496
+ margin-left: 25%;
497
+ padding-left: 10px;
498
+ }
499
+ .system-info-copy .system-info-copy-btn {
500
+ padding: 6px;
501
+ }
502
+ .system-info-copy .system-info-copy-btn .dashicons {
503
+ padding-right: 10px;
504
+ }
505
+ .template-updates-wrapper p {
506
+ margin-top: 0;
507
+ }
508
+ #tribe-help-sidebar {
509
+ margin: 20px 0 0 3%;
510
+ max-width: 225px;
511
+ width: 32%;
512
+ }
513
+ .tribe-help-plugin-info {
514
+ border: 1px solid #ccc;
515
+ padding: 0 12px 12px;
516
+ }
517
+ .tribe-help-plugin-info dt,
518
+ .tribe-help-plugin-info dd {
519
+ display: inline;
520
+ margin: 0;
521
+ }
522
+ .tribe-help-plugin-info dt {
523
+ font-weight: bold;
524
+ }
525
+ .tribe-help-plugin-info dd::after {
526
+ content: '';
527
+ display: block;
528
+ height: .4em;
529
+ }
530
+ .tribe-help-plugin-info dd:last-child::after {
531
+ height: 0;
532
+ }
533
+ .tribe-help-plugin-info + .tribe-help-plugin-info {
534
+ margin-top: 20px;
535
+ }
536
+ .tribe-help-plugin-info > div {
537
+ line-height: 2em;
538
+ }
539
+ .tribe-help-plugin-info .star-rating {
540
+ display: inline-block;
541
+ margin-left: 3px;
542
+ position: relative;
543
+ top: -2px;
544
+ }
545
+ .tribe-help-plugin-info .tribe-list-addons {
546
+ color: #21a6cb;
547
+ font-size: 24px;
548
+ list-style: circle inside;
549
+ margin-bottom: 10px;
550
+ margin-top: 10px;
551
+ padding-left: 4px;
552
+ }
553
+ .tribe-help-plugin-info .tribe-list-addons a {
554
+ font-size: 13px;
555
+ left: -5px;
556
+ position: relative;
557
+ top: -5px;
558
+ }
559
+ .tribe-help-plugin-info .tribe-list-addons .tribe-active-addon {
560
+ list-style: disc inside;
561
+ }
562
+ /* = jQuery UI
563
+ =============================================*/
564
+ .ui-widget-overlay {
565
+ background: #666;
566
+ filter: Alpha(Opacity=50);
567
+ opacity: .50;
568
+ }
569
+ .ui-widget-shadow {
570
+ background: #000;
571
+ border-radius: 5px;
572
+ filter: Alpha(Opacity=20);
573
+ margin: -5px 0 0 -5px;
574
+ opacity: .20;
575
+ padding: 5px;
576
+ }
577
+ .ui-resizable {
578
+ position: relative;
579
+ }
580
+ .ui-resizable-handle {
581
+ display: block;
582
+ font-size: .1px;
583
+ position: absolute;
584
+ z-index: 99999;
585
+ }
586
+ .ui-resizable-disabled .ui-resizable-handle,
587
+ .ui-resizable-autohide .ui-resizable-handle {
588
+ display: none;
589
+ }
590
+ .ui-resizable-n {
591
+ cursor: n-resize;
592
+ height: 7px;
593
+ left: 0;
594
+ top: -5px;
595
+ width: 100%;
596
+ }
597
+ .ui-resizable-s {
598
+ bottom: -5px;
599
+ cursor: s-resize;
600
+ height: 7px;
601
+ left: 0;
602
+ width: 100%;
603
+ }
604
+ .ui-resizable-e {
605
+ cursor: e-resize;
606
+ height: 100%;
607
+ right: -5px;
608
+ top: 0;
609
+ width: 7px;
610
+ }
611
+ .ui-resizable-w {
612
+ cursor: w-resize;
613
+ height: 100%;
614
+ left: -5px;
615
+ top: 0;
616
+ width: 7px;
617
+ }
618
+ .ui-resizable-se {
619
+ bottom: 1px;
620
+ cursor: se-resize;
621
+ height: 12px;
622
+ right: 1px;
623
+ width: 12px;
624
+ }
625
+ .ui-resizable-sw {
626
+ bottom: -5px;
627
+ cursor: sw-resize;
628
+ height: 9px;
629
+ left: -5px;
630
+ width: 9px;
631
+ }
632
+ .ui-resizable-nw {
633
+ cursor: nw-resize;
634
+ height: 9px;
635
+ left: -5px;
636
+ top: -5px;
637
+ width: 9px;
638
+ }
639
+ .ui-resizable-ne {
640
+ cursor: ne-resize;
641
+ height: 9px;
642
+ right: -5px;
643
+ top: -5px;
644
+ width: 9px;
645
+ }
646
+ .ui-dialog {
647
+ padding: .2em;
648
+ position: relative;
649
+ width: 375px;
650
+ }
651
+ .ui-dialog .ui-dialog-titlebar {
652
+ padding: .5em .3em .3em 1em;
653
+ position: relative;
654
+ }
655
+ .ui-dialog .ui-dialog-title {
656
+ float: left;
657
+ margin: .1em 0 .2em;
658
+ }
659
+ .ui-dialog .ui-dialog-titlebar-close {
660
+ height: 18px;
661
+ margin: -10px 0 0 0;
662
+ padding: 1px;
663
+ position: absolute;
664
+ right: .3em;
665
+ top: 50%;
666
+ width: 19px;
667
+ }
668
+ .ui-dialog .ui-dialog-titlebar-close span {
669
+ display: block;
670
+ margin-left: -8px;
671
+ margin-top: -8px;
672
+ }
673
+ .ui-dialog .ui-dialog-titlebar-close:hover,
674
+ .ui-dialog .ui-dialog-titlebar-close:focus {
675
+ padding: 0;
676
+ }
677
+ .ui-dialog .ui-dialog-content {
678
+ background: none;
679
+ border: 0;
680
+ overflow: auto;
681
+ padding: .5em 1em;
682
+ zoom: 1;
683
+ }
684
+ .ui-dialog .ui-dialog-buttonpane {
685
+ background-image: none;
686
+ border-width: 1px 0 0 0;
687
+ margin: .5em 0 0 0;
688
+ padding: .3em 1em .5em !important;
689
+ text-align: right;
690
+ }
691
+ .ui-dialog .ui-dialog-buttonpane button {
692
+ cursor: pointer;
693
+ line-height: 1.4em;
694
+ margin: .5em .4em .5em !important;
695
+ overflow: visible;
696
+ padding: .2em .6em .3em;
697
+ text-shadow: none;
698
+ width: auto;
699
+ }
700
+ .ui-dialog .ui-resizable-se {
701
+ bottom: 3px;
702
+ height: 14px;
703
+ right: 3px;
704
+ width: 14px;
705
+ }
706
+ .ui-draggable .ui-dialog-titlebar {
707
+ cursor: move;
708
+ }
709
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
710
+ float: none !important;
711
+ text-align: center;
712
+ }
713
+ .ui-button-text-only .ui-button-text {
714
+ padding: .4em 1em;
715
+ }
716
+ .ui-button .ui-button-text {
717
+ display: block;
718
+ line-height: 1.4;
719
+ }
720
+ #ui-datepicker-div {
721
+ display: none;
722
+ }
723
+ #tribe-loading {
724
+ background: #fff;
725
+ background: rgba(255, 255, 255, .8);
726
+ display: none;
727
+ height: 100%;
728
+ left: 0;
729
+ position: absolute;
730
+ top: 0;
731
+ -webkit-transition: all 1s linear;
732
+ transition: all 1s linear;
733
+ width: 100%;
734
+ z-index: 4;
735
+ }
736
+ #tribe-loading span {
737
+ background: url(../images/tribe-loading.gif) 0 0 no-repeat;
738
+ background-size: 32px 32px;
739
+ height: 32px;
740
+ left: 50%;
741
+ margin: -16px 0 0 -16px;
742
+ position: absolute;
743
+ top: 50%;
744
+ width: 32px;
745
+ }
746
+ /* = Admin Retina Bits
747
+ =============================================*/
748
+ /* = TEC Welcome & Update Pages // Displays after installation & plugin update
749
+ ===============================================================================*/
750
+ .tribe_welcome_page,
751
+ .tribe_update_page {
752
+ max-width: 850px;
753
+ }
754
+ .tribe_welcome_page.wrap h1 {
755
+ font-size: 3em;
756
+ line-height: 1.2;
757
+ margin-top: 1em;
758
+ }
759
+ .tribe_welcome_page.wrap h1:before {
760
+ color: #555d66;
761
+ content: '\f145';
762
+ font-family: dashicons;
763
+ font-size: 0.9em;
764
+ line-height: 1;
765
+ margin-right: 5px;
766
+ position: relative;
767
+ top: 4px;
768
+ }
769
+ .tribe-half-column {
770
+ float: left;
771
+ margin-bottom: 30px;
772
+ margin-right: 5%;
773
+ width: 45%;
774
+ }
775
+ .tribe-row:before,
776
+ .tribe-row:after {
777
+ content: '';
778
+ display: table;
779
+ }
780
+ .tribe-row:after {
781
+ clear: both;
782
+ }
783
+ .tribe-row {
784
+ clear: both;
785
+ }
786
+ .tribe-row .tribe-half-column:last-child {
787
+ margin-right: 0;
788
+ width: 50%;
789
+ }
790
+ .tribe_welcome_page h2,
791
+ .tribe_welcome_page .tribe-half-column h4 {
792
+ font-size: 24px;
793
+ line-height: 1.2;
794
+ margin-bottom: 20px;
795
+ }
796
+ .tribe_update_page h2 {
797
+ font-size: 30px;
798
+ line-height: 1.2;
799
+ margin-bottom: 20px;
800
+ }
801
+ .tribe_welcome_page h3,
802
+ .tribe_update_page h3 {
803
+ font-size: 24px;
804
+ font-weight: 400;
805
+ line-height: 24px;
806
+ margin-top: 0;
807
+ }
808
+ .tribe_welcome_page h4,
809
+ .tribe_update_page h4 {
810
+ font-size: 18px;
811
+ font-weight: 600;
812
+ line-height: 18px;
813
+ margin: 0;
814
+ }
815
+ .tribe_welcome_page p,
816
+ .tribe_update_page p {
817
+ font-size: 15px;
818
+ }
819
+ .tribe_welcome_page li {
820
+ font-size: 14px;
821
+ margin-bottom: 10px;
822
+ }
823
+ p.tribe-welcome-message {
824
+ font-size: 18px;
825
+ font-weight: 400;
826
+ }
827
+ .tribe_welcome_page .tribe-half-column h4 {
828
+ margin-top: 1em;
829
+ }
830
+ /* "Calendar" dashicon */
831
+ .tribe_welcome_page .tribe-half-column h4:before {
832
+ color: #555d66;
833
+ content: '\f145';
834
+ font-family: dashicons;
835
+ font-size: 21px;
836
+ line-height: 1;
837
+ margin-right: 10px;
838
+ position: relative;
839
+ top: 2px;
840
+ }
841
+ /* "Life preserver" dashicon */
842
+ .tribe_welcome_page .tribe-half-column h4[data-tribe-icon="dashicons-sos"]:before {
843
+ content: '\f468';
844
+ }
845
+ /* "Graduation cap" dashicon */
846
+ .tribe_welcome_page .tribe-half-column h4[data-tribe-icon="dashicons-welcome-learn-more"]:before {
847
+ content: '\f118';
848
+ }
849
+ /* "Megaphone" dashicon */
850
+ .tribe_welcome_page .tribe-half-column h4[data-tribe-icon="dashicons-megaphone"]:before {
851
+ content: '\f488';
852
+ }
853
+ /* "Heart" dashicon */
854
+ .tribe_welcome_page .tribe-half-column h4[data-tribe-icon="dashicons-heart"]:before {
855
+ content: '\f487';
856
+ }
857
+ .tribe_update_page h4:before {
858
+ content: '\f145';
859
+ font-family: dashicons;
860
+ font-size: 34px;
861
+ line-height: 1;
862
+ margin-right: 5px;
863
+ position: relative;
864
+ top: 5px;
865
+ }
866
+ .tribe-welcome-video-wrapper {
867
+ height: 0;
868
+ margin-bottom: 40px;
869
+ padding-bottom: 56.25%; /* 16:9 */
870
+ padding-top: 25px;
871
+ position: relative;
872
+ }
873
+ .tribe-welcome-video-wrapper iframe {
874
+ height: 100%;
875
+ left: 0;
876
+ position: absolute;
877
+ top: 0;
878
+ width: 100%;
879
+ }
880
+ a.tribe-rating-link {
881
+ text-decoration: none;
882
+ }
883
+ .tribe-welcome-links,
884
+ .tribe-update-links {
885
+ margin-top: 30px;
886
+ }
887
+ .tribe_welcome_page li:before,
888
+ .tribe_update_page li:before {
889
+ content: '\2022';
890
+ padding-right: 3px;
891
+ }
892
+ .tribe_update_page .rss-widget {
893
+ margin: 1em 0;
894
+ }
895
+ .tribe_update_page a.rsswidget {
896
+ font-size: 14px;
897
+ font-weight: 400;
898
+ line-height: 1;
899
+ }
900
+ .tribe_update_page .rss-widget li:before {
901
+ display: none;
902
+ }
903
+ /* Media Queries for Mobile Dashboard */
904
+ .tribe-update-bar {
905
+ display: inline-block;
906
+ }
907
+ .tribe-update-bar .progress {
908
+ border: 1px solid #ccc;
909
+ float: left;
910
+ margin-right: 1rem;
911
+ padding: 1px;
912
+ width: 18rem;
913
+ }
914
+ .tribe-update-bar .progress .bar {
915
+ background: #ffba00;
916
+ height: 1rem;
917
+ width: 1%;
918
+ }
919
+ .tribe-update-bar .progress .bar {
920
+ background: #7ad03a;
921
+ }
922
+ /* = Modals/thickbox dialogs
923
+ ============================ */
924
+ #tribe-dialog-wrapper > div {
925
+ padding: 1rem;
926
+ }
927
+ #tribe-dialog-wrapper > div .stage {
928
+ display: none;
929
+ }
930
+ #tribe-dialog-wrapper #heading {
931
+ background: white;
932
+ }
933
+ #tribe-dialog-wrapper label {
934
+ display: block;
935
+ }
936
+ #tribe-dialog-wrapper .select-single-container {
937
+ border: 1px solid #888;
938
+ overflow-y: scroll;
939
+ height: 300px;
940
+ }
941
+ #tribe-dialog-wrapper .select-single-container label {
942
+ opacity: 1;
943
+ padding: 3px 5px;
944
+ -webkit-transition: opacity 0.2s;
945
+ transition: opacity 0.2s;
946
+ }
947
+ #tribe-dialog-wrapper .select-single-container label:nth-child(odd) {
948
+ background: white;
949
+ }
950
+ #tribe-dialog-wrapper .select-single-container label.selected {
951
+ background: #0073aa;
952
+ color: white;
953
+ font-weight: bold;
954
+ }
955
+ #tribe-dialog-wrapper .select-single-container label input {
956
+ display: none;
957
+ }
958
+ #tribe-dialog-wrapper .select-single-container.updating label {
959
+ opacity: 0.35;
960
+ -webkit-transition: opacity 0.2s;
961
+ transition: opacity 0.2s;
962
+ }
963
+ /* Useful to ensure modals rise above the grey 'miasma' */
964
+ .ui-front {
965
+ z-index: 1000000;
966
+ }
967
+ /* Select2 Specific rule */
968
+ .select2-container .select2-choice abbr {
969
+ top: 6px;
970
+ }
971
+ .wp-list-table.plugins .column-description .update-message {
972
+ color: #d54e21;
973
+ }
974
+ .api-check {
975
+ padding: 1em;
976
+ min-height: 100px;
977
+ }
978
+ .api-check + .notice-dismiss:hover:before {
979
+ color: #fff;
980
+ }
981
+ .api-check:before,
982
+ .api-check:after {
983
+ content: '';
984
+ display: table;
985
+ }
986
+ .api-check:after {
987
+ clear: both;
988
+ }
989
+ .api-check .tribe-mascot {
990
+ bottom: 0;
991
+ display: none;
992
+ padding: 0 1rem 0 0;
993
+ position: absolute;
994
+ right: 0;
995
+ top: 0;
996
+ }
997
+ .api-check .tribe-mascot img {
998
+ display: inline-block;
999
+ max-height: 150px;
1000
+ max-width: 150px;
1001
+ height: 100%;
1002
+ width: auto;
1003
+ vertical-align: middle;
1004
+ }
1005
+ .api-check p {
1006
+ line-height: 1.7;
1007
+ margin-bottom: 1em;
1008
+ }
1009
+ .api-check a {
1010
+ text-decoration: none;
1011
+ }
1012
+ .api-check a:hover {
1013
+ text-decoration: underline;
1014
+ }
1015
+ .api-check .plugin-list {
1016
+ display: inline;
1017
+ font-weight: 600;
1018
+ margin: 0;
1019
+ padding: 0;
1020
+ }
1021
+ .api-check .plugin-list span.plugin-invalid:after {
1022
+ content: ', ';
1023
+ }
1024
+ .api-check .plugin-list span.plugin-invalid:last-of-type:after {
1025
+ content: '';
1026
+ }
1027
+ .tribe-marketing-notice {
1028
+ padding: 1em;
1029
+ }
1030
+ .tribe-marketing-notice + .notice-dismiss:hover:before {
1031
+ color: #fff;
1032
+ }
1033
+ .tribe-marketing-notice:before,
1034
+ .tribe-marketing-notice:after {
1035
+ content: '';
1036
+ display: table;
1037
+ }
1038
+ .tribe-marketing-notice:after {
1039
+ clear: both;
1040
+ }
1041
+ .tribe-marketing-notice .tribe-notice-icon {
1042
+ bottom: 0;
1043
+ display: none;
1044
+ padding: 1rem;
1045
+ position: absolute;
1046
+ left: 0;
1047
+ top: 0;
1048
+ width: 125px;
1049
+ }
1050
+ .tribe-marketing-notice .tribe-notice-icon:before {
1051
+ content: '';
1052
+ display: inline-block;
1053
+ height: 100%;
1054
+ width: 1%;
1055
+ vertical-align: middle;
1056
+ }
1057
+ .tribe-marketing-notice .tribe-notice-icon img {
1058
+ display: inline-block;
1059
+ max-height: 100%;
1060
+ max-width: 96%;
1061
+ vertical-align: middle;
1062
+ }
1063
+ .tribe-marketing-notice h3 {
1064
+ margin-bottom: 0.5em;
1065
+ margin-top: 0.5em;
1066
+ }
1067
+ .tribe-marketing-notice p {
1068
+ line-height: 1.7;
1069
+ margin-bottom: 0.5em;
1070
+ }
1071
+ .tribe-marketing-notice a {
1072
+ text-decoration: none;
1073
+ }
1074
+ .tribe-marketing-notice a:hover {
1075
+ text-decoration: underline;
1076
+ }
1077
+ .tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary {
1078
+ margin: 10px 10px 0 0;
1079
+ }
1080
+ .tribe-ea-dropdown,
1081
+ .tribe-dropdown {
1082
+ max-width: 100%;
1083
+ width: auto;
1084
+ }
1085
+ .tribe-ea-dropdown.select2-container-active .select2-choice, .tribe-dropdown.select2-container-active .select2-choice {
1086
+ border-color: #5897fb;
1087
+ box-shadow: 0 0 5px rgba( 0, 0, 0, .1 );
1088
+ }
1089
+ .tribe-ea-dropdown.select2-dropdown-open .select2-choice, .tribe-dropdown.select2-dropdown-open .select2-choice {
1090
+ border-bottom-left-radius: 0;
1091
+ border-bottom-right-radius: 0;
1092
+ border-color: #aaa;
1093
+ }
1094
+ .tribe-ea-dropdown .select2-choice, .tribe-dropdown .select2-choice {
1095
+ background-image: none;
1096
+ border-radius: 3px;
1097
+ border: 1px solid #ccc;
1098
+ }
1099
+ .tribe-ea-dropdown .select2-choice > .select2-chosen, .tribe-dropdown .select2-choice > .select2-chosen {
1100
+ white-space: normal;
1101
+ }
1102
+ .tribe-ea-dropdown .select2-choice .select2-arrow, .tribe-dropdown .select2-choice .select2-arrow {
1103
+ background-image: none;
1104
+ background: transparent;
1105
+ border-left: 0;
1106
+ }
1107
+ .tribe-ea-dropdown .select2-choice div, .tribe-dropdown .select2-choice div {
1108
+ background-image: none;
1109
+ background: none;
1110
+ border-left: 0;
1111
+ }
1112
+ .tribe-ea-dropdown.select2-container-multi .select2-choices, .tribe-dropdown.select2-container-multi .select2-choices {
1113
+ background-image: none;
1114
+ border-radius: 3px;
1115
+ border: 1px solid #ccc;
1116
+ min-height: 25px;
1117
+ }
1118
+ .tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-field, .tribe-dropdown.select2-container-multi .select2-choices .select2-search-field {
1119
+ line-height: 25px;
1120
+ }
1121
+ .tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-field input, .tribe-dropdown.select2-container-multi .select2-choices .select2-search-field input {
1122
+ padding-top: 0;
1123
+ padding-bottom: 0;
1124
+ }
1125
+ .tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice, .tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice {
1126
+ margin-top: 2px;
1127
+ padding-top: 0;
1128
+ padding-bottom: 0;
1129
+ line-height: 19px;
1130
+ }
1131
+ .tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice div, .tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice div {
1132
+ line-height: inherit;
1133
+ }
1134
+ .tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice-close, .tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice-close {
1135
+ top: 3px;
1136
+ left: 4px;
1137
+ -webkit-transition-property: border,color;
1138
+ transition-property: border,color;
1139
+ }
1140
+ .select2-results .select2-selected {
1141
+ display: block;
1142
+ }
1143
+ .select2-results .select2-selected > .select2-result-label {
1144
+ background-color: #efefef;
1145
+ color: #a1a1a1;
1146
+ cursor: default;
1147
+ }
1148
+ .select2-results li.select2-result-with-children > .select2-result-label {
1149
+ font-weight: normal;
1150
+ }
1151
+ .select2-results li.select2-result-with-children.select2-selected {
1152
+ display: block;
1153
+ }
1154
+ .select2-results li.select2-result-with-children.select2-selected .select2-result {
1155
+ display: block;
1156
+ }
1157
+ .select2-results li.select2-result-with-children.select2-selected > .select2-result-label {
1158
+ background-color: #efefef;
1159
+ color: #a1a1a1;
1160
+ cursor: default;
1161
+ }
1162
+ .select2-results li.select2-result-with-children.select2-result-unselectable > .select2-result-label {
1163
+ color: #939393;
1164
+ font-weight: normal;
1165
+ }
1166
+ /*
1167
+ Red button styles.
1168
+
1169
+ Credit to https://github.com/jensjns/wp-admin-red-button
1170
+ =============================================*/
1171
+ .wp-core-ui .button-red {
1172
+ background-color: #a00;
1173
+ border-bottom-color: #8D1F21;
1174
+ border-color: #9B2124;
1175
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
1176
+ color: #fff;
1177
+ text-decoration: none;
1178
+ text-shadow: 0 1px 0 rgba(0,0,0,0.1);
1179
+ }
1180
+ .wp-core-ui .button-red.hover,
1181
+ .wp-core-ui .button-red:hover,
1182
+ .wp-core-ui .button-red.focus,
1183
+ .wp-core-ui .button-red:focus {
1184
+ background-color: #a00;
1185
+ border-color: #7F1C1F;
1186
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
1187
+ color: #fff;
1188
+ text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
1189
+ }
1190
+ .wp-core-ui .button-red.focus,
1191
+ .wp-core-ui .button-red:focus {
1192
+ border-color: #500F0E;
1193
+ box-shadow: inset 0 1px 0 rgba(120,200,230,0.6), 1px 1px 2px rgba(0,0,0,0.4);
1194
+ }
1195
+ .wp-core-ui .button-red.active,
1196
+ .wp-core-ui .button-red.active:hover,
1197
+ .wp-core-ui .button-red.active:focus,
1198
+ .wp-core-ui .button-red:active {
1199
+ background: #7F1C1F;
1200
+ border-color: #601312 #AE2426 #AE2426 #AE2426;
1201
+ box-shadow: inset 0 1px 0 rgba(0,0,0,0.1);
1202
+ color: rgba(255,255,255,0.95);
1203
+ text-shadow: 0 1px 0 rgba(0,0,0,0.1);
1204
+ }
1205
+ .wp-core-ui .button-red[disabled],
1206
+ .wp-core-ui .button-red:disabled,
1207
+ .wp-core-ui .button-red-disabled {
1208
+ color: #E79496 !important;
1209
+ background: #BA292B !important;
1210
+ border-color: #7F1C1F !important;
1211
+ box-shadow: none !important;
1212
+ text-shadow: 0 -1px 0 rgba(0,0,0,0.1) !important;
1213
+ cursor: default;
1214
+ }
1215
+ .ticket_form .select2-container .select2-choice .select2-arrow {
1216
+ display: none;
1217
+ }
1218
+ /* Clearfix Utility */
1219
+ .clear {
1220
+ zoom: 1;
1221
+ }
1222
+ .clear:after,
1223
+ .clear:before {
1224
+ content: " ";
1225
+ display: table;
1226
+ }
1227
+ .clear:after {
1228
+ clear: both;
1229
+ }
1230
+ /* from https://codepen.io/lajlev/pen/diKbz */
1231
+ .checkmark:after {
1232
+ /*Add another block-level blank space*/
1233
+ content: '';
1234
+ display: block;
1235
+
1236
+ /*Make it a small rectangle so the border will create an L-shape*/
1237
+ width: 8px;
1238
+ height: 15px;
1239
+
1240
+ /*Add a white border on the bottom and left, creating that 'L' */
1241
+ border: solid #0AB152;
1242
+ border-width: 0 3px 3px 0;
1243
+
1244
+ /*Rotate the L 45 degrees to turn it into a checkmark*/
1245
+ -webkit-transform: rotate(45deg);
1246
+ transform: rotate(45deg);
1247
+ }
1248
+ .checkmark.checkmark-right:after {
1249
+ float: right;
1250
+ margin-right: 2em;
1251
+ }
1252
+ .checkmark.checkmark-left:after {
1253
+ float: left;
1254
+ margin-left: 2em;
1255
+ }
1256
+ .checkmark.no-checkmark:after {
1257
+ display: none;
1258
+ }
1259
+ .complete,
1260
+ .ok,
1261
+ .yes,
1262
+ .on,
1263
+ [data-status="complete"],
1264
+ [data-status="ok"],
1265
+ [data-status="yes"],
1266
+ [data-status="on"] {
1267
+ color: #0AB152;
1268
+ }
1269
+ .incomplete,
1270
+ .ko,
1271
+ .no,
1272
+ .off,
1273
+ [data-status="incomplete"],
1274
+ [data-status="ko"],
1275
+ [data-status="no"],
1276
+ [data-status="off"] {
1277
+ color: #FF2500;
1278
+ }
1279
+ /*
1280
+ * Plugin install CSS
1281
+ */
1282
+ .plugin-card-the-events-calendar .column-rating,
1283
+ .plugin-card-the-events-calendar .column-updated,
1284
+ .plugin-card-the-events-calendar .column-downloaded,
1285
+ .plugin-card-events-calendar-pro .column-rating,
1286
+ .plugin-card-events-calendar-pro .column-updated,
1287
+ .plugin-card-events-calendar-pro .column-downloaded,
1288
+ .plugin-card-event-tickets .column-rating,
1289
+ .plugin-card-event-tickets .column-updated,
1290
+ .plugin-card-event-tickets .column-downloaded,
1291
+ .plugin-card-event-tickets-plus .column-rating,
1292
+ .plugin-card-event-tickets-plus .column-updated,
1293
+ .plugin-card-event-tickets-plus .column-downloaded,
1294
+ .plugin-card-events-community .column-rating,
1295
+ .plugin-card-events-community .column-updated,
1296
+ .plugin-card-events-community .column-downloaded,
1297
+ .plugin-card-events-community-tickets .column-rating,
1298
+ .plugin-card-events-community-tickets .column-updated,
1299
+ .plugin-card-events-community-tickets .column-downloaded,
1300
+ .plugin-card-tribe-eventbrite .column-rating,
1301
+ .plugin-card-tribe-eventbrite .column-updated,
1302
+ .plugin-card-tribe-eventbrite .column-downloaded,
1303
+ .plugin-card-tribe-filterbar .column-rating,
1304
+ .plugin-card-tribe-filterbar .column-updated,
1305
+ .plugin-card-tribe-filterbar .column-downloaded,
1306
+ .plugin-card-image-widget .column-rating,
1307
+ .plugin-card-image-widget .column-updated,
1308
+ .plugin-card-image-widget .column-downloaded,
1309
+ .plugin-card-image-widget-plus .column-rating,
1310
+ .plugin-card-image-widget-plus .column-updated,
1311
+ .plugin-card-image-widget-plus .column-downloaded {
1312
+ display: none;
1313
+ }
1314
+ @media
1315
+ only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) {
1316
+
1317
+ #tribe-loading span {
1318
+ background-image: url(../images/tribe-loading@2x.gif);
1319
+ }
1320
+ }
1321
+ @media screen and (max-width: 782px) {
1322
+
1323
+ .tribe-half-column,
1324
+ .tribe-row .tribe-half-column:last-child {
1325
+ margin: 0 0 20px 0;
1326
+ width: 100%;
1327
+ }
1328
+
1329
+ input[type='email'] {
1330
+ width: 100%;
1331
+ }
1332
+ }
1333
+ @media screen and ( max-width: 782px ) {
1334
+
1335
+ .events-cal .subsubsub {
1336
+ float: none;
1337
+ }
1338
+
1339
+ .events-cal .search-box {
1340
+ width: 98%;
1341
+ }
1342
+
1343
+ .events-cal #search-submit {
1344
+ width: 100%;
1345
+ }
1346
+
1347
+ .events-cal .tablenav.top {
1348
+ display: none;
1349
+ }
1350
+ }
1351
+ @media screen and (min-width: 500px) {
1352
+ .api-check .tribe-mascot {
1353
+ display: block
1354
+ }
1355
+ .api-check .notice-content {
1356
+ margin-right: 180px
1357
+ }
1358
+ }
1359
+ @media screen and (min-width: 600px) and (max-width: 782px ) {
1360
+ .tribe-marketing-notice .tribe-notice-icon {
1361
+ width: 135px
1362
+ }
1363
+ .tribe-marketing-notice .tribe-notice-content {
1364
+ margin-left: 145px
1365
+ }
1366
+ }
1367
+ @media screen and (min-width: 600px) {
1368
+ .tribe-marketing-notice .tribe-notice-icon {
1369
+ display: block
1370
+ }
1371
+ }
1372
+ @media screen and (min-width: 782px) {
1373
+ .tribe-marketing-notice .tribe-notice-content {
1374
+ margin-left: 130px
1375
+ }
1376
+ }
1377
+ @media screen and (max-width: 956px) {
1378
+
1379
+ .tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary {
1380
+ margin: 0 0 10px 0;
1381
+ }
1382
+
1383
+ .tribe-marketing-notice.tribe-bf-2018-tec em {
1384
+ clear: both;
1385
+ display: block;
1386
+ }
1387
+ }
common/src/resources/css/tribe-common-admin.min.css CHANGED
@@ -1 +1 @@
1
- .invalid input{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input::-moz-placeholder,textarea::-moz-placeholder{color:#999}input:-ms-input-placeholder,input::-ms-input-placeholder,textarea:-ms-input-placeholder,textarea::-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{text-indent:0;margin-left:1px}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{height:18px;margin:10px 0;width:250px}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:Alpha(Opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page,.tribe_welcome_page{max-width:850px}.tribe_welcome_page.wrap h1{font-size:3em;line-height:1.2;margin-top:1em}.tribe_welcome_page.wrap h1:before{color:#555d66;content:"\f145";font-family:dashicons;font-size:.9em;line-height:1;margin-right:5px;position:relative;top:4px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_welcome_page .tribe-half-column h4,.tribe_welcome_page h2{font-size:24px;line-height:1.2;margin-bottom:20px}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3,.tribe_welcome_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4,.tribe_welcome_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p,.tribe_welcome_page p{font-size:15px}.tribe_welcome_page li{font-size:14px;margin-bottom:10px}p.tribe-welcome-message{font-size:18px;font-weight:400}.tribe_welcome_page .tribe-half-column h4{margin-top:1em}.tribe_welcome_page .tribe-half-column h4:before{color:#555d66;content:"\f145";font-family:dashicons;font-size:21px;line-height:1;margin-right:10px;position:relative;top:2px}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-sos]:before{content:"\f468"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-welcome-learn-more]:before{content:"\f118"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-megaphone]:before{content:"\f488"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-heart]:before{content:"\f487"}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}.tribe-welcome-video-wrapper{height:0;margin-bottom:40px;padding-bottom:56.25%;padding-top:25px;position:relative}.tribe-welcome-video-wrapper iframe{height:100%;left:0;position:absolute;top:0;width:100%}a.tribe-rating-link{text-decoration:none}.tribe-update-links,.tribe-welcome-links{margin-top:30px}.tribe_update_page li:before,.tribe_welcome_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#ffba00;height:1rem;width:1%;background:#7ad03a}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;overflow-y:scroll;height:300px}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{padding:1em;min-height:100px}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;max-height:150px;max-width:150px;height:100%;width:auto;vertical-align:middle}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-notice-icon{bottom:0;display:none;padding:1rem;position:absolute;left:0;top:0;width:125px}.tribe-marketing-notice .tribe-notice-icon:before{content:"";display:inline-block;height:100%;width:1%;vertical-align:middle}.tribe-marketing-notice .tribe-notice-icon img{display:inline-block;max-height:100%;max-width:96%;vertical-align:middle}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}.tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary{margin:10px 10px 0 0}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container .selection,.tribe-ea-dropdown.select2-container .selection{margin-top:inherit}.tribe-dropdown .select2-selection--single,.tribe-ea-dropdown .select2-selection--single{height:32px}.tribe-dropdown .select2-selection--single .select2-selection__clear,.tribe-ea-dropdown .select2-selection--single .select2-selection__clear{line-height:28px}.tribe-dropdown .select2-selection--single .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--single .select2-selection__rendered{line-height:32px;padding-right:28px}.tribe-dropdown.select2-container--focus .select2-selection--single,.tribe-ea-dropdown.select2-container--focus .select2-selection--single{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-container--open .select2-search__field,.tribe-ea-dropdown.select2-container--open .select2-search__field{padding:0}.tribe-dropdown.select2-container--open .select2-dropdown--below,.tribe-ea-dropdown.select2-container--open .select2-dropdown--below{margin-top:-1px;border-top:1px solid #aaa}.tribe-dropdown.select2-container--open .select2-dropdown--above,.tribe-ea-dropdown.select2-container--open .select2-dropdown--above{margin-bottom:-16px;border-bottom:1px solid #aaa}.tribe-dropdown.select2-container--open .select2-selection--single,.tribe-ea-dropdown.select2-container--open .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown.select2-container--open .select2-selection__arrow b,.tribe-ea-dropdown.select2-container--open .select2-selection__arrow b{transform:rotate(180deg)}.tribe-dropdown.select2-selection--single,.tribe-ea-dropdown.select2-selection--single{background-image:none;border-radius:3px;border:1px solid #ccc;overflow:hidden}.tribe-dropdown.select2-selection--single>.select2-selection__rendered,.tribe-ea-dropdown.select2-selection--single>.select2-selection__rendered{white-space:normal}.tribe-dropdown.select2-selection--single .select2-selection__arrow,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow{background-image:none;background:transparent;border-left:0;top:2px;width:26px}.tribe-dropdown.select2-selection--single .select2-selection__arrow b,.tribe-ea-dropdown.select2-selection--single .select2-selection__arrow b{background:#fff url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;background-size:auto;background-size:16px 16px;border:0;top:0;bottom:0;left:0;right:0;display:block;width:auto;height:auto;margin:0;padding:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered{background-image:none;border-radius:3px;border:1px solid #ccc;min-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline{line-height:25px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-search--inline input{padding-top:0;padding-bottom:0}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice{margin-top:2px;padding-top:0;padding-bottom:0;line-height:19px}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice div{line-height:inherit}.tribe-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove,.tribe-ea-dropdown .select2-selection--multiple .select2-selection__rendered .select2-selection__choice__remove{top:3px;left:4px;transition-property:border,color}.select2-results .select2-results__option{color:#939393;font-weight:400;margin-bottom:0}.select2-results .select2-results__option[aria-disabled=true]{background-color:#e0e0e0}.select2-results.select2-results__option--highlighted{background-color:#efefef;color:#a1a1a1;cursor:default;display:block}.wp-core-ui .button-red{background-color:#a00;border-bottom-color:#8d1f21;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{color:#e79496!important;background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important;cursor:default}.ticket_form .select2-container .select2-selection--single .select2-selection__arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{content:"";display:block;width:8px;height:15px;border:solid #0ab152;border-width:0 3px 3px 0;transform:rotate(45deg)}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}}@media screen and (max-width:782px){.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-notice-icon{width:135px}.tribe-marketing-notice .tribe-notice-content{margin-left:145px}}@media screen and (min-width:600px){.tribe-marketing-notice .tribe-notice-icon{display:block}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-notice-content{margin-left:130px}}@media screen and (max-width:956px){.tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary{margin:0 0 10px}.tribe-marketing-notice.tribe-bf-2018-tec em{clear:both;display:block}}
1
+ .invalid input{border:2px solid red!important}.valid input{border:1px solid green}.clearfix{zoom:1}.placeholder{color:#999;cursor:text;padding:4px}input::-moz-placeholder,textarea::-moz-placeholder{color:#999}input:-ms-input-placeholder,input::-ms-input-placeholder,textarea:-ms-input-placeholder,textarea::-ms-input-placeholder{color:#999}input::placeholder,textarea::placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.bubble{background-color:#f9f9f9;border:1px solid #dfdfdf;border-radius:3px;border-spacing:0;padding:10px}.tribe-sticky-tooltip{color:#bbb}td.tribe_message{padding-bottom:10px!important}#tribe_thanks{float:left;margin:5px 0 0;width:200px}.tribe_brand{font-family:Georgia,serif!important;font-size:17px!important;font-weight:400;margin:8px 0}#tribe-upgrade{background:#f6f6f6;border:1px solid #ccc;border-radius:5px;margin:20px 0 30px;padding:0 20px 20px}#tribe-upgrade .message{background-color:#ffffe0;border:1px solid #e6db55;border-radius:3px;padding:6px 12px}table.plugins .tribe-plugin-update-message{background:#d54e21;color:#fff;display:inline-table;margin:6px 0;padding:10px 12px}table.plugins .tribe-plugin-update-message h4{display:inline;font-weight:700;margin-right:8px}table.plugins .tribe-plugin-update-message h4:after{content:" \00BB "}table.plugins .tribe-plugin-update-message a{color:#fff;text-decoration:underline}.tribe-settings-form{max-width:1000px}.tribe-settings-form fieldset{clear:both;display:inline-block;padding:10px 0}.tribe-settings-form fieldset.tribe-field-license_key legend{width:auto}.tribe-settings-form legend{float:left;font-weight:700;margin-right:20px;width:220px}.tribe-settings-form .tribe-field-wrap{float:left;max-width:500px}.tribe-settings-form .tribe-field-wrap :first-child{margin-top:0}.tribe-settings-form .tribe-field-checkbox_list label,.tribe-settings-form .tribe-field-radio label{display:block;margin:5px 0 5px 20px;text-indent:-20px}.tribe-settings-form .tribe-field-checkbox_list label>p,.tribe-settings-form .tribe-field-radio label>p{text-indent:0;margin-left:1px}.tribe-settings-form .tribe-field-checkbox_list label input,.tribe-settings-form .tribe-field-radio label input{margin-right:5px}.tribe-settings-form .tribe-settings-form-wrap .description,.tribe-settings-form .tribe-settings-form-wrap fieldset,.tribe-settings-form fieldset[id^=tribe-field-geoloc_]{padding-left:12px}.tribe-settings-form .tribe-settings-form-wrap fieldset .description{margin-left:0;max-width:450px;padding-left:0}.tribe-settings-form .tribe-settings-form-wrap fieldset .tribe-style-selection{margin-bottom:18px}.tribe-settings-form .tribe-settings-form-wrap #tribe-field-stylesheetOption .description{color:#999;margin-left:1px}.tribe-settings-form .tribe-settings-form-wrap h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}.tribe-settings-form .tribe-settings-form-wrap .contained,.tribe-settings-form .tribe-settings-form-wrap .system-info,.tribe-settings-form .tribe-settings-form-wrap .tribe-sysinfo-optin-msg,.tribe-settings-form .tribe-settings-form-wrap h3+p{margin:0 0 10px;padding-left:12px}.tribe_settings .tribe-field-indent{margin-left:245px}.tribe_settings #pu_dashboard_message{display:none}.tribe_settings .tribe-errors-list{margin-left:15px}.tribe_settings .expiring-license{color:red}.tribe_settings .tribe-error{border:1px solid red}.tribe_settings .tribe-field-description{margin-bottom:0;position:relative;top:-12px}.tribe_settings #ical-link{top:-14px}#modern-tribe-info{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:8px 20px 12px}#modern-tribe-info img{height:18px;margin:10px 0;width:250px}#modern-tribe-info ul{list-style:disc;margin-left:20px}#modern-tribe-info ul ul{list-style:circle}.tribe-field-inline-dropdown{margin-left:0;margin-right:0}.tribe-field-inline-text{line-height:28px;margin:0 2px}.tribe-field-textarea.tribe-size-small textarea{height:60px;width:180px}.tribe-field-textarea.tribe-size-medium textarea{height:80px;width:300px}.tribe-field-textarea.tribe-size-large textarea{height:120px;width:450px}.tribe-field-email.tribe-size-small input,.tribe-field-license_key.tribe-size-small input,.tribe-field-text.tribe-size-small input{width:50px}.tribe-field-email.tribe-size-medium input,.tribe-field-license_key.tribe-size-medium input,.tribe-field-text.tribe-size-medium input{width:225px}.tribe-field-email.tribe-size-large input,.tribe-field-license_key.tribe-size-large input,.tribe-field-text.tribe-size-large input{width:450px}.tribe-field-dropdown.tribe-size-small select{width:100px}.tribe-field-dropdown.tribe-size-medium select{width:300px}.tribe-field-dropdown.tribe-size-large select{width:450px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap{max-width:600px}.tribe-field-wrapped_html.tribe-size-large .tribe-field-wrap .description{max-width:100%}.tribe-field-dropdown_chosen.tribe-size-small select{width:100px}.tribe-field-dropdown_chosen.tribe-size-medium select{width:200px}.tribe-field-dropdown_chosen.tribe-size-large select{width:300px}.tribe-field-wrap .tooltip:first-child{font-style:normal}.tribe-field.indent{margin-left:252px;width:75%}.tribe-field.indent legend{font-weight:400;width:auto}.tribe-field.indent .tribe-field-wrap{padding-right:12px}.tribe-field.indent.tribe-field-radio .tribe-field-wrap{clear:left;margin-top:12px}.tribe-field.light-bordered{background-color:#fff;border:1px solid #d3d3d3}.ajax-loading-license,.invalid-key,.valid-key{display:none;margin:0 5px}.ajax-loading-license{position:relative;top:5px}.key-validity{display:inline-block}.invalid-key,.optin-fail{color:red}.optin-success,.valid-key{color:green}.valid-key.service-msg{color:#b72}#additional-field-table{margin-bottom:20px}.tribe-admin-box-left{float:left;width:20%}.tribe-admin-box-left,.tribe-admin-box-right{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;margin:20px 0;padding:0 20px 15px}.tribe-admin-box-right{float:right;width:68%}.ajax-loader{float:right;margin:10px}.tribe-arrangeable-item{border:1px solid #d3d3d3;border-radius:3px}.tribe-arrangeable-item .ui-state-default{border:none}.tribe-arrangeable-item-top{padding:6px}.tribe-arrangeable-item-top:hover{cursor:move}.tribe-arrangeable-action{float:right}.tribe-arrangeable-child{background-color:#f9f9f9;border-top:1px solid #d3d3d3;display:none;padding:25px}.tribe-arrangeable-child label{display:block;margin:0 0 7px}.tribe_events_active_filter_type_options{margin:10px 0}.tribe_events_active_filter_type_options label{margin:7px 0}#event_organizer td small,.OrganizerInfo td small{display:block;margin:0;max-width:250px}#event_organizer .organizer-email,.OrganizerInfo .organizer-email{vertical-align:top}.tribe-table-field-label{max-width:100%;width:200px}#tribe-help-general,#tribe-help-sidebar{float:left;margin-top:20px}#tribe-help-general p{margin-left:15px}#tribe-help-general ul{list-style-type:square}#tribe-help-general ol,#tribe-help-general ul{margin-bottom:20px;margin-left:35px}#tribe-help-general h3{background-color:#f9f9f9;margin-bottom:10px;padding:6px 0 6px 12px}#tribe-help-general h3~h3{margin-top:2.25em}#tribe-help-general h3+p{margin:0 0 20px;padding-left:12px}#tribe-help-general{width:65%}.tribe-help-section{padding-bottom:10px}.tribe-section-type-box{background-color:#f9f9f9;border:1px solid #ccc;border-radius:4px;padding:8px 20px 12px}.tribe-section-type-box img{height:auto;margin:10px 0;max-width:300px}.tribe-section-type-box ul{list-style:disc;margin-left:20px}.tribe-section-type-box ul ul{list-style:circle}#tribe-log-controls{padding-bottom:1rem;padding-left:12px}#tribe-log-controls>div{display:inline-block;padding-right:1rem}#tribe-log-controls .working{opacity:1;transition:opacity .2s}#tribe-log-controls .working.hidden{opacity:0;transition:opacity .2s}#tribe-log-viewer,#tribe-system-info dl.support-stats,.template-updates-wrapper{background:#000;border-radius:2px;color:#888;max-height:400px;overflow:scroll;padding:10px}#tribe-system-info dl.support-stats dt,.template-updates-wrapper dt{clear:both;float:left;font-weight:700;text-transform:uppercase;width:25%}#tribe-system-info dl.support-stats dd,.template-updates-wrapper dd{margin-left:25%;padding-left:10px}.system-info-copy .system-info-copy-btn{padding:6px}.system-info-copy .system-info-copy-btn .dashicons{padding-right:10px}.template-updates-wrapper p{margin-top:0}#tribe-help-sidebar{margin:20px 0 0 3%;max-width:225px;width:32%}.tribe-help-plugin-info{border:1px solid #ccc;padding:0 12px 12px}.tribe-help-plugin-info dd,.tribe-help-plugin-info dt{display:inline;margin:0}.tribe-help-plugin-info dt{font-weight:700}.tribe-help-plugin-info dd:after{content:"";display:block;height:.4em}.tribe-help-plugin-info dd:last-child:after{height:0}.tribe-help-plugin-info+.tribe-help-plugin-info{margin-top:20px}.tribe-help-plugin-info>div{line-height:2em}.tribe-help-plugin-info .star-rating{display:inline-block;margin-left:3px;position:relative;top:-2px}.tribe-help-plugin-info .tribe-list-addons{color:#21a6cb;font-size:24px;list-style:circle inside;margin-bottom:10px;margin-top:10px;padding-left:4px}.tribe-help-plugin-info .tribe-list-addons a{font-size:13px;left:-5px;position:relative;top:-5px}.tribe-help-plugin-info .tribe-list-addons .tribe-active-addon{list-style:disc inside}.ui-widget-overlay{background:#666;filter:Alpha(Opacity=50);opacity:.5}.ui-widget-shadow{background:#000;border-radius:5px;filter:Alpha(Opacity=20);margin:-5px 0 0 -5px;opacity:.2;padding:5px}.ui-resizable{position:relative}.ui-resizable-handle{display:block;font-size:.1px;position:absolute;z-index:99999}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;left:0;top:-5px;width:100%}.ui-resizable-s{bottom:-5px;cursor:s-resize;height:7px;left:0;width:100%}.ui-resizable-e{cursor:e-resize;height:100%;right:-5px;top:0;width:7px}.ui-resizable-w{cursor:w-resize;height:100%;left:-5px;top:0;width:7px}.ui-resizable-se{bottom:1px;cursor:se-resize;height:12px;right:1px;width:12px}.ui-resizable-sw{bottom:-5px;cursor:sw-resize;height:9px;left:-5px;width:9px}.ui-resizable-nw{cursor:nw-resize;height:9px;left:-5px;top:-5px;width:9px}.ui-resizable-ne{cursor:ne-resize;height:9px;right:-5px;top:-5px;width:9px}.ui-dialog{padding:.2em;position:relative;width:375px}.ui-dialog .ui-dialog-titlebar{padding:.5em .3em .3em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0 .2em}.ui-dialog .ui-dialog-titlebar-close{height:18px;margin:-10px 0 0;padding:1px;position:absolute;right:.3em;top:50%;width:19px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin-left:-8px;margin-top:-8px}.ui-dialog .ui-dialog-titlebar-close:focus,.ui-dialog .ui-dialog-titlebar-close:hover{padding:0}.ui-dialog .ui-dialog-content{background:none;border:0;overflow:auto;padding:.5em 1em;zoom:1}.ui-dialog .ui-dialog-buttonpane{background-image:none;border-width:1px 0 0;margin:.5em 0 0;padding:.3em 1em .5em!important;text-align:right}.ui-dialog .ui-dialog-buttonpane button{cursor:pointer;line-height:1.4em;margin:.5em .4em!important;overflow:visible;padding:.2em .6em .3em;text-shadow:none;width:auto}.ui-dialog .ui-resizable-se{bottom:3px;height:14px;right:3px;width:14px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:none!important;text-align:center}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button .ui-button-text{display:block;line-height:1.4}#ui-datepicker-div{display:none}#tribe-loading{background:#fff;background:hsla(0,0%,100%,.8);display:none;height:100%;left:0;position:absolute;top:0;transition:all 1s linear;width:100%;z-index:4}#tribe-loading span{background:url(../images/tribe-loading.gif) 0 0 no-repeat;background-size:32px 32px;height:32px;left:50%;margin:-16px 0 0 -16px;position:absolute;top:50%;width:32px}.tribe_update_page,.tribe_welcome_page{max-width:850px}.tribe_welcome_page.wrap h1{font-size:3em;line-height:1.2;margin-top:1em}.tribe_welcome_page.wrap h1:before{color:#555d66;content:"\f145";font-family:dashicons;font-size:.9em;line-height:1;margin-right:5px;position:relative;top:4px}.tribe-half-column{float:left;margin-bottom:30px;margin-right:5%;width:45%}.tribe-row:after,.tribe-row:before{content:"";display:table}.tribe-row,.tribe-row:after{clear:both}.tribe-row .tribe-half-column:last-child{margin-right:0;width:50%}.tribe_welcome_page .tribe-half-column h4,.tribe_welcome_page h2{font-size:24px;line-height:1.2;margin-bottom:20px}.tribe_update_page h2{font-size:30px;line-height:1.2;margin-bottom:20px}.tribe_update_page h3,.tribe_welcome_page h3{font-size:24px;font-weight:400;line-height:24px;margin-top:0}.tribe_update_page h4,.tribe_welcome_page h4{font-size:18px;font-weight:600;line-height:18px;margin:0}.tribe_update_page p,.tribe_welcome_page p{font-size:15px}.tribe_welcome_page li{font-size:14px;margin-bottom:10px}p.tribe-welcome-message{font-size:18px;font-weight:400}.tribe_welcome_page .tribe-half-column h4{margin-top:1em}.tribe_welcome_page .tribe-half-column h4:before{color:#555d66;content:"\f145";font-family:dashicons;font-size:21px;line-height:1;margin-right:10px;position:relative;top:2px}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-sos]:before{content:"\f468"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-welcome-learn-more]:before{content:"\f118"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-megaphone]:before{content:"\f488"}.tribe_welcome_page .tribe-half-column h4[data-tribe-icon=dashicons-heart]:before{content:"\f487"}.tribe_update_page h4:before{content:"\f145";font-family:dashicons;font-size:34px;line-height:1;margin-right:5px;position:relative;top:5px}.tribe-welcome-video-wrapper{height:0;margin-bottom:40px;padding-bottom:56.25%;padding-top:25px;position:relative}.tribe-welcome-video-wrapper iframe{height:100%;left:0;position:absolute;top:0;width:100%}a.tribe-rating-link{text-decoration:none}.tribe-update-links,.tribe-welcome-links{margin-top:30px}.tribe_update_page li:before,.tribe_welcome_page li:before{content:"\2022";padding-right:3px}.tribe_update_page .rss-widget{margin:1em 0}.tribe_update_page a.rsswidget{font-size:14px;font-weight:400;line-height:1}.tribe_update_page .rss-widget li:before{display:none}.tribe-update-bar{display:inline-block}.tribe-update-bar .progress{border:1px solid #ccc;float:left;margin-right:1rem;padding:1px;width:18rem}.tribe-update-bar .progress .bar{background:#ffba00;height:1rem;width:1%;background:#7ad03a}#tribe-dialog-wrapper>div{padding:1rem}#tribe-dialog-wrapper>div .stage{display:none}#tribe-dialog-wrapper #heading{background:#fff}#tribe-dialog-wrapper label{display:block}#tribe-dialog-wrapper .select-single-container{border:1px solid #888;overflow-y:scroll;height:300px}#tribe-dialog-wrapper .select-single-container label{opacity:1;padding:3px 5px;transition:opacity .2s}#tribe-dialog-wrapper .select-single-container label:nth-child(odd){background:#fff}#tribe-dialog-wrapper .select-single-container label.selected{background:#0073aa;color:#fff;font-weight:700}#tribe-dialog-wrapper .select-single-container label input{display:none}#tribe-dialog-wrapper .select-single-container.updating label{opacity:.35;transition:opacity .2s}.ui-front{z-index:1000000}.select2-container .select2-choice abbr{top:6px}.wp-list-table.plugins .column-description .update-message{color:#d54e21}.api-check{padding:1em;min-height:100px}.api-check+.notice-dismiss:hover:before{color:#fff}.api-check:after,.api-check:before{content:"";display:table}.api-check:after{clear:both}.api-check .tribe-mascot{bottom:0;display:none;padding:0 1rem 0 0;position:absolute;right:0;top:0}.api-check .tribe-mascot img{display:inline-block;max-height:150px;max-width:150px;height:100%;width:auto;vertical-align:middle}.api-check p{line-height:1.7;margin-bottom:1em}.api-check a{text-decoration:none}.api-check a:hover{text-decoration:underline}.api-check .plugin-list{display:inline;font-weight:600;margin:0;padding:0}.api-check .plugin-list span.plugin-invalid:after{content:", "}.api-check .plugin-list span.plugin-invalid:last-of-type:after{content:""}.tribe-marketing-notice{padding:1em}.tribe-marketing-notice+.notice-dismiss:hover:before{color:#fff}.tribe-marketing-notice:after,.tribe-marketing-notice:before{content:"";display:table}.tribe-marketing-notice:after{clear:both}.tribe-marketing-notice .tribe-notice-icon{bottom:0;display:none;padding:1rem;position:absolute;left:0;top:0;width:125px}.tribe-marketing-notice .tribe-notice-icon:before{content:"";display:inline-block;height:100%;width:1%;vertical-align:middle}.tribe-marketing-notice .tribe-notice-icon img{display:inline-block;max-height:100%;max-width:96%;vertical-align:middle}.tribe-marketing-notice h3{margin-bottom:.5em;margin-top:.5em}.tribe-marketing-notice p{line-height:1.7;margin-bottom:.5em}.tribe-marketing-notice a{text-decoration:none}.tribe-marketing-notice a:hover{text-decoration:underline}.tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary{margin:10px 10px 0 0}.tribe-dropdown,.tribe-ea-dropdown{max-width:100%;width:auto}.tribe-dropdown.select2-container-active .select2-choice,.tribe-ea-dropdown.select2-container-active .select2-choice{border-color:#5897fb;box-shadow:0 0 5px rgba(0,0,0,.1)}.tribe-dropdown.select2-dropdown-open .select2-choice,.tribe-ea-dropdown.select2-dropdown-open .select2-choice{border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:#aaa}.tribe-dropdown .select2-choice,.tribe-ea-dropdown .select2-choice{background-image:none;border-radius:3px;border:1px solid #ccc}.tribe-dropdown .select2-choice>.select2-chosen,.tribe-ea-dropdown .select2-choice>.select2-chosen{white-space:normal}.tribe-dropdown .select2-choice .select2-arrow,.tribe-ea-dropdown .select2-choice .select2-arrow{background-image:none;background:transparent;border-left:0}.tribe-dropdown .select2-choice div,.tribe-ea-dropdown .select2-choice div{background-image:none;background:none;border-left:0}.tribe-dropdown.select2-container-multi .select2-choices,.tribe-ea-dropdown.select2-container-multi .select2-choices{background-image:none;border-radius:3px;border:1px solid #ccc;min-height:25px}.tribe-dropdown.select2-container-multi .select2-choices .select2-search-field,.tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-field{line-height:25px}.tribe-dropdown.select2-container-multi .select2-choices .select2-search-field input,.tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-field input{padding-top:0;padding-bottom:0}.tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice,.tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice{margin-top:2px;padding-top:0;padding-bottom:0;line-height:19px}.tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice div,.tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice div{line-height:inherit}.tribe-dropdown.select2-container-multi .select2-choices .select2-search-choice-close,.tribe-ea-dropdown.select2-container-multi .select2-choices .select2-search-choice-close{top:3px;left:4px;transition-property:border,color}.select2-results .select2-selected{display:block}.select2-results .select2-selected>.select2-result-label{background-color:#efefef;color:#a1a1a1;cursor:default}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:400}.select2-results li.select2-result-with-children.select2-selected,.select2-results li.select2-result-with-children.select2-selected .select2-result{display:block}.select2-results li.select2-result-with-children.select2-selected>.select2-result-label{background-color:#efefef;color:#a1a1a1;cursor:default}.select2-results li.select2-result-with-children.select2-result-unselectable>.select2-result-label{color:#939393;font-weight:400}.wp-core-ui .button-red{background-color:#a00;border-bottom-color:#8d1f21;border-color:#9b2124;box-shadow:inset 0 1px 0 rgba(120,200,230,.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red.hover,.wp-core-ui .button-red:focus,.wp-core-ui .button-red:hover{background-color:#a00;border-color:#7f1c1f;box-shadow:inset 0 1px 0 rgba(120,200,230,.6);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.3)}.wp-core-ui .button-red.focus,.wp-core-ui .button-red:focus{border-color:#500f0e;box-shadow:inset 0 1px 0 rgba(120,200,230,.6),1px 1px 2px rgba(0,0,0,.4)}.wp-core-ui .button-red.active,.wp-core-ui .button-red.active:focus,.wp-core-ui .button-red.active:hover,.wp-core-ui .button-red:active{background:#7f1c1f;border-color:#601312 #ae2426 #ae2426;box-shadow:inset 0 1px 0 rgba(0,0,0,.1);color:hsla(0,0%,100%,.95);text-shadow:0 1px 0 rgba(0,0,0,.1)}.wp-core-ui .button-red-disabled,.wp-core-ui .button-red:disabled,.wp-core-ui .button-red[disabled]{color:#e79496!important;background:#ba292b!important;border-color:#7f1c1f!important;box-shadow:none!important;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important;cursor:default}.ticket_form .select2-container .select2-choice .select2-arrow{display:none}.clear{zoom:1}.clear:after,.clear:before{content:" ";display:table}.clear:after{clear:both}.checkmark:after{content:"";display:block;width:8px;height:15px;border:solid #0ab152;border-width:0 3px 3px 0;transform:rotate(45deg)}.checkmark.checkmark-right:after{float:right;margin-right:2em}.checkmark.checkmark-left:after{float:left;margin-left:2em}.checkmark.no-checkmark:after{display:none}.complete,.ok,.on,.yes,[data-status=complete],[data-status=ok],[data-status=on],[data-status=yes]{color:#0ab152}.incomplete,.ko,.no,.off,[data-status=incomplete],[data-status=ko],[data-status=no],[data-status=off]{color:#ff2500}.plugin-card-event-tickets-plus .column-downloaded,.plugin-card-event-tickets-plus .column-rating,.plugin-card-event-tickets-plus .column-updated,.plugin-card-event-tickets .column-downloaded,.plugin-card-event-tickets .column-rating,.plugin-card-event-tickets .column-updated,.plugin-card-events-calendar-pro .column-downloaded,.plugin-card-events-calendar-pro .column-rating,.plugin-card-events-calendar-pro .column-updated,.plugin-card-events-community-tickets .column-downloaded,.plugin-card-events-community-tickets .column-rating,.plugin-card-events-community-tickets .column-updated,.plugin-card-events-community .column-downloaded,.plugin-card-events-community .column-rating,.plugin-card-events-community .column-updated,.plugin-card-image-widget-plus .column-downloaded,.plugin-card-image-widget-plus .column-rating,.plugin-card-image-widget-plus .column-updated,.plugin-card-image-widget .column-downloaded,.plugin-card-image-widget .column-rating,.plugin-card-image-widget .column-updated,.plugin-card-the-events-calendar .column-downloaded,.plugin-card-the-events-calendar .column-rating,.plugin-card-the-events-calendar .column-updated,.plugin-card-tribe-eventbrite .column-downloaded,.plugin-card-tribe-eventbrite .column-rating,.plugin-card-tribe-eventbrite .column-updated,.plugin-card-tribe-filterbar .column-downloaded,.plugin-card-tribe-filterbar .column-rating,.plugin-card-tribe-filterbar .column-updated{display:none}@media only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min--moz-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){#tribe-loading span{background-image:url(../images/tribe-loading@2x.gif)}}@media screen and (max-width:782px){.tribe-half-column,.tribe-row .tribe-half-column:last-child{margin:0 0 20px;width:100%}input[type=email]{width:100%}}@media screen and (max-width:782px){.events-cal .subsubsub{float:none}.events-cal .search-box{width:98%}.events-cal #search-submit{width:100%}.events-cal .tablenav.top{display:none}}@media screen and (min-width:500px){.api-check .tribe-mascot{display:block}.api-check .notice-content{margin-right:180px}}@media screen and (min-width:600px) and (max-width:782px){.tribe-marketing-notice .tribe-notice-icon{width:135px}.tribe-marketing-notice .tribe-notice-content{margin-left:145px}}@media screen and (min-width:600px){.tribe-marketing-notice .tribe-notice-icon{display:block}}@media screen and (min-width:782px){.tribe-marketing-notice .tribe-notice-content{margin-left:130px}}@media screen and (max-width:956px){.tribe-marketing-notice.tribe-bf-2018-tec .button.button-primary{margin:0 0 10px}.tribe-marketing-notice.tribe-bf-2018-tec em{clear:both;display:block}}
common/src/resources/css/tribe-ui.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ .tribe-button {
12
+ border: 0;
13
+ border-radius: 3px;
14
+ background: #009FF1 -webkit-gradient( linear, left top, left bottom, from(#009FF1), to(#0080DB));
15
+ background: #009FF1 linear-gradient( to bottom, #009FF1, #0080DB);
16
+ cursor: pointer;
17
+ color: #fff;
18
+ display: inline-block;
19
+ font-size: 14px;
20
+ font-weight: 400;
21
+ font-family: sans-serif;
22
+ letter-spacing: 1px;
23
+ line-height: 1;
24
+ height: auto;
25
+ padding: 10px;
26
+ text-align: center;
27
+ -webkit-transition: all .15s ease-in;
28
+ transition: all .15s ease-in;
29
+ -webkit-font-smoothing: subpixel-antialiased;
30
+ }
31
+
32
+ .tribe-button:hover,
33
+ .tribe-button:active,
34
+ .tribe-button:focus {
35
+ background: #0080DB;
36
+ }
common/src/resources/css/tribe-ui.min.css CHANGED
@@ -1 +1 @@
1
- .tribe-button{border:0;border-radius:3px;background:#009ff1 linear-gradient(180deg,#009ff1,#0080db);cursor:pointer;color:#fff;display:inline-block;font-size:14px;font-weight:400;font-family:sans-serif;letter-spacing:1px;line-height:1;height:auto;padding:10px;text-align:center;transition:all .15s ease-in;-webkit-font-smoothing:subpixel-antialiased}.tribe-button:active,.tribe-button:focus,.tribe-button:hover{background:#0080db}.hide-before-select2-init{display:none}
1
+ .tribe-button{border:0;border-radius:3px;background:#009ff1 linear-gradient(180deg,#009ff1,#0080db);cursor:pointer;color:#fff;display:inline-block;font-size:14px;font-weight:400;font-family:sans-serif;letter-spacing:1px;line-height:1;height:auto;padding:10px;text-align:center;transition:all .15s ease-in;-webkit-font-smoothing:subpixel-antialiased}.tribe-button:active,.tribe-button:focus,.tribe-button:hover{background:#0080db}
common/src/resources/css/validation.css ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This CSS file was auto-generated via PostCSS
3
+ *
4
+ * Contributors should avoid editing this file, but instead edit the associated
5
+ * src/resources/postcss/ file. For more information, check out our engineering
6
+ * docs on how we handle CSS in our engineering docs.
7
+ *
8
+ * @see: http://moderntribe.github.io/products-engineering/css/
9
+ */
10
+
11
+ .tribe-validation input[type="text"].tribe-validation-error, .tribe-validation input[type="password"].tribe-validation-error, .tribe-validation input[type="checkbox"].tribe-validation-error, .tribe-validation input[type="color"].tribe-validation-error, .tribe-validation input[type="date"].tribe-validation-error, .tribe-validation input[type="datetime"].tribe-validation-error, .tribe-validation input[type="datetime-local"].tribe-validation-error, .tribe-validation input[type="email"].tribe-validation-error, .tribe-validation input[type="month"].tribe-validation-error, .tribe-validation input[type="number"].tribe-validation-error, .tribe-validation input[type="search"].tribe-validation-error, .tribe-validation input[type="radio"].tribe-validation-error, .tribe-validation input[type="tel"].tribe-validation-error, .tribe-validation input[type="text"].tribe-validation-error, .tribe-validation input[type="time"].tribe-validation-error, .tribe-validation input[type="url"].tribe-validation-error, .tribe-validation input[type="week"].tribe-validation-error, .tribe-validation select.tribe-validation-error, .tribe-validation textarea.tribe-validation-error {
12
+ border-color: #dc3232;
13
+ }
14
+
15
+
16
+ .tribe-validation .tribe-dropdown.tribe-validation-error .select2-choice {
17
+ border-color: #dc3232;
18
+ }
common/src/resources/images/app-shop-community.jpg CHANGED
Binary file
common/src/resources/images/app-shop-eventbrite.jpg CHANGED
Binary file
common/src/resources/images/app-shop-ical.jpg CHANGED
Binary file
common/src/resources/images/app-shop-pro.jpg CHANGED
Binary file
common/src/resources/images/app-shop-promoter.jpg CHANGED
Binary file
common/src/resources/images/app-shop-tickets-plus.jpg CHANGED
Binary file
common/src/resources/images/donate-link-screenshot.png CHANGED
Binary file
common/src/resources/images/gutenberg-admin-notice-TEC.png CHANGED
Binary file
common/src/resources/images/gutenberg-admin-notice-tickets.png CHANGED
Binary file
common/src/resources/images/mascot.png CHANGED
Binary file
common/src/resources/js/app/components.js ADDED
@@ -0,0 +1,21779 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var tribe = typeof tribe === "object" ? tribe : {}; tribe["common"] = tribe["common"] || {}; tribe["common"]["components"] =
2
+ /******/ (function(modules) { // webpackBootstrap
3
+ /******/ // The module cache
4
+ /******/ var installedModules = {};
5
+ /******/
6
+ /******/ // The require function
7
+ /******/ function __webpack_require__(moduleId) {
8
+ /******/
9
+ /******/ // Check if module is in cache
10
+ /******/ if(installedModules[moduleId]) {
11
+ /******/ return installedModules[moduleId].exports;
12
+ /******/ }
13
+ /******/ // Create a new module (and put it into the cache)
14
+ /******/ var module = installedModules[moduleId] = {
15
+ /******/ i: moduleId,
16
+ /******/ l: false,
17
+ /******/ exports: {}
18
+ /******/ };
19
+ /******/
20
+ /******/ // Execute the module function
21
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22
+ /******/
23
+ /******/ // Flag the module as loaded
24
+ /******/ module.l = true;
25
+ /******/
26
+ /******/ // Return the exports of the module
27
+ /******/ return module.exports;
28
+ /******/ }
29
+ /******/
30
+ /******/
31
+ /******/ // expose the modules object (__webpack_modules__)
32
+ /******/ __webpack_require__.m = modules;
33
+ /******/
34
+ /******/ // expose the module cache
35
+ /******/ __webpack_require__.c = installedModules;
36
+ /******/
37
+ /******/ // define getter function for harmony exports
38
+ /******/ __webpack_require__.d = function(exports, name, getter) {
39
+ /******/ if(!__webpack_require__.o(exports, name)) {
40
+ /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41
+ /******/ }
42
+ /******/ };
43
+ /******/
44
+ /******/ // define __esModule on exports
45
+ /******/ __webpack_require__.r = function(exports) {
46
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48
+ /******/ }
49
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
50
+ /******/ };
51
+ /******/
52
+ /******/ // create a fake namespace object
53
+ /******/ // mode & 1: value is a module id, require it
54
+ /******/ // mode & 2: merge all properties of value into the ns
55
+ /******/ // mode & 4: return value when already ns object
56
+ /******/ // mode & 8|1: behave like require
57
+ /******/ __webpack_require__.t = function(value, mode) {
58
+ /******/ if(mode & 1) value = __webpack_require__(value);
59
+ /******/ if(mode & 8) return value;
60
+ /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61
+ /******/ var ns = Object.create(null);
62
+ /******/ __webpack_require__.r(ns);
63
+ /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64
+ /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65
+ /******/ return ns;
66
+ /******/ };
67
+ /******/
68
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
69
+ /******/ __webpack_require__.n = function(module) {
70
+ /******/ var getter = module && module.__esModule ?
71
+ /******/ function getDefault() { return module['default']; } :
72
+ /******/ function getModuleExports() { return module; };
73
+ /******/ __webpack_require__.d(getter, 'a', getter);
74
+ /******/ return getter;
75
+ /******/ };
76
+ /******/
77
+ /******/ // Object.prototype.hasOwnProperty.call
78
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79
+ /******/
80
+ /******/ // __webpack_public_path__
81
+ /******/ __webpack_require__.p = "";
82
+ /******/
83
+ /******/
84
+ /******/ // Load entry module and return exports
85
+ /******/ return __webpack_require__(__webpack_require__.s = 669);
86
+ /******/ })
87
+ /************************************************************************/
88
+ /******/ ([
89
+ /* 0 */
90
+ /***/ (function(module, exports, __webpack_require__) {
91
+
92
+ /**
93
+ * Copyright (c) 2013-present, Facebook, Inc.
94
+ *
95
+ * This source code is licensed under the MIT license found in the
96
+ * LICENSE file in the root directory of this source tree.
97
+ */
98
+
99
+ if (false) { var throwOnDirectAccess, ReactIs; } else {
100
+ // By explicitly using `prop-types` you are opting into new production behavior.
101
+ // http://fb.me/prop-types-in-prod
102
+ module.exports = __webpack_require__(311)();
103
+ }
104
+
105
+
106
+ /***/ }),
107
+ /* 1 */,
108
+ /* 2 */
109
+ /***/ (function(module, exports) {
110
+
111
+ module.exports = React;
112
+
113
+ /***/ }),
114
+ /* 3 */,
115
+ /* 4 */
116
+ /***/ (function(module, exports, __webpack_require__) {
117
+
118
+ "use strict";
119
+
120
+
121
+ exports.__esModule = true;
122
+
123
+ var _assign = __webpack_require__(278);
124
+
125
+ var _assign2 = _interopRequireDefault(_assign);
126
+
127
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
128
+
129
+ exports.default = _assign2.default || function (target) {
130
+ for (var i = 1; i < arguments.length; i++) {
131
+ var source = arguments[i];
132
+
133
+ for (var key in source) {
134
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
135
+ target[key] = source[key];
136
+ }
137
+ }
138
+ }
139
+
140
+ return target;
141
+ };
142
+
143
+ /***/ }),
144
+ /* 5 */,
145
+ /* 6 */
146
+ /***/ (function(module, exports) {
147
+
148
+ /**
149
+ * Checks if `value` is classified as an `Array` object.
150
+ *
151
+ * @static
152
+ * @memberOf _
153
+ * @since 0.1.0
154
+ * @category Lang
155
+ * @param {*} value The value to check.
156
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
157
+ * @example
158
+ *
159
+ * _.isArray([1, 2, 3]);
160
+ * // => true
161
+ *
162
+ * _.isArray(document.body.children);
163
+ * // => false
164
+ *
165
+ * _.isArray('abc');
166
+ * // => false
167
+ *
168
+ * _.isArray(_.noop);
169
+ * // => false
170
+ */
171
+ var isArray = Array.isArray;
172
+
173
+ module.exports = isArray;
174
+
175
+
176
+ /***/ }),
177
+ /* 7 */
178
+ /***/ (function(module, exports) {
179
+
180
+ /**
181
+ * This method returns `undefined`.
182
+ *
183
+ * @static
184
+ * @memberOf _
185
+ * @since 2.3.0
186
+ * @category Util
187
+ * @example
188
+ *
189
+ * _.times(2, _.noop);
190
+ * // => [undefined, undefined]
191
+ */
192
+ function noop() {
193
+ // No operation performed.
194
+ }
195
+
196
+ module.exports = noop;
197
+
198
+
199
+ /***/ }),
200
+ /* 8 */,
201
+ /* 9 */
202
+ /***/ (function(module, exports) {
203
+
204
+ // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
205
+ var global = module.exports = typeof window != 'undefined' && window.Math == Math
206
+ ? window : typeof self != 'undefined' && self.Math == Math ? self
207
+ // eslint-disable-next-line no-new-func
208
+ : Function('return this')();
209
+ if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
210
+
211
+
212
+ /***/ }),
213
+ /* 10 */
214
+ /***/ (function(module, exports) {
215
+
216
+ var core = module.exports = { version: '2.6.10' };
217
+ if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
218
+
219
+
220
+ /***/ }),
221
+ /* 11 */
222
+ /***/ (function(module, exports, __webpack_require__) {
223
+
224
+ var freeGlobal = __webpack_require__(137);
225
+
226
+ /** Detect free variable `self`. */
227
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
228
+
229
+ /** Used as a reference to the global object. */
230
+ var root = freeGlobal || freeSelf || Function('return this')();
231
+
232
+ module.exports = root;
233
+
234
+
235
+ /***/ }),
236
+ /* 12 */
237
+ /***/ (function(module, exports, __webpack_require__) {
238
+
239
+ var store = __webpack_require__(101)('wks');
240
+ var uid = __webpack_require__(69);
241
+ var Symbol = __webpack_require__(9).Symbol;
242
+ var USE_SYMBOL = typeof Symbol == 'function';
243
+
244
+ var $exports = module.exports = function (name) {
245
+ return store[name] || (store[name] =
246
+ USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
247
+ };
248
+
249
+ $exports.store = store;
250
+
251
+
252
+ /***/ }),
253
+ /* 13 */
254
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
255
+
256
+ "use strict";
257
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return PREFIX_COMMON_STORE; });
258
+ var PREFIX_COMMON_STORE = '@@MT/COMMON';
259
+
260
+ /***/ }),
261
+ /* 14 */
262
+ /***/ (function(module, exports) {
263
+
264
+ /**
265
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
266
+ * and has a `typeof` result of "object".
267
+ *
268
+ * @static
269
+ * @memberOf _
270
+ * @since 4.0.0
271
+ * @category Lang
272
+ * @param {*} value The value to check.
273
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
274
+ * @example
275
+ *
276
+ * _.isObjectLike({});
277
+ * // => true
278
+ *
279
+ * _.isObjectLike([1, 2, 3]);
280
+ * // => true
281
+ *
282
+ * _.isObjectLike(_.noop);
283
+ * // => false
284
+ *
285
+ * _.isObjectLike(null);
286
+ * // => false
287
+ */
288
+ function isObjectLike(value) {
289
+ return value != null && typeof value == 'object';
290
+ }
291
+
292
+ module.exports = isObjectLike;
293
+
294
+
295
+ /***/ }),
296
+ /* 15 */
297
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
298
+
299
+ "use strict";
300
+ __webpack_require__.r(__webpack_exports__);
301
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__DO_NOT_USE__ActionTypes", function() { return ActionTypes; });
302
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "applyMiddleware", function() { return applyMiddleware; });
303
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bindActionCreators", function() { return bindActionCreators; });
304
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineReducers", function() { return combineReducers; });
305
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "compose", function() { return compose; });
306
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createStore", function() { return createStore; });
307
+ /* harmony import */ var symbol_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(123);
308
+
309
+
310
+ /**
311
+ * These are private action types reserved by Redux.
312
+ * For any unknown actions, you must return the current state.
313
+ * If the current state is undefined, you must return the initial state.
314
+ * Do not reference these action types directly in your code.
315
+ */
316
+ var randomString = function randomString() {
317
+ return Math.random().toString(36).substring(7).split('').join('.');
318
+ };
319
+
320
+ var ActionTypes = {
321
+ INIT: "@@redux/INIT" + randomString(),
322
+ REPLACE: "@@redux/REPLACE" + randomString(),
323
+ PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {
324
+ return "@@redux/PROBE_UNKNOWN_ACTION" + randomString();
325
+ }
326
+ };
327
+
328
+ /**
329
+ * @param {any} obj The object to inspect.
330
+ * @returns {boolean} True if the argument appears to be a plain object.
331
+ */
332
+ function isPlainObject(obj) {
333
+ if (typeof obj !== 'object' || obj === null) return false;
334
+ var proto = obj;
335
+
336
+ while (Object.getPrototypeOf(proto) !== null) {
337
+ proto = Object.getPrototypeOf(proto);
338
+ }
339
+
340
+ return Object.getPrototypeOf(obj) === proto;
341
+ }
342
+
343
+ /**
344
+ * Creates a Redux store that holds the state tree.
345
+ * The only way to change the data in the store is to call `dispatch()` on it.
346
+ *
347
+ * There should only be a single store in your app. To specify how different
348
+ * parts of the state tree respond to actions, you may combine several reducers
349
+ * into a single reducer function by using `combineReducers`.
350
+ *
351
+ * @param {Function} reducer A function that returns the next state tree, given
352
+ * the current state tree and the action to handle.
353
+ *
354
+ * @param {any} [preloadedState] The initial state. You may optionally specify it
355
+ * to hydrate the state from the server in universal apps, or to restore a
356
+ * previously serialized user session.
357
+ * If you use `combineReducers` to produce the root reducer function, this must be
358
+ * an object with the same shape as `combineReducers` keys.
359
+ *
360
+ * @param {Function} [enhancer] The store enhancer. You may optionally specify it
361
+ * to enhance the store with third-party capabilities such as middleware,
362
+ * time travel, persistence, etc. The only store enhancer that ships with Redux
363
+ * is `applyMiddleware()`.
364
+ *
365
+ * @returns {Store} A Redux store that lets you read the state, dispatch actions
366
+ * and subscribe to changes.
367
+ */
368
+
369
+ function createStore(reducer, preloadedState, enhancer) {
370
+ var _ref2;
371
+
372
+ if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {
373
+ throw new Error('It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function.');
374
+ }
375
+
376
+ if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
377
+ enhancer = preloadedState;
378
+ preloadedState = undefined;
379
+ }
380
+
381
+ if (typeof enhancer !== 'undefined') {
382
+ if (typeof enhancer !== 'function') {
383
+ throw new Error('Expected the enhancer to be a function.');
384
+ }
385
+
386
+ return enhancer(createStore)(reducer, preloadedState);
387
+ }
388
+
389
+ if (typeof reducer !== 'function') {
390
+ throw new Error('Expected the reducer to be a function.');
391
+ }
392
+
393
+ var currentReducer = reducer;
394
+ var currentState = preloadedState;
395
+ var currentListeners = [];
396
+ var nextListeners = currentListeners;
397
+ var isDispatching = false;
398
+ /**
399
+ * This makes a shallow copy of currentListeners so we can use
400
+ * nextListeners as a temporary list while dispatching.
401
+ *
402
+ * This prevents any bugs around consumers calling
403
+ * subscribe/unsubscribe in the middle of a dispatch.
404
+ */
405
+
406
+ function ensureCanMutateNextListeners() {
407
+ if (nextListeners === currentListeners) {
408
+ nextListeners = currentListeners.slice();
409
+ }
410
+ }
411
+ /**
412
+ * Reads the state tree managed by the store.
413
+ *
414
+ * @returns {any} The current state tree of your application.
415
+ */
416
+
417
+
418
+ function getState() {
419
+ if (isDispatching) {
420
+ throw new Error('You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');
421
+ }
422
+
423
+ return currentState;
424
+ }
425
+ /**
426
+ * Adds a change listener. It will be called any time an action is dispatched,
427
+ * and some part of the state tree may potentially have changed. You may then
428
+ * call `getState()` to read the current state tree inside the callback.
429
+ *
430
+ * You may call `dispatch()` from a change listener, with the following
431
+ * caveats:
432
+ *
433
+ * 1. The subscriptions are snapshotted just before every `dispatch()` call.
434
+ * If you subscribe or unsubscribe while the listeners are being invoked, this
435
+ * will not have any effect on the `dispatch()` that is currently in progress.
436
+ * However, the next `dispatch()` call, whether nested or not, will use a more
437
+ * recent snapshot of the subscription list.
438
+ *
439
+ * 2. The listener should not expect to see all state changes, as the state
440
+ * might have been updated multiple times during a nested `dispatch()` before
441
+ * the listener is called. It is, however, guaranteed that all subscribers
442
+ * registered before the `dispatch()` started will be called with the latest
443
+ * state by the time it exits.
444
+ *
445
+ * @param {Function} listener A callback to be invoked on every dispatch.
446
+ * @returns {Function} A function to remove this change listener.
447
+ */
448
+
449
+
450
+ function subscribe(listener) {
451
+ if (typeof listener !== 'function') {
452
+ throw new Error('Expected the listener to be a function.');
453
+ }
454
+
455
+ if (isDispatching) {
456
+ throw new Error('You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.');
457
+ }
458
+
459
+ var isSubscribed = true;
460
+ ensureCanMutateNextListeners();
461
+ nextListeners.push(listener);
462
+ return function unsubscribe() {
463
+ if (!isSubscribed) {
464
+ return;
465
+ }
466
+
467
+ if (isDispatching) {
468
+ throw new Error('You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api-reference/store#subscribe(listener) for more details.');
469
+ }
470
+
471
+ isSubscribed = false;
472
+ ensureCanMutateNextListeners();
473
+ var index = nextListeners.indexOf(listener);
474
+ nextListeners.splice(index, 1);
475
+ };
476
+ }
477
+ /**
478
+ * Dispatches an action. It is the only way to trigger a state change.
479
+ *
480
+ * The `reducer` function, used to create the store, will be called with the
481
+ * current state tree and the given `action`. Its return value will
482
+ * be considered the **next** state of the tree, and the change listeners
483
+ * will be notified.
484
+ *
485
+ * The base implementation only supports plain object actions. If you want to
486
+ * dispatch a Promise, an Observable, a thunk, or something else, you need to
487
+ * wrap your store creating function into the corresponding middleware. For
488
+ * example, see the documentation for the `redux-thunk` package. Even the
489
+ * middleware will eventually dispatch plain object actions using this method.
490
+ *
491
+ * @param {Object} action A plain object representing “what changed”. It is
492
+ * a good idea to keep actions serializable so you can record and replay user
493
+ * sessions, or use the time travelling `redux-devtools`. An action must have
494
+ * a `type` property which may not be `undefined`. It is a good idea to use
495
+ * string constants for action types.
496
+ *
497
+ * @returns {Object} For convenience, the same action object you dispatched.
498
+ *
499
+ * Note that, if you use a custom middleware, it may wrap `dispatch()` to
500
+ * return something else (for example, a Promise you can await).
501
+ */
502
+
503
+
504
+ function dispatch(action) {
505
+ if (!isPlainObject(action)) {
506
+ throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
507
+ }
508
+
509
+ if (typeof action.type === 'undefined') {
510
+ throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
511
+ }
512
+
513
+ if (isDispatching) {
514
+ throw new Error('Reducers may not dispatch actions.');
515
+ }
516
+
517
+ try {
518
+ isDispatching = true;
519
+ currentState = currentReducer(currentState, action);
520
+ } finally {
521
+ isDispatching = false;
522
+ }
523
+
524
+ var listeners = currentListeners = nextListeners;
525
+
526
+ for (var i = 0; i < listeners.length; i++) {
527
+ var listener = listeners[i];
528
+ listener();
529
+ }
530
+
531
+ return action;
532
+ }
533
+ /**
534
+ * Replaces the reducer currently used by the store to calculate the state.
535
+ *
536
+ * You might need this if your app implements code splitting and you want to
537
+ * load some of the reducers dynamically. You might also need this if you
538
+ * implement a hot reloading mechanism for Redux.
539
+ *
540
+ * @param {Function} nextReducer The reducer for the store to use instead.
541
+ * @returns {void}
542
+ */
543
+
544
+
545
+ function replaceReducer(nextReducer) {
546
+ if (typeof nextReducer !== 'function') {
547
+ throw new Error('Expected the nextReducer to be a function.');
548
+ }
549
+
550
+ currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.
551
+ // Any reducers that existed in both the new and old rootReducer
552
+ // will receive the previous state. This effectively populates
553
+ // the new state tree with any relevant data from the old one.
554
+
555
+ dispatch({
556
+ type: ActionTypes.REPLACE
557
+ });
558
+ }
559
+ /**
560
+ * Interoperability point for observable/reactive libraries.
561
+ * @returns {observable} A minimal observable of state changes.
562
+ * For more information, see the observable proposal:
563
+ * https://github.com/tc39/proposal-observable
564
+ */
565
+
566
+
567
+ function observable() {
568
+ var _ref;
569
+
570
+ var outerSubscribe = subscribe;
571
+ return _ref = {
572
+ /**
573
+ * The minimal observable subscription method.
574
+ * @param {Object} observer Any object that can be used as an observer.
575
+ * The observer object should have a `next` method.
576
+ * @returns {subscription} An object with an `unsubscribe` method that can
577
+ * be used to unsubscribe the observable from the store, and prevent further
578
+ * emission of values from the observable.
579
+ */
580
+ subscribe: function subscribe(observer) {
581
+ if (typeof observer !== 'object' || observer === null) {
582
+ throw new TypeError('Expected the observer to be an object.');
583
+ }
584
+
585
+ function observeState() {
586
+ if (observer.next) {
587
+ observer.next(getState());
588
+ }
589
+ }
590
+
591
+ observeState();
592
+ var unsubscribe = outerSubscribe(observeState);
593
+ return {
594
+ unsubscribe: unsubscribe
595
+ };
596
+ }
597
+ }, _ref[symbol_observable__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"]] = function () {
598
+ return this;
599
+ }, _ref;
600
+ } // When a store is created, an "INIT" action is dispatched so that every
601
+ // reducer returns their initial state. This effectively populates
602
+ // the initial state tree.
603
+
604
+
605
+ dispatch({
606
+ type: ActionTypes.INIT
607
+ });
608
+ return _ref2 = {
609
+ dispatch: dispatch,
610
+ subscribe: subscribe,
611
+ getState: getState,
612
+ replaceReducer: replaceReducer
613
+ }, _ref2[symbol_observable__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"]] = observable, _ref2;
614
+ }
615
+
616
+ /**
617
+ * Prints a warning in the console if it exists.
618
+ *
619
+ * @param {String} message The warning message.
620
+ * @returns {void}
621
+ */
622
+ function warning(message) {
623
+ /* eslint-disable no-console */
624
+ if (typeof console !== 'undefined' && typeof console.error === 'function') {
625
+ console.error(message);
626
+ }
627
+ /* eslint-enable no-console */
628
+
629
+
630
+ try {
631
+ // This error was thrown as a convenience so that if you enable
632
+ // "break on all exceptions" in your console,
633
+ // it would pause the execution at this line.
634
+ throw new Error(message);
635
+ } catch (e) {} // eslint-disable-line no-empty
636
+
637
+ }
638
+
639
+ function getUndefinedStateErrorMessage(key, action) {
640
+ var actionType = action && action.type;
641
+ var actionDescription = actionType && "action \"" + String(actionType) + "\"" || 'an action';
642
+ return "Given " + actionDescription + ", reducer \"" + key + "\" returned undefined. " + "To ignore an action, you must explicitly return the previous state. " + "If you want this reducer to hold no value, you can return null instead of undefined.";
643
+ }
644
+
645
+ function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
646
+ var reducerKeys = Object.keys(reducers);
647
+ var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';
648
+
649
+ if (reducerKeys.length === 0) {
650
+ return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
651
+ }
652
+
653
+ if (!isPlainObject(inputState)) {
654
+ return "The " + argumentName + " has unexpected type of \"" + {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] + "\". Expected argument to be an object with the following " + ("keys: \"" + reducerKeys.join('", "') + "\"");
655
+ }
656
+
657
+ var unexpectedKeys = Object.keys(inputState).filter(function (key) {
658
+ return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];
659
+ });
660
+ unexpectedKeys.forEach(function (key) {
661
+ unexpectedKeyCache[key] = true;
662
+ });
663
+ if (action && action.type === ActionTypes.REPLACE) return;
664
+
665
+ if (unexpectedKeys.length > 0) {
666
+ return "Unexpected " + (unexpectedKeys.length > 1 ? 'keys' : 'key') + " " + ("\"" + unexpectedKeys.join('", "') + "\" found in " + argumentName + ". ") + "Expected to find one of the known reducer keys instead: " + ("\"" + reducerKeys.join('", "') + "\". Unexpected keys will be ignored.");
667
+ }
668
+ }
669
+
670
+ function assertReducerShape(reducers) {
671
+ Object.keys(reducers).forEach(function (key) {
672
+ var reducer = reducers[key];
673
+ var initialState = reducer(undefined, {
674
+ type: ActionTypes.INIT
675
+ });
676
+
677
+ if (typeof initialState === 'undefined') {
678
+ throw new Error("Reducer \"" + key + "\" returned undefined during initialization. " + "If the state passed to the reducer is undefined, you must " + "explicitly return the initial state. The initial state may " + "not be undefined. If you don't want to set a value for this reducer, " + "you can use null instead of undefined.");
679
+ }
680
+
681
+ if (typeof reducer(undefined, {
682
+ type: ActionTypes.PROBE_UNKNOWN_ACTION()
683
+ }) === 'undefined') {
684
+ throw new Error("Reducer \"" + key + "\" returned undefined when probed with a random type. " + ("Don't try to handle " + ActionTypes.INIT + " or other actions in \"redux/*\" ") + "namespace. They are considered private. Instead, you must return the " + "current state for any unknown actions, unless it is undefined, " + "in which case you must return the initial state, regardless of the " + "action type. The initial state may not be undefined, but can be null.");
685
+ }
686
+ });
687
+ }
688
+ /**
689
+ * Turns an object whose values are different reducer functions, into a single
690
+ * reducer function. It will call every child reducer, and gather their results
691
+ * into a single state object, whose keys correspond to the keys of the passed
692
+ * reducer functions.
693
+ *
694
+ * @param {Object} reducers An object whose values correspond to different
695
+ * reducer functions that need to be combined into one. One handy way to obtain
696
+ * it is to use ES6 `import * as reducers` syntax. The reducers may never return
697
+ * undefined for any action. Instead, they should return their initial state
698
+ * if the state passed to them was undefined, and the current state for any
699
+ * unrecognized action.
700
+ *
701
+ * @returns {Function} A reducer function that invokes every reducer inside the
702
+ * passed object, and builds a state object with the same shape.
703
+ */
704
+
705
+
706
+ function combineReducers(reducers) {
707
+ var reducerKeys = Object.keys(reducers);
708
+ var finalReducers = {};
709
+
710
+ for (var i = 0; i < reducerKeys.length; i++) {
711
+ var key = reducerKeys[i];
712
+
713
+ if (false) {}
714
+
715
+ if (typeof reducers[key] === 'function') {
716
+ finalReducers[key] = reducers[key];
717
+ }
718
+ }
719
+
720
+ var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same
721
+ // keys multiple times.
722
+
723
+ var unexpectedKeyCache;
724
+
725
+ if (false) {}
726
+
727
+ var shapeAssertionError;
728
+
729
+ try {
730
+ assertReducerShape(finalReducers);
731
+ } catch (e) {
732
+ shapeAssertionError = e;
733
+ }
734
+
735
+ return function combination(state, action) {
736
+ if (state === void 0) {
737
+ state = {};
738
+ }
739
+
740
+ if (shapeAssertionError) {
741
+ throw shapeAssertionError;
742
+ }
743
+
744
+ if (false) { var warningMessage; }
745
+
746
+ var hasChanged = false;
747
+ var nextState = {};
748
+
749
+ for (var _i = 0; _i < finalReducerKeys.length; _i++) {
750
+ var _key = finalReducerKeys[_i];
751
+ var reducer = finalReducers[_key];
752
+ var previousStateForKey = state[_key];
753
+ var nextStateForKey = reducer(previousStateForKey, action);
754
+
755
+ if (typeof nextStateForKey === 'undefined') {
756
+ var errorMessage = getUndefinedStateErrorMessage(_key, action);
757
+ throw new Error(errorMessage);
758
+ }
759
+
760
+ nextState[_key] = nextStateForKey;
761
+ hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
762
+ }
763
+
764
+ return hasChanged ? nextState : state;
765
+ };
766
+ }
767
+
768
+ function bindActionCreator(actionCreator, dispatch) {
769
+ return function () {
770
+ return dispatch(actionCreator.apply(this, arguments));
771
+ };
772
+ }
773
+ /**
774
+ * Turns an object whose values are action creators, into an object with the
775
+ * same keys, but with every function wrapped into a `dispatch` call so they
776
+ * may be invoked directly. This is just a convenience method, as you can call
777
+ * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
778
+ *
779
+ * For convenience, you can also pass an action creator as the first argument,
780
+ * and get a dispatch wrapped function in return.
781
+ *
782
+ * @param {Function|Object} actionCreators An object whose values are action
783
+ * creator functions. One handy way to obtain it is to use ES6 `import * as`
784
+ * syntax. You may also pass a single function.
785
+ *
786
+ * @param {Function} dispatch The `dispatch` function available on your Redux
787
+ * store.
788
+ *
789
+ * @returns {Function|Object} The object mimicking the original object, but with
790
+ * every action creator wrapped into the `dispatch` call. If you passed a
791
+ * function as `actionCreators`, the return value will also be a single
792
+ * function.
793
+ */
794
+
795
+
796
+ function bindActionCreators(actionCreators, dispatch) {
797
+ if (typeof actionCreators === 'function') {
798
+ return bindActionCreator(actionCreators, dispatch);
799
+ }
800
+
801
+ if (typeof actionCreators !== 'object' || actionCreators === null) {
802
+ throw new Error("bindActionCreators expected an object or a function, instead received " + (actionCreators === null ? 'null' : typeof actionCreators) + ". " + "Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?");
803
+ }
804
+
805
+ var boundActionCreators = {};
806
+
807
+ for (var key in actionCreators) {
808
+ var actionCreator = actionCreators[key];
809
+
810
+ if (typeof actionCreator === 'function') {
811
+ boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
812
+ }
813
+ }
814
+
815
+ return boundActionCreators;
816
+ }
817
+
818
+ function _defineProperty(obj, key, value) {
819
+ if (key in obj) {
820
+ Object.defineProperty(obj, key, {
821
+ value: value,
822
+ enumerable: true,
823
+ configurable: true,
824
+ writable: true
825
+ });
826
+ } else {
827
+ obj[key] = value;
828
+ }
829
+
830
+ return obj;
831
+ }
832
+
833
+ function ownKeys(object, enumerableOnly) {
834
+ var keys = Object.keys(object);
835
+
836
+ if (Object.getOwnPropertySymbols) {
837
+ keys.push.apply(keys, Object.getOwnPropertySymbols(object));
838
+ }
839
+
840
+ if (enumerableOnly) keys = keys.filter(function (sym) {
841
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
842
+ });
843
+ return keys;
844
+ }
845
+
846
+ function _objectSpread2(target) {
847
+ for (var i = 1; i < arguments.length; i++) {
848
+ var source = arguments[i] != null ? arguments[i] : {};
849
+
850
+ if (i % 2) {
851
+ ownKeys(source, true).forEach(function (key) {
852
+ _defineProperty(target, key, source[key]);
853
+ });
854
+ } else if (Object.getOwnPropertyDescriptors) {
855
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
856
+ } else {
857
+ ownKeys(source).forEach(function (key) {
858
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
859
+ });
860
+ }
861
+ }
862
+
863
+ return target;
864
+ }
865
+
866
+ /**
867
+ * Composes single-argument functions from right to left. The rightmost
868
+ * function can take multiple arguments as it provides the signature for
869
+ * the resulting composite function.
870
+ *
871
+ * @param {...Function} funcs The functions to compose.
872
+ * @returns {Function} A function obtained by composing the argument functions
873
+ * from right to left. For example, compose(f, g, h) is identical to doing
874
+ * (...args) => f(g(h(...args))).
875
+ */
876
+ function compose() {
877
+ for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
878
+ funcs[_key] = arguments[_key];
879
+ }
880
+
881
+ if (funcs.length === 0) {
882
+ return function (arg) {
883
+ return arg;
884
+ };
885
+ }
886
+
887
+ if (funcs.length === 1) {
888
+ return funcs[0];
889
+ }
890
+
891
+ return funcs.reduce(function (a, b) {
892
+ return function () {
893
+ return a(b.apply(void 0, arguments));
894
+ };
895
+ });
896
+ }
897
+
898
+ /**
899
+ * Creates a store enhancer that applies middleware to the dispatch method
900
+ * of the Redux store. This is handy for a variety of tasks, such as expressing
901
+ * asynchronous actions in a concise manner, or logging every action payload.
902
+ *
903
+ * See `redux-thunk` package as an example of the Redux middleware.
904
+ *
905
+ * Because middleware is potentially asynchronous, this should be the first
906
+ * store enhancer in the composition chain.
907
+ *
908
+ * Note that each middleware will be given the `dispatch` and `getState` functions
909
+ * as named arguments.
910
+ *
911
+ * @param {...Function} middlewares The middleware chain to be applied.
912
+ * @returns {Function} A store enhancer applying the middleware.
913
+ */
914
+
915
+ function applyMiddleware() {
916
+ for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {
917
+ middlewares[_key] = arguments[_key];
918
+ }
919
+
920
+ return function (createStore) {
921
+ return function () {
922
+ var store = createStore.apply(void 0, arguments);
923
+
924
+ var _dispatch = function dispatch() {
925
+ throw new Error('Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');
926
+ };
927
+
928
+ var middlewareAPI = {
929
+ getState: store.getState,
930
+ dispatch: function dispatch() {
931
+ return _dispatch.apply(void 0, arguments);
932
+ }
933
+ };
934
+ var chain = middlewares.map(function (middleware) {
935
+ return middleware(middlewareAPI);
936
+ });
937
+ _dispatch = compose.apply(void 0, chain)(store.dispatch);
938
+ return _objectSpread2({}, store, {
939
+ dispatch: _dispatch
940
+ });
941
+ };
942
+ };
943
+ }
944
+
945
+ /*
946
+ * This is a dummy function to check if the function name has been altered by minification.
947
+ * If the function has been minified and NODE_ENV !== 'production', warn the user.
948
+ */
949
+
950
+ function isCrushed() {}
951
+
952
+ if (false) {}
953
+
954
+
955
+
956
+
957
+ /***/ }),
958
+ /* 16 */
959
+ /***/ (function(module, exports, __webpack_require__) {
960
+
961
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
962
+ Copyright (c) 2017 Jed Watson.
963
+ Licensed under the MIT License (MIT), see
964
+ http://jedwatson.github.io/classnames
965
+ */
966
+ /* global define */
967
+
968
+ (function () {
969
+ 'use strict';
970
+
971
+ var hasOwn = {}.hasOwnProperty;
972
+
973
+ function classNames () {
974
+ var classes = [];
975
+
976
+ for (var i = 0; i < arguments.length; i++) {
977
+ var arg = arguments[i];
978
+ if (!arg) continue;
979
+
980
+ var argType = typeof arg;
981
+
982
+ if (argType === 'string' || argType === 'number') {
983
+ classes.push(arg);
984
+ } else if (Array.isArray(arg) && arg.length) {
985
+ var inner = classNames.apply(null, arg);
986
+ if (inner) {
987
+ classes.push(inner);
988
+ }
989
+ } else if (argType === 'object') {
990
+ for (var key in arg) {
991
+ if (hasOwn.call(arg, key) && arg[key]) {
992
+ classes.push(key);
993
+ }
994
+ }
995
+ }
996
+ }
997
+
998
+ return classes.join(' ');
999
+ }
1000
+
1001
+ if ( true && module.exports) {
1002
+ classNames.default = classNames;
1003
+ module.exports = classNames;
1004
+ } else if (true) {
1005
+ // register as 'classnames', consistent with npm package name
1006
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
1007
+ return classNames;
1008
+ }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
1009
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1010
+ } else {}
1011
+ }());
1012
+
1013
+
1014
+ /***/ }),
1015
+ /* 17 */
1016
+ /***/ (function(module, exports, __webpack_require__) {
1017
+
1018
+ var isObject = __webpack_require__(24);
1019
+ module.exports = function (it) {
1020
+ if (!isObject(it)) throw TypeError(it + ' is not an object!');
1021
+ return it;
1022
+ };
1023
+
1024
+
1025
+ /***/ }),
1026
+ /* 18 */
1027
+ /***/ (function(module, exports) {
1028
+
1029
+ /**
1030
+ * Checks if `value` is the
1031
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
1032
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1033
+ *
1034
+ * @static
1035
+ * @memberOf _
1036
+ * @since 0.1.0
1037
+ * @category Lang
1038
+ * @param {*} value The value to check.
1039
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
1040
+ * @example
1041
+ *
1042
+ * _.isObject({});
1043
+ * // => true
1044
+ *
1045
+ * _.isObject([1, 2, 3]);
1046
+ * // => true
1047
+ *
1048
+ * _.isObject(_.noop);
1049
+ * // => true
1050
+ *
1051
+ * _.isObject(null);
1052
+ * // => false
1053
+ */
1054
+ function isObject(value) {
1055
+ var type = typeof value;
1056
+ return value != null && (type == 'object' || type == 'function');
1057
+ }
1058
+
1059
+ module.exports = isObject;
1060
+
1061
+
1062
+ /***/ }),
1063
+ /* 19 */
1064
+ /***/ (function(module, exports, __webpack_require__) {
1065
+
1066
+ var global = __webpack_require__(9);
1067
+ var core = __webpack_require__(10);
1068
+ var ctx = __webpack_require__(40);
1069
+ var hide = __webpack_require__(30);
1070
+ var has = __webpack_require__(36);
1071
+ var PROTOTYPE = 'prototype';
1072
+
1073
+ var $export = function (type, name, source) {
1074
+ var IS_FORCED = type & $export.F;
1075
+ var IS_GLOBAL = type & $export.G;
1076
+ var IS_STATIC = type & $export.S;
1077
+ var IS_PROTO = type & $export.P;
1078
+ var IS_BIND = type & $export.B;
1079
+ var IS_WRAP = type & $export.W;
1080
+ var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
1081
+ var expProto = exports[PROTOTYPE];
1082
+ var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE];
1083
+ var key, own, out;
1084
+ if (IS_GLOBAL) source = name;
1085
+ for (key in source) {
1086
+ // contains in native
1087
+ own = !IS_FORCED && target && target[key] !== undefined;
1088
+ if (own && has(exports, key)) continue;
1089
+ // export native or passed
1090
+ out = own ? target[key] : source[key];
1091
+ // prevent global pollution for namespaces
1092
+ exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
1093
+ // bind timers to global for call from export context
1094
+ : IS_BIND && own ? ctx(out, global)
1095
+ // wrap global constructors for prevent change them in library
1096
+ : IS_WRAP && target[key] == out ? (function (C) {
1097
+ var F = function (a, b, c) {
1098
+ if (this instanceof C) {
1099
+ switch (arguments.length) {
1100
+ case 0: return new C();
1101
+ case 1: return new C(a);
1102
+ case 2: return new C(a, b);
1103
+ } return new C(a, b, c);
1104
+ } return C.apply(this, arguments);
1105
+ };
1106
+ F[PROTOTYPE] = C[PROTOTYPE];
1107
+ return F;
1108
+ // make static versions for prototype methods
1109
+ })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
1110
+ // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%
1111
+ if (IS_PROTO) {
1112
+ (exports.virtual || (exports.virtual = {}))[key] = out;
1113
+ // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%
1114
+ if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out);
1115
+ }
1116
+ }
1117
+ };
1118
+ // type bitmap
1119
+ $export.F = 1; // forced
1120
+ $export.G = 2; // global
1121
+ $export.S = 4; // static
1122
+ $export.P = 8; // proto
1123
+ $export.B = 16; // bind
1124
+ $export.W = 32; // wrap
1125
+ $export.U = 64; // safe
1126
+ $export.R = 128; // real proto method for `library`
1127
+ module.exports = $export;
1128
+
1129
+
1130
+ /***/ }),
1131
+ /* 20 */
1132
+ /***/ (function(module, exports, __webpack_require__) {
1133
+
1134
+ // Thank's IE8 for his funny defineProperty
1135
+ module.exports = !__webpack_require__(50)(function () {
1136
+ return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
1137
+ });
1138
+
1139
+
1140
+ /***/ }),
1141
+ /* 21 */
1142
+ /***/ (function(module, exports, __webpack_require__) {
1143
+
1144
+ var Symbol = __webpack_require__(37),
1145
+ getRawTag = __webpack_require__(222),
1146
+ objectToString = __webpack_require__(223);
1147
+
1148
+ /** `Object#toString` result references. */
1149
+ var nullTag = '[object Null]',
1150
+ undefinedTag = '[object Undefined]';
1151
+
1152
+ /** Built-in value references. */
1153
+ var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1154
+
1155
+ /**
1156
+ * The base implementation of `getTag` without fallbacks for buggy environments.
1157
+ *
1158
+ * @private
1159
+ * @param {*} value The value to query.
1160
+ * @returns {string} Returns the `toStringTag`.
1161
+ */
1162
+ function baseGetTag(value) {
1163
+ if (value == null) {
1164
+ return value === undefined ? undefinedTag : nullTag;
1165
+ }
1166
+ return (symToStringTag && symToStringTag in Object(value))
1167
+ ? getRawTag(value)
1168
+ : objectToString(value);
1169
+ }
1170
+
1171
+ module.exports = baseGetTag;
1172
+
1173
+
1174
+ /***/ }),
1175
+ /* 22 */
1176
+ /***/ (function(module, exports, __webpack_require__) {
1177
+
1178
+ "use strict";
1179
+
1180
+
1181
+ exports.__esModule = true;
1182
+
1183
+ var _typeof2 = __webpack_require__(204);
1184
+
1185
+ var _typeof3 = _interopRequireDefault(_typeof2);
1186
+
1187
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1188
+
1189
+ exports.default = function (self, call) {
1190
+ if (!self) {
1191
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
1192
+ }
1193
+
1194
+ return call && ((typeof call === "undefined" ? "undefined" : (0, _typeof3.default)(call)) === "object" || typeof call === "function") ? call : self;
1195
+ };
1196
+
1197
+ /***/ }),
1198
+ /* 23 */
1199
+ /***/ (function(module, exports, __webpack_require__) {
1200
+
1201
+ var anObject = __webpack_require__(17);
1202
+ var IE8_DOM_DEFINE = __webpack_require__(166);
1203
+ var toPrimitive = __webpack_require__(112);
1204
+ var dP = Object.defineProperty;
1205
+
1206
+ exports.f = __webpack_require__(20) ? Object.defineProperty : function defineProperty(O, P, Attributes) {
1207
+ anObject(O);
1208
+ P = toPrimitive(P, true);
1209
+ anObject(Attributes);
1210
+ if (IE8_DOM_DEFINE) try {
1211
+ return dP(O, P, Attributes);
1212
+ } catch (e) { /* empty */ }
1213
+ if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
1214
+ if ('value' in Attributes) O[P] = Attributes.value;
1215
+ return O;
1216
+ };
1217
+
1218
+
1219
+ /***/ }),
1220
+ /* 24 */
1221
+ /***/ (function(module, exports) {
1222
+
1223
+ module.exports = function (it) {
1224
+ return typeof it === 'object' ? it !== null : typeof it === 'function';
1225
+ };
1226
+
1227
+
1228
+ /***/ }),
1229
+ /* 25 */
1230
+ /***/ (function(module, exports, __webpack_require__) {
1231
+
1232
+ var baseIsNative = __webpack_require__(221),
1233
+ getValue = __webpack_require__(226);
1234
+
1235
+ /**
1236
+ * Gets the native function at `key` of `object`.
1237
+ *
1238
+ * @private
1239
+ * @param {Object} object The object to query.
1240
+ * @param {string} key The key of the method to get.
1241
+ * @returns {*} Returns the function if it's native, else `undefined`.
1242
+ */
1243
+ function getNative(object, key) {
1244
+ var value = getValue(object, key);
1245
+ return baseIsNative(value) ? value : undefined;
1246
+ }
1247
+
1248
+ module.exports = getNative;
1249
+
1250
+
1251
+ /***/ }),
1252
+ /* 26 */
1253
+ /***/ (function(module, exports, __webpack_require__) {
1254
+
1255
+ "use strict";
1256
+
1257
+
1258
+ exports.__esModule = true;
1259
+
1260
+ exports.default = function (instance, Constructor) {
1261
+ if (!(instance instanceof Constructor)) {
1262
+ throw new TypeError("Cannot call a class as a function");
1263
+ }
1264
+ };
1265
+
1266
+ /***/ }),
1267
+ /* 27 */
1268
+ /***/ (function(module, exports, __webpack_require__) {
1269
+
1270
+ "use strict";
1271
+
1272
+
1273
+ exports.__esModule = true;
1274
+
1275
+ var _defineProperty = __webpack_require__(205);
1276
+
1277
+ var _defineProperty2 = _interopRequireDefault(_defineProperty);
1278
+
1279
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1280
+
1281
+ exports.default = function () {
1282
+ function defineProperties(target, props) {
1283
+ for (var i = 0; i < props.length; i++) {
1284
+ var descriptor = props[i];
1285
+ descriptor.enumerable = descriptor.enumerable || false;
1286
+ descriptor.configurable = true;
1287
+ if ("value" in descriptor) descriptor.writable = true;
1288
+ (0, _defineProperty2.default)(target, descriptor.key, descriptor);
1289
+ }
1290
+ }
1291
+
1292
+ return function (Constructor, protoProps, staticProps) {
1293
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
1294
+ if (staticProps) defineProperties(Constructor, staticProps);
1295
+ return Constructor;
1296
+ };
1297
+ }();
1298
+
1299
+ /***/ }),
1300
+ /* 28 */
1301
+ /***/ (function(module, exports, __webpack_require__) {
1302
+
1303
+ "use strict";
1304
+
1305
+
1306
+ exports.__esModule = true;
1307
+
1308
+ var _setPrototypeOf = __webpack_require__(396);
1309
+
1310
+ var _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf);
1311
+
1312
+ var _create = __webpack_require__(400);
1313
+
1314
+ var _create2 = _interopRequireDefault(_create);
1315
+
1316
+ var _typeof2 = __webpack_require__(204);
1317
+
1318
+ var _typeof3 = _interopRequireDefault(_typeof2);
1319
+
1320
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1321
+
1322
+ exports.default = function (subClass, superClass) {
1323
+ if (typeof superClass !== "function" && superClass !== null) {
1324
+ throw new TypeError("Super expression must either be null or a function, not " + (typeof superClass === "undefined" ? "undefined" : (0, _typeof3.default)(superClass)));
1325
+ }
1326
+
1327
+ subClass.prototype = (0, _create2.default)(superClass && superClass.prototype, {
1328
+ constructor: {
1329
+ value: subClass,
1330
+ enumerable: false,
1331
+ writable: true,
1332
+ configurable: true
1333
+ }
1334
+ });
1335
+ if (superClass) _setPrototypeOf2.default ? (0, _setPrototypeOf2.default)(subClass, superClass) : subClass.__proto__ = superClass;
1336
+ };
1337
+
1338
+ /***/ }),
1339
+ /* 29 */
1340
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
1341
+
1342
+ "use strict";
1343
+ __webpack_require__.r(__webpack_exports__);
1344
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "get", function() { return get; });
1345
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "google", function() { return google; });
1346
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "config", function() { return config; });
1347
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "common", function() { return common; });
1348
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "adminUrl", function() { return adminUrl; });
1349
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rest", function() { return rest; });
1350
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "restNonce", function() { return restNonce; });
1351
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dateSettings", function() { return dateSettings; });
1352
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "editorConstants", function() { return editorConstants; });
1353
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "list", function() { return list; });
1354
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tec", function() { return tec; });
1355
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "editor", function() { return editor; });
1356
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "settings", function() { return settings; });
1357
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapsAPI", function() { return mapsAPI; });
1358
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "priceSettings", function() { return priceSettings; });
1359
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tecDateSettings", function() { return tecDateSettings; });
1360
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timezoneHtml", function() { return timezoneHtml; });
1361
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultTimes", function() { return defaultTimes; });
1362
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pro", function() { return pro; });
1363
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "editorDefaults", function() { return editorDefaults; });
1364
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tickets", function() { return tickets; });
1365
+ /**
1366
+ * @todo: handle globals in a better way
1367
+ */
1368
+ var get = function get(key, defaultValue) {
1369
+ return window[key] || defaultValue;
1370
+ };
1371
+ var google = function google() {
1372
+ return get('google');
1373
+ };
1374
+
1375
+ // Localized Config
1376
+ var config = function config() {
1377
+ return get('tribe_editor_config', {});
1378
+ };
1379
+
1380
+ // Common
1381
+ var common = function common() {
1382
+ return config().common || {};
1383
+ };
1384
+ var adminUrl = function adminUrl() {
1385
+ return common().adminUrl || '';
1386
+ };
1387
+ var rest = function rest() {
1388
+ return common().rest || {};
1389
+ };
1390
+ var restNonce = function restNonce() {
1391
+ return rest().nonce || {};
1392
+ };
1393
+ var dateSettings = function dateSettings() {
1394
+ return common().dateSettings || {};
1395
+ };
1396
+ var editorConstants = function editorConstants() {
1397
+ return common().constants || {};
1398
+ };
1399
+ var list = function list() {
1400
+ return {
1401
+ countries: common().countries || {},
1402
+ us_states: common().usStates || {}
1403
+ };
1404
+ };
1405
+
1406
+ // TEC
1407
+ var t