FooGallery – Image Gallery WordPress Plugin - Version 1.9.8

Version Description

  • New : Added RankMath compatibility - sitemap image indexing.
  • New : Added new setting under Hover Effects : Invert Color. Invert the caption icon colors from dark to light.
  • New : All hover and loading icons converted to SVG format.
  • New : Lazy load gallery images when editing a gallery (improved performance for large galleries in the admin). [//]: # fs_premium_only_begin
  • New : FooGallery PRO Lightbox added!!
  • New : Lightbox settings tab for PRO lightbox, including thumb slider, autoprogress and many more!
  • New : Added new setting under Advanced : Thumbnail Cropping. Allow for background fill with a custom color and no cropping.
  • New : Added new setting under Captions : Caption Type. Allow for custom captions. [//]: # fs_premium_only_end
  • Fix : Previews not updating in some cases.
  • Update : FooGallery client side 1.4.0 (MAJOR UPDATE).
Download this release

Release Info

Developer bradvin
Plugin Icon 128x128 FooGallery – Image Gallery WordPress Plugin
Version 1.9.8
Comparing to
See all releases

Code changes from version 1.8.18 to 1.9.8

Files changed (73) hide show
  1. README.txt +56 -6
  2. css/admin-foogallery.css +23 -1
  3. extensions/albums/admin/class-metaboxes.php +1 -1
  4. extensions/albums/class-albums-extension.php +13 -0
  5. extensions/default-templates/functions.php +2 -2
  6. extensions/default-templates/shared/css/admin-foogallery.css +39 -21
  7. extensions/default-templates/shared/css/foogallery.css +227 -353
  8. extensions/default-templates/shared/css/foogallery.min.css +1 -1
  9. extensions/default-templates/shared/img/circle-plus.png +0 -0
  10. extensions/default-templates/shared/img/circle-plus@2x.png +0 -0
  11. extensions/default-templates/shared/img/circle-plus@3x.png +0 -0
  12. extensions/default-templates/shared/img/external.png +0 -0
  13. extensions/default-templates/shared/img/external@2x.png +0 -0
  14. extensions/default-templates/shared/img/external@3x.png +0 -0
  15. extensions/default-templates/shared/img/eye.png +0 -0
  16. extensions/default-templates/shared/img/eye@2x.png +0 -0
  17. extensions/default-templates/shared/img/eye@3x.png +0 -0
  18. extensions/default-templates/shared/img/icons.svg +168 -0
  19. extensions/default-templates/shared/img/image.png +0 -0
  20. extensions/default-templates/shared/img/image@2x.png +0 -0
  21. extensions/default-templates/shared/img/image@3x.png +0 -0
  22. extensions/default-templates/shared/img/plus.png +0 -0
  23. extensions/default-templates/shared/img/plus@2x.png +0 -0
  24. extensions/default-templates/shared/img/plus@3x.png +0 -0
  25. extensions/default-templates/shared/img/video-1.png +0 -0
  26. extensions/default-templates/shared/img/video-1@2x.png +0 -0
  27. extensions/default-templates/shared/img/video-1@3x.png +0 -0
  28. extensions/default-templates/shared/img/video-2.png +0 -0
  29. extensions/default-templates/shared/img/video-2@2x.png +0 -0
  30. extensions/default-templates/shared/img/video-2@3x.png +0 -0
  31. extensions/default-templates/shared/img/video-3.png +0 -0
  32. extensions/default-templates/shared/img/video-3@2x.png +0 -0
  33. extensions/default-templates/shared/img/video-3@3x.png +0 -0
  34. extensions/default-templates/shared/img/video-4.png +0 -0
  35. extensions/default-templates/shared/img/video-4@2x.png +0 -0
  36. extensions/default-templates/shared/img/video-4@3x.png +0 -0
  37. extensions/default-templates/shared/img/video-default.png +0 -0
  38. extensions/default-templates/shared/img/video-default@2x.png +0 -0
  39. extensions/default-templates/shared/img/video-default@3x.png +0 -0
  40. extensions/default-templates/shared/img/zoom.png +0 -0
  41. extensions/default-templates/shared/img/zoom2.png +0 -0
  42. extensions/default-templates/shared/img/zoom2@2x.png +0 -0
  43. extensions/default-templates/shared/img/zoom2@3x.png +0 -0
  44. extensions/default-templates/shared/img/zoom3.png +0 -0
  45. extensions/default-templates/shared/img/zoom3@2x.png +0 -0
  46. extensions/default-templates/shared/img/zoom3@3x.png +0 -0
  47. extensions/default-templates/shared/img/zoom@2x.png +0 -0
  48. extensions/default-templates/shared/img/zoom@3x.png +0 -0
  49. extensions/default-templates/shared/js/foogallery.js +2937 -1727
  50. extensions/default-templates/shared/js/foogallery.min.js +4 -4
  51. extensions/default-templates/thumbnail/class-thumbnail-gallery-template.php +15 -0
  52. foogallery.php +321 -321
  53. gutenberg/class-foogallery-blocks.php +4 -5
  54. gutenberg/dist/blocks.build.js +1 -1
  55. gutenberg/dist/blocks.editor.build.css +2 -2
  56. gutenberg/src/block/edit/components/inspector-controls/editor.scss +1 -1
  57. gutenberg/src/block/index.js +3 -0
  58. includes/admin/class-gallery-metabox-items.php +4 -0
  59. includes/class-foogallery-common-fields.php +22 -2
  60. includes/class-foogallery-datasource-media_library.php +12 -4
  61. includes/class-foogallery-upgrade.php +3 -14
  62. includes/class-foogallery.php +7 -0
  63. includes/compatibility/class-foobox-compatibility.php +1 -1
  64. includes/functions.php +21 -1
  65. includes/includes.php +2 -1
  66. includes/public/class-foogallery-template-loader.php +28 -0
  67. includes/public/class-public.php +1 -0
  68. includes/public/class-rank-math-seo-sitemaps.php +42 -0
  69. includes/public/class-yoast-seo-sitemaps.php +1 -1
  70. includes/render-functions.php +93 -72
  71. js/admin-foogallery-attachment-autosave.js +16 -27
  72. js/admin-foogallery.js +41 -13
  73. js/foogallery.admin.min.js +1 -1
README.txt CHANGED
@@ -1,18 +1,22 @@
1
- === WordPress Responsive Gallery Plugin - FooGallery ===
2
  Contributors: bradvin, steveush, fooplugins
3
  Donate link: http://fooplugins.com
4
- Tags: gallery, image gallery, photo gallery, responsive gallery, masonry gallery
5
  Requires at least: 3.9
6
- Tested up to: 5.3.2
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Why choose FooGallery? Stunning image gallery layouts, responsive, retina-ready, lightning fast, easy to use. Gutenberg Ready!
12
 
13
  == Description ==
14
 
15
- Why choose FooGallery? Stunning image gallery layouts, responsive, retina-ready, lightning fast, easy to use. Gutenberg Ready! Built to be highly configurable and extensible for developers or freelancers.
 
 
 
 
16
 
17
  [View the FooGallery Homepage](http://fooplugins.com/foogallery)
18
 
@@ -46,6 +50,7 @@ Why choose FooGallery? Stunning image gallery layouts, responsive, retina-ready,
46
 
47
  **PRO Features**
48
 
 
49
  * Polaroid PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-polaroid-gallery/)
50
  * Grid PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-grid-gallery/)
51
  * Slider PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-slider-gallery/)
@@ -143,7 +148,7 @@ Do you have any caching setup at your website host? If so, clear/purge those cac
143
  First thing to do is restore your site to it's previous working state.
144
  1. Get access to your site via FTP, or SFTP.
145
  2. Navigate to the wp-content/plugins folder.
146
- 3. Rename the foogallery folder to foogallery1 in order to deactivate the pluing.
147
  4. At this point, your site should be working again.
148
  5. Please contact our support and provide the following info:
149
  * What version of WordPress you are running.
@@ -167,6 +172,11 @@ Have you enabled retina support for your galleries? To enable retina support, ed
167
 
168
  Yes, video is supported in FooGallery PRO!
169
 
 
 
 
 
 
170
  = How do I get albums working? =
171
 
172
  Simply go to the FooGallery extensions page and activate the Albums extension. If you do not see a button to activate the albums extension, reload the extensions list by clicking the reload button.
@@ -185,15 +195,55 @@ Update now to get all the latest features, bug fixes and improvements!
185
 
186
  == Changelog ==
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  = 1.8.18 =
189
  * New : Elementor compatibility - gallery previews in Elementor editor work, and added a FooGallery widget to the Elementor editor
 
 
 
 
 
 
190
  * Fix : Images in Yoast SEO sitemaps pull correctly for all types of gallery embedding
191
  * Fix : Lazy-load issues on certain browsers (reverted back to old logic)
192
  * Fix : Updated WPThumb so that images with querystrings in the URL will work
193
  * Fix : Minor security issue fixed on the FooGallery settings page (only exploitable by administrators)
194
 
195
  = 1.8.14 =
 
 
 
 
196
  * New : Added setting to move "Add Media" button to front of attachment listing (Advanced tab in FooGallery Settings)
 
 
 
 
197
  * Fix : Lazy-load issues with Gutenberg Editor
198
  * Fix : Simple portfolio layout issue with certain themes
199
  * Update : FooGallery client side 1.3.4
1
+ === WordPress Gallery Plugin - FooGallery ===
2
  Contributors: bradvin, steveush, fooplugins
3
  Donate link: http://fooplugins.com
4
+ Tags: gallery, image gallery, wordpress gallery plugin, responsive gallery, best gallery plugin
5
  Requires at least: 3.9
6
+ Tested up to: 5.4
7
  Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ FooGallery is an easy-to-use WordPress gallery plugin, with stunning gallery layouts. It is also responsive, retina-ready and supports lazy loading for lightning fast photo galleries.
12
 
13
  == Description ==
14
 
15
+ FooGallery is an easy-to-use WordPress gallery plugin, with stunning gallery layouts. It is also responsive, retina-ready and supports lazy loading for lightning fast photo galleries.
16
+
17
+ Live previews are available while creating a gallery, and also within the Gutenberg block editor with our FooGallery Block. FooGallery was built to be highly configurable and extendable for developers or freelancers.
18
+
19
+ We have done the research and compared the best free gallery plugins out there, and we know that the free version of FooGallery is the best gallery plugin available!
20
 
21
  [View the FooGallery Homepage](http://fooplugins.com/foogallery)
22
 
50
 
51
  **PRO Features**
52
 
53
+ * FooGallery PRO Lightbox built in!
54
  * Polaroid PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-polaroid-gallery/)
55
  * Grid PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-grid-gallery/)
56
  * Slider PRO Gallery Template - [demo](https://fooplugins.com/foogallery/wordpress-slider-gallery/)
148
  First thing to do is restore your site to it's previous working state.
149
  1. Get access to your site via FTP, or SFTP.
150
  2. Navigate to the wp-content/plugins folder.
151
+ 3. Rename the foogallery folder to foogallery1 in order to deactivate the plugin.
152
  4. At this point, your site should be working again.
153
  5. Please contact our support and provide the following info:
154
  * What version of WordPress you are running.
172
 
173
  Yes, video is supported in FooGallery PRO!
174
 
175
+ = Do I need to install a separate plugin to show a lightbox? =
176
+
177
+ For the Free version of FooGallery - Yes, you will need to install FooBox Image Lightbox.
178
+ For the PRO version of FooGallery - No, we have built in a uniquely beautiful lightbox!
179
+
180
  = How do I get albums working? =
181
 
182
  Simply go to the FooGallery extensions page and activate the Albums extension. If you do not see a button to activate the albums extension, reload the extensions list by clicking the reload button.
195
 
196
  == Changelog ==
197
 
198
+ = 1.9.8 =
199
+ * New : Added RankMath compatibility - sitemap image indexing.
200
+ * New : Added new setting under Hover Effects : Invert Color. Invert the caption icon colors from dark to light.
201
+ * New : All hover and loading icons converted to SVG format.
202
+ * New : Lazy load gallery images when editing a gallery (improved performance for large galleries in the admin).
203
+ [//]: # fs_premium_only_begin
204
+ * New : FooGallery PRO Lightbox added!!
205
+ * New : Lightbox settings tab for PRO lightbox, including thumb slider, autoprogress and many more!
206
+ * New : Added new setting under Advanced : Thumbnail Cropping. Allow for background fill with a custom color and no cropping.
207
+ * New : Added new setting under Captions : Caption Type. Allow for custom captions.
208
+ [//]: # fs_premium_only_end
209
+ * Fix : Previews not updating in some cases.
210
+ * Update : FooGallery client side 1.4.0 (MAJOR UPDATE).
211
+
212
+ = 1.8.20 =
213
+ * Fix : Fix for Masonry template layout issue in Firefox
214
+ [//]: # fs_premium_only_begin
215
+ * Fix : Fixed Media Library issues in WP 5.3
216
+ * New : Instagram datasource - now works with Video
217
+ * Fix : Instagram datasource - fixed a bunch of issues and changed how it pulls data from Instagram.
218
+ * Fix : Post Query datasource - fixed a few UI bugs.
219
+ * Fix : fixed video bugs, and better support for videos in dynamic galleries
220
+ * Fix : better support for FooBox sharing with albums
221
+ [//]: # fs_premium_only_end
222
+ * Update : FooGallery client side 1.3.6
223
+
224
  = 1.8.18 =
225
  * New : Elementor compatibility - gallery previews in Elementor editor work, and added a FooGallery widget to the Elementor editor
226
+ [//]: # fs_premium_only_begin
227
+ * New : Instagram datasource - populate galleries from your Instagram account
228
+ * New : Post Query datasource - populate galleries with the featured images from your posts/pages
229
+ * Fix : Images not being resized for certain datasources
230
+ * Fix : Caching issues when using taxonomy attributes in shortcode e.g. media_tags=cars
231
+ [//]: # fs_premium_only_end
232
  * Fix : Images in Yoast SEO sitemaps pull correctly for all types of gallery embedding
233
  * Fix : Lazy-load issues on certain browsers (reverted back to old logic)
234
  * Fix : Updated WPThumb so that images with querystrings in the URL will work
235
  * Fix : Minor security issue fixed on the FooGallery settings page (only exploitable by administrators)
236
 
237
  = 1.8.14 =
238
+ [//]: # fs_premium_only_begin
239
+ * New : Better messages for Media Tags & Categories datasources
240
+ * New : Ability to reload datasource modal without refreshing
241
+ [//]: # fs_premium_only_end
242
  * New : Added setting to move "Add Media" button to front of attachment listing (Advanced tab in FooGallery Settings)
243
+ [//]: # fs_premium_only_begin
244
+ * Fix : Real Media Library was not picking up featured images
245
+ * Fix : Albums were not working correctly with galleries that load from other datasources
246
+ [//]: # fs_premium_only_end
247
  * Fix : Lazy-load issues with Gutenberg Editor
248
  * Fix : Simple portfolio layout issue with certain themes
249
  * Update : FooGallery client side 1.3.4
css/admin-foogallery.css CHANGED
@@ -188,6 +188,12 @@
188
  margin-bottom: 10px;
189
  }
190
 
 
 
 
 
 
 
191
  .foogallery_metabox_field-htmlicon input:checked + label {
192
  border:solid 3px #444;
193
  background: #888;
@@ -291,7 +297,7 @@
291
  .foogallery-metabox-settings th {
292
  font-weight: normal;
293
  padding: 10px;
294
- width: 180px;
295
  }
296
 
297
  .foogallery-metabox-settings tr {
@@ -525,4 +531,20 @@ button[data-balloon]{overflow:visible}[data-balloon]{position:relative}[data-bal
525
  left: 300px;
526
  right: 0;
527
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  }
188
  margin-bottom: 10px;
189
  }
190
 
191
+ .foogallery_template_field_id-lightbox_custom_button_theme .foogallery_metabox_field-htmlicon label,
192
+ .foogallery_template_field_id-lightbox_custom_button_highlight .foogallery_metabox_field-htmlicon label
193
+ {
194
+ padding:0px;
195
+ }
196
+
197
  .foogallery_metabox_field-htmlicon input:checked + label {
198
  border:solid 3px #444;
199
  background: #888;
297
  .foogallery-metabox-settings th {
298
  font-weight: normal;
299
  padding: 10px;
300
+ width: 200px;
301
  }
302
 
303
  .foogallery-metabox-settings tr {
531
  left: 300px;
532
  right: 0;
533
  }
534
+ }
535
+
536
+ .foogallery-attachments-list {
537
+ max-height: 486px;
538
+ /*max-height: 324px;*/
539
+ /*max-height: 162px;*/
540
+ overflow: hidden auto;
541
+ list-style: none;
542
+ border: 1px solid #ccd0d4;
543
+ padding: 10px;
544
+ }
545
+ .foogallery-attachments-list:after,
546
+ .foogallery-attachments-list-bar:after {
547
+ content: '';
548
+ display: block;
549
+ clear: both;
550
  }
extensions/albums/admin/class-metaboxes.php CHANGED
@@ -231,7 +231,7 @@ if ( ! class_exists( 'FooGallery_Admin_Album_MetaBoxes' ) ) {
231
  <div class="thumbnail" style="display: table;">
232
  <div style="display: table-cell; vertical-align: middle; text-align: center;">
233
  <img src="<?php echo $img_src; ?>"/>
234
- <h3><?php echo $title; ?>
235
  <span><?php echo $images; ?></span>
236
  </h3>
237
  </div>
231
  <div class="thumbnail" style="display: table;">
232
  <div style="display: table-cell; vertical-align: middle; text-align: center;">
233
  <img src="<?php echo $img_src; ?>"/>
234
+ <h3><?php echo esc_html( $title ); ?>
235
  <span><?php echo $images; ?></span>
236
  </h3>
237
  </div>
extensions/albums/class-albums-extension.php CHANGED
@@ -34,6 +34,19 @@ if ( ! class_exists( 'FooGallery_Albums_Extension' ) ) {
34
  add_action( 'foogallery_extension_activated-albums', array( $this, 'flush_rewrite_rules' ) );
35
  add_filter( 'foogallery_alter_album_template_field', array( $this, 'alter_gallery_template_field' ), 10, 2 );
36
  add_filter( 'foogallery_albums_supports_video-stack', '__return_true' );
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
 
39
  function includes() {
34
  add_action( 'foogallery_extension_activated-albums', array( $this, 'flush_rewrite_rules' ) );
35
  add_filter( 'foogallery_alter_album_template_field', array( $this, 'alter_gallery_template_field' ), 10, 2 );
36
  add_filter( 'foogallery_albums_supports_video-stack', '__return_true' );
37
+
38
+ add_filter( 'fooboxshare_use_permalink', array( $this, 'check_for_albums_for_fooboxshare' ) );
39
+ }
40
+
41
+ function check_for_albums_for_fooboxshare( $default ) {
42
+
43
+ $album_gallery = foogallery_album_get_current_gallery();
44
+
45
+ if ( !empty( $album_gallery) ) {
46
+ return false;
47
+ }
48
+
49
+ return $default;
50
  }
51
 
52
  function includes() {
extensions/default-templates/functions.php CHANGED
@@ -7,7 +7,7 @@
7
  * Enqueue the core FooGallery stylesheet used by all default templates
8
  */
9
  function foogallery_enqueue_core_gallery_template_style() {
10
- $filename = foogallery_get_setting( 'enable_debugging', false ) ? '' : '.min';
11
  $css = apply_filters( 'foogallery_core_gallery_style', FOOGALLERY_DEFAULT_TEMPLATES_EXTENSION_SHARED_URL . 'css/foogallery' . $filename . '.css' );
12
  foogallery_enqueue_style( 'foogallery-core', $css, array(), FOOGALLERY_VERSION );
13
  }
@@ -16,7 +16,7 @@ function foogallery_enqueue_core_gallery_template_style() {
16
  * Enqueue the core FooGallery script used by all default templates
17
  */
18
  function foogallery_enqueue_core_gallery_template_script() {
19
- $filename = foogallery_get_setting( 'enable_debugging', false ) ? '' : '.min';
20
  $js = apply_filters( 'foogallery_core_gallery_script', FOOGALLERY_DEFAULT_TEMPLATES_EXTENSION_SHARED_URL . 'js/foogallery' . $filename . '.js' );
21
  wp_enqueue_script( 'foogallery-core', $js, array('jquery'), FOOGALLERY_VERSION );
22
  }
7
  * Enqueue the core FooGallery stylesheet used by all default templates
8
  */
9
  function foogallery_enqueue_core_gallery_template_style() {
10
+ $filename = foogallery_is_debug() ? '' : '.min';
11
  $css = apply_filters( 'foogallery_core_gallery_style', FOOGALLERY_DEFAULT_TEMPLATES_EXTENSION_SHARED_URL . 'css/foogallery' . $filename . '.css' );
12
  foogallery_enqueue_style( 'foogallery-core', $css, array(), FOOGALLERY_VERSION );
13
  }
16
  * Enqueue the core FooGallery script used by all default templates
17
  */
18
  function foogallery_enqueue_core_gallery_template_script() {
19
+ $filename = foogallery_is_debug() ? '' : '.min';
20
  $js = apply_filters( 'foogallery_core_gallery_script', FOOGALLERY_DEFAULT_TEMPLATES_EXTENSION_SHARED_URL . 'js/foogallery' . $filename . '.js' );
21
  wp_enqueue_script( 'foogallery-core', $js, array('jquery'), FOOGALLERY_VERSION );
22
  }
extensions/default-templates/shared/css/admin-foogallery.css CHANGED
@@ -1,56 +1,52 @@
1
  .foogallery-setting-caption_icon,
2
  .foogallery-setting-loading_icon,
3
- .foogallery-setting-video_overlay {
 
4
  content: "";
5
  display: inline-block;
6
  position: relative;
7
- width: 40px;
8
- height: 40px;
9
  margin: 0;
10
  background: transparent no-repeat center center;
11
- background-size: 40px 40px;
12
  vertical-align: middle;
13
  }
14
  .foogallery-setting-caption_icon.fg-hover-zoom {
15
- background-image: url('../img/zoom.png');
16
  }
17
  .foogallery-setting-caption_icon.fg-hover-zoom2 {
18
- background-image: url('../img/zoom2.png');
19
  }
20
  .foogallery-setting-caption_icon.fg-hover-zoom3 {
21
- background-image: url('../img/zoom3.png');
22
  }
23
  .foogallery-setting-caption_icon.fg-hover-plus {
24
- background-image: url('../img/plus.png');
25
  }
26
  .foogallery-setting-caption_icon.fg-hover-circle-plus {
27
- background-image: url('../img/circle-plus.png');
28
  }
29
  .foogallery-setting-caption_icon.fg-hover-eye {
30
- background-image: url('../img/eye.png');
31
  }
32
  .foogallery-setting-caption_icon.fg-hover-external {
33
- background-image: url('../img/external.png');
34
  }
35
-
36
  .foogallery-setting-video_overlay.fg-video-default {
37
- background-image: url('../img/video-default.png');
38
  }
39
-
40
  .foogallery-setting-video_overlay.fg-video-1 {
41
- background-image: url('../img/video-1.png');
42
  }
43
-
44
  .foogallery-setting-video_overlay.fg-video-2 {
45
- background-image: url('../img/video-2.png');
46
  }
47
-
48
  .foogallery-setting-video_overlay.fg-video-3 {
49
- background-image: url('../img/video-3.png');
50
  }
51
-
52
  .foogallery-setting-video_overlay.fg-video-4 {
53
- background-image: url('../img/video-4.png');
54
  }
55
 
56
  .foogallery_template_field_type-htmlicon.foogallery_template_field_id-loading_icon td label {
@@ -96,4 +92,26 @@
96
 
97
  .fg-item-inner {
98
  margin: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  }
1
  .foogallery-setting-caption_icon,
2
  .foogallery-setting-loading_icon,
3
+ .foogallery-setting-video_overlay,
4
+ .foogallery-setting-panel_theme {
5
  content: "";
6
  display: inline-block;
7
  position: relative;
8
+ width: 32px;
9
+ height: 32px;
10
  margin: 0;
11
  background: transparent no-repeat center center;
12
+ background-size: 32px 32px;
13
  vertical-align: middle;
14
  }
15
  .foogallery-setting-caption_icon.fg-hover-zoom {
16
+ background-image: url('../img/icons.svg#zoom-light');
17
  }
18
  .foogallery-setting-caption_icon.fg-hover-zoom2 {
19
+ background-image: url('../img/icons.svg#zoom2-light');
20
  }
21
  .foogallery-setting-caption_icon.fg-hover-zoom3 {
22
+ background-image: url('../img/icons.svg#zoom3-light');
23
  }
24
  .foogallery-setting-caption_icon.fg-hover-plus {
25
+ background-image: url('../img/icons.svg#plus-light');
26
  }
27
  .foogallery-setting-caption_icon.fg-hover-circle-plus {
28
+ background-image: url('../img/icons.svg#circle-plus-light');
29
  }
30
  .foogallery-setting-caption_icon.fg-hover-eye {
31
+ background-image: url('../img/icons.svg#eye-light');
32
  }
33
  .foogallery-setting-caption_icon.fg-hover-external {
34
+ background-image: url('../img/icons.svg#external-light');
35
  }
 
36
  .foogallery-setting-video_overlay.fg-video-default {
37
+ background-image: url('../img/icons.svg#video-default-light');
38
  }
 
39
  .foogallery-setting-video_overlay.fg-video-1 {
40
+ background-image: url('../img/icons.svg#video-1-light');
41
  }
 
42
  .foogallery-setting-video_overlay.fg-video-2 {
43
+ background-image: url('../img/icons.svg#video-2-light');
44
  }
 
45
  .foogallery-setting-video_overlay.fg-video-3 {
46
+ background-image: url('../img/icons.svg#video-3-light');
47
  }
 
48
  .foogallery-setting-video_overlay.fg-video-4 {
49
+ background-image: url('../img/icons.svg#video-4-light');
50
  }
51
 
52
  .foogallery_template_field_type-htmlicon.foogallery_template_field_id-loading_icon td label {
92
 
93
  .fg-item-inner {
94
  margin: 0;
95
+ }
96
+
97
+ .foogallery-setting-panel_theme.fg-light {
98
+ background-color: #fff;
99
+ }
100
+ .foogallery-setting-panel_theme.fg-dark {
101
+ background-color: #292929;
102
+ }
103
+ .foogallery-setting-panel_theme.fg-blue {
104
+ background-color: #3079ed;
105
+ }
106
+ .foogallery-setting-panel_theme.fg-purple {
107
+ background-color: #6816c2;
108
+ }
109
+ .foogallery-setting-panel_theme.fg-green {
110
+ background-color: #027339;
111
+ }
112
+ .foogallery-setting-panel_theme.fg-red {
113
+ background-color: #c22b24;
114
+ }
115
+ .foogallery-setting-panel_theme.fg-orange {
116
+ background-color: #e57731;
117
  }
extensions/default-templates/shared/css/foogallery.css CHANGED
@@ -32,33 +32,20 @@
32
  border: solid 0 transparent;
33
  }
34
 
35
- .foogallery .fg-item.fg-loading,
36
- .foogallery .fg-item.fg-error {
37
- background: no-repeat center;
38
- }
39
-
40
- .foogallery .fg-item.fg-error {
41
- background-image: url('../img/image.png');
42
- }
43
-
44
- /* @2x Images (Pixel Ratio of 1.25+) */
45
- @media only screen and (-o-min-device-pixel-ratio: 5/4),
46
- only screen and (-webkit-min-device-pixel-ratio: 1.25),
47
- only screen and (min-device-pixel-ratio: 1.25),
48
- only screen and (min-resolution: 1.25dppx) {
49
- .foogallery .fg-item.fg-error {
50
- background-image: url('../img/image@2x.png');
51
- }
52
- }
53
-
54
- /* @3x Images (Pixel Ratio of 2.25+) */
55
- @media only screen and (-o-min-device-pixel-ratio: 9/4),
56
- only screen and (-webkit-min-device-pixel-ratio: 2.25),
57
- only screen and (min-device-pixel-ratio: 2.25),
58
- only screen and (min-resolution: 2.25dppx) {
59
- .foogallery .fg-item.fg-error {
60
- background-image: url('../img/image@3x.png');
61
- }
62
  }
63
 
64
  .foogallery .fg-item.fg-loaded {
@@ -89,6 +76,22 @@ only screen and (min-resolution: 2.25dppx) {
89
  text-decoration: none;
90
  box-shadow: none;
91
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  .foogallery .fg-image-wrap {
93
  display: block;
94
  position: relative;
@@ -233,163 +236,33 @@ only screen and (min-resolution: 2.25dppx) {
233
  .fg-loading-default .fg-loader {
234
  border-radius: 50%;
235
  text-indent: -9999em;
236
- -webkit-animation: loading-default 1.1s infinite ease;
237
- animation: loading-default 1.1s infinite ease;
 
 
 
 
 
 
 
 
238
  }
239
 
240
  @-webkit-keyframes loading-default {
241
- 0%,
242
- 100% {
243
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 1),
244
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
245
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
246
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
247
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
248
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
249
- -2.6em 0 0 0 rgba(130, 130, 130, 0.5),
250
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.7);
251
- }
252
- 12.5% {
253
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.7),
254
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 1), 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
255
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
256
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
257
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
258
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
259
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.5);
260
- }
261
- 25% {
262
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.5),
263
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.7),
264
- 2.5em 0 0 0 rgba(130, 130, 130, 1), 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
265
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
266
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
267
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
268
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
269
- }
270
- 37.5% {
271
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
272
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.5),
273
- 2.5em 0 0 0 rgba(130, 130, 130, 0.7),
274
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 1), 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
275
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
276
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
277
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
278
- }
279
- 50% {
280
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
281
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
282
- 2.5em 0 0 0 rgba(130, 130, 130, 0.5),
283
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.7),
284
- 0 2.5em 0 0 rgba(130, 130, 130, 1), -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
285
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
286
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
287
- }
288
- 62.5% {
289
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
290
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
291
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
292
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.5),
293
- 0 2.5em 0 0 rgba(130, 130, 130, 0.7),
294
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 1), -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
295
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
296
- }
297
- 75% {
298
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
299
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
300
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
301
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
302
- 0 2.5em 0 0 rgba(130, 130, 130, 0.5),
303
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.7),
304
- -2.6em 0 0 0 rgba(130, 130, 130, 1), -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
305
  }
306
- 87.5% {
307
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
308
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
309
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
310
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
311
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
312
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.5),
313
- -2.6em 0 0 0 rgba(130, 130, 130, 0.7),
314
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 1);
315
  }
316
  }
317
 
318
  @keyframes loading-default {
319
- 0%,
320
- 100% {
321
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 1),
322
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
323
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
324
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
325
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
326
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
327
- -2.6em 0 0 0 rgba(130, 130, 130, 0.5),
328
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.7);
329
- }
330
- 12.5% {
331
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.7),
332
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 1), 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
333
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
334
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
335
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
336
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
337
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.5);
338
- }
339
- 25% {
340
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.5),
341
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.7),
342
- 2.5em 0 0 0 rgba(130, 130, 130, 1), 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
343
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
344
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
345
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
346
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
347
- }
348
- 37.5% {
349
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
350
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.5),
351
- 2.5em 0 0 0 rgba(130, 130, 130, 0.7),
352
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 1), 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
353
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
354
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
355
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
356
- }
357
- 50% {
358
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
359
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
360
- 2.5em 0 0 0 rgba(130, 130, 130, 0.5),
361
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.7),
362
- 0 2.5em 0 0 rgba(130, 130, 130, 1), -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
363
- -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
364
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
365
- }
366
- 62.5% {
367
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
368
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
369
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
370
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.5),
371
- 0 2.5em 0 0 rgba(130, 130, 130, 0.7),
372
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 1), -2.6em 0 0 0 rgba(130, 130, 130, 0.2),
373
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
374
- }
375
- 75% {
376
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
377
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
378
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
379
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
380
- 0 2.5em 0 0 rgba(130, 130, 130, 0.5),
381
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.7),
382
- -2.6em 0 0 0 rgba(130, 130, 130, 1), -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2);
383
  }
384
- 87.5% {
385
- box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 0.2),
386
- 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
387
- 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
388
- 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
389
- 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
390
- -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.5),
391
- -2.6em 0 0 0 rgba(130, 130, 130, 0.7),
392
- -1.8em -1.8em 0 0 rgba(130, 130, 130, 1);
393
  }
394
  }
395
  .fg-loading-bars .fg-loader,
@@ -727,12 +600,22 @@ only screen and (min-resolution: 2.25dppx) {
727
  border: none;
728
  text-align: center;
729
  cursor: pointer;
 
730
  }
731
  .foogallery .fg-caption a {
732
  text-decoration: none;
733
  color: #fff;
734
  border-bottom: 1px solid #FFF;
735
  }
 
 
 
 
 
 
 
 
 
736
  .foogallery .fg-caption a:hover {
737
  border-bottom: none;
738
  }
@@ -776,192 +659,182 @@ only screen and (min-resolution: 2.25dppx) {
776
  left: 0;
777
  transform: translateY(-50%);
778
  }
779
- .foogallery.fg-caption-hover .fg-item.fg-loaded .fg-thumb:before {
780
  display: none;
781
  }
782
  /* Icon & Overlay */
783
- .foogallery.fg-hover-zoom .fg-thumb:before,
784
- .foogallery.fg-hover-zoom2 .fg-thumb:before,
785
- .foogallery.fg-hover-zoom3 .fg-thumb:before,
786
- .foogallery.fg-hover-plus .fg-thumb:before,
787
- .foogallery.fg-hover-circle-plus .fg-thumb:before,
788
- .foogallery.fg-hover-eye .fg-thumb:before,
789
- .foogallery.fg-hover-external .fg-thumb:before,
790
- .foogallery.fg-hover-tint .fg-thumb:before {
791
  content: "";
792
  display: block;
793
  position: absolute;
794
- visibility: hidden;
795
- opacity: 0;
796
- top: 0;
797
- bottom: 0;
798
- left: 0;
799
- right: 0;
800
- z-index: 8;
801
- background: rgba(0,0,0,0.5) no-repeat center center;
802
  background-size: 32px 32px;
 
 
803
  }
804
-
805
- .foogallery.fg-hover-zoom .fg-item-inner:hover .fg-thumb:before,
806
- .foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-thumb:before,
807
- .foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-thumb:before,
808
- .foogallery.fg-hover-plus .fg-item-inner:hover .fg-thumb:before,
809
- .foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-thumb:before,
810
- .foogallery.fg-hover-eye .fg-item-inner:hover .fg-thumb:before,
811
- .foogallery.fg-hover-external .fg-item-inner:hover .fg-thumb:before,
812
- .foogallery.fg-hover-tint .fg-item-inner:hover .fg-thumb:before,
813
- .foogallery.fg-hover-zoom .fg-thumb:focus:before,
814
- .foogallery.fg-hover-zoom2 .fg-thumb:focus:before,
815
- .foogallery.fg-hover-zoom3 .fg-thumb:focus:before,
816
- .foogallery.fg-hover-plus .fg-thumb:focus:before,
817
- .foogallery.fg-hover-circle-plus .fg-thumb:focus:before,
818
- .foogallery.fg-hover-eye .fg-thumb:focus:before,
819
- .foogallery.fg-hover-external .fg-thumb:focus:before,
820
- .foogallery.fg-hover-tint .fg-thumb:focus:before {
821
- visibility: visible;
822
- opacity: 1;
823
- }
824
-
825
- /* Support captions showing the icon */
826
- .foogallery.fg-hover-zoom .fg-caption-inner:before,
827
- .foogallery.fg-hover-zoom2 .fg-caption-inner:before,
828
- .foogallery.fg-hover-zoom3 .fg-caption-inner:before,
829
- .foogallery.fg-hover-plus .fg-caption-inner:before,
830
- .foogallery.fg-hover-circle-plus .fg-caption-inner:before,
831
- .foogallery.fg-hover-eye .fg-caption-inner:before,
832
- .foogallery.fg-hover-external .fg-caption-inner:before,
833
- .foogallery.fg-hover-tint .fg-caption-inner:before {
834
  content: "";
835
- display: inline-block;
836
  position: relative;
837
  width: 32px;
838
  height: 32px;
839
  margin: 10px 0 5px 0;
840
- background: transparent no-repeat center center;
841
  background-size: 32px 32px;
842
  vertical-align: middle;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  }
844
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
845
 
846
- .foogallery.fg-hover-zoom .fg-thumb:before,
847
  .foogallery.fg-hover-zoom .fg-caption-inner:before {
848
- background-image: url('../img/zoom.png');
 
 
 
 
849
  }
850
 
851
- .foogallery.fg-hover-zoom2 .fg-thumb:before,
852
  .foogallery.fg-hover-zoom2 .fg-caption-inner:before {
853
- background-image: url('../img/zoom2.png');
 
 
 
 
854
  }
855
 
856
- .foogallery.fg-hover-zoom3 .fg-thumb:before,
857
  .foogallery.fg-hover-zoom3 .fg-caption-inner:before {
858
- background-image: url('../img/zoom3.png');
 
 
 
 
859
  }
860
 
861
- .foogallery.fg-hover-plus .fg-thumb:before,
862
  .foogallery.fg-hover-plus .fg-caption-inner:before {
863
- background-image: url('../img/plus.png');
 
 
 
 
864
  }
865
 
866
- .foogallery.fg-hover-circle-plus .fg-thumb:before,
867
  .foogallery.fg-hover-circle-plus .fg-caption-inner:before {
868
- background-image: url('../img/circle-plus.png');
 
 
 
 
869
  }
870
 
871
- .foogallery.fg-hover-eye .fg-thumb:before,
872
  .foogallery.fg-hover-eye .fg-caption-inner:before {
873
- background-image: url('../img/eye.png');
 
 
 
 
874
  }
875
 
876
- .foogallery.fg-hover-external .fg-thumb:before,
877
  .foogallery.fg-hover-external .fg-caption-inner:before {
878
- background-image: url('../img/external.png');
879
  }
880
-
881
- /* @2x Images (Pixel Ratio of 1.25+) */
882
- @media only screen and (-o-min-device-pixel-ratio: 5/4),
883
- only screen and (-webkit-min-device-pixel-ratio: 1.25),
884
- only screen and (min-device-pixel-ratio: 1.25),
885
- only screen and (min-resolution: 1.25dppx) {
886
-
887
- .foogallery.fg-hover-zoom .fg-thumb:before,
888
- .foogallery.fg-hover-zoom .fg-caption-inner:before {
889
- background-image: url('../img/zoom@2x.png');
890
- }
891
-
892
- .foogallery.fg-hover-zoom2 .fg-thumb:before,
893
- .foogallery.fg-hover-zoom2 .fg-caption-inner:before {
894
- background-image: url('../img/zoom2@2x.png');
895
- }
896
-
897
- .foogallery.fg-hover-zoom3 .fg-thumb:before,
898
- .foogallery.fg-hover-zoom3 .fg-caption-inner:before {
899
- background-image: url('../img/zoom3@2x.png');
900
- }
901
-
902
- .foogallery.fg-hover-plus .fg-thumb:before,
903
- .foogallery.fg-hover-plus .fg-caption-inner:before {
904
- background-image: url('../img/plus@2x.png');
905
- }
906
-
907
- .foogallery.fg-hover-circle-plus .fg-thumb:before,
908
- .foogallery.fg-hover-circle-plus .fg-caption-inner:before {
909
- background-image: url('../img/circle-plus@2x.png');
910
- }
911
-
912
- .foogallery.fg-hover-eye .fg-thumb:before,
913
- .foogallery.fg-hover-eye .fg-caption-inner:before {
914
- background-image: url('../img/eye@2x.png');
915
- }
916
-
917
- .foogallery.fg-hover-external .fg-thumb:before,
918
- .foogallery.fg-hover-external .fg-caption-inner:before {
919
- background-image: url('../img/external@2x.png');
920
- }
921
-
922
  }
923
 
924
- /* @3x Images (Pixel Ratio of 2.25+) */
925
- @media only screen and (-o-min-device-pixel-ratio: 9/4),
926
- only screen and (-webkit-min-device-pixel-ratio: 2.25),
927
- only screen and (min-device-pixel-ratio: 2.25),
928
- only screen and (min-resolution: 2.25dppx) {
929
-
930
- .foogallery.fg-hover-zoom .fg-thumb:before,
931
- .foogallery.fg-hover-zoom .fg-caption-inner:before {
932
- background-image: url('../img/zoom@3x.png');
933
- }
934
-
935
- .foogallery.fg-hover-zoom2 .fg-thumb:before,
936
- .foogallery.fg-hover-zoom2 .fg-caption-inner:before {
937
- background-image: url('../img/zoom2@3x.png');
938
- }
939
-
940
- .foogallery.fg-hover-zoom3 .fg-thumb:before,
941
- .foogallery.fg-hover-zoom3 .fg-caption-inner:before {
942
- background-image: url('../img/zoom3@3x.png');
943
- }
944
-
945
- .foogallery.fg-hover-plus .fg-thumb:before,
946
- .foogallery.fg-hover-plus .fg-caption-inner:before {
947
- background-image: url('../img/plus@3x.png');
948
- }
949
 
950
- .foogallery.fg-hover-circle-plus .fg-thumb:before,
951
- .foogallery.fg-hover-circle-plus .fg-caption-inner:before {
952
- background-image: url('../img/circle-plus@3x.png');
953
- }
 
 
 
 
954
 
955
- .foogallery.fg-hover-eye .fg-thumb:before,
956
- .foogallery.fg-hover-eye .fg-caption-inner:before {
957
- background-image: url('../img/eye@3x.png');
958
- }
 
 
 
 
959
 
960
- .foogallery.fg-hover-external .fg-thumb:before,
961
- .foogallery.fg-hover-external .fg-caption-inner:before {
962
- background-image: url('../img/external@3x.png');
963
- }
 
 
 
 
964
 
 
 
 
 
 
 
 
965
  }
966
  /* Transitions */
967
  .foogallery.fg-caption-hover.fg-hover-instant .fg-caption,
@@ -974,21 +847,22 @@ only screen and (min-resolution: 2.25dppx) {
974
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,
975
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,
976
  .foogallery.fg-caption-hover.fg-hover-scale .fg-caption,
977
- .foogallery.fg-hover-instant .fg-thumb:before,
978
- .foogallery.fg-hover-fade .fg-thumb:before,
979
- .foogallery.fg-hover-slide-up .fg-thumb:before,
980
- .foogallery.fg-hover-slide-down .fg-thumb:before,
981
- .foogallery.fg-hover-slide-left .fg-thumb:before,
982
- .foogallery.fg-hover-slide-right .fg-thumb:before,
983
  .foogallery.fg-hover-push .fg-thumb,
984
- .foogallery.fg-hover-colorize .fg-thumb:before,
985
- .foogallery.fg-hover-grayscale .fg-thumb:before,
986
  .foogallery.fg-hover-scale .fg-item,
987
- .foogallery.fg-hover-scale .fg-thumb:before,
988
  .foogallery.fg-hover-colorize .fg-image,
989
  .foogallery.fg-hover-grayscale .fg-image {
990
  transition-timing-function: ease;
991
  transition-duration: 300ms;
 
992
  }
993
  /* Colorize */
994
  .foogallery.fg-hover-colorize .fg-image {
@@ -1005,7 +879,7 @@ only screen and (min-resolution: 2.25dppx) {
1005
  -webkit-filter: none;
1006
  filter: none;
1007
  }
1008
- .foogallery.fg-hover-colorize .fg-thumb:before,
1009
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-caption {
1010
  display: block;
1011
  left: 0;
@@ -1013,13 +887,13 @@ only screen and (min-resolution: 2.25dppx) {
1013
  bottom: 0;
1014
  transition-property: visibility, opacity, background-color;
1015
  }
1016
- .foogallery.fg-hover-colorize .fg-item-inner:hover .fg-thumb:before,
1017
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption {
1018
  visibility: visible;
1019
  opacity: 1;
1020
  }
1021
  /* Fade */
1022
- .foogallery.fg-hover-fade .fg-loaded .fg-thumb:before,
1023
  .foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption {
1024
  display: block;
1025
  left: 0;
@@ -1027,7 +901,7 @@ only screen and (min-resolution: 2.25dppx) {
1027
  bottom: 0;
1028
  transition-property: visibility, opacity, background-color;
1029
  }
1030
- .foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1031
  .foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption {
1032
  visibility: visible;
1033
  opacity: 1;
@@ -1049,7 +923,7 @@ only screen and (min-resolution: 2.25dppx) {
1049
  filter: gray;
1050
  opacity: 1;
1051
  }
1052
- .foogallery.fg-hover-grayscale .fg-thumb:before,
1053
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption {
1054
  display: block;
1055
  left: 0;
@@ -1057,13 +931,13 @@ only screen and (min-resolution: 2.25dppx) {
1057
  bottom: 0;
1058
  transition-property: visibility, opacity, background-color;
1059
  }
1060
- .foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-thumb:before,
1061
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption {
1062
  visibility: visible;
1063
  opacity: 1;
1064
  }
1065
  /* Instant */
1066
- .foogallery.fg-hover-instant .fg-loaded .fg-thumb:before,
1067
  .foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption {
1068
  display: block;
1069
  left: 0;
@@ -1071,13 +945,13 @@ only screen and (min-resolution: 2.25dppx) {
1071
  bottom: 0;
1072
  transition-property: none;
1073
  }
1074
- .foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1075
  .foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption {
1076
  visibility: visible;
1077
  opacity: 1;
1078
  }
1079
  /* Push */
1080
- .foogallery.fg-hover-push .fg-loaded .fg-thumb:before,
1081
  .foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption {
1082
  display: block;
1083
  left: 0;
@@ -1108,7 +982,7 @@ only screen and (min-resolution: 2.25dppx) {
1108
  transform: scale(1.048);
1109
  z-index: 10;
1110
  }
1111
- .foogallery.fg-hover-scale .fg-thumb:before,
1112
  .foogallery.fg-caption-hover.fg-hover-scale .fg-caption {
1113
  display: block;
1114
  left: 0;
@@ -1116,19 +990,19 @@ only screen and (min-resolution: 2.25dppx) {
1116
  bottom: 0;
1117
  transition-property: visibility, opacity, background-color;
1118
  }
1119
- .foogallery.fg-hover-scale .fg-item-inner:hover .fg-thumb:before,
1120
  .foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption {
1121
  visibility: visible;
1122
  opacity: 1;
1123
  }
1124
  /* Slide */
1125
- .foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before,
1126
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,
1127
- .foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before,
1128
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,
1129
- .foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before,
1130
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,
1131
- .foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before,
1132
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption {
1133
  display: block;
1134
  left: 0;
@@ -1138,38 +1012,38 @@ only screen and (min-resolution: 2.25dppx) {
1138
  visibility: visible;
1139
  opacity: 1;
1140
  }
1141
- .foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1142
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,
1143
- .foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1144
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,
1145
- .foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1146
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,
1147
- .foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-thumb:before,
1148
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption {
1149
  transform: translateY(0) translateX(0);
1150
  }
1151
 
1152
 
1153
  /* Slide Up */
1154
- .foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before,
1155
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption {
1156
  transform: translateY(100%);
1157
  }
1158
 
1159
  /* Slide Down */
1160
- .foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before,
1161
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption {
1162
  transform: translateY(-100%);
1163
  }
1164
 
1165
  /* Slide Left */
1166
- .foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before,
1167
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption {
1168
  transform: translateX(100%);
1169
  }
1170
 
1171
  /* Slide Right */
1172
- .foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before,
1173
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption {
1174
  transform: translateX(-100%);
1175
  }
@@ -1663,7 +1537,7 @@ only screen and (min-resolution: 2.25dppx) {
1663
  .foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before {
1664
  display: none;
1665
  }
1666
- .foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-thumb:before {
1667
  display: block;
1668
  }
1669
  .foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption {
@@ -1794,8 +1668,8 @@ only screen and (min-resolution: 2.25dppx) {
1794
 
1795
  /* Some badly written themes apply min-width:0 and min-height:0 to every element in the page which causes layout issues with flex. */
1796
  .fg-simple_portfolio .fg-thumb {
1797
- min-width: unset;
1798
- min-height: unset;
1799
  }
1800
 
1801
  /* Reset captions for the portfolio */
@@ -1837,7 +1711,7 @@ only screen and (min-resolution: 2.25dppx) {
1837
  .foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before {
1838
  display: none;
1839
  }
1840
- .foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-thumb:before {
1841
  display: block;
1842
  }
1843
  .foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption {
32
  border: solid 0 transparent;
33
  }
34
 
35
+ .foogallery .fg-item.fg-error:before {
36
+ content: "";
37
+ display: block;
38
+ position: absolute;
39
+ top: 50%;
40
+ left: 50%;
41
+ transform: translateX(-50%) translateY(-50%);
42
+ width: 32px;
43
+ height: 32px;
44
+ background-image: url('../img/icons.svg#image');
45
+ background-color: transparent;
46
+ background-repeat: no-repeat;
47
+ background-position: center center;
48
+ background-size: 32px 32px;
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
 
51
  .foogallery .fg-item.fg-loaded {
76
  text-decoration: none;
77
  box-shadow: none;
78
  }
79
+ .foogallery .fg-image-overlay {
80
+ position: absolute;
81
+ top: 0;
82
+ right: 0;
83
+ bottom: 0;
84
+ left: 0;
85
+ z-index: 8;
86
+ visibility: hidden;
87
+ opacity: 0;
88
+ background-color: rgba(0,0,0,0.6);
89
+ color: #fff;
90
+ }
91
+ .foogallery.fg-light-overlays .fg-image-overlay {
92
+ background-color: rgba(255,255,255,0.8);
93
+ color: #333;
94
+ }
95
  .foogallery .fg-image-wrap {
96
  display: block;
97
  position: relative;
236
  .fg-loading-default .fg-loader {
237
  border-radius: 50%;
238
  text-indent: -9999em;
239
+ box-shadow: 0 -2.6em 0 0 rgba(130, 130, 130, 1),
240
+ 1.8em -1.8em 0 0 rgba(130, 130, 130, 0.2),
241
+ 2.5em 0 0 0 rgba(130, 130, 130, 0.2),
242
+ 1.75em 1.75em 0 0 rgba(130, 130, 130, 0.2),
243
+ 0 2.5em 0 0 rgba(130, 130, 130, 0.2),
244
+ -1.8em 1.8em 0 0 rgba(130, 130, 130, 0.2),
245
+ -2.6em 0 0 0 rgba(130, 130, 130, 0.5),
246
+ -1.8em -1.8em 0 0 rgba(130, 130, 130, 0.7);
247
+ -webkit-animation: loading-default 1.1s infinite steps(8, start);
248
+ animation: loading-default 1.1s infinite steps(8, start);
249
  }
250
 
251
  @-webkit-keyframes loading-default {
252
+ 0% {
253
+ transform: rotate(0deg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  }
255
+ 100% {
256
+ transform: rotate(360deg);
 
 
 
 
 
 
 
257
  }
258
  }
259
 
260
  @keyframes loading-default {
261
+ 0% {
262
+ transform: rotate(0deg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
+ 100% {
265
+ transform: rotate(360deg);
 
 
 
 
 
 
 
266
  }
267
  }
268
  .fg-loading-bars .fg-loader,
600
  border: none;
601
  text-align: center;
602
  cursor: pointer;
603
+ margin: 0;
604
  }
605
  .foogallery .fg-caption a {
606
  text-decoration: none;
607
  color: #fff;
608
  border-bottom: 1px solid #FFF;
609
  }
610
+ .foogallery.fg-light-overlays .fg-caption {
611
+ background-color: rgba(255,255,255,0.8);
612
+ color: #333;
613
+ }
614
+ .foogallery.fg-light-overlays .fg-caption a {
615
+ color: #333;
616
+ border-bottom-color: #333;
617
+ }
618
+
619
  .foogallery .fg-caption a:hover {
620
  border-bottom: none;
621
  }
659
  left: 0;
660
  transform: translateY(-50%);
661
  }
662
+ .foogallery.fg-caption-hover .fg-item.fg-loaded .fg-image-overlay {
663
  display: none;
664
  }
665
  /* Icon & Overlay */
666
+ .foogallery .fg-image-overlay:before {
 
 
 
 
 
 
 
667
  content: "";
668
  display: block;
669
  position: absolute;
670
+ top: 50%;
671
+ left: 50%;
672
+ transform: translateX(-50%) translateY(-50%);
673
+ width: 32px;
674
+ height: 32px;
 
 
 
675
  background-size: 32px 32px;
676
+ background-position: center center;
677
+ background-repeat: no-repeat;
678
  }
679
+ .foogallery .fg-caption-inner:before {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
680
  content: "";
681
+ display: none;
682
  position: relative;
683
  width: 32px;
684
  height: 32px;
685
  margin: 10px 0 5px 0;
 
686
  background-size: 32px 32px;
687
  vertical-align: middle;
688
+ background-position: center center;
689
+ background-repeat: no-repeat;
690
+ }
691
+ .foogallery.fg-hover-zoom .fg-caption-inner:before,
692
+ .foogallery.fg-hover-zoom2 .fg-caption-inner:before,
693
+ .foogallery.fg-hover-zoom3 .fg-caption-inner:before,
694
+ .foogallery.fg-hover-plus .fg-caption-inner:before,
695
+ .foogallery.fg-hover-circle-plus .fg-caption-inner:before,
696
+ .foogallery.fg-hover-eye .fg-caption-inner:before,
697
+ .foogallery.fg-hover-external .fg-caption-inner:before,
698
+ .foogallery.fg-hover-tint .fg-caption-inner:before,
699
+ .foogallery.fg-video-default .fg-caption-inner:before,
700
+ .foogallery.fg-video-1 .fg-caption-inner:before,
701
+ .foogallery.fg-video-2 .fg-caption-inner:before,
702
+ .foogallery.fg-video-3 .fg-caption-inner:before,
703
+ .foogallery.fg-video-4 .fg-caption-inner:before {
704
+ display: inline-block;
705
  }
706
 
707
+ .foogallery.fg-hover-zoom .fg-item-inner:hover .fg-image-overlay,
708
+ .foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-image-overlay,
709
+ .foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-image-overlay,
710
+ .foogallery.fg-hover-plus .fg-item-inner:hover .fg-image-overlay,
711
+ .foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-image-overlay,
712
+ .foogallery.fg-hover-eye .fg-item-inner:hover .fg-image-overlay,
713
+ .foogallery.fg-hover-external .fg-item-inner:hover .fg-image-overlay,
714
+ .foogallery.fg-hover-tint .fg-item-inner:hover .fg-image-overlay,
715
+ .foogallery.fg-video-default .fg-type-video .fg-item-inner:hover .fg-image-overlay,
716
+ .foogallery.fg-video-1 .fg-type-video .fg-item-inner:hover .fg-image-overlay,
717
+ .foogallery.fg-video-2 .fg-type-video .fg-item-inner:hover .fg-image-overlay,
718
+ .foogallery.fg-video-3 .fg-type-video .fg-item-inner:hover .fg-image-overlay,
719
+ .foogallery.fg-video-4 .fg-type-video .fg-item-inner:hover .fg-image-overlay {
720
+ visibility: visible;
721
+ opacity: 1;
722
+ }
723
+ .foogallery.fg-video-sticky .fg-type-video.fg-loaded .fg-item-inner .fg-image-overlay {
724
+ background-color: transparent;
725
+ visibility: visible;
726
+ opacity: 1;
727
+ }
728
+ .foogallery.fg-video-sticky .fg-type-video .fg-caption-inner:before {
729
+ display: none;
730
+ }
731
 
732
+ .foogallery.fg-hover-zoom .fg-image-overlay:before,
733
  .foogallery.fg-hover-zoom .fg-caption-inner:before {
734
+ background-image: url('../img/icons.svg#zoom-light');
735
+ }
736
+ .foogallery.fg-light-overlays.fg-hover-zoom .fg-image-overlay:before,
737
+ .foogallery.fg-light-overlays.fg-hover-zoom .fg-caption-inner:before {
738
+ background-image: url('../img/icons.svg#zoom-dark');
739
  }
740
 
741
+ .foogallery.fg-hover-zoom2 .fg-image-overlay:before,
742
  .foogallery.fg-hover-zoom2 .fg-caption-inner:before {
743
+ background-image: url('../img/icons.svg#zoom2-light');
744
+ }
745
+ .foogallery.fg-light-overlays.fg-hover-zoom2 .fg-image-overlay:before,
746
+ .foogallery.fg-light-overlays.fg-hover-zoom2 .fg-caption-inner:before {
747
+ background-image: url('../img/icons.svg#zoom2-dark');
748
  }
749
 
750
+ .foogallery.fg-hover-zoom3 .fg-image-overlay:before,
751
  .foogallery.fg-hover-zoom3 .fg-caption-inner:before {
752
+ background-image: url('../img/icons.svg#zoom3-light');
753
+ }
754
+ .foogallery.fg-light-overlays.fg-hover-zoom3 .fg-image-overlay:before,
755
+ .foogallery.fg-light-overlays.fg-hover-zoom3 .fg-caption-inner:before {
756
+ background-image: url('../img/icons.svg#zoom3-dark');
757
  }
758
 
759
+ .foogallery.fg-hover-plus .fg-image-overlay:before,
760
  .foogallery.fg-hover-plus .fg-caption-inner:before {
761
+ background-image: url('../img/icons.svg#plus-light');
762
+ }
763
+ .foogallery.fg-light-overlays.fg-hover-plus .fg-image-overlay:before,
764
+ .foogallery.fg-light-overlays.fg-hover-plus .fg-caption-inner:before {
765
+ background-image: url('../img/icons.svg#plus-dark');
766
  }
767
 
768
+ .foogallery.fg-hover-circle-plus .fg-image-overlay:before,
769
  .foogallery.fg-hover-circle-plus .fg-caption-inner:before {
770
+ background-image: url('../img/icons.svg#circle-plus-light');
771
+ }
772
+ .foogallery.fg-light-overlays.fg-hover-circle-plus .fg-image-overlay:before,
773
+ .foogallery.fg-light-overlays.fg-hover-circle-plus .fg-caption-inner:before {
774
+ background-image: url('../img/icons.svg#circle-plus-dark');
775
  }
776
 
777
+ .foogallery.fg-hover-eye .fg-image-overlay:before,
778
  .foogallery.fg-hover-eye .fg-caption-inner:before {
779
+ background-image: url('../img/icons.svg#eye-light');
780
+ }
781
+ .foogallery.fg-light-overlays.fg-hover-eye .fg-image-overlay:before,
782
+ .foogallery.fg-light-overlays.fg-hover-eye .fg-caption-inner:before {
783
+ background-image: url('../img/icons.svg#eye-dark');
784
  }
785
 
786
+ .foogallery.fg-hover-external .fg-image-overlay:before,
787
  .foogallery.fg-hover-external .fg-caption-inner:before {
788
+ background-image: url('../img/icons.svg#external-light');
789
  }
790
+ .foogallery.fg-light-overlays.fg-hover-external .fg-image-overlay:before,
791
+ .foogallery.fg-light-overlays.fg-hover-external .fg-caption-inner:before {
792
+ background-image: url('../img/icons.svg#external-dark');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
  }
794
 
795
+ .foogallery.fg-video-default .fg-type-video .fg-image-overlay:before,
796
+ .foogallery.fg-video-default .fg-type-video .fg-caption-inner:before {
797
+ background-image: url('../img/icons.svg#video-default-light');
798
+ }
799
+ .foogallery.fg-light-overlays.fg-video-default .fg-type-video .fg-image-overlay:before,
800
+ .foogallery.fg-light-overlays.fg-video-default .fg-type-video .fg-caption-inner:before {
801
+ background-image: url('../img/icons.svg#video-default-dark');
802
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
803
 
804
+ .foogallery.fg-video-1 .fg-type-video .fg-image-overlay:before,
805
+ .foogallery.fg-video-1 .fg-type-video .fg-caption-inner:before {
806
+ background-image: url('../img/icons.svg#video-1-light');
807
+ }
808
+ .foogallery.fg-light-overlays.fg-video-1 .fg-type-video .fg-image-overlay:before,
809
+ .foogallery.fg-light-overlays.fg-video-1 .fg-type-video .fg-caption-inner:before {
810
+ background-image: url('../img/icons.svg#video-1-dark');
811
+ }
812
 
813
+ .foogallery.fg-video-2 .fg-type-video .fg-image-overlay:before,
814
+ .foogallery.fg-video-2 .fg-type-video .fg-caption-inner:before {
815
+ background-image: url('../img/icons.svg#video-2-light');
816
+ }
817
+ .foogallery.fg-light-overlays.fg-video-2 .fg-type-video .fg-image-overlay:before,
818
+ .foogallery.fg-light-overlays.fg-video-2 .fg-type-video .fg-caption-inner:before {
819
+ background-image: url('../img/icons.svg#video-2-dark');
820
+ }
821
 
822
+ .foogallery.fg-video-3 .fg-type-video .fg-image-overlay:before,
823
+ .foogallery.fg-video-3 .fg-type-video .fg-caption-inner:before {
824
+ background-image: url('../img/icons.svg#video-3-light');
825
+ }
826
+ .foogallery.fg-light-overlays.fg-video-3 .fg-type-video .fg-image-overlay:before,
827
+ .foogallery.fg-light-overlays.fg-video-3 .fg-type-video .fg-caption-inner:before {
828
+ background-image: url('../img/icons.svg#video-3-dark');
829
+ }
830
 
831
+ .foogallery.fg-video-4 .fg-type-video .fg-image-overlay:before,
832
+ .foogallery.fg-video-4 .fg-type-video .fg-caption-inner:before {
833
+ background-image: url('../img/icons.svg#video-4-light');
834
+ }
835
+ .foogallery.fg-light-overlays.fg-video-4 .fg-type-video .fg-image-overlay:before,
836
+ .foogallery.fg-light-overlays.fg-video-4 .fg-type-video .fg-caption-inner:before {
837
+ background-image: url('../img/icons.svg#video-4-dark');
838
  }
839
  /* Transitions */
840
  .foogallery.fg-caption-hover.fg-hover-instant .fg-caption,
847
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,
848
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,
849
  .foogallery.fg-caption-hover.fg-hover-scale .fg-caption,
850
+ .foogallery.fg-hover-instant .fg-image-overlay,
851
+ .foogallery.fg-hover-fade .fg-image-overlay,
852
+ .foogallery.fg-hover-slide-up .fg-image-overlay,
853
+ .foogallery.fg-hover-slide-down .fg-image-overlay,
854
+ .foogallery.fg-hover-slide-left .fg-image-overlay,
855
+ .foogallery.fg-hover-slide-right .fg-image-overlay,
856
  .foogallery.fg-hover-push .fg-thumb,
857
+ .foogallery.fg-hover-colorize .fg-image-overlay,
858
+ .foogallery.fg-hover-grayscale .fg-image-overlay,
859
  .foogallery.fg-hover-scale .fg-item,
860
+ .foogallery.fg-hover-scale .fg-image-overlay,
861
  .foogallery.fg-hover-colorize .fg-image,
862
  .foogallery.fg-hover-grayscale .fg-image {
863
  transition-timing-function: ease;
864
  transition-duration: 300ms;
865
+ backface-visibility: hidden;
866
  }
867
  /* Colorize */
868
  .foogallery.fg-hover-colorize .fg-image {
879
  -webkit-filter: none;
880
  filter: none;
881
  }
882
+ .foogallery.fg-hover-colorize .fg-image-overlay,
883
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-caption {
884
  display: block;
885
  left: 0;
887
  bottom: 0;
888
  transition-property: visibility, opacity, background-color;
889
  }
890
+ .foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image-overlay,
891
  .foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption {
892
  visibility: visible;
893
  opacity: 1;
894
  }
895
  /* Fade */
896
+ .foogallery.fg-hover-fade .fg-loaded .fg-image-overlay,
897
  .foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption {
898
  display: block;
899
  left: 0;
901
  bottom: 0;
902
  transition-property: visibility, opacity, background-color;
903
  }
904
+ .foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-image-overlay,
905
  .foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption {
906
  visibility: visible;
907
  opacity: 1;
923
  filter: gray;
924
  opacity: 1;
925
  }
926
+ .foogallery.fg-hover-grayscale .fg-image-overlay,
927
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption {
928
  display: block;
929
  left: 0;
931
  bottom: 0;
932
  transition-property: visibility, opacity, background-color;
933
  }
934
+ .foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image-overlay,
935
  .foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption {
936
  visibility: visible;
937
  opacity: 1;
938
  }
939
  /* Instant */
940
+ .foogallery.fg-hover-instant .fg-loaded .fg-image-overlay,
941
  .foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption {
942
  display: block;
943
  left: 0;
945
  bottom: 0;
946
  transition-property: none;
947
  }
948
+ .foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-image-overlay,
949
  .foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption {
950
  visibility: visible;
951
  opacity: 1;
952
  }
953
  /* Push */
954
+ .foogallery.fg-hover-push .fg-loaded .fg-image-overlay,
955
  .foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption {
956
  display: block;
957
  left: 0;
982
  transform: scale(1.048);
983
  z-index: 10;
984
  }
985
+ .foogallery.fg-hover-scale .fg-image-overlay,
986
  .foogallery.fg-caption-hover.fg-hover-scale .fg-caption {
987
  display: block;
988
  left: 0;
990
  bottom: 0;
991
  transition-property: visibility, opacity, background-color;
992
  }
993
+ .foogallery.fg-hover-scale .fg-item-inner:hover .fg-image-overlay,
994
  .foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption {
995
  visibility: visible;
996
  opacity: 1;
997
  }
998
  /* Slide */
999
+ .foogallery.fg-hover-slide-up .fg-loaded .fg-image-overlay,
1000
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,
1001
+ .foogallery.fg-hover-slide-down .fg-loaded .fg-image-overlay,
1002
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,
1003
+ .foogallery.fg-hover-slide-left .fg-loaded .fg-image-overlay,
1004
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,
1005
+ .foogallery.fg-hover-slide-right .fg-loaded .fg-image-overlay,
1006
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption {
1007
  display: block;
1008
  left: 0;
1012
  visibility: visible;
1013
  opacity: 1;
1014
  }
1015
+ .foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-image-overlay,
1016
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,
1017
+ .foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-image-overlay,
1018
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,
1019
+ .foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-image-overlay,
1020
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,
1021
+ .foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-image-overlay,
1022
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption {
1023
  transform: translateY(0) translateX(0);
1024
  }
1025
 
1026
 
1027
  /* Slide Up */
1028
+ .foogallery.fg-hover-slide-up .fg-loaded .fg-image-overlay,
1029
  .foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption {
1030
  transform: translateY(100%);
1031
  }
1032
 
1033
  /* Slide Down */
1034
+ .foogallery.fg-hover-slide-down .fg-loaded .fg-image-overlay,
1035
  .foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption {
1036
  transform: translateY(-100%);
1037
  }
1038
 
1039
  /* Slide Left */
1040
+ .foogallery.fg-hover-slide-left .fg-loaded .fg-image-overlay,
1041
  .foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption {
1042
  transform: translateX(100%);
1043
  }
1044
 
1045
  /* Slide Right */
1046
+ .foogallery.fg-hover-slide-right .fg-loaded .fg-image-overlay,
1047
  .foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption {
1048
  transform: translateX(-100%);
1049
  }
1537
  .foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before {
1538
  display: none;
1539
  }
1540
+ .foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-image-overlay {
1541
  display: block;
1542
  }
1543
  .foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption {
1668
 
1669
  /* Some badly written themes apply min-width:0 and min-height:0 to every element in the page which causes layout issues with flex. */
1670
  .fg-simple_portfolio .fg-thumb {
1671
+ min-width: auto;
1672
+ min-height: auto;
1673
  }
1674
 
1675
  /* Reset captions for the portfolio */
1711
  .foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before {
1712
  display: none;
1713
  }
1714
+ .foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-image-overlay {
1715
  display: block;
1716
  }
1717
  .foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption {
extensions/default-templates/shared/css/foogallery.min.css CHANGED
@@ -1 +1 @@
1
- .foogallery,.foogallery *{box-sizing:border-box}.foogallery{display:block;z-index:1;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;position:relative;line-height:0;font-size:0;width:100%;max-width:100%}.foogallery .fg-item{display:inline-block;position:relative;background-color:transparent;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.foogallery .fg-item-inner{display:block;position:relative;visibility:hidden;overflow:hidden;opacity:0;z-index:3;margin:0;border:solid 0 transparent}.foogallery .fg-item.fg-error,.foogallery .fg-item.fg-loading{background:no-repeat center}.foogallery .fg-item.fg-error{background-image:url(../img/image.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery .fg-item.fg-error{background-image:url(../img/image@3x.png)}}.foogallery .fg-item.fg-loaded{z-index:4}.foogallery .fg-loaded .fg-item-inner{visibility:visible;opacity:1;z-index:5}.foogallery .fg-error .fg-item-inner{pointer-events:none;cursor:default}.foogallery .fg-thumb{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:4;box-shadow:none}.foogallery .fg-thumb:focus,.foogallery .fg-thumb:hover{border:none;outline:0;text-decoration:none;box-shadow:none}.foogallery .fg-image-wrap{display:block;position:relative}.foogallery .fg-image{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:5;max-width:none;height:auto;margin:0}.foogallery .fg-loaded .fg-thumb{z-index:6}.foogallery .fg-loaded .fg-image{z-index:7}.foogallery.fg-light .fg-item-inner{background-color:#fff;color:#333;border-color:#fff}.foogallery.fg-dark .fg-item-inner{background-color:#333;color:#fff;border-color:#333}.foogallery.fg-light .fg-item.fg-error,.foogallery.fg-light .fg-item.fg-idle,.foogallery.fg-light .fg-item.fg-loading{background-color:#eee;box-shadow:inset 0 0 0 1px #ddd}.foogallery.fg-dark .fg-item.fg-error,.foogallery.fg-dark .fg-item.fg-idle,.foogallery.fg-dark .fg-item.fg-loading{background-color:#444;box-shadow:inset 0 0 0 1px #333}.foogallery.fg-border-thin .fg-item-inner{border-width:4px}.foogallery.fg-border-medium .fg-item-inner{border-width:10px}.foogallery.fg-border-thick .fg-item-inner{border-width:16px}.foogallery.fg-light.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-dark.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-light.fg-shadow-small .fg-item-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-light.fg-shadow-medium .fg-item-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-light.fg-shadow-large .fg-item-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-shadow-inset-small .fg-thumb:after{display:block;content:"";position:absolute;top:0;left:0;right:0;bottom:0;z-index:7}.foogallery.fg-dark.fg-shadow-inset-small .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-small .fg-thumb:after{box-shadow:inset 0 1px 4px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-medium .fg-thumb:after{box-shadow:inset 0 1px 10px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-large .fg-thumb:after{box-shadow:inset 0 1px 16px 0 rgba(0,0,0,.3)}.foogallery.fg-round-full.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-small .fg-thumb:after{border-radius:50%}.foogallery.fg-round-small .fg-item,.foogallery.fg-round-small .fg-item-inner{border-radius:5px}.foogallery.fg-round-medium .fg-item,.foogallery.fg-round-medium .fg-item-inner{border-radius:10px}.foogallery.fg-round-large .fg-item,.foogallery.fg-round-large .fg-item-inner{border-radius:15px}.foogallery.fg-round-full .fg-item,.foogallery.fg-round-full .fg-item-inner{border-radius:50%}.foogallery .fg-loader{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:1em;height:1em;font-size:5px;visibility:hidden;opacity:0}.foogallery .fg-loading .fg-loader{visibility:visible;opacity:1}.fg-loading-default .fg-loader{border-radius:50%;text-indent:-9999em;-webkit-animation:loading-default 1.1s infinite ease;animation:loading-default 1.1s infinite ease}@-webkit-keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}@keyframes loading-default{0%,100%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7)}12.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.7),1.8em -1.8em 0 0 rgba(130,130,130,1),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.5)}25%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.5),1.8em -1.8em 0 0 rgba(130,130,130,.7),2.5em 0 0 0 rgba(130,130,130,1),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}37.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.5),2.5em 0 0 0 rgba(130,130,130,.7),1.75em 1.75em 0 0 rgba(130,130,130,1),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}50%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.5),1.75em 1.75em 0 0 rgba(130,130,130,.7),0 2.5em 0 0 rgba(130,130,130,1),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}62.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.5),0 2.5em 0 0 rgba(130,130,130,.7),-1.8em 1.8em 0 0 rgba(130,130,130,1),-2.6em 0 0 0 rgba(130,130,130,.2),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}75%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.5),-1.8em 1.8em 0 0 rgba(130,130,130,.7),-2.6em 0 0 0 rgba(130,130,130,1),-1.8em -1.8em 0 0 rgba(130,130,130,.2)}87.5%{box-shadow:0 -2.6em 0 0 rgba(130,130,130,.2),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.5),-2.6em 0 0 0 rgba(130,130,130,.7),-1.8em -1.8em 0 0 rgba(130,130,130,1)}}.fg-loading-bars .fg-loader,.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{background:rgba(130,130,130,1);-webkit-animation:loading-bars 1s infinite ease-in-out;animation:loading-bars 1s infinite ease-in-out;width:1em;height:4em}.fg-loading-bars .fg-loader{color:rgba(130,130,130,1);text-indent:-9999em;font-size:4px;-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{position:absolute;top:0;content:''}.fg-loading-bars .fg-loader:before{left:-1.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-bars .fg-loader:after{left:1.5em}@-webkit-keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}@keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}.fg-loading-trail .fg-loader{color:#828282;font-size:20px;text-indent:-9999em;overflow:hidden;border-radius:50%;-webkit-animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease;animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease}@-webkit-keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@-webkit-keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.fg-loading-pulse .fg-loader,.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{border-radius:50%;width:2.5em;height:2.5em;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation:loading-pulse 1.8s infinite ease-in-out;animation:loading-pulse 1.8s infinite ease-in-out}.fg-loading-pulse .fg-loader{color:#828282;font-size:4px;text-indent:-9999em;transform:translateX(-50%) translateY(-150%);-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{content:'';position:absolute;top:0}.fg-loading-pulse .fg-loader:before{left:-3.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-pulse .fg-loader:after{left:3.5em}@-webkit-keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}@keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}.fg-loading-dots .fg-loader{color:#828282;font-size:5px;border-radius:50%;text-indent:-9999em;-webkit-animation:loading-dots 1.3s infinite linear;animation:loading-dots 1.3s infinite linear}@-webkit-keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}@keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}.fg-loading-partial .fg-loader,.fg-loading-partial .fg-loader:after{border-radius:50%;width:10em;height:10em}.fg-loading-partial .fg-loader{font-size:4px;text-indent:-9999em;border-top:1.1em solid rgba(130,130,130,.2);border-right:1.1em solid rgba(130,130,130,.2);border-bottom:1.1em solid rgba(130,130,130,.2);border-left:1.1em solid #828282;-webkit-animation:loading-partial 1.1s infinite linear;animation:loading-partial 1.1s infinite linear}@-webkit-keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.foogallery.fg-loaded-drop .fg-item,.foogallery.fg-loaded-fade-in .fg-item,.foogallery.fg-loaded-flip .fg-item,.foogallery.fg-loaded-fly .fg-item,.foogallery.fg-loaded-scale-up .fg-item,.foogallery.fg-loaded-slide-down .fg-item,.foogallery.fg-loaded-slide-left .fg-item,.foogallery.fg-loaded-slide-right .fg-item,.foogallery.fg-loaded-slide-up .fg-item,.foogallery.fg-loaded-swing-down .fg-item{transition-timing-function:ease;transition-duration:650ms;transition-property:background-color,transform}.foogallery.fg-loaded-drop .fg-item-inner,.foogallery.fg-loaded-fade-in .fg-item-inner,.foogallery.fg-loaded-flip .fg-item-inner,.foogallery.fg-loaded-fly .fg-item-inner,.foogallery.fg-loaded-scale-up .fg-item-inner,.foogallery.fg-loaded-slide-down .fg-item-inner,.foogallery.fg-loaded-slide-left .fg-item-inner,.foogallery.fg-loaded-slide-right .fg-item-inner,.foogallery.fg-loaded-slide-up .fg-item-inner,.foogallery.fg-loaded-swing-down .fg-item-inner{transition-timing-function:ease;transition-duration:650ms}.foogallery.fg-loaded-drop .fg-item.fg-loaded,.foogallery.fg-loaded-flip .fg-item.fg-loaded,.foogallery.fg-loaded-fly .fg-item.fg-loaded,.foogallery.fg-loaded-swing-down .fg-item.fg-loaded{perspective:1300px}.foogallery.fg-loaded-fade-in .fg-item-inner{transition-property:visibility,opacity}.foogallery .fg-caption{visibility:hidden;opacity:0;background-color:rgba(0,0,0,.6);color:#fff;position:absolute;z-index:8;width:100%;max-height:100%;overflow:hidden;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:13px;font-weight:400;line-height:1.3;border:none;text-align:center;cursor:pointer}.foogallery .fg-caption a{text-decoration:none;color:#fff;border-bottom:1px solid #fff}.foogallery .fg-caption a:hover{border-bottom:none}.foogallery .fg-caption-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16px;font-weight:400;padding:5px}.foogallery .fg-caption-desc{padding:5px}.foogallery .fg-caption-title+.fg-caption-desc{padding-top:0}.foogallery.fg-caption-always .fg-caption .fg-caption-inner:before{display:none}.foogallery.fg-caption-always .fg-item.fg-loaded .fg-caption{left:0;bottom:0;transition-timing-function:ease;transition-duration:.3s;transition-property:visibility,opacity;visibility:visible;opacity:1;text-align:left}.foogallery.fg-caption-hover .fg-caption .fg-caption-inner{width:100%;max-height:100%;position:absolute;top:50%;left:0;transform:translateY(-50%)}.foogallery.fg-caption-hover .fg-item.fg-loaded .fg-thumb:before{display:none}.foogallery.fg-hover-circle-plus .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{content:"";display:block;position:absolute;visibility:hidden;opacity:0;top:0;bottom:0;left:0;right:0;z-index:8;background:rgba(0,0,0,.5) no-repeat center center;background-size:32px 32px}.foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-circle-plus .fg-thumb:focus:before,.foogallery.fg-hover-external .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-external .fg-thumb:focus:before,.foogallery.fg-hover-eye .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-eye .fg-thumb:focus:before,.foogallery.fg-hover-plus .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-plus .fg-thumb:focus:before,.foogallery.fg-hover-tint .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-tint .fg-thumb:focus:before,.foogallery.fg-hover-zoom .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom .fg-thumb:focus:before,.foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom2 .fg-thumb:focus:before,.foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-zoom3 .fg-thumb:focus:before{visibility:visible;opacity:1}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-tint .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-caption-inner:before{content:"";display:inline-block;position:relative;width:32px;height:32px;margin:10px 0 5px 0;background:transparent no-repeat center center;background-size:32px 32px;vertical-align:middle}.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external.png)}@media only screen and (-o-min-device-pixel-ratio:5/4),only screen and (-webkit-min-device-pixel-ratio:1.25),only screen and (min-device-pixel-ratio:1.25),only screen and (min-resolution:1.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@2x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@2x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@2x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@2x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@2x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@2x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@2x.png)}}@media only screen and (-o-min-device-pixel-ratio:9/4),only screen and (-webkit-min-device-pixel-ratio:2.25),only screen and (min-device-pixel-ratio:2.25),only screen and (min-resolution:2.25dppx){.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-thumb:before{background-image:url(../img/zoom@3x.png)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-thumb:before{background-image:url(../img/zoom2@3x.png)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-thumb:before{background-image:url(../img/zoom3@3x.png)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-thumb:before{background-image:url(../img/plus@3x.png)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-thumb:before{background-image:url(../img/circle-plus@3x.png)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-thumb:before{background-image:url(../img/eye@3x.png)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-thumb:before{background-image:url(../img/external@3x.png)}}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-caption-hover.fg-hover-fade .fg-caption,.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-caption-hover.fg-hover-instant .fg-caption,.foogallery.fg-caption-hover.fg-hover-push .fg-caption,.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-down .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-caption,.foogallery.fg-hover-colorize .fg-image,.foogallery.fg-hover-colorize .fg-thumb:before,.foogallery.fg-hover-fade .fg-thumb:before,.foogallery.fg-hover-grayscale .fg-image,.foogallery.fg-hover-grayscale .fg-thumb:before,.foogallery.fg-hover-instant .fg-thumb:before,.foogallery.fg-hover-push .fg-thumb,.foogallery.fg-hover-scale .fg-item,.foogallery.fg-hover-scale .fg-thumb:before,.foogallery.fg-hover-slide-down .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-thumb:before{transition-timing-function:ease;transition-duration:.3s}.foogallery.fg-hover-colorize .fg-image{filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");filter:gray;-webkit-filter:grayscale(100%);-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image{-webkit-filter:none;filter:none}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-hover-colorize .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-hover-grayscale .fg-image{-webkit-filter:none;filter:none;-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image{-webkit-filter:grayscale(1);-webkit-filter:grayscale(100%);filter:grayscale(100%);filter:gray;opacity:1}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-hover-grayscale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:none}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transform:translateX(100%);visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb{transition-property:transform}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-caption{transform:translateY(0)}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb,.foogallery.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb{transform:translateX(-100%)}.foogallery.fg-hover-scale .fg-item{transition-property:transform;z-index:4}.foogallery.fg-hover-scale .fg-item:hover{transform:scale(1.048);z-index:10}.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-hover-scale .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-scale .fg-item-inner:hover .fg-thumb:before{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{display:block;left:0;top:0;bottom:0;transition-property:transform,background-color,opacity,visibility;visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-thumb:before,.foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-thumb:before{transform:translateY(0) translateX(0)}.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-up .fg-loaded .fg-thumb:before{transform:translateY(100%)}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-thumb:before{transform:translateY(-100%)}.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-hover-slide-left .fg-loaded .fg-thumb:before{transform:translateX(100%)}.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-hover-slide-right .fg-loaded .fg-thumb:before{transform:translateX(-100%)}.fg-paging-container,.fg-paging-container *,.fg-paging-container :after,.fg-paging-container :before{box-sizing:border-box}.fg-paging-container{display:block;padding:15px;text-align:center;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fg-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.fg-paging-container .fg-dot-item,.fg-paging-container .fg-dots{display:inline-block;margin:0;padding:0;outline:0;list-style:none}.fg-paging-container .fg-dot-item .fg-dot-link{display:inline-block;margin:3px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;user-select:none;background-image:none;text-decoration:none;border:1px solid transparent;position:relative;border-radius:50%;padding:0;font-size:0;outline:0;color:transparent;box-shadow:none}.fg-paging-container .fg-dot-item .fg-dot-link:before{content:"";background-color:transparent;border:1px solid transparent;display:block;border-radius:50%;width:9px;height:9px;padding:0;margin:2px}.fg-paging-container .fg-dot-item .fg-dot-link:active,.fg-paging-container .fg-dot-item .fg-dot-link:focus,.fg-paging-container .fg-dot-item .fg-dot-link:hover{text-decoration:none;box-shadow:none;outline:0}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container .fg-dot-item.fg-selected .fg-dot-link{cursor:not-allowed;pointer-events:none}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link{cursor:not-allowed;pointer-events:none;outline:0}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link{background-color:#eee;border-color:#9d9d9d}.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link{border-color:#888}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#666;border-color:#888}.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#eee;border-color:#9d9d9d;opacity:.5}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link{background-color:#666;border-color:#333}.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link{border-color:#444}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#333;border-color:#444}.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#666;border-color:#333;opacity:.5}.fg-default:after{content:'';display:block;clear:both}.fg-default .fg-item,.fg-default .fg-item-inner,.fg-default .fg-thumb{display:inline-block;vertical-align:top;max-width:100%}.fg-default .fg-image{border-radius:0;display:block;max-width:100%;height:auto;margin:0;padding:0}.fg-default .fg-image{vertical-align:top}.fg-default.fg-left{text-align:left}.fg-default.fg-center{text-align:center}.fg-default.fg-right{text-align:right}.fg-default.fg-gutter-5{padding-left:5px;margin-bottom:-5px}.fg-default.fg-gutter-5 .fg-item{margin-right:5px;margin-bottom:5px}.fg-default.fg-gutter-10{padding-left:10px;margin-bottom:-10px}.fg-default.fg-gutter-10 .fg-item{margin-right:10px;margin-bottom:10px}.fg-default.fg-gutter-15{padding-left:15px;margin-bottom:-15px}.fg-default.fg-gutter-15 .fg-item{margin-right:15px;margin-bottom:15px}.fg-default.fg-gutter-20{padding-left:20px;margin-bottom:-20px}.fg-default.fg-gutter-20 .fg-item{margin-right:20px;margin-bottom:20px}.fg-default.fg-gutter-25{padding-left:25px;margin-bottom:-25px}.fg-default.fg-gutter-25 .fg-item{margin-right:25px;margin-bottom:25px}.fg-masonry *{box-sizing:border-box}.foogallery.fg-masonry.fg-center{margin:0 auto}.fg-masonry .fg-thumb{display:block}.fg-masonry.fg-masonry-fixed .fg-thumb{display:inline-block}.fg-masonry.fg-masonry-fixed .fg-image{max-width:100%}.fg-masonry .fg-column-width{display:inline-block;visibility:hidden;height:0;border:solid 0 transparent}.fg-masonry.fg-masonry-2col .fg-image,.fg-masonry.fg-masonry-3col .fg-image,.fg-masonry.fg-masonry-4col .fg-image,.fg-masonry.fg-masonry-5col .fg-image{width:100%;height:auto;max-width:100%}.fg-masonry .fg-item{line-height:0;font-size:0}.fg-masonry.fg-masonry-fixed .fg-column-width,.fg-masonry.fg-masonry-fixed .fg-item{max-width:100%}.fg-masonry.fg-masonry-2col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-2col .fg-column-width{width:49%}.fg-masonry.fg-masonry-2col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-3col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-3col .fg-column-width{width:32%}.fg-masonry.fg-masonry-3col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-4col .fg-item{margin-bottom:1%;width:24%}.fg-masonry.fg-masonry-4col .fg-column-width{width:24%}.fg-masonry.fg-masonry-4col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item{margin-bottom:0;width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width{width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item{margin-bottom:3%;width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width{width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:19%}.fg-masonry.fg-masonry-5col .fg-column-width{width:19%}.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}@media screen and (max-width:720px){.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:32%}.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:480px){.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:49%}.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:320px){.fg-masonry.fg-masonry-2col .fg-item,.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:100%}.fg-masonry.fg-masonry-2col .fg-column-width,.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col .fg-gutter-width,.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:0}}.foogallery.fg-border-thin .fg-column-width{border-width:4px}.foogallery.fg-border-medium .fg-column-width{border-width:10px}.foogallery.fg-border-thick .fg-column-width{border-width:16px}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner{display:block;position:relative;max-height:none;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-masonry.fg-captions-bottom .fg-caption-desc,.fg-masonry.fg-captions-bottom .fg-caption-title{text-align:left}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption,.fg-masonry.fg-captions-bottom.fg-light .fg-caption{color:#828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a:hover,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a:hover{border-bottom:none}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{color:#222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{color:#fff}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-masonry.fg-captions-bottom .fg-caption{border-width:10px}.fg-masonry.fg-captions-bottom .fg-caption-title+.fg-caption-desc{margin-top:4px}.fg-masonry.fg-captions-bottom.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.fg-masonry.fg-captions-bottom.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption{border-width:16px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-justified{box-sizing:border-box;position:relative}.foogallery.fg-justified .fg-image,.foogallery.fg-justified .fg-item,.foogallery.fg-justified .fg-item-inner,.foogallery.fg-justified .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0}.fg-justified .fg-item{visibility:visible;position:absolute}.fg-justified .fg-item-inner{position:relative;width:100%;height:100%}.fg-justified .fg-thumb{position:relative;overflow:hidden}.fg-justified .fg-image{z-index:1}.fg-justified .fg-item.fg-positioned .fg-image-wrap,.fg-justified .fg-item.fg-positioned .fg-thumb{width:100%;height:100%}.fg-justified .fg-item.fg-positioned .fg-image{width:100%;height:auto;min-height:100%;top:50%;transform:translateY(-50%)}.fg-simple_portfolio{display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;align-content:center}.fg-simple_portfolio .fg-item{position:relative;flex:1;margin:10px;min-width:250px;max-width:250px}.fg-simple_portfolio .fg-item-inner{display:flex;flex-direction:column;margin:0;height:100%}.fg-simple_portfolio.fg-captions-top .fg-item-inner{flex-direction:column-reverse}.fg-simple_portfolio .fg-image{height:auto;width:100%}.fg-simple_portfolio .fg-thumb{min-width:unset;min-height:unset}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:100%;height:100%;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-simple_portfolio .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner{display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-thumb:before{display:block}.foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-simple_portfolio .fg-caption-title{text-align:left}.fg-simple_portfolio .fg-caption-desc{text-align:left}.fg-simple_portfolio.fg-dark .fg-caption,.fg-simple_portfolio.fg-light .fg-caption{color:#828282}.fg-simple_portfolio.fg-dark .fg-caption a,.fg-simple_portfolio.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-simple_portfolio.fg-dark .fg-caption a:hover,.fg-simple_portfolio.fg-light .fg-caption a:hover{border-bottom:none}.fg-simple_portfolio.fg-light .fg-caption-title,.fg-simple_portfolio.fg-light .fg-caption-title a{color:#222}.fg-simple_portfolio.fg-dark .fg-caption-title,.fg-simple_portfolio.fg-dark .fg-caption-title a{color:#fff}.fg-simple_portfolio.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-simple_portfolio.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-simple_portfolio .fg-caption{border-width:0}.fg-simple_portfolio .fg-caption-title+.fg-caption-desc{margin-top:4px}.fg-simple_portfolio.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.fg-simple_portfolio.fg-captions-top.fg-border-thin .fg-caption{border-width:4px 4px 10px 4px}.fg-simple_portfolio.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.fg-simple_portfolio.fg-border-thick .fg-caption{border-width:16px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 16px 0}.fg-simple_portfolio.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.foogallery.fg-preset.fg-polaroid .fg-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .35s,background-color .65s}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n+1){-webkit-transform:rotate(3deg);transform:rotate(3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n){-webkit-transform:rotate(-3deg);transform:rotate(-3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(3n){-webkit-transform:rotate(1deg);transform:rotate(1deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(5n){-webkit-transform:rotate(-2deg);transform:rotate(-2deg)}.foogallery.fg-preset.fg-polaroid .fg-item:hover{-webkit-transform:rotate(0);transform:rotate(0)}.foogallery.fg-preset.fg-polaroid .fg-caption{position:relative;width:auto;font-family:"Segoe Print Regular",-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}.foogallery.fg-preset.fg-polaroid .fg-caption-inner,.foogallery.fg-preset.fg-polaroid .fg-caption-title{position:relative;width:auto}.foogallery.fg-preset.fg-polaroid .fg-caption-title{text-align:center}.foogallery.fg-preset.fg-polaroid .fg-caption-desc{display:none}.foogallery.fg-light.fg-preset.fg-polaroid .fg-caption-title,.foogallery.fg-preset.fg-polaroid .fg-caption-title{color:#333}.foogallery.fg-dark.fg-preset.fg-polaroid .fg-caption-title{color:#fff}.foogallery.fg-preset.fg-polaroid .fg-caption{border-style:solid;border-color:transparent;border-width:10px}.foogallery.fg-preset.fg-polaroid .fg-caption-title+.fg-caption-desc{margin-top:4px}.foogallery.fg-preset.fg-polaroid.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thin .fg-caption{border-width:4px 4px 10px 4px}.foogallery.fg-preset.fg-polaroid.fg-border-medium .fg-caption{border-width:10px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption{border-width:16px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 16px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-image-viewer{display:block;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.fg-image-viewer.fg-left{text-align:left}.fg-image-viewer.fg-center{text-align:center}.fg-image-viewer.fg-right{text-align:right}.fiv-inner{position:relative;display:inline-block;max-width:100%;overflow:hidden;z-index:6}.fiv-inner .fiv-inner-container{position:relative;overflow:hidden;max-width:100%;border-style:solid;border-width:0;border-bottom-width:4px;z-index:5}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:active,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:hover,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:visited{position:relative;display:block;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item{position:absolute;visibility:visible;opacity:1;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item:first-of-type{position:relative}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb img{display:block;max-width:100%;height:auto;border:none;outline:0;text-decoration:none}.fg-image-viewer .fiv-inner .fiv-ctrls{display:block;text-align:center;font-size:14px;border-style:solid;line-height:34px}.fg-image-viewer .fiv-inner .fiv-ctrls:after{content:'';display:block;clear:both}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count{display:inline-block;font-weight:400;margin:0}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;min-width:80px;position:relative;overflow:hidden;transition:background-color .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{display:block;position:absolute;font-size:24px;line-height:30px;top:0;left:0;width:100%;transform:translateY(0);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover:before{transform:translateY(-100%)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev span{display:block;width:100%;transform:translateY(100%);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover span{transform:translateY(0)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{float:left}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{content:'\2190'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next{float:right}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before{content:'\2192'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count span{margin:0 4px}/*!* Theme - Default (Light) *!*//*!* Theme - Dark *!*/.foogallery.fg-image-viewer.fg-caption-always .fg-item-inner .fg-caption{padding:0;border:none;background:#000;background:-moz-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:-webkit-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:linear-gradient(to right,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%)}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-desc{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title+.fg-caption-desc{padding:0 10px 10px 10px}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-light .fiv-inner .fiv-inner-container{background-color:#fff;color:#333;border-color:#fff}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#f2f2f2}.fg-image-viewer.fg-light .fiv-next,.fg-image-viewer.fg-light .fiv-prev{box-shadow:inset 0 0 0 1px #ddd}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-dark .fiv-inner .fiv-inner-container{background-color:#333;color:#fff;border-color:#333}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#444}.fg-image-viewer.fg-dark .fiv-next,.fg-image-viewer.fg-dark .fiv-prev{box-shadow:inset 0 0 0 1px #222}.foogallery.fg-image-viewer.fg-border-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin .fg-item-inner{border-width:0}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-inner-container{border-width:4px}.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-inner-container{border-width:10px}.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-inner-container{border-width:16px}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-ctrls{border-top-width:1px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-round-small .fiv-inner{border-radius:5px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-round-medium .fiv-inner{border-radius:10px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-round-large .fiv-inner{border-radius:15px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-full .fiv-inner,.foogallery.fg-image-viewer.fg-round-full .fiv-next,.foogallery.fg-image-viewer.fg-round-full .fiv-prev{border-radius:50%}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fg-item-inner{box-shadow:none}.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fiv-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fiv-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fiv-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-thumbnail,.foogallery.fg-thumbnail.fg-center{text-align:center}.foogallery.fg-thumbnail.fg-left{text-align:left}.foogallery.fg-thumbnail.fg-right{text-align:right}.foogallery.fg-thumbnail.fg-float-left{float:left;width:auto}.foogallery.fg-thumbnail.fg-float-right{float:right;width:auto}.foogallery.fg-thumbnail .fg-item{display:inline-block;vertical-align:top;max-width:100%}.foogallery.fg-thumbnail .fg-image{max-width:100%}.foogallery.fg-thumbnail .fg-st-hidden{display:none}
1
+ .foogallery,.foogallery *{box-sizing:border-box}.foogallery{display:block;z-index:1;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;position:relative;line-height:0;font-size:0;width:100%;max-width:100%}.foogallery .fg-item{display:inline-block;position:relative;background-color:transparent;z-index:2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.foogallery .fg-item-inner{display:block;position:relative;visibility:hidden;overflow:hidden;opacity:0;z-index:3;margin:0;border:solid 0 transparent}.foogallery .fg-item.fg-error:before{content:"";display:block;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:32px;height:32px;background-image:url(../img/icons.svg#image);background-color:transparent;background-repeat:no-repeat;background-position:center center;background-size:32px 32px}.foogallery .fg-item.fg-loaded{z-index:4}.foogallery .fg-loaded .fg-item-inner{visibility:visible;opacity:1;z-index:5}.foogallery .fg-error .fg-item-inner{pointer-events:none;cursor:default}.foogallery .fg-thumb{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:4;box-shadow:none}.foogallery .fg-thumb:focus,.foogallery .fg-thumb:hover{border:none;outline:0;text-decoration:none;box-shadow:none}.foogallery .fg-image-overlay{position:absolute;top:0;right:0;bottom:0;left:0;z-index:8;visibility:hidden;opacity:0;background-color:rgba(0,0,0,.6);color:#fff}.foogallery.fg-light-overlays .fg-image-overlay{background-color:rgba(255,255,255,.8);color:#333}.foogallery .fg-image-wrap{display:block;position:relative}.foogallery .fg-image{display:block;position:relative;border:none;outline:0;text-decoration:none;z-index:5;max-width:none;height:auto;margin:0}.foogallery .fg-loaded .fg-thumb{z-index:6}.foogallery .fg-loaded .fg-image{z-index:7}.foogallery.fg-light .fg-item-inner{background-color:#fff;color:#333;border-color:#fff}.foogallery.fg-dark .fg-item-inner{background-color:#333;color:#fff;border-color:#333}.foogallery.fg-light .fg-item.fg-error,.foogallery.fg-light .fg-item.fg-idle,.foogallery.fg-light .fg-item.fg-loading{background-color:#eee;box-shadow:inset 0 0 0 1px #ddd}.foogallery.fg-dark .fg-item.fg-error,.foogallery.fg-dark .fg-item.fg-idle,.foogallery.fg-dark .fg-item.fg-loading{background-color:#444;box-shadow:inset 0 0 0 1px #333}.foogallery.fg-border-thin .fg-item-inner{border-width:4px}.foogallery.fg-border-medium .fg-item-inner{border-width:10px}.foogallery.fg-border-thick .fg-item-inner{border-width:16px}.foogallery.fg-light.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-dark.fg-shadow-outline .fg-item-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-light.fg-shadow-small .fg-item-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-light.fg-shadow-medium .fg-item-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-light.fg-shadow-large .fg-item-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-shadow-inset-small .fg-thumb:after{display:block;content:"";position:absolute;top:0;left:0;right:0;bottom:0;z-index:7}.foogallery.fg-dark.fg-shadow-inset-small .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-small .fg-thumb:after{box-shadow:inset 0 1px 4px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-medium .fg-thumb:after{box-shadow:inset 0 1px 10px 0 rgba(0,0,0,.3)}.foogallery.fg-dark.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-light.fg-shadow-inset-large .fg-thumb:after{box-shadow:inset 0 1px 16px 0 rgba(0,0,0,.3)}.foogallery.fg-round-full.fg-shadow-inset-large .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-medium .fg-thumb:after,.foogallery.fg-round-full.fg-shadow-inset-small .fg-thumb:after{border-radius:50%}.foogallery.fg-round-small .fg-item,.foogallery.fg-round-small .fg-item-inner{border-radius:5px}.foogallery.fg-round-medium .fg-item,.foogallery.fg-round-medium .fg-item-inner{border-radius:10px}.foogallery.fg-round-large .fg-item,.foogallery.fg-round-large .fg-item-inner{border-radius:15px}.foogallery.fg-round-full .fg-item,.foogallery.fg-round-full .fg-item-inner{border-radius:50%}.foogallery .fg-loader{position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:1em;height:1em;font-size:5px;visibility:hidden;opacity:0}.foogallery .fg-loading .fg-loader{visibility:visible;opacity:1}.fg-loading-default .fg-loader{border-radius:50%;text-indent:-9999em;box-shadow:0 -2.6em 0 0 rgba(130,130,130,1),1.8em -1.8em 0 0 rgba(130,130,130,.2),2.5em 0 0 0 rgba(130,130,130,.2),1.75em 1.75em 0 0 rgba(130,130,130,.2),0 2.5em 0 0 rgba(130,130,130,.2),-1.8em 1.8em 0 0 rgba(130,130,130,.2),-2.6em 0 0 0 rgba(130,130,130,.5),-1.8em -1.8em 0 0 rgba(130,130,130,.7);-webkit-animation:loading-default 1.1s infinite steps(8,start);animation:loading-default 1.1s infinite steps(8,start)}@-webkit-keyframes loading-default{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}@keyframes loading-default{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.fg-loading-bars .fg-loader,.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{background:rgba(130,130,130,1);-webkit-animation:loading-bars 1s infinite ease-in-out;animation:loading-bars 1s infinite ease-in-out;width:1em;height:4em}.fg-loading-bars .fg-loader{color:rgba(130,130,130,1);text-indent:-9999em;font-size:4px;-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-bars .fg-loader:after,.fg-loading-bars .fg-loader:before{position:absolute;top:0;content:''}.fg-loading-bars .fg-loader:before{left:-1.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-bars .fg-loader:after{left:1.5em}@-webkit-keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}@keyframes loading-bars{0%,100%,80%{box-shadow:0 0;height:4em}40%{box-shadow:0 -2em;height:5em}}.fg-loading-trail .fg-loader{color:#828282;font-size:20px;text-indent:-9999em;overflow:hidden;border-radius:50%;-webkit-animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease;animation:loading-trail-1 1.7s infinite ease,loading-trail-2 1.7s infinite ease}@-webkit-keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@keyframes loading-trail-1{0%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}5%,95%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}10%,59%{box-shadow:0 -.83em 0 -.4em,-.087em -.825em 0 -.42em,-.173em -.812em 0 -.44em,-.256em -.789em 0 -.46em,-.297em -.775em 0 -.477em}20%{box-shadow:0 -.83em 0 -.4em,-.338em -.758em 0 -.42em,-.555em -.617em 0 -.44em,-.671em -.488em 0 -.46em,-.749em -.34em 0 -.477em}38%{box-shadow:0 -.83em 0 -.4em,-.377em -.74em 0 -.42em,-.645em -.522em 0 -.44em,-.775em -.297em 0 -.46em,-.82em -.09em 0 -.477em}100%{box-shadow:0 -.83em 0 -.4em,0 -.83em 0 -.42em,0 -.83em 0 -.44em,0 -.83em 0 -.46em,0 -.83em 0 -.477em}}@-webkit-keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-trail-2{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.fg-loading-pulse .fg-loader,.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{border-radius:50%;width:2.5em;height:2.5em;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation:loading-pulse 1.8s infinite ease-in-out;animation:loading-pulse 1.8s infinite ease-in-out}.fg-loading-pulse .fg-loader{color:#828282;font-size:4px;text-indent:-9999em;transform:translateX(-50%) translateY(-150%);-webkit-animation-delay:-.16s;animation-delay:-.16s}.fg-loading-pulse .fg-loader:after,.fg-loading-pulse .fg-loader:before{content:'';position:absolute;top:0}.fg-loading-pulse .fg-loader:before{left:-3.5em;-webkit-animation-delay:-.32s;animation-delay:-.32s}.fg-loading-pulse .fg-loader:after{left:3.5em}@-webkit-keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}@keyframes loading-pulse{0%,100%,80%{box-shadow:0 2.5em 0 -1.3em}40%{box-shadow:0 2.5em 0 0}}.fg-loading-dots .fg-loader{color:#828282;font-size:5px;border-radius:50%;text-indent:-9999em;-webkit-animation:loading-dots 1.3s infinite linear;animation:loading-dots 1.3s infinite linear}@-webkit-keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}@keyframes loading-dots{0%,100%{box-shadow:0 -3em 0 .2em,2em -2em 0 0,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 0}12.5%{box-shadow:0 -3em 0 0,2em -2em 0 .2em,3em 0 0 0,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}25%{box-shadow:0 -3em 0 -.5em,2em -2em 0 0,3em 0 0 .2em,2em 2em 0 0,0 3em 0 -1em,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}37.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 0,2em 2em 0 .2em,0 3em 0 0,-2em 2em 0 -1em,-3em 0 0 -1em,-2em -2em 0 -1em}50%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 0,0 3em 0 .2em,-2em 2em 0 0,-3em 0 0 -1em,-2em -2em 0 -1em}62.5%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 0,-2em 2em 0 .2em,-3em 0 0 0,-2em -2em 0 -1em}75%{box-shadow:0 -3em 0 -1em,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 .2em,-2em -2em 0 0}87.5%{box-shadow:0 -3em 0 0,2em -2em 0 -1em,3em 0 0 -1em,2em 2em 0 -1em,0 3em 0 -1em,-2em 2em 0 0,-3em 0 0 0,-2em -2em 0 .2em}}.fg-loading-partial .fg-loader,.fg-loading-partial .fg-loader:after{border-radius:50%;width:10em;height:10em}.fg-loading-partial .fg-loader{font-size:4px;text-indent:-9999em;border-top:1.1em solid rgba(130,130,130,.2);border-right:1.1em solid rgba(130,130,130,.2);border-bottom:1.1em solid rgba(130,130,130,.2);border-left:1.1em solid #828282;-webkit-animation:loading-partial 1.1s infinite linear;animation:loading-partial 1.1s infinite linear}@-webkit-keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}@keyframes loading-partial{0%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(0);transform:translateX(-50%) translateY(-50%) rotate(0)}100%{-webkit-transform:translateX(-50%) translateY(-50%) rotate(360deg);transform:translateX(-50%) translateY(-50%) rotate(360deg)}}.foogallery.fg-loaded-drop .fg-item,.foogallery.fg-loaded-fade-in .fg-item,.foogallery.fg-loaded-flip .fg-item,.foogallery.fg-loaded-fly .fg-item,.foogallery.fg-loaded-scale-up .fg-item,.foogallery.fg-loaded-slide-down .fg-item,.foogallery.fg-loaded-slide-left .fg-item,.foogallery.fg-loaded-slide-right .fg-item,.foogallery.fg-loaded-slide-up .fg-item,.foogallery.fg-loaded-swing-down .fg-item{transition-timing-function:ease;transition-duration:650ms;transition-property:background-color,transform}.foogallery.fg-loaded-drop .fg-item-inner,.foogallery.fg-loaded-fade-in .fg-item-inner,.foogallery.fg-loaded-flip .fg-item-inner,.foogallery.fg-loaded-fly .fg-item-inner,.foogallery.fg-loaded-scale-up .fg-item-inner,.foogallery.fg-loaded-slide-down .fg-item-inner,.foogallery.fg-loaded-slide-left .fg-item-inner,.foogallery.fg-loaded-slide-right .fg-item-inner,.foogallery.fg-loaded-slide-up .fg-item-inner,.foogallery.fg-loaded-swing-down .fg-item-inner{transition-timing-function:ease;transition-duration:650ms}.foogallery.fg-loaded-drop .fg-item.fg-loaded,.foogallery.fg-loaded-flip .fg-item.fg-loaded,.foogallery.fg-loaded-fly .fg-item.fg-loaded,.foogallery.fg-loaded-swing-down .fg-item.fg-loaded{perspective:1300px}.foogallery.fg-loaded-fade-in .fg-item-inner{transition-property:visibility,opacity}.foogallery .fg-caption{visibility:hidden;opacity:0;background-color:rgba(0,0,0,.6);color:#fff;position:absolute;z-index:8;width:100%;max-height:100%;overflow:hidden;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:13px;font-weight:400;line-height:1.3;border:none;text-align:center;cursor:pointer;margin:0}.foogallery .fg-caption a{text-decoration:none;color:#fff;border-bottom:1px solid #fff}.foogallery.fg-light-overlays .fg-caption{background-color:rgba(255,255,255,.8);color:#333}.foogallery.fg-light-overlays .fg-caption a{color:#333;border-bottom-color:#333}.foogallery .fg-caption a:hover{border-bottom:none}.foogallery .fg-caption-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:16px;font-weight:400;padding:5px}.foogallery .fg-caption-desc{padding:5px}.foogallery .fg-caption-title+.fg-caption-desc{padding-top:0}.foogallery.fg-caption-always .fg-caption .fg-caption-inner:before{display:none}.foogallery.fg-caption-always .fg-item.fg-loaded .fg-caption{left:0;bottom:0;transition-timing-function:ease;transition-duration:.3s;transition-property:visibility,opacity;visibility:visible;opacity:1;text-align:left}.foogallery.fg-caption-hover .fg-caption .fg-caption-inner{width:100%;max-height:100%;position:absolute;top:50%;left:0;transform:translateY(-50%)}.foogallery.fg-caption-hover .fg-item.fg-loaded .fg-image-overlay{display:none}.foogallery .fg-image-overlay:before{content:"";display:block;position:absolute;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);width:32px;height:32px;background-size:32px 32px;background-position:center center;background-repeat:no-repeat}.foogallery .fg-caption-inner:before{content:"";display:none;position:relative;width:32px;height:32px;margin:10px 0 5px 0;background-size:32px 32px;vertical-align:middle;background-position:center center;background-repeat:no-repeat}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-tint .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-video-1 .fg-caption-inner:before,.foogallery.fg-video-2 .fg-caption-inner:before,.foogallery.fg-video-3 .fg-caption-inner:before,.foogallery.fg-video-4 .fg-caption-inner:before,.foogallery.fg-video-default .fg-caption-inner:before{display:inline-block}.foogallery.fg-hover-circle-plus .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-external .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-eye .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-plus .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-tint .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-zoom .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-zoom2 .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-zoom3 .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-video-1 .fg-type-video .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-video-2 .fg-type-video .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-video-3 .fg-type-video .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-video-4 .fg-type-video .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-video-default .fg-type-video .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-video-sticky .fg-type-video.fg-loaded .fg-item-inner .fg-image-overlay{background-color:transparent;visibility:visible;opacity:1}.foogallery.fg-video-sticky .fg-type-video .fg-caption-inner:before{display:none}.foogallery.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-hover-zoom .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom-light)}.foogallery.fg-light-overlays.fg-hover-zoom .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-zoom .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom-dark)}.foogallery.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-hover-zoom2 .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom2-light)}.foogallery.fg-light-overlays.fg-hover-zoom2 .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-zoom2 .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom2-dark)}.foogallery.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-hover-zoom3 .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom3-light)}.foogallery.fg-light-overlays.fg-hover-zoom3 .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-zoom3 .fg-image-overlay:before{background-image:url(../img/icons.svg#zoom3-dark)}.foogallery.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-hover-plus .fg-image-overlay:before{background-image:url(../img/icons.svg#plus-light)}.foogallery.fg-light-overlays.fg-hover-plus .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-plus .fg-image-overlay:before{background-image:url(../img/icons.svg#plus-dark)}.foogallery.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-hover-circle-plus .fg-image-overlay:before{background-image:url(../img/icons.svg#circle-plus-light)}.foogallery.fg-light-overlays.fg-hover-circle-plus .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-circle-plus .fg-image-overlay:before{background-image:url(../img/icons.svg#circle-plus-dark)}.foogallery.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-hover-eye .fg-image-overlay:before{background-image:url(../img/icons.svg#eye-light)}.foogallery.fg-light-overlays.fg-hover-eye .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-eye .fg-image-overlay:before{background-image:url(../img/icons.svg#eye-dark)}.foogallery.fg-hover-external .fg-caption-inner:before,.foogallery.fg-hover-external .fg-image-overlay:before{background-image:url(../img/icons.svg#external-light)}.foogallery.fg-light-overlays.fg-hover-external .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-hover-external .fg-image-overlay:before{background-image:url(../img/icons.svg#external-dark)}.foogallery.fg-video-default .fg-type-video .fg-caption-inner:before,.foogallery.fg-video-default .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-default-light)}.foogallery.fg-light-overlays.fg-video-default .fg-type-video .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-video-default .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-default-dark)}.foogallery.fg-video-1 .fg-type-video .fg-caption-inner:before,.foogallery.fg-video-1 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-1-light)}.foogallery.fg-light-overlays.fg-video-1 .fg-type-video .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-video-1 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-1-dark)}.foogallery.fg-video-2 .fg-type-video .fg-caption-inner:before,.foogallery.fg-video-2 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-2-light)}.foogallery.fg-light-overlays.fg-video-2 .fg-type-video .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-video-2 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-2-dark)}.foogallery.fg-video-3 .fg-type-video .fg-caption-inner:before,.foogallery.fg-video-3 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-3-light)}.foogallery.fg-light-overlays.fg-video-3 .fg-type-video .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-video-3 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-3-dark)}.foogallery.fg-video-4 .fg-type-video .fg-caption-inner:before,.foogallery.fg-video-4 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-4-light)}.foogallery.fg-light-overlays.fg-video-4 .fg-type-video .fg-caption-inner:before,.foogallery.fg-light-overlays.fg-video-4 .fg-type-video .fg-image-overlay:before{background-image:url(../img/icons.svg#video-4-dark)}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-caption-hover.fg-hover-fade .fg-caption,.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-caption-hover.fg-hover-instant .fg-caption,.foogallery.fg-caption-hover.fg-hover-push .fg-caption,.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-down .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-caption,.foogallery.fg-hover-colorize .fg-image,.foogallery.fg-hover-colorize .fg-image-overlay,.foogallery.fg-hover-fade .fg-image-overlay,.foogallery.fg-hover-grayscale .fg-image,.foogallery.fg-hover-grayscale .fg-image-overlay,.foogallery.fg-hover-instant .fg-image-overlay,.foogallery.fg-hover-push .fg-thumb,.foogallery.fg-hover-scale .fg-image-overlay,.foogallery.fg-hover-scale .fg-item,.foogallery.fg-hover-slide-down .fg-image-overlay,.foogallery.fg-hover-slide-left .fg-image-overlay,.foogallery.fg-hover-slide-right .fg-image-overlay,.foogallery.fg-hover-slide-up .fg-image-overlay{transition-timing-function:ease;transition-duration:.3s;backface-visibility:hidden}.foogallery.fg-hover-colorize .fg-image{filter:url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'saturate\' values=\'0\'/></filter></svg>#grayscale");filter:gray;-webkit-filter:grayscale(100%);-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image{-webkit-filter:none;filter:none}.foogallery.fg-caption-hover.fg-hover-colorize .fg-caption,.foogallery.fg-hover-colorize .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-colorize .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-colorize .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-fade .fg-loaded .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-hover-grayscale .fg-image{-webkit-filter:none;filter:none;-webkit-transition-property:-webkit-filter;transition-property:filter}.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image{-webkit-filter:grayscale(1);-webkit-filter:grayscale(100%);filter:grayscale(100%);filter:gray;opacity:1}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-caption,.foogallery.fg-hover-grayscale .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-grayscale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-grayscale .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:none}.foogallery.fg-caption-hover.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-instant .fg-loaded .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-image-overlay{display:block;left:0;top:0;bottom:0;transform:translateX(100%);visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-caption,.foogallery.fg-hover-push .fg-loaded .fg-thumb{transition-property:transform}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-caption{transform:translateY(0)}.foogallery.fg-caption-hover.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb,.foogallery.fg-hover-push .fg-loaded .fg-item-inner:hover .fg-thumb{transform:translateX(-100%)}.foogallery.fg-hover-scale .fg-item{transition-property:transform;z-index:4}.foogallery.fg-hover-scale .fg-item:hover{transform:scale(1.048);z-index:10}.foogallery.fg-caption-hover.fg-hover-scale .fg-caption,.foogallery.fg-hover-scale .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:visibility,opacity,background-color}.foogallery.fg-caption-hover.fg-hover-scale .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-scale .fg-item-inner:hover .fg-image-overlay{visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-image-overlay,.foogallery.fg-hover-slide-left .fg-loaded .fg-image-overlay,.foogallery.fg-hover-slide-right .fg-loaded .fg-image-overlay,.foogallery.fg-hover-slide-up .fg-loaded .fg-image-overlay{display:block;left:0;top:0;bottom:0;transition-property:transform,background-color,opacity,visibility;visibility:visible;opacity:1}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-slide-left .fg-loaded .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-slide-right .fg-loaded .fg-item-inner:hover .fg-image-overlay,.foogallery.fg-hover-slide-up .fg-loaded .fg-item-inner:hover .fg-image-overlay{transform:translateY(0) translateX(0)}.foogallery.fg-caption-hover.fg-hover-slide-up .fg-loaded .fg-caption,.foogallery.fg-hover-slide-up .fg-loaded .fg-image-overlay{transform:translateY(100%)}.foogallery.fg-caption-hover.fg-hover-slide-down .fg-loaded .fg-caption,.foogallery.fg-hover-slide-down .fg-loaded .fg-image-overlay{transform:translateY(-100%)}.foogallery.fg-caption-hover.fg-hover-slide-left .fg-loaded .fg-caption,.foogallery.fg-hover-slide-left .fg-loaded .fg-image-overlay{transform:translateX(100%)}.foogallery.fg-caption-hover.fg-hover-slide-right .fg-loaded .fg-caption,.foogallery.fg-hover-slide-right .fg-loaded .fg-image-overlay{transform:translateX(-100%)}.fg-paging-container,.fg-paging-container *,.fg-paging-container :after,.fg-paging-container :before{box-sizing:border-box}.fg-paging-container{display:block;padding:15px;text-align:center;font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fg-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.fg-paging-container .fg-dot-item,.fg-paging-container .fg-dots{display:inline-block;margin:0;padding:0;outline:0;list-style:none}.fg-paging-container .fg-dot-item .fg-dot-link{display:inline-block;margin:3px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;user-select:none;background-image:none;text-decoration:none;border:1px solid transparent;position:relative;border-radius:50%;padding:0;font-size:0;outline:0;color:transparent;box-shadow:none}.fg-paging-container .fg-dot-item .fg-dot-link:before{content:"";background-color:transparent;border:1px solid transparent;display:block;border-radius:50%;width:9px;height:9px;padding:0;margin:2px}.fg-paging-container .fg-dot-item .fg-dot-link:active,.fg-paging-container .fg-dot-item .fg-dot-link:focus,.fg-paging-container .fg-dot-item .fg-dot-link:hover{text-decoration:none;box-shadow:none;outline:0}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container .fg-dot-item.fg-selected .fg-dot-link{cursor:not-allowed;pointer-events:none}.fg-paging-container .fg-dot-item.fg-disabled .fg-dot-link{cursor:not-allowed;pointer-events:none;outline:0}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link{background-color:#eee;border-color:#9d9d9d}.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link{border-color:#888}.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-light .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-light .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#666;border-color:#888}.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-light .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#eee;border-color:#9d9d9d;opacity:.5}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:before{transition-timing-function:ease-out;transition-duration:.3s;transition-property:color,border-color,background-color}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link{background-color:#666;border-color:#333}.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link{border-color:#444}.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:focus:before,.fg-paging-container.fg-dark .fg-dot-item .fg-dot-link:hover:before,.fg-paging-container.fg-dark .fg-dot-item.fg-selected .fg-dot-link:before{background-color:#333;border-color:#444}.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:focus,.fg-paging-container.fg-dark .fg-dot-item.fg-disabled .fg-dot-link:hover{background-color:#666;border-color:#333;opacity:.5}.fg-default:after{content:'';display:block;clear:both}.fg-default .fg-item,.fg-default .fg-item-inner,.fg-default .fg-thumb{display:inline-block;vertical-align:top;max-width:100%}.fg-default .fg-image{border-radius:0;display:block;max-width:100%;height:auto;margin:0;padding:0}.fg-default .fg-image{vertical-align:top}.fg-default.fg-left{text-align:left}.fg-default.fg-center{text-align:center}.fg-default.fg-right{text-align:right}.fg-default.fg-gutter-5{padding-left:5px;margin-bottom:-5px}.fg-default.fg-gutter-5 .fg-item{margin-right:5px;margin-bottom:5px}.fg-default.fg-gutter-10{padding-left:10px;margin-bottom:-10px}.fg-default.fg-gutter-10 .fg-item{margin-right:10px;margin-bottom:10px}.fg-default.fg-gutter-15{padding-left:15px;margin-bottom:-15px}.fg-default.fg-gutter-15 .fg-item{margin-right:15px;margin-bottom:15px}.fg-default.fg-gutter-20{padding-left:20px;margin-bottom:-20px}.fg-default.fg-gutter-20 .fg-item{margin-right:20px;margin-bottom:20px}.fg-default.fg-gutter-25{padding-left:25px;margin-bottom:-25px}.fg-default.fg-gutter-25 .fg-item{margin-right:25px;margin-bottom:25px}.fg-masonry *{box-sizing:border-box}.foogallery.fg-masonry.fg-center{margin:0 auto}.fg-masonry .fg-thumb{display:block}.fg-masonry.fg-masonry-fixed .fg-thumb{display:inline-block}.fg-masonry.fg-masonry-fixed .fg-image{max-width:100%}.fg-masonry .fg-column-width{display:inline-block;visibility:hidden;height:0;border:solid 0 transparent}.fg-masonry.fg-masonry-2col .fg-image,.fg-masonry.fg-masonry-3col .fg-image,.fg-masonry.fg-masonry-4col .fg-image,.fg-masonry.fg-masonry-5col .fg-image{width:100%;height:auto;max-width:100%}.fg-masonry .fg-item{line-height:0;font-size:0}.fg-masonry.fg-masonry-fixed .fg-column-width,.fg-masonry.fg-masonry-fixed .fg-item{max-width:100%}.fg-masonry.fg-masonry-2col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-2col .fg-column-width{width:49%}.fg-masonry.fg-masonry-2col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-3col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-3col .fg-column-width{width:32%}.fg-masonry.fg-masonry-3col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-4col .fg-item{margin-bottom:1%;width:24%}.fg-masonry.fg-masonry-4col .fg-column-width{width:24%}.fg-masonry.fg-masonry-4col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item{margin-bottom:0;width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width{width:25%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item{margin-bottom:3%;width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width{width:22%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width{width:3%}.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:19%}.fg-masonry.fg-masonry-5col .fg-column-width{width:19%}.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:20%}.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:17%}.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}@media screen and (max-width:720px){.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:32%}.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:32%}.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:33%}.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:30%}.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:480px){.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:49%}.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:49%}.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:1%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:50%}.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:47%}.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:3%}}@media screen and (max-width:320px){.fg-masonry.fg-masonry-2col .fg-item,.fg-masonry.fg-masonry-3col .fg-item,.fg-masonry.fg-masonry-4col .fg-item,.fg-masonry.fg-masonry-5col .fg-item{margin-bottom:1%;width:100%}.fg-masonry.fg-masonry-2col .fg-column-width,.fg-masonry.fg-masonry-3col .fg-column-width,.fg-masonry.fg-masonry-4col .fg-column-width,.fg-masonry.fg-masonry-5col .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col .fg-gutter-width,.fg-masonry.fg-masonry-3col .fg-gutter-width,.fg-masonry.fg-masonry-4col .fg-gutter-width,.fg-masonry.fg-masonry-5col .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-item{margin-bottom:0;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-none .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-none .fg-gutter-width{width:0}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-item,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-item{margin-bottom:3%;width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-column-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-column-width{width:100%}.fg-masonry.fg-masonry-2col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-3col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-4col.fg-gutter-large .fg-gutter-width,.fg-masonry.fg-masonry-5col.fg-gutter-large .fg-gutter-width{width:0}}.foogallery.fg-border-thin .fg-column-width{border-width:4px}.foogallery.fg-border-medium .fg-column-width{border-width:10px}.foogallery.fg-border-thick .fg-column-width{border-width:16px}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner{display:block;position:relative;max-height:none;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-masonry.fg-captions-bottom .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-hover .fg-item-inner .fg-image-overlay{display:block}.foogallery.fg-masonry.fg-captions-bottom.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-masonry.fg-captions-bottom .fg-caption-desc,.fg-masonry.fg-captions-bottom .fg-caption-title{text-align:left}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption,.fg-masonry.fg-captions-bottom.fg-light .fg-caption{color:#828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption a:hover,.fg-masonry.fg-captions-bottom.fg-light .fg-caption a:hover{border-bottom:none}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{color:#222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title,.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{color:#fff}.fg-masonry.fg-captions-bottom.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-masonry.fg-captions-bottom.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-masonry.fg-captions-bottom .fg-caption{border-width:10px}.fg-masonry.fg-captions-bottom .fg-caption-title+.fg-caption-desc{margin-top:4px}.fg-masonry.fg-captions-bottom.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.fg-masonry.fg-captions-bottom.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption{border-width:16px 0 0 0}.fg-masonry.fg-captions-bottom.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-justified{box-sizing:border-box;position:relative}.foogallery.fg-justified .fg-image,.foogallery.fg-justified .fg-item,.foogallery.fg-justified .fg-item-inner,.foogallery.fg-justified .fg-thumb{box-sizing:border-box;display:block;margin:0;padding:0}.fg-justified .fg-item{visibility:visible;position:absolute}.fg-justified .fg-item-inner{position:relative;width:100%;height:100%}.fg-justified .fg-thumb{position:relative;overflow:hidden}.fg-justified .fg-image{z-index:1}.fg-justified .fg-item.fg-positioned .fg-image-wrap,.fg-justified .fg-item.fg-positioned .fg-thumb{width:100%;height:100%}.fg-justified .fg-item.fg-positioned .fg-image{width:100%;height:auto;min-height:100%;top:50%;transform:translateY(-50%)}.fg-simple_portfolio{display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;align-content:center}.fg-simple_portfolio .fg-item{position:relative;flex:1;margin:10px;min-width:250px;max-width:250px}.fg-simple_portfolio .fg-item-inner{display:flex;flex-direction:column;margin:0;height:100%}.fg-simple_portfolio.fg-captions-top .fg-item-inner{flex-direction:column-reverse}.fg-simple_portfolio .fg-image{height:auto;width:100%}.fg-simple_portfolio .fg-thumb{min-width:auto;min-height:auto}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption{visibility:visible;opacity:1;font-size:13px;position:relative;display:block;top:auto;bottom:auto;left:auto;right:auto;width:100%;height:100%;text-transform:none;transform:none;transition:none;background-color:transparent;border-style:solid;border-color:transparent}.foogallery.fg-simple_portfolio .fg-item-inner:hover .fg-caption{transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner{display:block;top:auto;bottom:auto;left:auto;right:auto;width:auto;height:auto;border:none;transform:none;transition:none}.foogallery.fg-simple_portfolio .fg-item-inner .fg-caption-inner:before{display:none}.foogallery.fg-simple_portfolio.fg-caption-hover .fg-item-inner .fg-image-overlay{display:block}.foogallery.fg-simple_portfolio.fg-caption-always .fg-item-inner:hover .fg-caption{visibility:visible;opacity:1}.fg-simple_portfolio .fg-caption-title{text-align:left}.fg-simple_portfolio .fg-caption-desc{text-align:left}.fg-simple_portfolio.fg-dark .fg-caption,.fg-simple_portfolio.fg-light .fg-caption{color:#828282}.fg-simple_portfolio.fg-dark .fg-caption a,.fg-simple_portfolio.fg-light .fg-caption a{color:#828282;border-bottom:1px solid #828282}.fg-simple_portfolio.fg-dark .fg-caption a:hover,.fg-simple_portfolio.fg-light .fg-caption a:hover{border-bottom:none}.fg-simple_portfolio.fg-light .fg-caption-title,.fg-simple_portfolio.fg-light .fg-caption-title a{color:#222}.fg-simple_portfolio.fg-dark .fg-caption-title,.fg-simple_portfolio.fg-dark .fg-caption-title a{color:#fff}.fg-simple_portfolio.fg-light .fg-caption-title a{border-bottom:1px solid #222}.fg-simple_portfolio.fg-dark .fg-caption-title a{border-bottom:1px solid #fff}.fg-simple_portfolio .fg-caption{border-width:0}.fg-simple_portfolio .fg-caption-title+.fg-caption-desc{margin-top:4px}.fg-simple_portfolio.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.fg-simple_portfolio.fg-captions-top.fg-border-thin .fg-caption{border-width:4px 4px 10px 4px}.fg-simple_portfolio.fg-border-medium .fg-caption{border-width:10px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.fg-simple_portfolio.fg-border-thick .fg-caption{border-width:16px 0 0 0}.fg-simple_portfolio.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 16px 0}.fg-simple_portfolio.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.foogallery.fg-preset.fg-polaroid .fg-item{-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .35s,background-color .65s}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n+1){-webkit-transform:rotate(3deg);transform:rotate(3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(2n){-webkit-transform:rotate(-3deg);transform:rotate(-3deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(3n){-webkit-transform:rotate(1deg);transform:rotate(1deg)}.foogallery.fg-preset.fg-polaroid .fg-item:nth-child(5n){-webkit-transform:rotate(-2deg);transform:rotate(-2deg)}.foogallery.fg-preset.fg-polaroid .fg-item:hover{-webkit-transform:rotate(0);transform:rotate(0)}.foogallery.fg-preset.fg-polaroid .fg-caption{position:relative;width:auto;font-family:"Segoe Print Regular",-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif}.foogallery.fg-preset.fg-polaroid .fg-caption-inner,.foogallery.fg-preset.fg-polaroid .fg-caption-title{position:relative;width:auto}.foogallery.fg-preset.fg-polaroid .fg-caption-title{text-align:center}.foogallery.fg-preset.fg-polaroid .fg-caption-desc{display:none}.foogallery.fg-light.fg-preset.fg-polaroid .fg-caption-title,.foogallery.fg-preset.fg-polaroid .fg-caption-title{color:#333}.foogallery.fg-dark.fg-preset.fg-polaroid .fg-caption-title{color:#fff}.foogallery.fg-preset.fg-polaroid .fg-caption{border-style:solid;border-color:transparent;border-width:10px}.foogallery.fg-preset.fg-polaroid .fg-caption-title+.fg-caption-desc{margin-top:4px}.foogallery.fg-preset.fg-polaroid.fg-border-thin .fg-caption{border-width:10px 4px 4px 4px}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thin .fg-caption{border-width:4px 4px 10px 4px}.foogallery.fg-preset.fg-polaroid.fg-border-medium .fg-caption{border-width:10px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-medium .fg-caption{border-width:0 0 10px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption{border-width:16px 0 0 0}.foogallery.fg-preset.fg-polaroid.fg-captions-top.fg-border-thick .fg-caption{border-width:0 0 16px 0}.foogallery.fg-preset.fg-polaroid.fg-border-thick .fg-caption-title+.fg-caption-desc{margin-top:10px}.fg-image-viewer{display:block;font-family:'Open Sans','Helvetica Neue',Arial,sans-serif}.fg-image-viewer.fg-left{text-align:left}.fg-image-viewer.fg-center{text-align:center}.fg-image-viewer.fg-right{text-align:right}.fiv-inner{position:relative;display:inline-block;max-width:100%;overflow:hidden;z-index:6}.fiv-inner .fiv-inner-container{position:relative;overflow:hidden;max-width:100%;border-style:solid;border-width:0;border-bottom-width:4px;z-index:5}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:active,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:hover,.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb:visited{position:relative;display:block;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item{position:absolute;visibility:visible;opacity:1;border:none;outline:0;text-decoration:none;box-shadow:none;max-width:100%}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item:first-of-type{position:relative}.fg-image-viewer .fiv-inner .fiv-inner-container .fg-item .fg-thumb img{display:block;max-width:100%;height:auto;border:none;outline:0;text-decoration:none}.fg-image-viewer .fiv-inner .fiv-ctrls{display:block;text-align:center;font-size:14px;border-style:solid;line-height:34px}.fg-image-viewer .fiv-inner .fiv-ctrls:after{content:'';display:block;clear:both}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count{display:inline-block;font-weight:400;margin:0}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;min-width:80px;position:relative;overflow:hidden;transition:background-color .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{display:block;position:absolute;font-size:24px;line-height:30px;top:0;left:0;width:100%;transform:translateY(0);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover:before,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover:before{transform:translateY(-100%)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev span{display:block;width:100%;transform:translateY(100%);transition:transform .3s}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:hover span,.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:hover span{transform:translateY(0)}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev{float:left}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-prev:before{content:'\2190'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next{float:right}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-next:before{content:'\2192'}.fg-image-viewer .fiv-inner .fiv-ctrls .fiv-count span{margin:0 4px}/*!* Theme - Default (Light) *!*//*!* Theme - Dark *!*/.foogallery.fg-image-viewer.fg-caption-always .fg-item-inner .fg-caption{padding:0;border:none;background:#000;background:-moz-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:-webkit-linear-gradient(left,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%);background:linear-gradient(to right,rgba(0,0,0,.8) 0,rgba(0,0,0,.8) 60%,rgba(0,0,0,0) 100%)}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-desc{padding:10px 10px 10px 10px}.foogallery.fg-image-viewer.fg-caption-always .fg-caption-title+.fg-caption-desc{padding:0 10px 10px 10px}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-light .fiv-inner .fiv-inner-container{background-color:#fff;color:#333;border-color:#fff}.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-light .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#f2f2f2}.fg-image-viewer.fg-light .fiv-next,.fg-image-viewer.fg-light .fiv-prev{box-shadow:inset 0 0 0 1px #ddd}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-count,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev,.fg-image-viewer.fg-dark .fiv-inner .fiv-inner-container{background-color:#333;color:#fff;border-color:#333}.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-next:hover,.fg-image-viewer.fg-dark .fiv-inner .fiv-ctrls .fiv-prev:hover{background-color:#444}.fg-image-viewer.fg-dark .fiv-next,.fg-image-viewer.fg-dark .fiv-prev{box-shadow:inset 0 0 0 1px #222}.foogallery.fg-image-viewer.fg-border-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin .fg-item-inner{border-width:0}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-inner-container{border-width:4px}.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-inner-container{border-width:10px}.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-inner-container{border-width:16px}.foogallery.fg-image-viewer .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-medium .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thick .fiv-ctrls,.foogallery.fg-image-viewer.fg-border-thin .fiv-ctrls{border-top-width:1px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-round-small .fiv-inner{border-radius:5px}.foogallery.fg-image-viewer.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-round-small .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-small .fiv-prev,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-small .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-round-medium .fiv-inner{border-radius:10px}.foogallery.fg-image-viewer.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-round-medium .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-medium .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-medium .fiv-prev,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-medium .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-round-large .fiv-inner{border-radius:15px}.foogallery.fg-image-viewer.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-round-large .fg-item-inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.foogallery.fg-image-viewer.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thin.fg-round-large .fiv-prev{border-radius:11px}.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-medium.fg-round-large .fiv-prev{border-radius:5px}.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fg-item-inner,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-next,.foogallery.fg-image-viewer.fg-border-thick.fg-round-large .fiv-prev{border-radius:3px}.foogallery.fg-image-viewer.fg-round-full .fiv-inner,.foogallery.fg-image-viewer.fg-round-full .fiv-next,.foogallery.fg-image-viewer.fg-round-full .fiv-prev{border-radius:50%}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fg-item-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fg-item-inner{box-shadow:none}.foogallery.fg-image-viewer.fg-light.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #ddd}.foogallery.fg-image-viewer.fg-dark.fg-shadow-outline .fiv-inner{box-shadow:0 0 0 1px #222}.foogallery.fg-image-viewer.fg-dark.fg-shadow-small .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-small .fiv-inner{box-shadow:0 1px 4px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-medium .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-medium .fiv-inner{box-shadow:0 1px 10px 0 rgba(0,0,0,.5)}.foogallery.fg-image-viewer.fg-dark.fg-shadow-large .fiv-inner,.foogallery.fg-image-viewer.fg-light.fg-shadow-large .fiv-inner{box-shadow:0 1px 16px 0 rgba(0,0,0,.5)}.foogallery.fg-thumbnail,.foogallery.fg-thumbnail.fg-center{text-align:center}.foogallery.fg-thumbnail.fg-left{text-align:left}.foogallery.fg-thumbnail.fg-right{text-align:right}.foogallery.fg-thumbnail.fg-float-left{float:left;width:auto}.foogallery.fg-thumbnail.fg-float-right{float:right;width:auto}.foogallery.fg-thumbnail .fg-item{display:inline-block;vertical-align:top;max-width:100%}.foogallery.fg-thumbnail .fg-image{max-width:100%}.foogallery.fg-thumbnail .fg-st-hidden{display:none}
extensions/default-templates/shared/img/circle-plus.png DELETED
Binary file
extensions/default-templates/shared/img/circle-plus@2x.png DELETED
Binary file
extensions/default-templates/shared/img/circle-plus@3x.png DELETED
Binary file
extensions/default-templates/shared/img/external.png DELETED
Binary file
extensions/default-templates/shared/img/external@2x.png DELETED
Binary file
extensions/default-templates/shared/img/external@3x.png DELETED
Binary file
extensions/default-templates/shared/img/eye.png DELETED
Binary file
extensions/default-templates/shared/img/eye@2x.png DELETED
Binary file
extensions/default-templates/shared/img/eye@3x.png DELETED
Binary file
extensions/default-templates/shared/img/icons.svg ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
2
+ <style>
3
+ .icon { display: none; fill: #999; }
4
+ .icon:target { display: inline; }
5
+ .dark { fill: #333; }
6
+ .light { fill: #FFF; }
7
+ </style>
8
+ <defs>
9
+ <path id="image-def" d="M15 1h-14c-0.55 0-1 0.45-1 1v12c0 0.55 0.45 1 1 1h14c0.55 0 1-0.45 1-1v-12c0-0.55-0.45-1-1-1zM11.5 3c0.828 0 1.5 0.672 1.5 1.5s-0.672 1.5-1.5 1.5-1.5-0.672-1.5-1.5 0.672-1.5 1.5-1.5zM14 13h-12v-2l3.5-6 4 5h1l3.5-3v6z"/>
10
+ <path id="zoom-def" d="M15.56 15.56c-0.587 0.587-1.538 0.587-2.125 0l-2.652-2.652c-1.090 0.699-2.379 1.116-3.771 1.116-3.872 0-7.012-3.139-7.012-7.012s3.14-7.012 7.012-7.012c3.873 0 7.012 3.139 7.012 7.012 0 1.392-0.417 2.68-1.116 3.771l2.652 2.652c0.587 0.587 0.587 1.538 0 2.125zM7.012 2.003c-2.766 0-5.009 2.243-5.009 5.009s2.243 5.009 5.009 5.009c2.766 0 5.009-2.242 5.009-5.009s-2.242-5.009-5.009-5.009zM8.014 10.017h-2.003v-2.003h-2.003v-2.003h2.003v-2.003h2.003v2.003h2.003v2.003h-2.003v2.003z"/>
11
+ <path id="zoom2-def" d="M15.56 15.56c-0.587 0.587-1.538 0.587-2.125 0l-2.652-2.652c-1.090 0.699-2.379 1.116-3.771 1.116-3.872 0-7.012-3.139-7.012-7.012s3.14-7.012 7.012-7.012c3.873 0 7.012 3.139 7.012 7.012 0 1.391-0.417 2.68-1.116 3.771l2.652 2.652c0.587 0.587 0.587 1.538 0 2.125zM7.012 2.003c-2.766 0-5.009 2.242-5.009 5.009s2.243 5.009 5.009 5.009c2.766 0 5.009-2.242 5.009-5.009s-2.242-5.009-5.009-5.009z"/>
12
+ <g id="zoom3-def">
13
+ <path d="M8.667 7.333h-1.333v-1.333c0-0.184-0.149-0.333-0.333-0.333s-0.333 0.149-0.333 0.333v1.333h-1.333c-0.184 0-0.333 0.149-0.333 0.333s0.149 0.333 0.333 0.333h1.333v1.333c0 0.184 0.149 0.333 0.333 0.333s0.333-0.149 0.333-0.333v-1.333h1.333c0.184 0 0.333-0.149 0.333-0.333s-0.149-0.333-0.333-0.333z"/>
14
+ <path d="M12.288 9.98l-0.857-0.858c0.151-0.459 0.236-0.947 0.236-1.455 0-2.573-2.094-4.667-4.667-4.667s-4.667 2.094-4.667 4.667 2.094 4.667 4.667 4.667c0.509 0 0.997-0.085 1.456-0.236l1.549 1.547 0.043 0.037c0.401 0.337 0.899 0.523 1.403 0.523 1.151 0 2.087-0.936 2.087-2.087 0-0.56-0.219-1.085-0.616-1.479l-0.633-0.657zM3.667 7.667c0-1.838 1.495-3.333 3.333-3.333s3.333 1.495 3.333 3.333-1.495 3.333-3.333 3.333-3.333-1.495-3.333-3.333z"/>
15
+ </g>
16
+ <path id="circle-plus-def" d="M8 0c-4.418 0-8 3.582-8 8s3.582 8 8 8 8-3.582 8-8-3.582-8-8-8zM9 9v4h-2v-4h-4v-2h4v-4h2v4h4v2h-4z"/>
17
+ <path id="plus-def" d="M15.5 6h-5.5v-5.5c0-0.276-0.224-0.5-0.5-0.5h-3c-0.276 0-0.5 0.224-0.5 0.5v5.5h-5.5c-0.276 0-0.5 0.224-0.5 0.5v3c0 0.276 0.224 0.5 0.5 0.5h5.5v5.5c0 0.276 0.224 0.5 0.5 0.5h3c0.276 0 0.5-0.224 0.5-0.5v-5.5h5.5c0.276 0 0.5-0.224 0.5-0.5v-3c0-0.276-0.224-0.5-0.5-0.5z"/>
18
+ <path id="eye-def" d="M5.998 8c0 1.104 0.896 2 2 2s2-0.896 2-2v-0.017c-0.214 0.217-0.507 0.35-0.833 0.35-0.644 0-1.167-0.523-1.167-1.167 0-0.463 0.273-0.867 0.663-1.053-0.207-0.073-0.43-0.113-0.663-0.113-1.103 0-2 0.897-2 2zM15.552 6.863c-1.24-1.577-4.26-4.197-7.55-4.197-3.293 0-6.316 2.62-7.557 4.197-0.28 0.36-0.433 0.75-0.443 1.137 0.010 0.387 0.163 0.777 0.443 1.137 1.24 1.577 4.26 4.197 7.553 4.197s6.313-2.62 7.553-4.197c0.283-0.36 0.437-0.75 0.447-1.137-0.010-0.387-0.163-0.777-0.447-1.137zM7.998 11.333c-1.84 0-3.333-1.493-3.333-3.333s1.493-3.333 3.333-3.333 3.333 1.493 3.333 3.333c-0 1.84-1.493 3.333-3.333 3.333z"/>
19
+ <path id="external-def" d="M2 2v12h12v-4h2v5c0 0.552-0.448 1-1 1h-14c-0.552 0-1-0.448-1-1v-14c0-0.552 0.448-1 1-1h5v2h-4zM8 0h7c0.552 0 1 0.448 1 1v7l-3-3l-6 6l-2-2l6-6z"/>
20
+ <path id="video-default-def" d="M0 8a8 8 0 0 0 16 0a8 8 0 0 0-16 0M6 5l5 3-5 3z" fill-rule="evenodd"/>
21
+ <path id="video-1-def" d="M3 2l10 6-10 6z"/>
22
+ <path id="video-2-def" d="M0 8C0 2 0 2 8 2C16 2 16 2 16 8C16 14 16 14 8 14C0 14 0 14 0 8zM6.5 5.5l4 2.5-4 2.5z" fill-rule="evenodd"/>
23
+ <path id="video-3-def" d="M0 8a8 8 0 0 0 16 0a8 8 0 0 0-16 0M1.5 8a6.5 6.5 0 0 0 13 0a6.5 6.5 0 0 0-13 0M6 5l5 3-5 3z" fill-rule="evenodd"/>
24
+ <path id="video-4-def" d="M0 1c0-0.552 0.448-1 1-1h14c0.552 0 1 0.448 1 1v14c0 0.552-0.448 1-1 1h-14c-0.552 0-1-0.448-1-1zM6 5l5 3-5 3z" fill-rule="evenodd"/>
25
+ </defs>
26
+ <!-- image -->
27
+ <g id="image" class="icon">
28
+ <use xlink:href="#image-def"/>
29
+ </g>
30
+ <g id="image-light" class="icon light">
31
+ <use xlink:href="#image-def"/>
32
+ </g>
33
+ <g id="image-dark" class="icon dark">
34
+ <use xlink:href="#image-def"/>
35
+ </g>
36
+
37
+ <!-- zoom -->
38
+ <g id="zoom" class="icon">
39
+ <use xlink:href="#zoom-def"/>
40
+ </g>
41
+ <g id="zoom-light" class="icon light">
42
+ <use xlink:href="#zoom-def"/>
43
+ </g>
44
+ <g id="zoom-dark" class="icon dark">
45
+ <use xlink:href="#zoom-def"/>
46
+ </g>
47
+
48
+ <!-- zoom2 -->
49
+ <g id="zoom2" class="icon">
50
+ <use xlink:href="#zoom2-def"/>
51
+ </g>
52
+ <g id="zoom2-light" class="icon light">
53
+ <use xlink:href="#zoom2-def"/>
54
+ </g>
55
+ <g id="zoom2-dark" class="icon dark">
56
+ <use xlink:href="#zoom2-def"/>
57
+ </g>
58
+
59
+ <!-- zoom3 -->
60
+ <g id="zoom3" class="icon">
61
+ <use xlink:href="#zoom3-def"/>
62
+ </g>
63
+ <g id="zoom3-light" class="icon light">
64
+ <use xlink:href="#zoom3-def"/>
65
+ </g>
66
+ <g id="zoom3-dark" class="icon dark">
67
+ <use xlink:href="#zoom3-def"/>
68
+ </g>
69
+
70
+ <!-- circle-plus -->
71
+ <g id="circle-plus" class="icon">
72
+ <use xlink:href="#circle-plus-def"/>
73
+ </g>
74
+ <g id="circle-plus-light" class="icon light">
75
+ <use xlink:href="#circle-plus-def"/>
76
+ </g>
77
+ <g id="circle-plus-dark" class="icon dark">
78
+ <use xlink:href="#circle-plus-def"/>
79
+ </g>
80
+
81
+ <!-- plus -->
82
+ <g id="plus" class="icon">
83
+ <use xlink:href="#plus-def"/>
84
+ </g>
85
+ <g id="plus-light" class="icon light">
86
+ <use xlink:href="#plus-def"/>
87
+ </g>
88
+ <g id="plus-dark" class="icon dark">
89
+ <use xlink:href="#plus-def"/>
90
+ </g>
91
+
92
+ <!-- eye -->
93
+ <g id="eye" class="icon">
94
+ <use xlink:href="#eye-def"/>
95
+ </g>
96
+ <g id="eye-light" class="icon light">
97
+ <use xlink:href="#eye-def"/>
98
+ </g>
99
+ <g id="eye-dark" class="icon dark">
100
+ <use xlink:href="#eye-def"/>
101
+ </g>
102
+
103
+ <!-- external -->
104
+ <g id="external" class="icon">
105
+ <use xlink:href="#external-def"/>
106
+ </g>
107
+ <g id="external-light" class="icon light">
108
+ <use xlink:href="#external-def"/>
109
+ </g>
110
+ <g id="external-dark" class="icon dark">
111
+ <use xlink:href="#external-def"/>
112
+ </g>
113
+
114
+ <!-- video-default -->
115
+ <g id="video-default" class="icon">
116
+ <use xlink:href="#video-default-def"/>
117
+ </g>
118
+ <g id="video-default-light" class="icon light">
119
+ <use xlink:href="#video-default-def"/>
120
+ </g>
121
+ <g id="video-default-dark" class="icon dark">
122
+ <use xlink:href="#video-default-def"/>
123
+ </g>
124
+
125
+ <!-- video-1 -->
126
+ <g id="video-1" class="icon">
127
+ <use xlink:href="#video-1-def"/>
128
+ </g>
129
+ <g id="video-1-light" class="icon light">
130
+ <use xlink:href="#video-1-def"/>
131
+ </g>
132
+ <g id="video-1-dark" class="icon dark">
133
+ <use xlink:href="#video-1-def"/>
134
+ </g>
135
+
136
+ <!-- video-2 -->
137
+ <g id="video-2" class="icon">
138
+ <use xlink:href="#video-2-def"/>
139
+ </g>
140
+ <g id="video-2-light" class="icon light">
141
+ <use xlink:href="#video-2-def"/>
142
+ </g>
143
+ <g id="video-2-dark" class="icon dark">
144
+ <use xlink:href="#video-2-def"/>
145
+ </g>
146
+
147
+ <!-- video-3 -->
148
+ <g id="video-3" class="icon">
149
+ <use xlink:href="#video-3-def"/>
150
+ </g>
151
+ <g id="video-3-light" class="icon light">
152
+ <use xlink:href="#video-3-def"/>
153
+ </g>
154
+ <g id="video-3-dark" class="icon dark">
155
+ <use xlink:href="#video-3-def"/>
156
+ </g>
157
+
158
+ <!-- video-4 -->
159
+ <g id="video-4" class="icon">
160
+ <use xlink:href="#video-4-def"/>
161
+ </g>
162
+ <g id="video-4-light" class="icon light">
163
+ <use xlink:href="#video-4-def"/>
164
+ </g>
165
+ <g id="video-4-dark" class="icon dark">
166
+ <use xlink:href="#video-4-def"/>
167
+ </g>
168
+ </svg>
extensions/default-templates/shared/img/image.png DELETED
Binary file
extensions/default-templates/shared/img/image@2x.png DELETED
Binary file
extensions/default-templates/shared/img/image@3x.png DELETED
Binary file
extensions/default-templates/shared/img/plus.png DELETED
Binary file
extensions/default-templates/shared/img/plus@2x.png DELETED
Binary file
extensions/default-templates/shared/img/plus@3x.png DELETED
Binary file
extensions/default-templates/shared/img/video-1.png DELETED
Binary file
extensions/default-templates/shared/img/video-1@2x.png DELETED
Binary file
extensions/default-templates/shared/img/video-1@3x.png DELETED
Binary file
extensions/default-templates/shared/img/video-2.png DELETED
Binary file
extensions/default-templates/shared/img/video-2@2x.png DELETED
Binary file
extensions/default-templates/shared/img/video-2@3x.png DELETED
Binary file
extensions/default-templates/shared/img/video-3.png DELETED
Binary file
extensions/default-templates/shared/img/video-3@2x.png DELETED
Binary file
extensions/default-templates/shared/img/video-3@3x.png DELETED
Binary file
extensions/default-templates/shared/img/video-4.png DELETED
Binary file
extensions/default-templates/shared/img/video-4@2x.png DELETED
Binary file
extensions/default-templates/shared/img/video-4@3x.png DELETED
Binary file
extensions/default-templates/shared/img/video-default.png DELETED
Binary file
extensions/default-templates/shared/img/video-default@2x.png DELETED
Binary file
extensions/default-templates/shared/img/video-default@3x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom.png DELETED
Binary file
extensions/default-templates/shared/img/zoom2.png DELETED
Binary file
extensions/default-templates/shared/img/zoom2@2x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom2@3x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom3.png DELETED
Binary file
extensions/default-templates/shared/img/zoom3@2x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom3@3x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom@2x.png DELETED
Binary file
extensions/default-templates/shared/img/zoom@3x.png DELETED
Binary file
extensions/default-templates/shared/js/foogallery.js CHANGED
@@ -3,7 +3,7 @@
3
  /**
4
  * @summary A reference to the jQuery object the plugin is registered with.
5
  * @memberof FooGallery
6
- * @name $
7
  * @type {jQuery}
8
  * @description This is used internally for all jQuery operations to help work around issues where multiple jQuery libraries have been included in a single page.
9
  * @example {@caption The following shows the issue when multiple jQuery's are included in a single page.}{@lang xml}
@@ -32,6 +32,7 @@
32
  * @external "jQuery.fn"
33
  * @see {@link http://learn.jquery.com/plugins/basic-plugin-creation/|How to Create a Basic Plugin | jQuery Learning Center}
34
  */
 
35
  })(
36
  // dependencies
37
  jQuery,
@@ -58,7 +59,7 @@
58
  );
59
  /*!
60
  * FooGallery.utils - Contains common utility methods and classes used in our plugins.
61
- * @version 0.1.3
62
  * @link https://github.com/steveush/foo-utils#readme
63
  * @copyright Steve Usher 2019
64
  * @license Released under the GPL-3.0 license.
@@ -111,7 +112,7 @@
111
  * @name version
112
  * @type {string}
113
  */
114
- version: '0.1.3'
115
  };
116
 
117
  /**
@@ -207,7 +208,7 @@
207
  })(jQuery);
208
  (function ($, _){
209
  // only register methods if this version is the current version
210
- if (_.version !== '0.1.3') return;
211
 
212
  /**
213
  * @summary Contains common type checking utility methods.
@@ -561,7 +562,7 @@
561
  );
562
  (function($, _, _is){
563
  // only register methods if this version is the current version
564
- if (_.version !== '0.1.3') return;
565
 
566
  /**
567
  * @memberof FooGallery.utils
@@ -1144,7 +1145,7 @@
1144
  );
1145
  (function(_, _is){
1146
  // only register methods if this version is the current version
1147
- if (_.version !== '0.1.3') return;
1148
 
1149
  /**
1150
  * @summary Contains common url utility methods.
@@ -1170,9 +1171,13 @@
1170
  */
1171
  _.url.parts = function(url){
1172
  _a.href = url;
 
 
 
 
1173
  return {
1174
- hash: _a.hash, host: _a.host, hostname: _a.hostname, href: _a.href,
1175
- origin: _a.origin, pathname: _a.pathname, port: _a.port,
1176
  protocol: _a.protocol, search: _a.search
1177
  };
1178
  };
@@ -1207,7 +1212,7 @@
1207
  * @function param
1208
  * @param {string} search - The search string to use (usually `location.search`).
1209
  * @param {string} key - The key of the parameter.
1210
- * @param {string} [value] - The value to set for the parameter. If not provided the current value for the `key` is returned.
1211
  * @returns {?string} The value of the `key` in the given `search` string if no `value` is supplied or `null` if the `key` does not exist.
1212
  * @returns {string} A modified `search` string if a `value` is supplied.
1213
  * @example <caption>Shows how to retrieve a parameter value from a search string.</caption>{@run true}
@@ -1234,11 +1239,11 @@
1234
  var regex, match, result, param;
1235
  if (_is.undef(value)){
1236
  regex = new RegExp('[?|&]' + key + '=([^&;]+?)(&|#|;|$)'); // regex to match the key and it's value but only capture the value
1237
- match = regex.exec(search) || [,""]; // match the param otherwise return an empty string match
1238
  result = match[1].replace(/\+/g, '%20'); // replace any + character's with spaces
1239
  return _is.string(result) && !_is.empty(result) ? decodeURIComponent(result) : null; // decode the result otherwise return null
1240
  }
1241
- if (value === "" || value === null){
1242
  regex = new RegExp('^([^#]*\?)(([^#]*)&)?' + key + '(\=[^&#]*)?(&|#|$)');
1243
  result = search.replace(regex, '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4');
1244
  } else {
@@ -1279,7 +1284,7 @@
1279
  );
1280
  (function (_, _is, _fn) {
1281
  // only register methods if this version is the current version
1282
- if (_.version !== '0.1.3') return;
1283
 
1284
  /**
1285
  * @summary Contains common string utility methods.
@@ -1367,7 +1372,7 @@
1367
  return false;
1368
  var parts = target.split(/\W/);
1369
  for (var i = 0, len = parts.length; i < len; i++){
1370
- if (ignoreCase ? parts[i].toUpperCase() == word.toUpperCase() : parts[i] == word) return true;
1371
  }
1372
  return false;
1373
  };
@@ -1388,8 +1393,8 @@
1388
  * console.log( _str.endsWith( "something", "no" ) ); // => false
1389
  */
1390
  _.str.endsWith = function (target, substr) {
1391
- if (!_is.string(target) || _is.empty(target) || !_is.string(substr) || _is.empty(substr)) return target == substr;
1392
- return target.slice(target.length - substr.length) == substr;
1393
  };
1394
 
1395
  /**
@@ -1507,7 +1512,7 @@
1507
  */
1508
  _.str.startsWith = function (target, substr) {
1509
  if (_is.empty(target) || _is.empty(substr)) return false;
1510
- return target.slice(0, substr.length) == substr;
1511
  };
1512
 
1513
  /**
@@ -1594,7 +1599,7 @@
1594
  );
1595
  (function($, _, _is, _fn, _str){
1596
  // only register methods if this version is the current version
1597
- if (_.version !== '0.1.3') return;
1598
 
1599
  /**
1600
  * @summary Contains common object utility methods.
@@ -1926,7 +1931,7 @@
1926
  );
1927
  (function($, _, _is){
1928
  // only register methods if this version is the current version
1929
- if (_.version !== '0.1.3') return;
1930
 
1931
  // any methods that have dependencies but don't fall into a specific subset or namespace can be added here
1932
 
@@ -2207,7 +2212,233 @@
2207
  );
2208
  (function($, _, _is){
2209
  // only register methods if this version is the current version
2210
- if (_.version !== '0.1.3') return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2211
 
2212
  /**
2213
  * @summary Contains common utility methods and members for the CSS transition property.
@@ -2229,7 +2460,7 @@
2229
  /**
2230
  * @ignore
2231
  * @summary Performs a one time test to see if transitions are supported
2232
- * @param {Element} el - An element to test with.
2233
  * @returns {boolean} `true` if transitions are supported.
2234
  */
2235
  function(el){
@@ -2261,7 +2492,7 @@
2261
  /**
2262
  * @ignore
2263
  * @summary Performs a one time test to determine which `transitionend` event to use for the current browser.
2264
- * @param {Element} el - An element to test with.
2265
  * @returns {?string} The correct `transitionend` event for the current browser, `null` if the browser doesn't support transitions.
2266
  */
2267
  function(el){
@@ -2288,9 +2519,9 @@
2288
  if (!_is.jq($element)) return def;
2289
  // we can use jQuery.css() method to retrieve the value cross browser
2290
  var duration = $element.css('transition-duration');
2291
- if (/^([\d\.]*)+?(ms|s)$/i.test(duration)){
2292
  // if we have a valid time value
2293
- var match = duration.match(/^([\d\.]*)+?(ms|s)$/i),
2294
  value = parseFloat(match[1]),
2295
  unit = match[2].toLowerCase();
2296
  if (unit === 's'){
@@ -2324,11 +2555,12 @@
2324
  * @see {@link https://developer.mozilla.org/en/docs/Web/CSS/transition-duration|transition-duration - CSS | MDN} for more information on the `transition-duration` CSS property.
2325
  */
2326
  _.transition.start = function($element, classNameOrFunc, state, timeout){
2327
- var deferred = $.Deferred();
2328
 
2329
  $element = $element.first();
2330
 
2331
  if (_.transition.supported){
 
2332
  var safety = $element.data('transition_safety');
2333
  if (_is.hash(safety) && _is.number(safety.timer)){
2334
  clearTimeout(safety.timer);
@@ -2356,8 +2588,7 @@
2356
  });
2357
  }
2358
 
2359
- setTimeout(function(){
2360
- // This is executed inside of a 20ms timeout to allow the binding of the event handler above to actually happen before the class is toggled
2361
  if (_is.fn(classNameOrFunc)){
2362
  classNameOrFunc.apply($element.get(0), [$element]);
2363
  } else {
@@ -2367,20 +2598,21 @@
2367
  // If the browser doesn't support transitions then just resolve the deferred
2368
  deferred.resolve();
2369
  }
2370
- }, 20);
2371
 
2372
- return deferred.promise();
2373
  };
2374
 
2375
  })(
2376
  // dependencies
2377
  FooGallery.utils.$,
2378
  FooGallery.utils,
2379
- FooGallery.utils.is
 
2380
  );
2381
  (function ($, _, _is, _obj, _fn) {
2382
  // only register methods if this version is the current version
2383
- if (_.version !== '0.1.3') return;
2384
 
2385
  /**
2386
  * @summary A base class providing some helper methods for prototypal inheritance.
@@ -2517,9 +2749,9 @@
2517
  FooGallery.utils.obj,
2518
  FooGallery.utils.fn
2519
  );
2520
- (function (_, _is) {
2521
  // only register methods if this version is the current version
2522
- if (_.version !== '0.1.3') return;
2523
 
2524
  _.Event = _.Class.extend(/** @lends FooGallery.utils.Event */{
2525
  /**
@@ -2543,6 +2775,10 @@
2543
  * eventClass.trigger(event);
2544
  */
2545
  construct: function(type){
 
 
 
 
2546
  /**
2547
  * @summary The type of event.
2548
  * @memberof FooGallery.utils.Event#
@@ -2550,7 +2786,15 @@
2550
  * @type {string}
2551
  * @readonly
2552
  */
2553
- this.type = type;
 
 
 
 
 
 
 
 
2554
  /**
2555
  * @summary Whether the default action should be taken or not.
2556
  * @memberof FooGallery.utils.Event#
@@ -2559,6 +2803,14 @@
2559
  * @readonly
2560
  */
2561
  this.defaultPrevented = false;
 
 
 
 
 
 
 
 
2562
  },
2563
  /**
2564
  * @summary Informs the class that raised this event that its default action should not be taken.
@@ -2567,6 +2819,15 @@
2567
  */
2568
  preventDefault: function(){
2569
  this.defaultPrevented = true;
 
 
 
 
 
 
 
 
 
2570
  }
2571
  });
2572
 
@@ -2595,6 +2856,13 @@
2595
  this.__handlers = {};
2596
  },
2597
  /**
 
 
 
 
 
 
 
2598
  * @summary Attach an event handler function for one or more events to the class.
2599
  * @memberof FooGallery.utils.EventClass#
2600
  * @function on
@@ -2604,54 +2872,105 @@
2604
  * @returns {this}
2605
  */
2606
  on: function(events, handler, thisArg){
2607
- if (!_is.string(events) || !_is.fn(handler)) return this;
2608
- thisArg = _is.undef(thisArg) ? this : thisArg;
2609
- var self = this, handlers = self.__handlers, exists;
2610
- events.split(" ").forEach(function(type){
2611
- if (!_is.array(handlers[type])){
2612
- handlers[type] = [];
2613
- }
2614
- exists = handlers[type].some(function(h){
2615
- return h.fn === handler && h.thisArg === thisArg;
2616
- });
2617
- if (!exists){
2618
- handlers[type].push({
2619
- fn: handler,
2620
- thisArg: thisArg
2621
  });
2622
- }
2623
- });
 
 
 
 
 
 
2624
  return self;
2625
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2626
  /**
 
 
 
 
 
 
 
2627
  * @summary Remove an event handler function for one or more events from the class.
2628
  * @memberof FooGallery.utils.EventClass#
2629
  * @function off
2630
  * @param {string} events - One or more space-separated event types.
2631
  * @param {function} handler - The handler to remove.
2632
  * @param {*} [thisArg] - The value of `this` within the `handler` function.
2633
- * @returns {FooGallery.utils.EventClass}
2634
  */
2635
  off: function(events, handler, thisArg){
2636
- if (!_is.string(events)) return this;
2637
- handler = _is.fn(handler) ? handler : null;
2638
- thisArg = _is.undef(thisArg) ? this : thisArg;
2639
- var self = this, handlers = self.__handlers;
2640
- events.split(" ").forEach(function(type){
2641
- if (_is.array(handlers[type])){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2642
  if (handler != null){
2643
- handlers[type] = handlers[type].filter(function(h){
2644
- return !(h.fn === handler && h.thisArg === thisArg);
2645
- });
2646
- if (handlers[type].length === 0){
2647
- delete handlers[type];
2648
- }
2649
- } else {
2650
- delete handlers[type];
2651
  }
 
 
 
 
 
 
 
2652
  }
2653
  });
2654
- return self;
2655
  },
2656
  /**
2657
  * @summary Trigger an event on the current class.
@@ -2662,39 +2981,39 @@
2662
  * @returns {(FooGallery.utils.Event|FooGallery.utils.Event[]|null)} Returns the {@link FooGallery.utils.Event|event object} of the triggered event. If more than one event was triggered an array of {@link FooGallery.utils.Event|event objects} is returned. If no `event` was supplied or triggered `null` is returned.
2663
  */
2664
  trigger: function(event, args){
2665
- var instance = event instanceof _.Event;
2666
- if (!instance && !_is.string(event)) return null;
2667
  args = _is.array(args) ? args : [];
2668
- var self = this,
2669
- handlers = self.__handlers,
2670
- result = [],
2671
- _trigger = function(e){
2672
- result.push(e);
2673
- if (!_is.array(handlers[e.type])) return;
2674
- handlers[e.type].forEach(function (h) {
2675
- h.fn.apply(h.thisArg, [e].concat(args));
2676
- });
2677
- };
2678
-
2679
- if (instance){
2680
- _trigger(event);
2681
- } else {
2682
  event.split(" ").forEach(function(type){
2683
- _trigger(new _.Event(type));
 
2684
  });
2685
  }
2686
  return _is.empty(result) ? null : (result.length === 1 ? result[0] : result);
 
 
 
 
 
 
 
 
 
2687
  }
2688
  });
2689
 
2690
  })(
2691
  // dependencies
2692
  FooGallery.utils,
2693
- FooGallery.utils.is
 
2694
  );
2695
  (function($, _, _is){
2696
  // only register methods if this version is the current version
2697
- if (_.version !== '0.1.3') return;
2698
 
2699
  _.Bounds = _.Class.extend(/** @lends FooGallery.utils.Bounds */{
2700
  /**
@@ -2793,73 +3112,367 @@
2793
  FooGallery.utils,
2794
  FooGallery.utils.is
2795
  );
2796
- (function($, _, _is, _fn){
2797
- // only register methods if this version is the current version
2798
- if (_.version !== '0.1.3') return;
2799
 
2800
- _.Factory = _.Class.extend(/** @lends FooGallery.utils.Factory */{
2801
- /**
2802
- * @summary A factory for classes allowing them to be registered and created using a friendly name.
2803
- * @constructs
2804
- * @description This class allows other classes to register themselves for use at a later time. Depending on how you intend to use the registered classes you can also specify a load and execution order through the `priority` parameter of the {@link FooGallery.utils.Factory#register|register} method.
2805
- * @augments FooGallery.utils.Class
2806
- * @borrows FooGallery.utils.Class.extend as extend
2807
- * @borrows FooGallery.utils.Class.override as override
2808
- */
2809
- construct: function(){
2810
- /**
2811
- * @summary An object containing all registered classes.
2812
- * @memberof FooGallery.utils.Factory#
2813
- * @name registered
2814
- * @type {Object.<string, Object>}
2815
- * @readonly
2816
- * @example {@caption The following shows the structure of this object. The `<name>` placeholders would be the name the class was registered with.}
2817
- * {
2818
- * "<name>": {
2819
- * "name": <string>,
2820
- * "klass": <function>,
2821
- * "priority": <number>
2822
- * },
2823
- * "<name>": {
2824
- * "name": <string>,
2825
- * "klass": <function>,
2826
- * "priority": <number>
2827
- * },
2828
- * ...
2829
- * }
2830
- */
2831
- this.registered = {};
2832
- },
2833
- /**
2834
- * @summary Checks if the factory contains a class registered using the supplied `name`.
2835
- * @memberof FooGallery.utils.Factory#
2836
- * @function contains
2837
- * @param {string} name - The name of the class to check.
2838
- * @returns {boolean}
2839
- * @example {@run true}
2840
- * // create a new instance of the factory, this is usually exposed by the class that will be using the factory.
2841
- * var factory = new FooGallery.utils.Factory();
2842
- *
2843
- * // create a class to register
2844
- * function Test(){}
2845
- *
2846
- * // register the class with the factory with the default priority
2847
- * factory.register( "test", Test );
2848
- *
2849
- * // test if the class was registered
2850
- * console.log( factory.contains( "test" ) ); // => true
2851
- */
2852
- contains: function(name){
2853
- return !_is.undef(this.registered[name]);
2854
- },
2855
- /**
2856
- * @summary Creates new instances of all registered classes using there registered priority and the supplied arguments.
2857
- * @memberof FooGallery.utils.Factory#
2858
- * @function load
2859
- * @param {Object.<string, function>} overrides - An object containing classes to override any matching registered classes with, if no overrides are required you can pass `false` or `null`.
2860
- * @param {*} arg1 - The first argument to supply when creating new instances of all registered classes.
2861
- * @param {...*} [argN] - Any number of additional arguments to supply when creating new instances of all registered classes.
2862
- * @returns {Array.<Object>} An array containing new instances of all registered classes.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2863
  * @description The class indexes within the result array are determined by the `priority` they were registered with, the higher the `priority` the lower the index.
2864
  *
2865
  * This method is designed to be used when all registered classes share a common interface or base type and constructor arguments.
@@ -3118,7 +3731,7 @@
3118
  );
3119
  (function(_, _fn, _str){
3120
  // only register methods if this version is the current version
3121
- if (_.version !== '0.1.3') return;
3122
 
3123
  // this is done to handle Content Security in Chrome and other browsers blocking access to the localStorage object under certain configurations.
3124
  // see: https://www.chromium.org/for-testers/bug-reporting-guidelines/uncaught-securityerror-failed-to-read-the-localstorage-property-from-window-access-is-denied-for-this-document
@@ -3222,6 +3835,250 @@
3222
  FooGallery.utils.fn,
3223
  FooGallery.utils.str
3224
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3225
  (function ($, _, _utils, _is, _fn) {
3226
 
3227
  _.debug = new _utils.Debugger("__FooGallery__");
@@ -3229,31 +4086,44 @@
3229
  /**
3230
  * @summary The url of an empty 1x1 pixel image used as the default value for the `placeholder` and `error` {@link FooGallery.defaults|options}.
3231
  * @memberof FooGallery
3232
- * @name emptyImage
3233
  * @type {string}
3234
  * @default "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
3235
  */
3236
- _.emptyImage = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
3237
 
3238
  /**
3239
  * @summary The name to use when getting or setting an instance of a {@link FooGallery.Template|template} on an element using jQuery's `.data()` method.
3240
  * @memberof FooGallery
3241
- * @name dataTemplate
3242
  * @type {string}
3243
  * @default "__FooGallery__"
3244
  */
3245
- _.dataTemplate = "__FooGallery__";
3246
 
3247
  /**
3248
  * @summary The name to use when getting or setting an instance of a {@link FooGallery.Item|item} on an element using jQuery's `.data()` method.
3249
  * @memberof FooGallery
3250
- * @name dataItem
3251
  * @type {string}
3252
  * @default "__FooGalleryItem__"
3253
  */
3254
- _.dataItem = "__FooGalleryItem__";
 
 
 
 
3255
 
3256
  _.init = function (options, element) {
 
 
 
 
 
 
 
 
 
3257
  return _.template.make(options, element).initialize();
3258
  };
3259
 
@@ -3313,9 +4183,10 @@
3313
  * </script>
3314
  */
3315
  $.fn.foogallery = function (options, ready) {
 
3316
  return this.each(function (i, element) {
3317
- var template = $.data(element, _.dataTemplate);
3318
  if (_is.string(options)) {
 
3319
  if (template instanceof _.Template) {
3320
  switch (options) {
3321
  case "layout":
@@ -3327,21 +4198,7 @@
3327
  }
3328
  }
3329
  } else {
3330
- if (template instanceof _.Template) {
3331
- template.destroy().then(function(){
3332
- _.template.make(options, element).initialize().then(function (template) {
3333
- if (_is.fn(ready)) {
3334
- ready(template);
3335
- }
3336
- });
3337
- });
3338
- } else {
3339
- _.template.make(options, element).initialize().then(function (template) {
3340
- if (_is.fn(ready)) {
3341
- ready(template);
3342
- }
3343
- });
3344
- }
3345
  }
3346
  });
3347
  };
@@ -3990,7 +4847,7 @@
3990
 
3991
  var instance = 0;
3992
 
3993
- _.Template = _utils.Class.extend(/** @lends FooGallery.Template */{
3994
  /**
3995
  * @summary The primary class for FooGallery, this controls the flow of the plugin across all templates.
3996
  * @memberof FooGallery
@@ -4003,6 +4860,7 @@
4003
  */
4004
  construct: function (options, element) {
4005
  var self = this;
 
4006
  /**
4007
  * @summary An instance specific namespace to use when binding events to global objects that could be shared across multiple galleries.
4008
  * @memberof FooGallery.Template#
@@ -4102,6 +4960,7 @@
4102
  * @private
4103
  */
4104
  self._initialize = null;
 
4105
  self.initializing = false;
4106
  self.initialized = false;
4107
  self.destroying = false;
@@ -4185,7 +5044,7 @@
4185
  } else {
4186
  self.$scrollParent = $(document);
4187
  }
4188
- self.$el.data(_.dataTemplate, self);
4189
 
4190
  // at this point we have our container element free of pre-existing instances so let's bind any event listeners supplied by the .on option
4191
  if (!_is.empty(self.opt.on)) {
@@ -4345,8 +5204,7 @@
4345
  */
4346
  var e = self.raise("post-init");
4347
  if (e.isDefaultPrevented()) return false;
4348
- var state = self.state.parse();
4349
- self.state.set(_is.empty(state) ? self.state.initial() : state);
4350
  self.$scrollParent.on("scroll" + self.namespace, {self: self}, _fn.throttle(function () {
4351
  self.loadAvailable();
4352
  }, 50));
@@ -4448,29 +5306,32 @@
4448
  * @summary Destroy the template.
4449
  * @memberof FooGallery.Template#
4450
  * @function destroy
 
4451
  * @returns {Promise}
4452
  * @description Once this method is called it can not be stopped and the template will be destroyed.
4453
  * @fires FooGallery.Template~"destroy.foogallery"
4454
  */
4455
- destroy: function () {
4456
- var self = this;
4457
  if (self.destroyed) return _fn.resolved;
4458
  self.destroying = true;
4459
  return $.Deferred(function (def) {
4460
  if (self.initializing && _is.promise(self._initialize)) {
4461
  self._initialize.always(function () {
4462
  self.destroying = false;
4463
- self.doDestroy();
4464
  def.resolve();
4465
  });
4466
  } else {
4467
  self.destroying = false;
4468
- self.doDestroy();
4469
  def.resolve();
4470
  }
4471
- }).promise();
 
 
4472
  },
4473
- doDestroy: function(){
4474
  var self = this;
4475
  if (self.destroyed) return;
4476
  /**
@@ -4489,9 +5350,10 @@
4489
  * });
4490
  */
4491
  self.raise("destroy");
 
4492
  self.$scrollParent.off(self.namespace);
4493
  $(window).off(self.namespace);
4494
- self.state.destroy();
4495
  if (self.filter) self.filter.destroy();
4496
  if (self.pages) self.pages.destroy();
4497
  self.items.destroy();
@@ -4514,7 +5376,7 @@
4514
  * });
4515
  */
4516
  self.raise("destroyed");
4517
- self.$el.removeData(_.dataTemplate);
4518
 
4519
  if (_is.empty(self._undo.classes)) self.$el.removeAttr("class");
4520
  else self.$el.attr("class", self._undo.classes);
@@ -4581,7 +5443,9 @@
4581
  _check: function (delay) {
4582
  delay = _is.number(delay) ? delay : 0;
4583
  var self = this;
4584
- setTimeout(function () {
 
 
4585
  if (self.initialized && (!self.destroying || !self.destroyed)) {
4586
  self.loadAvailable();
4587
  }
@@ -4608,13 +5472,15 @@
4608
  * });
4609
  */
4610
  raise: function (eventName, args) {
4611
- if (!_is.string(eventName) || _is.empty(eventName)) return null;
4612
  args = _is.array(args) ? args : [];
4613
  var self = this,
4614
  name = eventName.split(".")[0],
4615
  listener = _str.camel("on-" + name),
4616
  event = $.Event(name + ".foogallery");
4617
  args.unshift(self); // add self
 
 
4618
  self.$el.trigger(event, args);
4619
  _.debug.logf("{id}|{name}:", {id: self.id, name: name}, args);
4620
  if (_is.fn(self[listener])) {
@@ -4649,7 +5515,7 @@
4649
  /**
4650
  * @summary Gets the width of the FooGallery container.
4651
  * @memberof FooGallery.Template#
4652
- * @type function
4653
  * @name getContainerWidth
4654
  * @returns {number}
4655
  */
@@ -4661,6 +5527,21 @@
4661
  return self.$el.width();
4662
  },
4663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4664
  // ###############
4665
  // ## Listeners ##
4666
  // ###############
@@ -4696,7 +5577,18 @@
4696
  timeout: 60000,
4697
  srcset: "data-srcset-fg",
4698
  src: "data-src-fg",
4699
- template: {}
 
 
 
 
 
 
 
 
 
 
 
4700
  }, {
4701
  container: "foogallery"
4702
  }, {}, -100);
@@ -4755,7 +5647,7 @@
4755
  FooGallery.utils.fn,
4756
  FooGallery.utils.str
4757
  );
4758
- (function(_, _utils){
4759
 
4760
  _.Component = _utils.Class.extend(/** @lend FooGallery.Component */{
4761
  /**
@@ -4786,8 +5678,73 @@
4786
  }
4787
  });
4788
 
4789
- /**
4790
- * @summary A factory for registering and creating basic gallery components.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4791
  * @memberof FooGallery
4792
  * @name components
4793
  * @type {FooGallery.utils.Factory}
@@ -4796,9 +5753,10 @@
4796
 
4797
  })(
4798
  FooGallery,
4799
- FooGallery.utils
 
4800
  );
4801
- (function($, _, _is, _str){
4802
 
4803
  _.State = _.Component.extend(/** @lends FooGallery.State */{
4804
  /**
@@ -4840,6 +5798,17 @@
4840
  * @type {boolean}
4841
  */
4842
  self.enabled = self.opt.enabled;
 
 
 
 
 
 
 
 
 
 
 
4843
  /**
4844
  * @summary Which method of the history API to use by default when updating the state.
4845
  * @memberof FooGallery.State#
@@ -4849,19 +5818,23 @@
4849
  */
4850
  self.pushOrReplace = self.isPushOrReplace(self.opt.pushOrReplace) ? self.opt.pushOrReplace : "replace";
4851
 
 
 
4852
  var id = _str.escapeRegExp(self.tmpl.id),
 
4853
  values = _str.escapeRegExp(self.opt.values),
4854
  pair = _str.escapeRegExp(self.opt.pair);
4855
  /**
4856
  * @summary An object containing regular expressions used to test and parse a hash value into a state object.
4857
  * @memberof FooGallery.State#
4858
  * @name regex
4859
- * @type {{exists: RegExp, values: RegExp}}
4860
  * @readonly
4861
  * @description The regular expressions contained within this object are specific to this template and are created using the template {@link FooGallery.Template#id|id} and the delimiters from the {@link FooGallery.State#opt|options}.
4862
  */
4863
  self.regex = {
4864
  exists: new RegExp("^#"+id+"\\"+values+".+?"),
 
4865
  values: new RegExp("(\\w+)"+pair+"([^"+values+"]+)", "g")
4866
  };
4867
  },
@@ -4869,13 +5842,24 @@
4869
  * @summary Destroy the component clearing any current state from the url and preparing it for garbage collection.
4870
  * @memberof FooGallery.State#
4871
  * @function destroy
 
4872
  */
4873
- destroy: function(){
4874
  var self = this;
4875
- self.clear();
4876
  self.opt = self.regex = {};
4877
  self._super();
4878
  },
 
 
 
 
 
 
 
 
 
 
4879
  /**
4880
  * @summary Check if the supplied value is `"push"` or `"replace"`.
4881
  * @memberof FooGallery.State#
@@ -4893,7 +5877,8 @@
4893
  * @returns {boolean}
4894
  */
4895
  exists: function(){
4896
- return this.regex.exists.test(location.hash) && this.regex.values.test(location.hash);
 
4897
  },
4898
  /**
4899
  * @summary Parse the current url returning an object containing all values for the template.
@@ -4903,19 +5888,32 @@
4903
  * @description This method always returns an object, if successful the object contains properties otherwise it is just a plain empty object. For this method to be successful the current template {@link FooGallery.Template#id|id} must match the one from the url.
4904
  */
4905
  parse: function(){
4906
- var self = this, state = {};
4907
  if (self.exists()){
4908
  if (self.enabled){
4909
  state.id = self.tmpl.id;
 
4910
  var pairs = location.hash.match(self.regex.values);
4911
  $.each(pairs, function(i, pair){
4912
- var parts = pair.split(self.opt.pair);
4913
  if (parts.length === 2){
4914
- state[parts[0]] = parts[1].indexOf(self.opt.array) === -1
4915
- ? decodeURIComponent(parts[1].replace(/\+/g, '%20'))
4916
- : $.map(parts[1].split(self.opt.array), function(part){ return decodeURIComponent(part.replace(/\+/g, '%20')); });
4917
- if (_is.string(state[parts[0]]) && !isNaN(state[parts[0]])){
4918
- state[parts[0]] = parseInt(state[parts[0]]);
 
 
 
 
 
 
 
 
 
 
 
 
4919
  }
4920
  }
4921
  });
@@ -4938,21 +5936,21 @@
4938
  * @returns {string}
4939
  */
4940
  hashify: function(state){
4941
- var self = this;
4942
  if (_is.hash(state)){
4943
- var hash = [];
4944
- $.each(state, function(name, value){
4945
- if (!_is.empty(value) && name !== "id"){
4946
- if (_is.array(value)){
4947
- value = $.map(value, function(part){ return encodeURIComponent(part); }).join(self.opt.array);
4948
- } else {
4949
- value = encodeURIComponent(value);
4950
- }
4951
- hash.push(name + self.opt.pair + value);
4952
- }
4953
- });
4954
  if (hash.length > 0){
4955
- hash.unshift("#"+self.tmpl.id);
4956
  }
4957
  return hash.join(self.opt.values);
4958
  }
@@ -4968,8 +5966,8 @@
4968
  var self = this;
4969
  if (self.enabled && self.apiEnabled){
4970
  state.id = self.tmpl.id;
4971
- var hash = self.hashify(state), empty = _is.empty(hash);
4972
- history.replaceState(empty ? null : state, "", empty ? location.pathname + location.search : hash);
4973
  }
4974
  },
4975
  /**
@@ -4982,8 +5980,8 @@
4982
  var self = this;
4983
  if (self.enabled && self.apiEnabled){
4984
  state.id = self.tmpl.id;
4985
- var hash = self.hashify(state), empty = _is.empty(hash);
4986
- history.pushState(empty ? null : state, "", empty ? location.pathname + location.search : hash);
4987
  }
4988
  },
4989
  /**
@@ -5016,10 +6014,11 @@
5016
  * @description This method returns an initial start up state from the template options.
5017
  */
5018
  initial: function(){
5019
- var self = this, tmpl = self.tmpl, state = {};
5020
- if (tmpl.filter && !_is.empty(tmpl.filter.current)) state.f = tmpl.filter.current;
5021
- if (tmpl.pages && tmpl.pages.current > 1) state.p = tmpl.pages.current;
5022
- return state;
 
5023
  },
5024
  /**
5025
  * @summary Get the current state of the template.
@@ -5030,15 +6029,17 @@
5030
  * @description This method does not parse the history or url it returns the current state of the template itself. To parse the current url use the {@link FooGallery.State#parse|parse} method instead.
5031
  */
5032
  get: function(item){
5033
- var self = this, tmpl = self.tmpl, state = {};
5034
- if (item instanceof _.Item) state.i = item.id;
5035
- if (tmpl.filter && !_is.empty(tmpl.filter.current)){
5036
- state.f = tmpl.filter.current;
 
5037
  }
5038
- if (tmpl.pages && tmpl.pages.isValid(tmpl.pages.current)){
5039
- state.p = tmpl.pages.current;
 
5040
  }
5041
- return state;
5042
  },
5043
  /**
5044
  * @summary Set the current state of the template.
@@ -5050,34 +6051,30 @@
5050
  set: function(state){
5051
  var self = this, tmpl = self.tmpl;
5052
  if (_is.hash(state)){
 
5053
  tmpl.items.reset();
5054
- var item = tmpl.items.get(state.i);
5055
- if (tmpl.filter){
5056
- tmpl.filter.rebuild();
5057
- var tags = !_is.empty(state.f) ? state.f : [];
5058
- tmpl.filter.set(tags, false);
5059
- }
5060
- if (tmpl.pages){
5061
- tmpl.pages.rebuild();
5062
- var page = tmpl.pages.number(state.p);
5063
- if (item && !tmpl.pages.contains(page, item)){
5064
- page = tmpl.pages.find(item);
5065
- page = page !== 0 ? page : 1;
5066
  }
5067
- tmpl.pages.set(page, !_is.empty(state), false, true);
5068
- if (item && tmpl.pages.contains(page, item)){
5069
- item.scrollTo();
 
 
5070
  }
5071
- } else {
5072
- tmpl.items.detach(tmpl.items.all());
5073
- tmpl.items.create(tmpl.items.available(), true);
5074
- if (item){
5075
- item.scrollTo();
 
 
 
5076
  }
5077
- }
5078
- if (!_is.empty(state.i)){
5079
- state.i = null;
5080
- self.replace(state);
5081
  }
5082
  }
5083
  },
@@ -5086,10 +6083,16 @@
5086
  _.template.configure("core", {
5087
  state: {
5088
  enabled: false,
 
5089
  pushOrReplace: "replace",
 
5090
  values: "/",
5091
  pair: ":",
5092
- array: "+"
 
 
 
 
5093
  }
5094
  });
5095
 
@@ -5109,1143 +6112,658 @@
5109
  /**
5110
  * @summary An object used to store the state of a template.
5111
  * @typedef {object} FooGallery~State
5112
- * @property {number} [p] - The current page number.
5113
- * @property {string[]} [f] - The current filter array.
5114
- * @property {?string} [i] - The currently selected item.
5115
  */
5116
 
5117
  })(
5118
  FooGallery.$,
5119
  FooGallery,
5120
  FooGallery.utils.is,
5121
- FooGallery.utils.str
 
5122
  );
5123
  (function ($, _, _utils, _is, _fn, _obj) {
5124
 
5125
- _.Item = _.Component.extend(/** @lends FooGallery.Item */{
5126
  /**
5127
- * @summary The base class for an item.
5128
  * @memberof FooGallery
5129
- * @constructs Item
5130
- * @param {FooGallery.Template} template - The template this item belongs to.
5131
- * @param {FooGallery.Item~Options} [options] - The options to initialize the item with.
5132
  * @augments FooGallery.Component
5133
  * @borrows FooGallery.utils.Class.extend as extend
5134
  * @borrows FooGallery.utils.Class.override as override
5135
  */
5136
- construct: function (template, options) {
5137
  var self = this;
 
 
 
5138
  /**
5139
  * @ignore
5140
- * @memberof FooGallery.Item#
5141
  * @function _super
5142
  */
5143
  self._super(template);
5144
- self.cls = template.cls.item;
5145
- self.il8n = template.il8n.item;
5146
- self.sel = template.sel.item;
5147
- self.opt = _obj.extend({}, template.opt.item, options);
5148
-
5149
- /**
5150
- * @summary Whether or not the items' elements are appended to the template.
5151
- * @memberof FooGallery.Item#
5152
- * @name isAttached
5153
- * @type {boolean}
5154
- * @readonly
5155
- */
5156
- self.isAttached = false;
5157
- /**
5158
- * @summary Whether or not the items' elements are created and can be used.
5159
- * @memberof FooGallery.Item#
5160
- * @name isCreated
5161
- * @type {boolean}
5162
- * @readonly
5163
- */
5164
- self.isCreated = false;
5165
- /**
5166
- * @summary Whether or not the item has been destroyed and can not be used.
5167
- * @memberof FooGallery.Item#
5168
- * @name isDestroyed
5169
- * @type {boolean}
5170
- * @readonly
5171
- */
5172
- self.isDestroyed = false;
5173
- /**
5174
- * @summary Whether or not the items' image is currently loading.
5175
- * @memberof FooGallery.Item#
5176
- * @name isLoading
5177
- * @type {boolean}
5178
- * @readonly
5179
- */
5180
- self.isLoading = false;
5181
- /**
5182
- * @summary Whether or not the items' image has been loaded.
5183
- * @memberof FooGallery.Item#
5184
- * @name isLoaded
5185
- * @type {boolean}
5186
- * @readonly
5187
- */
5188
- self.isLoaded = false;
5189
- /**
5190
- * @summary Whether or not the items' image threw an error while loading.
5191
- * @memberof FooGallery.Item#
5192
- * @name isError
5193
- * @type {boolean}
5194
- * @readonly
5195
- */
5196
- self.isError = false;
5197
- /**
5198
- * @summary Whether or not this item was parsed from an existing DOM element.
5199
- * @memberof FooGallery.Item#
5200
- * @name isParsed
5201
- * @type {boolean}
5202
- * @readonly
5203
- */
5204
- self.isParsed = false;
5205
- /**
5206
- * @memberof FooGallery.Item#
5207
- * @name $el
5208
- * @type {?jQuery}
5209
- */
5210
- self.$el = null;
5211
- /**
5212
- * @memberof FooGallery.Item#
5213
- * @name $inner
5214
- * @type {?jQuery}
5215
- */
5216
- self.$inner = null;
5217
- /**
5218
- * @memberof FooGallery.Item#
5219
- * @name $anchor
5220
- * @type {?jQuery}
5221
- */
5222
- self.$anchor = null;
5223
- /**
5224
- * @memberof FooGallery.Item#
5225
- * @name $wrap
5226
- * @type {?jQuery}
5227
- */
5228
- self.$wrap = null;
5229
- /**
5230
- * @memberof FooGallery.Item#
5231
- * @name $image
5232
- * @type {?jQuery}
5233
- */
5234
- self.$image = null;
5235
- /**
5236
- * @memberof FooGallery.Item#
5237
- * @name $caption
5238
- * @type {?jQuery}
5239
- */
5240
- self.$caption = null;
5241
 
5242
- /**
5243
- * @memberof FooGallery.Item#
5244
- * @name fixLayout
5245
- * @type {boolean}
5246
- */
5247
- self.fixLayout = self.tmpl.opt.fixLayout;
5248
 
5249
- /**
5250
- * @memberof FooGallery.Item#
5251
- * @name type
5252
- * @type {string}
5253
- */
5254
- self.type = self.opt.type;
5255
- /**
5256
- * @memberof FooGallery.Item#
5257
- * @name id
5258
- * @type {string}
5259
- */
5260
- self.id = self.opt.id;
5261
- /**
5262
- * @memberof FooGallery.Item#
5263
- * @name href
5264
- * @type {string}
5265
- */
5266
- self.href = self.opt.href;
5267
- /**
5268
- * @memberof FooGallery.Item#
5269
- * @name src
5270
- * @type {string}
5271
- */
5272
- self.src = self.opt.src;
5273
- /**
5274
- * @memberof FooGallery.Item#
5275
- * @name srcset
5276
- * @type {string}
5277
- */
5278
- self.srcset = self.opt.srcset;
5279
- /**
5280
- * @memberof FooGallery.Item#
5281
- * @name width
5282
- * @type {number}
5283
- */
5284
- self.width = self.opt.width;
5285
- /**
5286
- * @memberof FooGallery.Item#
5287
- * @name height
5288
- * @type {number}
5289
- */
5290
- self.height = self.opt.height;
5291
- /**
5292
- * @memberof FooGallery.Item#
5293
- * @name title
5294
- * @type {string}
5295
- */
5296
- self.title = self.opt.title;
5297
- /**
5298
- * @memberof FooGallery.Item#
5299
- * @name alt
5300
- * @type {string}
5301
- */
5302
- self.alt = self.opt.alt;
5303
- /**
5304
- * @memberof FooGallery.Item#
5305
- * @name caption
5306
- * @type {string}
5307
- */
5308
- self.caption = _is.empty(self.opt.caption) ? self.title : self.opt.caption;
5309
- /**
5310
- * @memberof FooGallery.Item#
5311
- * @name description
5312
- * @type {string}
5313
- */
5314
- self.description = _is.empty(self.opt.description) ? self.alt : self.opt.description;
5315
- /**
5316
- * @memberof FooGallery.Item#
5317
- * @name attrItem
5318
- * @type {FooGallery.Item~Attributes}
5319
- */
5320
- self.attr = self.opt.attr;
5321
- /**
5322
- * @memberof FooGallery.Item#
5323
- * @name tags
5324
- * @type {string[]}
5325
- */
5326
- self.tags = self.opt.tags;
5327
- /**
5328
- * @memberof FooGallery.Item#
5329
- * @name maxWidth
5330
- * @type {?FooGallery.Item~maxWidthCallback}
5331
- */
5332
- self.maxWidth = self.opt.maxWidth;
5333
- /**
5334
- * @memberof FooGallery.Item#
5335
- * @name maxCaptionLength
5336
- * @type {number}
5337
- */
5338
- self.maxCaptionLength = self.opt.maxCaptionLength;
5339
- /**
5340
- * @memberof FooGallery.Item#
5341
- * @name maxDescriptionLength
5342
- * @type {number}
5343
- */
5344
- self.maxDescriptionLength = self.opt.maxDescriptionLength;
5345
- /**
5346
- * @memberof FooGallery.Item#
5347
- * @name showCaptionTitle
5348
- * @type {boolean}
5349
- */
5350
- self.showCaptionTitle = self.opt.showCaptionTitle;
5351
- /**
5352
- * @memberof FooGallery.Item#
5353
- * @name showCaptionDescription
5354
- * @type {boolean}
5355
- */
5356
- self.showCaptionDescription = self.opt.showCaptionDescription;
5357
- /**
5358
- * @summary The cached result of the last call to the {@link FooGallery.Item#getThumbUrl|getThumbUrl} method.
5359
- * @memberof FooGallery.Item#
5360
- * @name _thumbUrl
5361
- * @type {string}
5362
- * @private
5363
- */
5364
- self._thumbUrl = null;
5365
- /**
5366
- * @summary This property is used to store the promise created when loading an item for the first time.
5367
- * @memberof FooGallery.Item#
5368
- * @name _load
5369
- * @type {?Promise}
5370
- * @private
5371
- */
5372
- self._load = null;
5373
- /**
5374
- * @summary This property is used to store the init state of an item the first time it is parsed and is used to reset state during destroy.
5375
- * @memberof FooGallery.Item#
5376
- * @name _undo
5377
- * @type {object}
5378
- * @private
5379
- */
5380
- self._undo = {
5381
- classes: "",
5382
- style: "",
5383
- loader: false,
5384
- wrap: false,
5385
- placeholder: false
5386
  };
 
 
 
 
 
 
 
5387
  },
5388
  /**
5389
- * @summary Destroy the item preparing it for garbage collection.
5390
- * @memberof FooGallery.Item#
5391
- * @function destroy
 
 
5392
  */
5393
- destroy: function () {
5394
- var self = this;
5395
- /**
5396
- * @summary Raised when a template destroys an item.
5397
- * @event FooGallery.Template~"destroy-item.foogallery"
5398
- * @type {jQuery.Event}
5399
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5400
- * @param {FooGallery.Template} template - The template raising the event.
5401
- * @param {FooGallery.Item} item - The item to destroy.
5402
- * @returns {boolean} `true` if the {@link FooGallery.Item|`item`} has been successfully destroyed.
5403
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5404
- * $(".foogallery").foogallery({
5405
- * on: {
5406
- * "destroy-item.foogallery": function(event, template, item){
5407
- * // do something
5408
- * }
5409
- * }
5410
- * });
5411
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being destroyed.}
5412
- * $(".foogallery").foogallery({
5413
- * on: {
5414
- * "destroy-item.foogallery": function(event, template, item){
5415
- * if ("some condition"){
5416
- * // stop the item being destroyed
5417
- * event.preventDefault();
5418
- * }
5419
- * }
5420
- * }
5421
- * });
5422
- * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
5423
- * $(".foogallery").foogallery({
5424
- * on: {
5425
- * "destroy-item.foogallery": function(event, template, item){
5426
- * // stop the default logic
5427
- * event.preventDefault();
5428
- * // replacing it with your own destroying the item yourself
5429
- * item.$el.off(".foogallery").remove();
5430
- * item.$el = null;
5431
- * ...
5432
- * // once all destroy work is complete you must set tmpl to null
5433
- * item.tmpl = null;
5434
- * }
5435
- * }
5436
- * });
5437
- */
5438
- var e = self.tmpl.raise("destroy-item", [self]);
5439
- if (!e.isDefaultPrevented()) {
5440
- self.isDestroyed = self.doDestroyItem();
5441
  }
5442
- if (self.isDestroyed) {
5443
- /**
5444
- * @summary Raised after an item has been destroyed.
5445
- * @event FooGallery.Template~"destroyed-item.foogallery"
5446
- * @type {jQuery.Event}
5447
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5448
- * @param {FooGallery.Template} template - The template raising the event.
5449
- * @param {FooGallery.Item} item - The item that was destroyed.
5450
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5451
- * $(".foogallery").foogallery({
5452
- * on: {
5453
- * "destroyed-item.foogallery": function(event, template, item){
5454
- * // do something
5455
- * }
5456
- * }
5457
- * });
5458
- */
5459
- self.tmpl.raise("destroyed-item", [self]);
5460
- // call the original method that simply nulls the tmpl property
5461
- self._super();
5462
- }
5463
- return self.isDestroyed;
5464
  },
5465
  /**
5466
- * @summary Performs the actual destroy logic for the item.
5467
- * @memberof FooGallery.Item#
5468
- * @function doDestroyItem
5469
- * @returns {boolean}
 
5470
  */
5471
- doDestroyItem: function () {
5472
- var self = this;
5473
- if (self.isParsed) {
5474
- self.append();
5475
- if (_is.empty(self._undo.classes)) self.$el.removeAttr("class");
5476
- else self.$el.attr("class", self._undo.classes);
5477
-
5478
- if (_is.empty(self._undo.style)) self.$el.removeAttr("style");
5479
- else self.$el.attr("style", self._undo.style);
5480
-
5481
- if (self._undo.wrap) {
5482
- self.$image.unwrap();
5483
- }
5484
- if (self._undo.loader) {
5485
- self.$el.find(self.sel.loader).remove();
5486
- }
5487
- if (self._undo.placeholder && self.$image.prop("src") == _.emptyImage) {
5488
- self.$image.removeAttr("src");
5489
- }
5490
- } else if (self.isCreated) {
5491
- self.detach();
5492
- self.$el.remove();
5493
- }
5494
- return true;
5495
  },
5496
  /**
5497
- * @summary Parse the supplied element updating the current items' properties.
5498
- * @memberof FooGallery.Item#
5499
- * @function parse
5500
- * @param {(jQuery|HTMLElement|string)} element - The element to parse.
5501
- * @returns {boolean}
5502
- * @fires FooGallery.Template~"parse-item.foogallery"
5503
- * @fires FooGallery.Template~"parsed-item.foogallery"
5504
  */
5505
- parse: function (element) {
5506
- var self = this, $el = $(element);
5507
- /**
5508
- * @summary Raised when an item needs to parse properties from an element.
5509
- * @event FooGallery.Template~"parse-item.foogallery"
5510
- * @type {jQuery.Event}
5511
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5512
- * @param {FooGallery.Template} template - The template raising the event.
5513
- * @param {FooGallery.Item} item - The item to populate.
5514
- * @param {jQuery} $element - The jQuery object of the element to parse.
5515
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5516
- * $(".foogallery").foogallery({
5517
- * on: {
5518
- * "parse-item.foogallery": function(event, template, item, $element){
5519
- * // do something
5520
- * }
5521
- * }
5522
- * });
5523
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` properties being parsed from the `element`.}
5524
- * $(".foogallery").foogallery({
5525
- * on: {
5526
- * "parse-item.foogallery": function(event, template, item, $element){
5527
- * if ("some condition"){
5528
- * // stop the item being parsed
5529
- * event.preventDefault();
5530
- * }
5531
- * }
5532
- * }
5533
- * });
5534
- * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object and then populating the `item` properties from the `element`.}
5535
- * $(".foogallery").foogallery({
5536
- * on: {
5537
- * "parse-item.foogallery": function(event, template, item, $element){
5538
- * // stop the default logic
5539
- * event.preventDefault();
5540
- * // replacing it with your own setting each property of the item yourself
5541
- * item.$el = $element;
5542
- * ...
5543
- * // once all properties are set you must set isParsed to true
5544
- * item.isParsed = true;
5545
- * }
5546
- * }
5547
- * });
5548
- */
5549
- var e = self.tmpl.raise("parse-item", [self, $el]);
5550
- if (!e.isDefaultPrevented() && (self.isCreated = $el.is(self.sel.elem))) {
5551
- self.isParsed = self.doParseItem($el);
5552
- if (self.fixLayout) self.fix();
5553
- // We don't load the attributes when parsing as they are only ever used to create an item and if you're parsing it's already created.
5554
- }
5555
- if (self.isParsed) {
5556
- /**
5557
- * @summary Raised after an item has been parsed from an element.
5558
- * @event FooGallery.Template~"parsed-item.foogallery"
5559
- * @type {jQuery.Event}
5560
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5561
- * @param {FooGallery.Template} template - The template raising the event.
5562
- * @param {FooGallery.Item} item - The item that was parsed.
5563
- * @param {jQuery} $element - The jQuery object of the element that was parsed.
5564
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5565
- * $(".foogallery").foogallery({
5566
- * on: {
5567
- * "parsed-item.foogallery": function(event, template, item, $element){
5568
- * // do something
5569
- * }
5570
- * }
5571
- * });
5572
- */
5573
- self.tmpl.raise("parsed-item", [self]);
5574
- }
5575
- return self.isParsed;
5576
  },
5577
  /**
5578
- * @summary Performs the actual parse logic for the item.
5579
- * @memberof FooGallery.Item#
5580
- * @function doParseItem
5581
- * @param {jQuery} $el - The jQuery element to parse.
5582
- * @returns {boolean}
5583
  */
5584
- doParseItem: function ($el) {
5585
- var self = this, o = self.tmpl.opt, cls = self.cls, sel = self.sel;
5586
-
5587
- self._undo.classes = $el.attr("class") || "";
5588
- self._undo.style = $el.attr("style") || "";
5589
-
5590
- self.$el = $el.data(_.dataItem, self);
5591
- self.$inner = self.$el.children(sel.inner);
5592
- self.$anchor = self.$inner.children(sel.anchor).on("click.foogallery", {self: self}, self.onAnchorClick);
5593
- self.$image = self.$anchor.find(sel.image);
5594
- self.$caption = self.$inner.children(sel.caption.elem).on("click.foogallery", {self: self}, self.onCaptionClick);
5595
-
5596
- if ( !self.$el.length || !self.$inner.length || !self.$anchor.length || !self.$image.length ){
5597
- console.error("FooGallery Error: Invalid HTML markup. Check the item markup for additional elements or malformed HTML in the title or description.", self);
5598
- self.isError = true;
5599
- self.tmpl.raise("error-item", [self]);
5600
- if (self.$el.length !== 0){
5601
- self.$el.remove();
5602
- }
5603
- return false;
5604
- }
5605
-
5606
- self.isAttached = self.$el.parent().length > 0;
5607
- self.isLoading = self.$el.is(sel.loading);
5608
- self.isLoaded = self.$el.is(sel.loaded);
5609
- self.isError = self.$el.is(sel.error);
5610
-
5611
- var data = self.$anchor.data();
5612
- self.id = data.id || self.id;
5613
- self.tags = data.tags || self.tags;
5614
- self.href = data.href || self.$anchor.attr('href') || self.href;
5615
- self.src = self.$image.attr(o.src) || self.src;
5616
- self.srcset = self.$image.attr(o.srcset) || self.srcset;
5617
- self.width = parseInt(self.$image.attr("width")) || self.width;
5618
- self.height = parseInt(self.$image.attr("height")) || self.height;
5619
- self.title = self.$image.attr("title") || self.title;
5620
- self.alt = self.$image.attr("alt") || self.alt;
5621
- self.caption = data.title || data.captionTitle || self.caption || self.title;
5622
- self.description = data.description || data.captionDesc || self.description || self.alt;
5623
- // if the caption or description are not set yet try fetching it from the html
5624
- if (_is.empty(self.caption)) self.caption = $.trim(self.$caption.find(sel.caption.title).html());
5625
- if (_is.empty(self.description)) self.description = $.trim(self.$caption.find(sel.caption.description).html());
5626
- // enforce the max lengths for the caption and description
5627
- if (_is.number(self.maxCaptionLength) && self.maxCaptionLength > 0 && !_is.empty(self.caption) && _is.string(self.caption) && self.caption.length > self.maxCaptionLength) {
5628
- self.$caption.find(sel.caption.title).html(self.caption.substr(0, self.maxCaptionLength) + "&hellip;");
5629
- }
5630
- if (_is.number(self.maxDescriptionLength) && self.maxDescriptionLength > 0 && !_is.empty(self.description) && _is.string(self.description) && self.description.length > self.maxDescriptionLength) {
5631
- self.$caption.find(sel.caption.description).html(self.description.substr(0, self.maxDescriptionLength) + "&hellip;");
5632
- }
5633
- // check if the item has a wrap
5634
- if (self.$anchor.children(sel.wrap).length === 0) {
5635
- var $wrap = $("<span/>", {"class": cls.wrap});
5636
- self.$anchor.append($wrap.append(self.$image));
5637
- self._undo.wrap = true;
5638
- }
5639
- // check if the item has a loader
5640
- if (self.$el.children(sel.loader).length === 0) {
5641
- self.$el.append($("<div/>", {"class": cls.loader}));
5642
- self._undo.loader = true;
5643
- }
5644
- // if the image has no src url then set the placeholder
5645
- var img = self.$image.get(0);
5646
- if (_is.empty(img.src)) {
5647
- img.src = _.emptyImage;
5648
- self._undo.placeholder = true;
5649
- }
5650
- if (self.isCreated && self.isAttached && !self.isLoading && !self.isLoaded && !self.isError) {
5651
- self.$el.addClass(cls.idle);
5652
- }
5653
- return true;
5654
  },
5655
  /**
5656
- * @summary Create the items' DOM elements and populate the corresponding properties.
5657
- * @memberof FooGallery.Item#
5658
- * @function create
5659
- * @returns {boolean}
5660
- * @fires FooGallery.Template~"create-item.foogallery"
5661
- * @fires FooGallery.Template~"created-item.foogallery"
5662
  */
5663
- create: function () {
5664
- var self = this;
5665
- if (!self.isCreated && _is.string(self.href) && _is.string(self.src) && _is.number(self.width) && _is.number(self.height)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5666
  /**
5667
- * @summary Raised when an item needs to create its' elements.
5668
- * @event FooGallery.Template~"create-item.foogallery"
5669
  * @type {jQuery.Event}
5670
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5671
  * @param {FooGallery.Template} template - The template raising the event.
5672
- * @param {FooGallery.Item} item - The item to create the elements for.
 
5673
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5674
  * $(".foogallery").foogallery({
5675
  * on: {
5676
- * "create-item.foogallery": function(event, template, item){
5677
  * // do something
5678
  * }
5679
  * }
5680
  * });
5681
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being created.}
5682
  * $(".foogallery").foogallery({
5683
  * on: {
5684
- * "create-item.foogallery": function(event, template, item){
5685
  * if ("some condition"){
5686
- * // stop the item being created
5687
  * event.preventDefault();
5688
  * }
5689
  * }
5690
  * }
5691
  * });
5692
- * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
5693
- * $(".foogallery").foogallery({
5694
- * on: {
5695
- * "create-item.foogallery": function(event, template, item){
5696
- * // stop the default logic
5697
- * event.preventDefault();
5698
- * // replacing it with your own creating each element property of the item yourself
5699
- * item.$el = $("<div/>");
5700
- * ...
5701
- * // once all elements are created you must set isCreated to true
5702
- * item.isCreated = true;
5703
- * }
5704
- * }
5705
- * });
5706
  */
5707
- var e = self.tmpl.raise("create-item", [self]);
5708
  if (!e.isDefaultPrevented()) {
5709
- self.isCreated = self.doCreateItem();
5710
- }
5711
- if (self.isCreated) {
5712
- /**
5713
- * @summary Raised after an items' elements have been created.
5714
- * @event FooGallery.Template~"created-item.foogallery"
5715
- * @type {jQuery.Event}
5716
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5717
- * @param {FooGallery.Template} template - The template raising the event.
5718
- * @param {FooGallery.Item} item - The item that was created.
5719
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5720
- * $(".foogallery").foogallery({
5721
- * on: {
5722
- * "created-item.foogallery": function(event, template, item){
5723
- * // do something
5724
- * }
5725
- * }
5726
- * });
5727
- */
5728
- self.tmpl.raise("created-item", [self]);
5729
  }
5730
- }
5731
- return self.isCreated;
5732
- },
5733
- /**
5734
- * @summary Performs the actual create logic for the item.
5735
- * @memberof FooGallery.Item#
5736
- * @function doCreateItem
5737
- * @returns {boolean}
5738
- */
5739
- doCreateItem: function () {
5740
- var self = this, o = self.tmpl.opt, cls = self.cls, attr = self.attr;
5741
- attr.elem["class"] = cls.elem + " " + cls.idle;
5742
-
5743
- attr.inner["class"] = cls.inner;
5744
-
5745
- attr.anchor["class"] = cls.anchor;
5746
- attr.anchor["href"] = self.href;
5747
- attr.anchor["data-id"] = self.id;
5748
- attr.anchor["data-title"] = self.caption;
5749
- attr.anchor["data-description"] = self.description;
5750
- if (!_is.empty(self.tags)) {
5751
- attr.anchor["data-tags"] = JSON.stringify(self.tags);
5752
- }
5753
-
5754
- attr.image["class"] = cls.image;
5755
- attr.image["src"] = _.emptyImage;
5756
- attr.image[o.src] = self.src;
5757
- attr.image[o.srcset] = self.srcset;
5758
- attr.image["width"] = self.width;
5759
- attr.image["height"] = self.height;
5760
- attr.image["title"] = self.title;
5761
- attr.image["alt"] = self.alt;
5762
-
5763
- self.$el = $("<div/>").attr(attr.elem).data(_.dataItem, self);
5764
- self.$inner = $("<figure/>").attr(attr.inner).appendTo(self.$el);
5765
- self.$anchor = $("<a/>").attr(attr.anchor).appendTo(self.$inner).on("click.foogallery", {self: self}, self.onAnchorClick);
5766
- var $wrap = $("<span/>", {"class": cls.wrap}).appendTo(self.$anchor);
5767
- self.$image = $("<img/>").attr(attr.image).appendTo($wrap);
5768
 
5769
- cls = self.cls.caption;
5770
- attr = self.attr.caption;
5771
- attr.elem["class"] = cls.elem;
5772
- self.$caption = $("<figcaption/>").attr(attr.elem).on("click.foogallery", {self: self}, self.onCaptionClick);
5773
- attr.inner["class"] = cls.inner;
5774
- var $inner = $("<div/>").attr(attr.inner).appendTo(self.$caption);
5775
- var hasTitle = self.showCaptionTitle && !_is.empty(self.caption), hasDesc = self.showCaptionDescription && !_is.empty(self.description);
5776
- if (hasTitle || hasDesc) {
5777
- attr.title["class"] = cls.title;
5778
- attr.description["class"] = cls.description;
5779
- if (hasTitle) {
5780
- var $title = $("<div/>").attr(attr.title), titleHtml = self.caption;
5781
- // enforce the max length for the caption
5782
- if (_is.number(self.maxCaptionLength) && self.maxCaptionLength > 0 && _is.string(self.caption) && self.caption.length > self.maxCaptionLength) {
5783
- titleHtml = self.caption.substr(0, self.maxCaptionLength) + "&hellip;";
5784
- }
5785
- $title.get(0).innerHTML = titleHtml;
5786
- $inner.append($title);
5787
- }
5788
- if (hasDesc) {
5789
- var $desc = $("<div/>").attr(attr.description), descHtml = self.description;
5790
- // enforce the max length for the description
5791
- if (_is.number(self.maxDescriptionLength) && self.maxDescriptionLength > 0 && _is.string(self.description) && self.description.length > self.maxDescriptionLength) {
5792
- descHtml = self.description.substr(0, self.maxDescriptionLength) + "&hellip;";
5793
- }
5794
- $desc.get(0).innerHTML = descHtml;
5795
- $inner.append($desc);
5796
- }
5797
- }
5798
- self.$caption.appendTo(self.$inner);
5799
- // check if the item has a loader
5800
- if (self.$el.find(self.sel.loader).length === 0) {
5801
- self.$el.append($("<div/>", {"class": self.cls.loader}));
5802
- }
5803
- return true;
5804
- },
5805
- /**
5806
- * @summary Append the item to the current template.
5807
- * @memberof FooGallery.Item#
5808
- * @function append
5809
- * @returns {boolean}
5810
- * @fires FooGallery.Template~"append-item.foogallery"
5811
- * @fires FooGallery.Template~"appended-item.foogallery"
5812
- */
5813
- append: function () {
5814
- var self = this;
5815
- if (self.isCreated && !self.isAttached) {
5816
  /**
5817
- * @summary Raised when an item needs to append its elements to the template.
5818
- * @event FooGallery.Template~"append-item.foogallery"
5819
  * @type {jQuery.Event}
5820
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5821
  * @param {FooGallery.Template} template - The template raising the event.
5822
- * @param {FooGallery.Item} item - The item to append to the template.
5823
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5824
  * $(".foogallery").foogallery({
5825
  * on: {
5826
- * "append-item.foogallery": function(event, template, item){
5827
  * // do something
5828
  * }
5829
  * }
5830
  * });
5831
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being appended.}
5832
- * $(".foogallery").foogallery({
5833
- * on: {
5834
- * "append-item.foogallery": function(event, template, item){
5835
- * if ("some condition"){
5836
- * // stop the item being appended
5837
- * event.preventDefault();
5838
- * }
5839
- * }
5840
- * }
5841
- * });
5842
- * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
5843
  * $(".foogallery").foogallery({
5844
  * on: {
5845
- * "append-item.foogallery": function(event, template, item){
5846
- * // stop the default logic
5847
- * event.preventDefault();
5848
- * // replacing it with your own appending the item to the template
5849
- * item.$el.appendTo(template.$el);
5850
- * ...
5851
- * // once the item is appended you must set isAttached to true
5852
- * item.isAttached = true;
5853
  * }
5854
  * }
5855
  * });
5856
  */
5857
- var e = self.tmpl.raise("append-item", [self]);
5858
- if (!e.isDefaultPrevented()) {
5859
- self.tmpl.$el.append(self.$el);
5860
- if (self.fixLayout) self.fix();
5861
- self.isAttached = true;
5862
- }
5863
- if (self.isAttached) {
5864
- /**
5865
- * @summary Raised after an item has appended its' elements to the template.
5866
- * @event FooGallery.Template~"appended-item.foogallery"
5867
- * @type {jQuery.Event}
5868
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5869
- * @param {FooGallery.Template} template - The template raising the event.
5870
- * @param {FooGallery.Item} item - The item that was appended.
5871
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5872
- * $(".foogallery").foogallery({
5873
- * on: {
5874
- * "appended-item.foogallery": function(event, template, item){
5875
- * // do something
5876
- * }
5877
- * }
5878
- * });
5879
- */
5880
- self.tmpl.raise("appended-item", [self]);
5881
- }
5882
  }
5883
- return self.isAttached;
 
 
 
 
 
 
 
 
 
 
5884
  },
5885
  /**
5886
- * @summary Detach the item from the current template preserving its' data and events.
5887
- * @memberof FooGallery.Item#
5888
- * @function detach
5889
- * @returns {boolean}
 
 
 
 
 
 
 
5890
  */
5891
- detach: function () {
5892
- var self = this;
5893
- if (self.isCreated && self.isAttached) {
5894
  /**
5895
- * @summary Raised when an item needs to detach its' elements from the template.
5896
- * @event FooGallery.Template~"detach-item.foogallery"
5897
  * @type {jQuery.Event}
5898
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5899
  * @param {FooGallery.Template} template - The template raising the event.
5900
- * @param {FooGallery.Item} item - The item to detach from the template.
 
5901
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5902
  * $(".foogallery").foogallery({
5903
  * on: {
5904
- * "detach-item.foogallery": function(event, template, item){
5905
  * // do something
5906
  * }
5907
  * }
5908
  * });
5909
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being detached.}
5910
  * $(".foogallery").foogallery({
5911
  * on: {
5912
- * "detach-item.foogallery": function(event, template, item){
5913
  * if ("some condition"){
5914
- * // stop the item being detached
5915
  * event.preventDefault();
5916
  * }
5917
  * }
5918
  * }
5919
  * });
5920
- * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
5921
- * $(".foogallery").foogallery({
5922
- * on: {
5923
- * "detach-item.foogallery": function(event, template, item){
5924
- * // stop the default logic
5925
- * event.preventDefault();
5926
- * // replacing it with your own detaching the item from the template
5927
- * item.$el.detach();
5928
- * ...
5929
- * // once the item is detached you must set isAttached to false
5930
- * item.isAttached = false;
5931
- * }
5932
- * }
5933
- * });
5934
  */
5935
- var e = self.tmpl.raise("detach-item", [self]);
5936
  if (!e.isDefaultPrevented()) {
5937
- self.$el.detach();
5938
- if (self.fixLayout) self.unfix();
5939
- self.isAttached = false;
5940
  }
5941
- if (!self.isAttached) {
5942
- /**
5943
- * @summary Raised after an item has detached its' elements from the template.
5944
- * @event FooGallery.Template~"detached-item.foogallery"
5945
- * @type {jQuery.Event}
5946
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
5947
- * @param {FooGallery.Template} template - The template raising the event.
5948
- * @param {FooGallery.Item} item - The item that was detached.
5949
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
5950
- * $(".foogallery").foogallery({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5951
  * on: {
5952
- * "detached-item.foogallery": function(event, template, item){
5953
  * // do something
5954
  * }
5955
  * }
5956
  * });
5957
- */
5958
- self.tmpl.raise("detached-item", [self]);
5959
- }
5960
  }
5961
- return !self.isAttached;
5962
- },
5963
- /**
5964
- * @summary Load the items' {@link FooGallery.Item#$image|$image}.
5965
- * @memberof FooGallery.Item#
5966
- * @function load
5967
- * @returns {Promise.<FooGallery.Item>}
5968
- */
5969
- load: function () {
5970
- var self = this;
5971
- if (_is.promise(self._load)) return self._load;
5972
- if (!self.isCreated || !self.isAttached) return _fn.rejectWith("not created or attached");
5973
- var e = self.tmpl.raise("load-item", [self]);
5974
- if (e.isDefaultPrevented()) return _fn.rejectWith("default prevented");
5975
- var cls = self.cls, img = self.$image.get(0), placeholder = img.src;
5976
- self.isLoading = true;
5977
- self.$el.removeClass(cls.idle).removeClass(cls.loaded).removeClass(cls.error).addClass(cls.loading);
5978
- return self._load = $.Deferred(function (def) {
5979
- img.onload = function () {
5980
- img.onload = img.onerror = null;
5981
- self.isLoading = false;
5982
- self.isLoaded = true;
5983
- self.$el.removeClass(cls.loading).addClass(cls.loaded);
5984
- if (self.fixLayout) self.unfix();
5985
- self.tmpl.raise("loaded-item", [self]);
5986
- def.resolve(self);
5987
- };
5988
- img.onerror = function () {
5989
- img.onload = img.onerror = null;
5990
- self.isLoading = false;
5991
- self.isError = true;
5992
- self.$el.removeClass(cls.loading).addClass(cls.error);
5993
- if (_is.string(placeholder)) {
5994
- self.$image.prop("src", placeholder);
5995
- }
5996
- self.tmpl.raise("error-item", [self]);
5997
- def.reject(self);
5998
- };
5999
- // set everything in motion by setting the src
6000
- img.src = self.getThumbUrl();
6001
- if (img.complete){
6002
- img.onload();
6003
- }
6004
- }).promise();
6005
  },
6006
  /**
6007
- * @summary Attempts to set a inline width and height on the {@link FooGallery.Item#$image|$image} to prevent layout jumps.
6008
- * @memberof FooGallery.Item#
6009
- * @function fix
6010
- * @returns {FooGallery.Item}
 
 
 
6011
  */
6012
- fix: function () {
6013
- var self = this;
6014
- if (self.tmpl == null) return self;
6015
- if (self.isCreated && !self.isLoading && !self.isLoaded && !self.isError) {
6016
- var w = self.width, h = self.height, img = self.$image.get(0);
6017
- // if we have a base width and height to work with
6018
- if (!isNaN(w) && !isNaN(h) && !!img) {
6019
- // figure out the max image width and calculate the height the image should be displayed as
6020
- var width = _is.fn(self.maxWidth) ? self.maxWidth(self) : self.$image.width();
6021
- if (width <= 0) width = w;
6022
- var ratio = width / w, height = h * ratio;
6023
- // actually set the inline css on the image
6024
- self.$image.css({width: width, height: height});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6025
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6026
  }
6027
- return self;
6028
- },
6029
- /**
6030
- * @summary Removes any inline width and height values set on the {@link FooGallery.Item#$image|$image}.
6031
- * @memberof FooGallery.Item#
6032
- * @function unfix
6033
- * @returns {FooGallery.Item}
6034
- */
6035
- unfix: function () {
6036
- var self = this;
6037
- if (self.tmpl == null) return self;
6038
- if (self.isCreated) self.$image.css({width: '', height: ''});
6039
- return self;
6040
  },
6041
  /**
6042
- * @summary Inspect the `src` and `srcset` properties to determine which url to load for the thumb.
6043
- * @memberof FooGallery.Item#
6044
- * @function getThumbUrl
6045
- * @param {boolean} [refresh=false] - Whether or not to force refreshing of the cached value.
6046
- * @returns {string}
 
 
6047
  */
6048
- getThumbUrl: function (refresh) {
6049
- refresh = _is.boolean(refresh) ? refresh : false;
6050
  var self = this;
6051
- if (!refresh && _is.string(self._thumbUrl)) return self._thumbUrl;
6052
- return self._thumbUrl = _utils.src(self.src, self.srcset, self.width, self.height, self.$anchor.innerWidth(), self.$anchor.innerHeight());
6053
- },
6054
- /**
6055
- * @summary Scroll the item into the center of the viewport.
6056
- * @memberof FooGallery.Item#
6057
- * @function scrollTo
6058
- */
6059
- scrollTo: function (align) {
6060
- var self = this;
6061
- if (self.isAttached) {
6062
- var ib = self.bounds(), vb = _utils.getViewportBounds();
6063
- switch (align) {
6064
- case "top": // attempts to center the item horizontally but aligns the top with the middle of the viewport
6065
- ib.left += (ib.width / 2) - (vb.width / 2);
6066
- ib.top -= (vb.height / 5);
6067
- break;
6068
- default: // attempts to center the item in the viewport
6069
- ib.left += (ib.width / 2) - (vb.width / 2);
6070
- ib.top += (ib.height / 2) - (vb.height / 2);
6071
- break;
6072
- }
6073
- window.scrollTo(ib.left, ib.top);
6074
- }
6075
- return self;
6076
- },
6077
- /**
6078
- * @summary Get the bounds for the item.
6079
- * @memberof FooGallery.Item#
6080
- * @function bounds
6081
- * @returns {?FooGallery.utils.Bounds}
6082
- */
6083
- bounds: function () {
6084
- return this.isAttached ? _utils.getElementBounds(this.$el) : null;
6085
- },
6086
- /**
6087
- * @summary Checks if the item bounds intersects the supplied bounds.
6088
- * @memberof FooGallery.Item#
6089
- * @function intersects
6090
- * @param {FooGallery.utils.Bounds} bounds - The bounds to check.
6091
- * @returns {boolean}
6092
- */
6093
- intersects: function (bounds) {
6094
- return this.isAttached ? this.bounds().intersects(bounds) : false;
6095
- },
6096
- /**
6097
- * @summary Listens for the click event on the {@link FooGallery.Item#$anchor|$anchor} element and updates the state if enabled.
6098
- * @memberof FooGallery.Item#
6099
- * @function onAnchorClick
6100
- * @param {jQuery.Event} e - The jQuery.Event object for the click event.
6101
- * @private
6102
- */
6103
- onAnchorClick: function (e) {
6104
- var self = e.data.self,
6105
- state = self.tmpl.state.get(self);
6106
- self.tmpl.state.update(state);
6107
- },
6108
- /**
6109
- * @summary Listens for the click event on the {@link FooGallery.Item#$caption|$caption} element and redirects it to the anchor if required.
6110
- * @memberof FooGallery.Item#
6111
- * @function onCaptionClick
6112
- * @param {jQuery.Event} e - The jQuery.Event object for the click event.
6113
- * @private
6114
- */
6115
- onCaptionClick: function (e) {
6116
- var self = e.data.self;
6117
- if (self.$anchor.length > 0) {
6118
- self.$anchor.get(0).click();
6119
- }
6120
- }
6121
- });
6122
-
6123
- /**
6124
- * @summary Called when setting an items' image size to prevent layout jumps.
6125
- * @callback FooGallery.Item~maxWidthCallback
6126
- * @param {FooGallery.Item} item - The item to determine the maxWidth for.
6127
- * @returns {number} Returns the maximum width allowed for the {@link FooGallery.Item#$image|$image} element.
6128
- * @example {@caption An example of the default behavior this callback replaces would look like the below.}
6129
- * {
6130
- * "maxWidth": function(item){
6131
- * return item.$image.outerWidth();
6132
- * }
6133
- * }
6134
- */
6135
-
6136
- /**
6137
- * @summary A simple object containing an items' default values.
6138
- * @typedef {object} FooGallery.Item~Options
6139
- * @property {?string} [type="item"] - The `data-type` attribute for the anchor element.
6140
- * @property {?string} [id=null] - The `data-id` attribute for the outer element.
6141
- * @property {?string} [href=null] - The `href` attribute for the anchor element.
6142
- * @property {?string} [src=null] - The `src` attribute for the image element.
6143
- * @property {?string} [srcset=null] - The `srcset` attribute for the image element.
6144
- * @property {number} [width=0] - The width of the image.
6145
- * @property {number} [height=0] - The height of the image.
6146
- * @property {?string} [title=null] - The title for the image. This should be plain text.
6147
- * @property {?string} [alt=null] - The alt for the image. This should be plain text.
6148
- * @property {?string} [caption=null] - The caption for the image. This can contain HTML content.
6149
- * @property {?string} [description=null] - The description for the image. This can contain HTML content.
6150
- * @property {string[]} [tags=[]] - The `data-tags` attribute for the outer element.
6151
- * @property {?FooGallery.Item~maxWidthCallback} [maxWidth=null] - Called when setting an items' image size. If not supplied the images outer width is used.
6152
- * @property {number} [maxCaptionLength=0] - The max length of the title for the caption.
6153
- * @property {number} [maxDescriptionLength=0] - The max length of the description for the caption.
6154
- * @property {boolean} [showCaptionTitle=true] - Whether or not the caption title should be displayed.
6155
- * @property {boolean} [showCaptionDescription=true] - Whether or not the caption description should be displayed.
6156
- * @property {FooGallery.Item~Attributes} [attr] - Additional attributes to apply to the items' elements.
6157
- */
6158
- _.template.configure("core", {
6159
- item: {
6160
- type: "item",
6161
- id: "",
6162
- href: "",
6163
- src: "",
6164
- srcset: "",
6165
- width: 0,
6166
- height: 0,
6167
- title: "",
6168
- alt: "",
6169
- caption: "",
6170
- description: "",
6171
- tags: [],
6172
- maxWidth: null,
6173
- maxCaptionLength: 0,
6174
- maxDescriptionLength: 0,
6175
- showCaptionTitle: true,
6176
- showCaptionDescription: true,
6177
- attr: {
6178
- elem: {},
6179
- inner: {},
6180
- anchor: {},
6181
- image: {},
6182
- caption: {
6183
- elem: {},
6184
- inner: {},
6185
- title: {},
6186
- description: {}
6187
  }
6188
  }
 
6189
  }
6190
- }, {
6191
- item: {
6192
- elem: "fg-item",
6193
- inner: "fg-item-inner",
6194
- anchor: "fg-thumb",
6195
- wrap: "fg-image-wrap",
6196
- image: "fg-image",
6197
- loader: "fg-loader",
6198
- idle: "fg-idle",
6199
- loading: "fg-loading",
6200
- loaded: "fg-loaded",
6201
- error: "fg-error",
6202
- caption: {
6203
- elem: "fg-caption",
6204
- inner: "fg-caption-inner",
6205
- title: "fg-caption-title",
6206
- description: "fg-caption-desc"
6207
- }
6208
- }
6209
- }, {
6210
- item: {}
6211
  });
6212
 
6213
- _.components.register("item", _.Item);
6214
-
6215
- // ######################
6216
- // ## Type Definitions ##
6217
- // ######################
6218
-
6219
- /**
6220
- * @summary A simple object containing the CSS classes used by an item.
6221
- * @typedef {object} FooGallery.Item~CSSClasses
6222
- * @property {string} [elem="fg-item"] - The CSS class for the outer containing `div` element of an item.
6223
- * @property {string} [inner="fg-item-inner"] - The CSS class for the inner containing `div` element of an item.
6224
- * @property {string} [anchor="fg-thumb"] - The CSS class for the `a` element of an item.
6225
- * @property {string} [image="fg-image"] - The CSS class for the `img` element of an item.
6226
- * @property {string} [loading="fg-idle"] - The CSS class applied to an item that is waiting to be loaded.
6227
- * @property {string} [loading="fg-loading"] - The CSS class applied to an item while it is loading.
6228
- * @property {string} [loaded="fg-loaded"] - The CSS class applied to an item once it is loaded.
6229
- * @property {string} [error="fg-error"] - The CSS class applied to an item if it throws an error while loading.
6230
- * @property {object} [caption] - A simple object containing the CSS classes used by an items' caption.
6231
- * @property {string} [caption.elem="fg-caption"] - The CSS class for the outer containing `div` element of a caption.
6232
- * @property {string} [caption.inner="fg-caption-inner"] - The CSS class for the inner containing `div` element of a caption.
6233
- * @property {string} [caption.title="fg-caption-title"] - The CSS class for the title `div` element of a caption.
6234
- * @property {string} [caption.description="fg-caption-desc"] - The CSS class for the description `div` element of a caption.
6235
- */
6236
- /**
6237
- * @summary A simple object used to store any additional attributes to apply to an items' elements.
6238
- * @typedef {object} FooGallery.Item~Attributes
6239
- * @property {object} [elem={}] - The attributes to apply to the items' outer `<div/>` element.
6240
- * @property {object} [inner={}] - The attributes to apply to the items' inner element.
6241
- * @property {object} [anchor={}] - The attributes to apply to the items' anchor element.
6242
- * @property {object} [image={}] - The attributes to apply to the items' image element.
6243
- * @property {object} [caption] - A simple object used to store any additional attributes to apply to an items' caption elements.
6244
- * @property {object} [caption.elem={}] - The attributes to apply to the captions' outer `<div/>` element.
6245
- * @property {object} [caption.inner={}] - The attributes to apply to the captions' inner element.
6246
- * @property {object} [caption.title={}] - The attributes to apply to the captions' title element.
6247
- * @property {object} [caption.description={}] - The attributes to apply to the captions' description element.
6248
- */
6249
 
6250
  })(
6251
  FooGallery.$,
@@ -6255,603 +6773,1261 @@
6255
  FooGallery.utils.fn,
6256
  FooGallery.utils.obj
6257
  );
6258
- (function ($, _, _utils, _is, _fn, _obj) {
6259
 
6260
- _.Items = _.Component.extend(/** @lends FooGallery.Items */{
6261
  /**
6262
- * @summary This class controls everything related to items and serves as the base class for the various paging types.
6263
  * @memberof FooGallery
6264
- * @constructs Items
6265
- * @param {FooGallery.Template} template - The template for this component.
 
6266
  * @augments FooGallery.Component
6267
  * @borrows FooGallery.utils.Class.extend as extend
6268
  * @borrows FooGallery.utils.Class.override as override
6269
  */
6270
- construct: function (template) {
6271
  var self = this;
6272
  /**
6273
  * @ignore
6274
- * @memberof FooGallery.Items#
6275
  * @function _super
6276
  */
6277
  self._super(template);
6278
- self.idMap = {};
6279
- self._fetched = null;
6280
- self._arr = [];
6281
- self._available = [];
6282
- self._canvas = document.createElement("canvas");
6283
- // add the .all caption selector
6284
- var cls = self.tmpl.cls.item.caption;
6285
- self.tmpl.sel.item.caption.all = _utils.selectify([cls.elem, cls.inner, cls.title, cls.description]);
6286
- },
6287
- destroy: function () {
6288
- var self = this, items = self.all(), destroyed = [];
6289
- if (items.length > 0) {
6290
- /**
6291
- * @summary Raised before the template destroys its' items.
6292
- * @event FooGallery.Template~"destroy-items.foogallery"
6293
- * @type {jQuery.Event}
6294
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6295
- * @param {FooGallery.Template} template - The template raising the event.
6296
- * @param {FooGallery.Item[]} items - The array of items about to be destroyed.
6297
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6298
- * $(".foogallery").foogallery({
6299
- * on: {
6300
- * "destroy-items.foogallery": function(event, template, items){
6301
- * // do something
6302
- * }
6303
- * }
6304
- * });
6305
- */
6306
- self.tmpl.raise("destroy-items", [items]);
6307
- destroyed = $.map(items, function (item) {
6308
- return item.destroy() ? item : null;
6309
- });
6310
- /**
6311
- * @summary Raised after the template has destroyed items.
6312
- * @event FooGallery.Template~"destroyed-items.foogallery"
6313
- * @type {jQuery.Event}
6314
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6315
- * @param {FooGallery.Template} template - The template raising the event.
6316
- * @param {FooGallery.Item[]} items - The array of items destroyed.
6317
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6318
- * $(".foogallery").foogallery({
6319
- * on: {
6320
- * "destroyed-items.foogallery": function(event, template, items){
6321
- * // do something
6322
- * }
6323
- * }
6324
- * });
6325
- */
6326
- if (destroyed.length > 0) self.tmpl.raise("destroyed-items", [destroyed]);
6327
- // should we handle a case where the destroyed.length != items.length??
6328
- }
6329
- self.idMap = {};
6330
- self._canvas = self._fetched = null;
6331
- self._arr = [];
6332
- self._available = [];
6333
- self._super();
6334
- },
6335
- fetch: function (refresh) {
6336
- var self = this;
6337
- if (!refresh && _is.promise(self._fetched)) return self._fetched;
6338
- var fg = self.tmpl, selectors = fg.sel,
6339
- option = fg.opt.items,
6340
- def = $.Deferred();
6341
 
6342
- var items = self.make(fg.$el.find(selectors.item.elem));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6343
 
6344
- if (!_is.empty(option)) {
6345
- if (_is.array(option)) {
6346
- items.push.apply(items, self.make(option));
6347
- def.resolve(items);
6348
- } else if (_is.string(option)) {
6349
- $.get(option).then(function (response) {
6350
- items.push.apply(items, self.make(response));
6351
- def.resolve(items);
6352
- }, function (jqXHR, textStatus, errorThrown) {
6353
- console.log("FooGallery: GET items error.", option, jqXHR, textStatus, errorThrown);
6354
- def.resolve(items);
6355
- });
6356
- } else {
6357
- def.resolve(items);
6358
- }
6359
- } else {
6360
- items.push.apply(items, self.make(window[fg.id + "-items"]));
6361
- def.resolve(items);
6362
- }
6363
- def.then(function (items) {
6364
- self.setAll(items);
6365
- });
6366
- return self._fetched = def.promise();
6367
- },
6368
- all: function () {
6369
- return this._arr.slice();
6370
- },
6371
- count: function (all) {
6372
- return all ? this.all().length : this.available().length;
6373
- },
6374
- available: function () {
6375
- return this._available.slice();
6376
- },
6377
- get: function (id) {
6378
- return !_is.empty(id) && !!this.idMap[id] ? this.idMap[id] : null;
6379
- },
6380
- setAll: function (items) {
6381
- this._arr = _is.array(items) ? items : [];
6382
- this.idMap = this.createIdMap(items);
6383
- this._available = this.all();
6384
- },
6385
- setAvailable: function (items) {
6386
- this._available = _is.array(items) ? items : [];
6387
- },
6388
- reset: function () {
6389
- this.setAvailable(this.all());
6390
- },
6391
- /**
6392
- * @summary Filter the supplied `items` and return only those that can be loaded.
6393
- * @memberof FooGallery.Items#
6394
- * @function loadable
6395
- * @param {FooGallery.Item[]} items - The items to filter.
6396
- * @returns {FooGallery.Item[]}
6397
- */
6398
- loadable: function (items) {
6399
- var self = this, opt = self.tmpl.opt, viewport;
6400
- if (opt.lazy) {
6401
- viewport = _utils.getViewportBounds(opt.viewport);
6402
- }
6403
- return _is.array(items) ? $.map(items, function (item) {
6404
- return item.isCreated && item.isAttached && !item.isLoading && !item.isLoaded && !item.isError && (!opt.lazy || (opt.lazy && item.intersects(viewport))) ? item : null;
6405
- }) : [];
6406
- },
6407
- /**
6408
- * @summary Filter the supplied `items` and return only those that can be created.
6409
- * @memberof FooGallery.Items#
6410
- * @function creatable
6411
- * @param {FooGallery.Item[]} items - The items to filter.
6412
- * @returns {FooGallery.Item[]}
6413
- */
6414
- creatable: function (items) {
6415
- return _is.array(items) ? $.map(items, function (item) {
6416
- return item instanceof _.Item && !item.isCreated ? item : null;
6417
- }) : [];
6418
- },
6419
- /**
6420
- * @summary Filter the supplied `items` and return only those that can be appended.
6421
- * @memberof FooGallery.Items#
6422
- * @function appendable
6423
- * @param {FooGallery.Item[]} items - The items to filter.
6424
- * @returns {FooGallery.Item[]}
6425
- */
6426
- appendable: function (items) {
6427
- return _is.array(items) ? $.map(items, function (item) {
6428
- return item instanceof _.Item && item.isCreated && !item.isAttached ? item : null;
6429
- }) : [];
6430
- },
6431
- /**
6432
- * @summary Filter the supplied `items` and return only those that can be detached.
6433
- * @memberof FooGallery.Items#
6434
- * @function detachable
6435
- * @param {FooGallery.Item[]} items - The items to filter.
6436
- * @returns {FooGallery.Item[]}
6437
- */
6438
- detachable: function (items) {
6439
- return _is.array(items) ? $.map(items, function (item) {
6440
- return item instanceof _.Item && item.isCreated && item.isAttached ? item : null;
6441
- }) : [];
6442
- },
6443
- /**
6444
- * @summary Get a single jQuery object containing all the supplied items' elements.
6445
- * @memberof FooGallery.Items#
6446
- * @function jquerify
6447
- * @param {FooGallery.Item[]} items - The items to get a jQuery object for.
6448
- * @returns {jQuery}
6449
- */
6450
- jquerify: function (items) {
6451
- return $($.map(items, function (item) {
6452
- return item.$el.get();
6453
- }));
6454
- },
6455
- /**
6456
- * @summary Makes a jQuery object, NodeList or an array of elements or item options, into an array of {@link FooGallery.Item|item} objects.
6457
- * @memberof FooGallery.Items#
6458
- * @function make
6459
- * @param {(jQuery|NodeList|Node[]|FooGallery.Item~Options[])} items - The value to convert into an array of items.
6460
- * @returns {FooGallery.Item[]} The array of items successfully made.
6461
- * @fires FooGallery.Template~"make-items.foogallery"
6462
- * @fires FooGallery.Template~"made-items.foogallery"
6463
- * @fires FooGallery.Template~"parsed-items.foogallery"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6464
  */
6465
- make: function (items) {
6466
- var self = this, made = [];
6467
- if (_is.jq(items) || _is.array(items)) {
6468
- var parsed = [], arr = $.makeArray(items);
6469
- if (arr.length === 0) return made;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6470
  /**
6471
- * @summary Raised before the template makes an array of elements or item options into an array of {@link FooGallery.Item|item} objects.
6472
- * @event FooGallery.Template~"make-items.foogallery"
6473
  * @type {jQuery.Event}
6474
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6475
  * @param {FooGallery.Template} template - The template raising the event.
6476
- * @param {(HTMLElement[]|FooGallery.Item~Options[])} items - The array of Nodes or item options.
6477
- * @returns {(HTMLElement[]|FooGallery.Item~Options[])} A filtered list of items to make.
6478
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6479
  * $(".foogallery").foogallery({
6480
- * on: {
6481
- * "make-items.foogallery": function(event, template, items){
6482
- * // do something
6483
- * }
6484
- * }
6485
- * });
6486
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being made.}
6487
- * $(".foogallery").foogallery({
6488
- * on: {
6489
- * "make-items.foogallery": function(event, template, items){
6490
- * if ("some condition"){
6491
- * // stop any items being made
6492
- * event.preventDefault();
6493
- * }
6494
- * }
6495
- * }
6496
- * });
6497
  */
6498
- var e = self.tmpl.raise("make-items", [arr]);
6499
- if (!e.isDefaultPrevented()) {
6500
- made = $.map(arr, function (obj) {
6501
- var type = self.type(obj),
6502
- opt = _obj.extend(_is.hash(obj) ? obj : {}, {type: type});
6503
- var item = _.components.make(type, self.tmpl, opt);
6504
- if (_is.element(obj)) {
6505
- if (item.parse(obj)) {
6506
- parsed.push(item);
6507
- return item;
6508
- }
6509
- return null;
6510
- }
6511
- return item;
6512
- });
6513
- }
 
 
 
6514
 
6515
- /**
6516
- * @summary Raised after the template has made an array of {@link FooGallery.Item|item} objects.
6517
- * @event FooGallery.Template~"made-items.foogallery"
6518
- * @type {jQuery.Event}
6519
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6520
- * @param {FooGallery.Template} template - The template raising the event.
6521
- * @param {FooGallery.Item[]} items - The array of items made, this includes parsed items.
6522
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6523
- * $(".foogallery").foogallery({
6524
- * on: {
6525
- * "made-items.foogallery": function(event, template, items){
6526
- * // do something
6527
- * }
6528
- * }
6529
- * });
6530
- */
6531
- if (made.length > 0) self.tmpl.raise("made-items", [made]);
6532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6533
  /**
6534
- * @summary Raised after the template has parsed any elements into an array of {@link FooGallery.Item|item} objects.
6535
- * @event FooGallery.Template~"parsed-items.foogallery"
6536
  * @type {jQuery.Event}
6537
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6538
  * @param {FooGallery.Template} template - The template raising the event.
6539
- * @param {FooGallery.Item[]} items - The array of items parsed.
 
6540
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6541
  * $(".foogallery").foogallery({
6542
  * on: {
6543
- * "parsed-items.foogallery": function(event, template, items){
6544
  * // do something
6545
  * }
6546
  * }
6547
  * });
6548
  */
6549
- if (parsed.length > 0) self.tmpl.raise("parsed-items", [parsed]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6550
  }
6551
- return made;
6552
- },
6553
- type: function (objOrElement) {
6554
- var type;
6555
- if (_is.hash(objOrElement)) {
6556
- type = objOrElement.type;
6557
- } else if (_is.element(objOrElement)) {
6558
- var $el = $(objOrElement), item = this.tmpl.sel.item;
6559
- // if (_is.string(item.video) && $el.is(item.video)){
6560
- // type = "video";
6561
- // } else {
6562
- // }
6563
- type = $el.find(item.anchor).data("type");
 
 
 
 
 
 
 
 
 
 
 
 
6564
  }
6565
- return _is.string(type) && _.components.contains(type) ? type : "item";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6566
  },
6567
  /**
6568
- * @summary Create each of the supplied {@link FooGallery.Item|`items`} elements.
6569
- * @memberof FooGallery.Items#
6570
  * @function create
6571
- * @param {FooGallery.Item[]} items - The array of items to create.
6572
- * @param {boolean} [append=false] - Whether or not to automatically append the item after it is created.
6573
- * @returns {FooGallery.Item[]} The array of items that were created or if `append` is `true` the array of items that were appended.
6574
- * @description This will only create and/or append items that are not already created and/or appended so it is safe to call without worrying about the items' pre-existing state.
6575
- * @fires FooGallery.Template~"create-items.foogallery"
6576
- * @fires FooGallery.Template~"created-items.foogallery"
6577
- * @fires FooGallery.Template~"append-items.foogallery"
6578
- * @fires FooGallery.Template~"appended-items.foogallery"
6579
  */
6580
- create: function (items, append) {
6581
- var self = this, created = [], creatable = self.creatable(items);
6582
- if (creatable.length > 0) {
6583
  /**
6584
- * @summary Raised before the template creates the `items` elements.
6585
- * @event FooGallery.Template~"create-items.foogallery"
6586
  * @type {jQuery.Event}
6587
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6588
  * @param {FooGallery.Template} template - The template raising the event.
6589
- * @param {FooGallery.Item[]} items - The array of items to create.
6590
- * @param {boolean} [append=false] - Whether or not to automatically append the item after it is created.
6591
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6592
  * $(".foogallery").foogallery({
6593
  * on: {
6594
- * "create-items.foogallery": function(event, template, items){
6595
  * // do something
6596
  * }
6597
  * }
6598
  * });
6599
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being created.}
6600
  * $(".foogallery").foogallery({
6601
  * on: {
6602
- * "create-items.foogallery": function(event, template, items){
6603
  * if ("some condition"){
6604
- * // stop any items being created
6605
  * event.preventDefault();
6606
  * }
6607
  * }
6608
  * }
6609
  * });
6610
- */
6611
- var e = self.tmpl.raise("create-items", [creatable]);
6612
- if (!e.isDefaultPrevented()) {
6613
- created = $.map(creatable, function (item) {
6614
- return item.create() ? item : null;
6615
- });
6616
- }
6617
- /**
6618
- * @summary Raised after the template has created the `items` elements.
6619
- * @event FooGallery.Template~"created-items.foogallery"
6620
- * @type {jQuery.Event}
6621
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6622
- * @param {FooGallery.Template} template - The template raising the event.
6623
- * @param {FooGallery.Item[]} items - The array of items created.
6624
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6625
  * $(".foogallery").foogallery({
6626
  * on: {
6627
- * "created-items.foogallery": function(event, template, items){
6628
- * // do something
 
 
 
 
 
 
6629
  * }
6630
  * }
6631
  * });
6632
  */
6633
- if (created.length > 0) self.tmpl.raise("created-items", [created]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6634
  }
6635
- if (_is.boolean(append) ? append : false) return self.append(items);
6636
- return created;
6637
  },
6638
  /**
6639
- * @summary Append each of the supplied {@link FooGallery.Item|`items`} to the template.
6640
- * @memberof FooGallery.Items#
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6641
  * @function append
6642
- * @param {FooGallery.Item[]} items - The array of items to append.
6643
- * @returns {FooGallery.Item[]} The array of items that were appended.
6644
- * @fires FooGallery.Template~"append-items.foogallery"
6645
- * @fires FooGallery.Template~"appended-items.foogallery"
6646
  */
6647
- append: function (items) {
6648
- var self = this, appended = [], appendable = self.appendable(items);
6649
- if (appendable.length > 0) {
6650
  /**
6651
- * @summary Raised before the template appends any items to itself.
6652
- * @event FooGallery.Template~"append-items.foogallery"
6653
  * @type {jQuery.Event}
6654
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6655
  * @param {FooGallery.Template} template - The template raising the event.
6656
- * @param {FooGallery.Item[]} items - The array of items to append.
6657
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6658
  * $(".foogallery").foogallery({
6659
  * on: {
6660
- * "append-items.foogallery": function(event, template, items){
6661
  * // do something
6662
  * }
6663
  * }
6664
  * });
6665
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being appended.}
6666
  * $(".foogallery").foogallery({
6667
  * on: {
6668
- * "append-items.foogallery": function(event, template, items){
6669
  * if ("some condition"){
6670
- * // stop any items being appended
6671
  * event.preventDefault();
6672
  * }
6673
  * }
6674
  * }
6675
  * });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6676
  */
6677
- var e = self.tmpl.raise("append-items", [appendable]);
6678
  if (!e.isDefaultPrevented()) {
6679
- appended = $.map(appendable, function (item) {
6680
- return item.append() ? item : null;
6681
- });
6682
  }
6683
- /**
6684
- * @summary Raised after the template has appended items to itself.
6685
- * @event FooGallery.Template~"appended-items.foogallery"
6686
- * @type {jQuery.Event}
6687
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6688
- * @param {FooGallery.Template} template - The template raising the event.
6689
- * @param {FooGallery.Item[]} items - The array of items appended.
6690
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6691
- * $(".foogallery").foogallery({
 
6692
  * on: {
6693
- * "appended-items.foogallery": function(event, template, items){
6694
  * // do something
6695
  * }
6696
  * }
6697
  * });
6698
- */
6699
- if (appended.length > 0) self.tmpl.raise("appended-items", [appended]);
 
6700
  }
6701
- return appended;
6702
  },
6703
  /**
6704
- * @summary Detach each of the supplied {@link FooGallery.Item|`items`} from the template.
6705
- * @memberof FooGallery.Items#
6706
  * @function detach
6707
- * @param {FooGallery.Item[]} items - The array of items to detach.
6708
- * @returns {FooGallery.Item[]} The array of items that were detached.
6709
- * @fires FooGallery.Template~"detach-items.foogallery"
6710
- * @fires FooGallery.Template~"detached-items.foogallery"
6711
  */
6712
- detach: function (items) {
6713
- var self = this, detached = [], detachable = self.detachable(items);
6714
- if (detachable.length > 0) {
6715
  /**
6716
- * @summary Raised before the template detaches any items from itself.
6717
- * @event FooGallery.Template~"detach-items.foogallery"
6718
  * @type {jQuery.Event}
6719
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6720
  * @param {FooGallery.Template} template - The template raising the event.
6721
- * @param {FooGallery.Item[]} items - The array of items to detach.
6722
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6723
  * $(".foogallery").foogallery({
6724
  * on: {
6725
- * "detach-items.foogallery": function(event, template, items){
6726
  * // do something
6727
  * }
6728
  * }
6729
  * });
6730
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being detached.}
6731
  * $(".foogallery").foogallery({
6732
  * on: {
6733
- * "detach-items.foogallery": function(event, template, items){
6734
  * if ("some condition"){
6735
- * // stop any items being detached
6736
  * event.preventDefault();
6737
  * }
6738
  * }
6739
  * }
6740
  * });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6741
  */
6742
- var e = self.tmpl.raise("detach-items", [detachable]);
6743
  if (!e.isDefaultPrevented()) {
6744
- detached = $.map(detachable, function (item) {
6745
- return item.detach() ? item : null;
6746
- });
6747
  }
6748
- /**
6749
- * @summary Raised after the template has detached items from itself.
6750
- * @event FooGallery.Template~"detached-items.foogallery"
6751
- * @type {jQuery.Event}
6752
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6753
- * @param {FooGallery.Template} template - The template raising the event.
6754
- * @param {FooGallery.Item[]} items - The array of items detached.
6755
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6756
- * $(".foogallery").foogallery({
 
6757
  * on: {
6758
- * "detached-items.foogallery": function(event, template, items){
6759
  * // do something
6760
  * }
6761
  * }
6762
  * });
6763
- */
6764
- if (detached.length > 0) self.tmpl.raise("detached-items", [detached]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6765
  }
6766
- return detached;
6767
  },
6768
  /**
6769
- * @summary Load each of the supplied `items` images.
6770
- * @memberof FooGallery.Items#
6771
- * @function load
6772
- * @param {FooGallery.Item[]} items - The array of items to load.
6773
- * @returns {Promise<FooGallery.Item[]>} Resolved with an array of {@link FooGallery.Item|items} as the first argument. If no items are loaded this array is empty.
6774
- * @fires FooGallery.Template~"load-items.foogallery"
6775
- * @fires FooGallery.Template~"loaded-items.foogallery"
6776
  */
6777
- load: function (items) {
6778
- var self = this;
6779
- items = self.loadable(items);
6780
- if (items.length > 0) {
6781
- /**
6782
- * @summary Raised before the template loads any items.
6783
- * @event FooGallery.Template~"load-items.foogallery"
6784
- * @type {jQuery.Event}
6785
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6786
- * @param {FooGallery.Template} template - The template raising the event.
6787
- * @param {FooGallery.Item[]} items - The array of items to load.
6788
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6789
- * $(".foogallery").foogallery({
6790
- * on: {
6791
- * "load-items.foogallery": function(event, template, items){
6792
- * // do something
6793
- * }
6794
- * }
6795
- * });
6796
- * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any `items` being loaded.}
6797
- * $(".foogallery").foogallery({
6798
- * on: {
6799
- * "load-items.foogallery": function(event, template, items){
6800
- * if ("some condition"){
6801
- * // stop any items being loaded
6802
- * event.preventDefault();
6803
- * }
6804
- * }
6805
- * }
6806
- * });
6807
- */
6808
- var e = self.tmpl.raise("load-items", [items]);
6809
- if (!e.isDefaultPrevented()) {
6810
- var loading = $.map(items, function (item) {
6811
- return item.load();
6812
- });
6813
- return _fn.when(loading).done(function (loaded) {
6814
- /**
6815
- * @summary Raised after the template has loaded items.
6816
- * @event FooGallery.Template~"loaded-items.foogallery"
6817
- * @type {jQuery.Event}
6818
- * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6819
- * @param {FooGallery.Template} template - The template raising the event.
6820
- * @param {FooGallery.Item[]} items - The array of items that were loaded.
6821
- * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6822
- * $(".foogallery").foogallery({
6823
- * on: {
6824
- * "loaded-items.foogallery": function(event, template, items){
6825
- * // do something
6826
- * }
6827
- * }
6828
- * });
6829
- */
6830
- self.tmpl.raise("loaded-items", [loaded]);
6831
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6832
  }
6833
  }
6834
- return _fn.resolveWith([]);
6835
- },
6836
- createIdMap: function (items) {
6837
- var map = {};
6838
- $.each(items, function (i, item) {
6839
- if (_is.empty(item.id)) item.id = "" + (i + 1);
6840
- map[item.id] = item;
6841
- });
6842
- return map;
6843
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6844
  });
6845
 
6846
- _.components.register("items", _.Items);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6847
 
6848
  })(
6849
- FooGallery.$,
6850
- FooGallery,
6851
- FooGallery.utils,
6852
- FooGallery.utils.is,
6853
- FooGallery.utils.fn,
6854
- FooGallery.utils.obj
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6855
  );
6856
  (function ($, _, _utils, _is) {
6857
 
@@ -6879,6 +8055,24 @@
6879
  self.ctrls = [];
6880
  self._arr = [];
6881
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6882
  destroy: function () {
6883
  var self = this;
6884
  self._arr.splice(0, self._arr.length);
@@ -7357,6 +8551,14 @@
7357
  }
7358
  return self.style.sheet;
7359
  },
 
 
 
 
 
 
 
 
7360
  /**
7361
  * @summary Listens for the {@link FooGallery.Template~event:"pre-init.foogallery"|`pre-init.foogallery`} event.
7362
  * @memberof FooGallery.MasonryTemplate#
@@ -7433,9 +8635,10 @@
7433
  self.masonry.layout();
7434
  },
7435
  onReady: function(event, self){
7436
- self.masonry.layout();
7437
  },
7438
  onDestroy: function(event, self){
 
7439
  self.$el.find(self.sel.columnWidth).remove();
7440
  self.$el.find(self.sel.gutterWidth).remove();
7441
  if (self.style && self.style.parentNode){
@@ -7520,6 +8723,7 @@
7520
  });
7521
 
7522
  _.template.register("masonry", _.MasonryTemplate, {
 
7523
  template: {
7524
  initLayout: false,
7525
  isInitLayout: false,
@@ -7888,7 +9092,7 @@
7888
  maxRowHeight: "200%",
7889
  margins: 0,
7890
  lastRow: "center",
7891
- justifyThreshold: 0.5,
7892
  refreshInterval: 250
7893
  };
7894
 
@@ -8335,6 +9539,8 @@
8335
  }
8336
  };
8337
 
 
 
8338
  _.auto = function (options) {
8339
  _.autoDefaults = _obj.merge(_.autoDefaults, options);
8340
  };
@@ -8342,11 +9548,15 @@
8342
  _.load = _.reload = function(){
8343
  // this automatically initializes all templates on page load
8344
  $(function () {
8345
- $('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(_.autoDefaults);
 
 
8346
  });
8347
 
8348
  _utils.ready(function () {
8349
- $('[id^="foogallery-gallery-"].fg-ready').foogallery(_.autoDefaults);
 
 
8350
  });
8351
  };
8352
 
3
  /**
4
  * @summary A reference to the jQuery object the plugin is registered with.
5
  * @memberof FooGallery
6
+ * @function $
7
  * @type {jQuery}
8
  * @description This is used internally for all jQuery operations to help work around issues where multiple jQuery libraries have been included in a single page.
9
  * @example {@caption The following shows the issue when multiple jQuery's are included in a single page.}{@lang xml}
32
  * @external "jQuery.fn"
33
  * @see {@link http://learn.jquery.com/plugins/basic-plugin-creation/|How to Create a Basic Plugin | jQuery Learning Center}
34
  */
35
+
36
  })(
37
  // dependencies
38
  jQuery,
59
  );
60
  /*!
61
  * FooGallery.utils - Contains common utility methods and classes used in our plugins.
62
+ * @version 0.1.7
63
  * @link https://github.com/steveush/foo-utils#readme
64
  * @copyright Steve Usher 2019
65
  * @license Released under the GPL-3.0 license.
112
  * @name version
113
  * @type {string}
114
  */
115
+ version: '0.1.7'
116
  };
117
 
118
  /**
208
  })(jQuery);
209
  (function ($, _){
210
  // only register methods if this version is the current version
211
+ if (_.version !== '0.1.7') return;
212
 
213
  /**
214
  * @summary Contains common type checking utility methods.
562
  );
563
  (function($, _, _is){
564
  // only register methods if this version is the current version
565
+ if (_.version !== '0.1.7') return;
566
 
567
  /**
568
  * @memberof FooGallery.utils
1145
  );
1146
  (function(_, _is){
1147
  // only register methods if this version is the current version
1148
+ if (_.version !== '0.1.7') return;
1149
 
1150
  /**
1151
  * @summary Contains common url utility methods.
1171
  */
1172
  _.url.parts = function(url){
1173
  _a.href = url;
1174
+ var port = _a.port ? _a.port : (["http:","https:"].indexOf(_a.protocol) !== -1 ? (_a.protocol === "https:" ? "443" : "80") : ""),
1175
+ host = _a.hostname + (port ? ":" + port : ""),
1176
+ origin = _a.origin ? _a.origin : _a.protocol + "//" + host,
1177
+ pathname = _a.pathname.slice(0, 1) === "/" ? _a.pathname : "/" + _a.pathname;
1178
  return {
1179
+ hash: _a.hash, host: host, hostname: _a.hostname, href: _a.href,
1180
+ origin: origin, pathname: pathname, port: port,
1181
  protocol: _a.protocol, search: _a.search
1182
  };
1183
  };
1212
  * @function param
1213
  * @param {string} search - The search string to use (usually `location.search`).
1214
  * @param {string} key - The key of the parameter.
1215
+ * @param {?string} [value] - The value to set for the parameter. If not provided the current value for the `key` is returned.
1216
  * @returns {?string} The value of the `key` in the given `search` string if no `value` is supplied or `null` if the `key` does not exist.
1217
  * @returns {string} A modified `search` string if a `value` is supplied.
1218
  * @example <caption>Shows how to retrieve a parameter value from a search string.</caption>{@run true}
1239
  var regex, match, result, param;
1240
  if (_is.undef(value)){
1241
  regex = new RegExp('[?|&]' + key + '=([^&;]+?)(&|#|;|$)'); // regex to match the key and it's value but only capture the value
1242
+ match = regex.exec(search) || ["",""]; // match the param otherwise return an empty string match
1243
  result = match[1].replace(/\+/g, '%20'); // replace any + character's with spaces
1244
  return _is.string(result) && !_is.empty(result) ? decodeURIComponent(result) : null; // decode the result otherwise return null
1245
  }
1246
+ if (_is.empty(value)){
1247
  regex = new RegExp('^([^#]*\?)(([^#]*)&)?' + key + '(\=[^&#]*)?(&|#|$)');
1248
  result = search.replace(regex, '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4');
1249
  } else {
1284
  );
1285
  (function (_, _is, _fn) {
1286
  // only register methods if this version is the current version
1287
+ if (_.version !== '0.1.7') return;
1288
 
1289
  /**
1290
  * @summary Contains common string utility methods.
1372
  return false;
1373
  var parts = target.split(/\W/);
1374
  for (var i = 0, len = parts.length; i < len; i++){
1375
+ if (ignoreCase ? parts[i].toUpperCase() === word.toUpperCase() : parts[i] === word) return true;
1376
  }
1377
  return false;
1378
  };
1393
  * console.log( _str.endsWith( "something", "no" ) ); // => false
1394
  */
1395
  _.str.endsWith = function (target, substr) {
1396
+ if (!_is.string(target) || _is.empty(target) || !_is.string(substr) || _is.empty(substr)) return target === substr;
1397
+ return target.slice(target.length - substr.length) === substr;
1398
  };
1399
 
1400
  /**
1512
  */
1513
  _.str.startsWith = function (target, substr) {
1514
  if (_is.empty(target) || _is.empty(substr)) return false;
1515
+ return target.slice(0, substr.length) === substr;
1516
  };
1517
 
1518
  /**
1599
  );
1600
  (function($, _, _is, _fn, _str){
1601
  // only register methods if this version is the current version
1602
+ if (_.version !== '0.1.7') return;
1603
 
1604
  /**
1605
  * @summary Contains common object utility methods.
1931
  );
1932
  (function($, _, _is){
1933
  // only register methods if this version is the current version
1934
+ if (_.version !== '0.1.7') return;
1935
 
1936
  // any methods that have dependencies but don't fall into a specific subset or namespace can be added here
1937
 
2212
  );
2213
  (function($, _, _is){
2214
  // only register methods if this version is the current version
2215
+ if (_.version !== '0.1.7') return;
2216
+
2217
+ /**
2218
+ * @summary Contains common utility methods and members for the CSS animation property.
2219
+ * @memberof FooGallery.utils
2220
+ * @namespace animation
2221
+ */
2222
+ _.animation = {};
2223
+
2224
+ function raf(callback){
2225
+ return setTimeout(callback, 1);
2226
+ }
2227
+
2228
+ function caf(requestID){
2229
+ clearTimeout(requestID);
2230
+ }
2231
+
2232
+ /**
2233
+ * @summary A cross browser wrapper for the `requestAnimationFrame` method.
2234
+ * @memberof FooGallery.utils.animation
2235
+ * @function requestFrame
2236
+ * @param {function} callback - The function to call when it's time to update your animation for the next repaint.
2237
+ * @return {number} - The request id that uniquely identifies the entry in the callback list.
2238
+ */
2239
+ _.animation.requestFrame = (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || raf).bind(window);
2240
+
2241
+ /**
2242
+ * @summary A cross browser wrapper for the `cancelAnimationFrame` method.
2243
+ * @memberof FooGallery.utils.animation
2244
+ * @function cancelFrame
2245
+ * @param {number} requestID - The ID value returned by the call to {@link FooGallery.utils.animation.requestFrame|requestFrame} that requested the callback.
2246
+ */
2247
+ _.animation.cancelFrame = (window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || caf).bind(window);
2248
+
2249
+ // create a test element to check for the existence of the various animation properties
2250
+ var testElement = document.createElement('div');
2251
+
2252
+ /**
2253
+ * @summary Whether or not animations are supported by the current browser.
2254
+ * @memberof FooGallery.utils.animation
2255
+ * @name supported
2256
+ * @type {boolean}
2257
+ */
2258
+ _.animation.supported = (
2259
+ /**
2260
+ * @ignore
2261
+ * @summary Performs a one time test to see if animations are supported
2262
+ * @param {HTMLElement} el - An element to test with.
2263
+ * @returns {boolean} `true` if animations are supported.
2264
+ */
2265
+ function(el){
2266
+ var style = el.style;
2267
+ return _is.string(style['animation'])
2268
+ || _is.string(style['WebkitAnimation'])
2269
+ || _is.string(style['MozAnimation'])
2270
+ || _is.string(style['msAnimation'])
2271
+ || _is.string(style['OAnimation']);
2272
+ }
2273
+ )(testElement);
2274
+
2275
+ /**
2276
+ * @summary The `animationend` event name for the current browser.
2277
+ * @memberof FooGallery.utils.animation
2278
+ * @name end
2279
+ * @type {string}
2280
+ * @description Depending on the browser this returns one of the following values:
2281
+ *
2282
+ * <ul><!--
2283
+ * --><li>`"animationend"`</li><!--
2284
+ * --><li>`"webkitAnimationEnd"`</li><!--
2285
+ * --><li>`"msAnimationEnd"`</li><!--
2286
+ * --><li>`"oAnimationEnd"`</li><!--
2287
+ * --><li>`null` - If the browser doesn't support animations</li><!--
2288
+ * --></ul>
2289
+ */
2290
+ _.animation.end = (
2291
+ /**
2292
+ * @ignore
2293
+ * @summary Performs a one time test to determine which `animationend` event to use for the current browser.
2294
+ * @param {HTMLElement} el - An element to test with.
2295
+ * @returns {?string} The correct `animationend` event for the current browser, `null` if the browser doesn't support animations.
2296
+ */
2297
+ function(el){
2298
+ var style = el.style;
2299
+ if (_is.string(style['animation'])) return 'animationend';
2300
+ if (_is.string(style['WebkitAnimation'])) return 'webkitAnimationEnd';
2301
+ if (_is.string(style['MozAnimation'])) return 'animationend';
2302
+ if (_is.string(style['msAnimation'])) return 'msAnimationEnd';
2303
+ if (_is.string(style['OAnimation'])) return 'oAnimationEnd';
2304
+ return null;
2305
+ }
2306
+ )(testElement);
2307
+
2308
+ /**
2309
+ * @summary Gets the `animation-duration` value for the supplied jQuery element.
2310
+ * @memberof FooGallery.utils.animation
2311
+ * @function duration
2312
+ * @param {jQuery} $element - The jQuery element to retrieve the duration from.
2313
+ * @param {number} [def=0] - The default value to return if no duration is set.
2314
+ * @returns {number} The value of the `animation-duration` property converted to a millisecond value.
2315
+ */
2316
+ _.animation.duration = function($element, def){
2317
+ def = _is.number(def) ? def : 0;
2318
+ if (!_is.jq($element)) return def;
2319
+ // we can use jQuery.css() method to retrieve the value cross browser
2320
+ var duration = $element.css('animation-duration');
2321
+ if (/^([\d.]*)+?(ms|s)$/i.test(duration)){
2322
+ // if we have a valid time value
2323
+ var match = duration.match(/^([\d.]*)+?(ms|s)$/i),
2324
+ value = parseFloat(match[1]),
2325
+ unit = match[2].toLowerCase();
2326
+ if (unit === 's'){
2327
+ // convert seconds to milliseconds
2328
+ value = value * 1000;
2329
+ }
2330
+ return value;
2331
+ }
2332
+ return def;
2333
+ };
2334
+
2335
+ /**
2336
+ * @summary Gets the `animation-iteration-count` value for the supplied jQuery element.
2337
+ * @memberof FooGallery.utils.animation
2338
+ * @function iterations
2339
+ * @param {jQuery} $element - The jQuery element to retrieve the duration from.
2340
+ * @param {number} [def=1] - The default value to return if no iteration count is set.
2341
+ * @returns {number} The value of the `animation-iteration-count` property.
2342
+ */
2343
+ _.animation.iterations = function($element, def){
2344
+ def = _is.number(def) ? def : 1;
2345
+ if (!_is.jq($element)) return def;
2346
+ // we can use jQuery.css() method to retrieve the value cross browser
2347
+ var iterations = $element.css('animation-iteration-count');
2348
+ if (/^(\d+|infinite)$/i.test(iterations)){
2349
+ return iterations === "infinite" ? Infinity : parseInt(iterations);
2350
+ }
2351
+ return def;
2352
+ };
2353
+
2354
+ /**
2355
+ * @summary The callback function to execute when starting a animation.
2356
+ * @callback FooGallery.utils.animation~startCallback
2357
+ * @param {jQuery} $element - The element to start the animation on.
2358
+ * @this Element
2359
+ */
2360
+
2361
+ /**
2362
+ * @summary Start a animation by toggling the supplied `className` on the `$element`.
2363
+ * @memberof FooGallery.utils.animation
2364
+ * @function start
2365
+ * @param {jQuery} $element - The jQuery element to start the animation on.
2366
+ * @param {(string|FooGallery.utils.animation~startCallback)} classNameOrFunc - One or more class names (separated by spaces) to be toggled or a function that performs the required actions to start the animation.
2367
+ * @param {boolean} [state] - A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed.
2368
+ * @param {number} [timeout] - The maximum time, in milliseconds, to wait for the `animationend` event to be raised. If not provided this will be automatically set to the elements `animation-duration` multiplied by the `animation-iteration-count` property plus an extra 50 milliseconds.
2369
+ * @returns {Promise}
2370
+ * @description This method lets us use CSS animations by toggling a class and using the `animationend` event to perform additional actions once the animation has completed across all browsers. In browsers that do not support animations this method would behave the same as if just calling jQuery's `.toggleClass` method.
2371
+ *
2372
+ * The last parameter `timeout` is used to create a timer that behaves as a safety net in case the `animationend` event is never raised and ensures the deferred returned by this method is resolved or rejected within a specified time.
2373
+ *
2374
+ * If no `timeout` is supplied the `animation-duration` and `animation-iterations-count` must be set on the `$element` before this method is called so one can be generated.
2375
+ * @see {@link https://developer.mozilla.org/en/docs/Web/CSS/animation-duration|animation-duration - CSS | MDN} for more information on the `animation-duration` CSS property.
2376
+ */
2377
+ _.animation.start = function($element, classNameOrFunc, state, timeout){
2378
+ var deferred = $.Deferred(), promise = deferred.promise();
2379
+
2380
+ $element = $element.first();
2381
+
2382
+ if (_.animation.supported){
2383
+ $element.prop('offsetTop');
2384
+ var safety = $element.data('animation_safety');
2385
+ if (_is.hash(safety) && _is.number(safety.timer)){
2386
+ clearTimeout(safety.timer);
2387
+ $element.removeData('animation_safety').off(_.animation.end + '.utils');
2388
+ safety.deferred.reject();
2389
+ }
2390
+ if (!_is.number(timeout)){
2391
+ var iterations = _.animation.iterations($element);
2392
+ if (iterations === Infinity){
2393
+ deferred.reject("No timeout supplied with an infinite animation.");
2394
+ return promise;
2395
+ }
2396
+ timeout = (_.animation.duration($element) * iterations) + 50;
2397
+ }
2398
+ safety = {
2399
+ deferred: deferred,
2400
+ timer: setTimeout(function(){
2401
+ // This is the safety net in case a animation fails for some reason and the animationend event is never raised.
2402
+ // This will remove the bound event and resolve the deferred
2403
+ $element.removeData('animation_safety').off(_.animation.end + '.utils');
2404
+ deferred.resolve();
2405
+ }, timeout)
2406
+ };
2407
+ $element.data('animation_safety', safety);
2408
+
2409
+ $element.on(_.animation.end + '.utils', function(e){
2410
+ if ($element.is(e.target)){
2411
+ clearTimeout(safety.timer);
2412
+ $element.removeData('animation_safety').off(_.animation.end + '.utils');
2413
+ deferred.resolve();
2414
+ }
2415
+ });
2416
+ }
2417
+
2418
+ _.animation.requestFrame(function(){
2419
+ if (_is.fn(classNameOrFunc)){
2420
+ classNameOrFunc.apply($element.get(0), [$element]);
2421
+ } else {
2422
+ $element.toggleClass(classNameOrFunc, state);
2423
+ }
2424
+ if (!_.animation.supported){
2425
+ // If the browser doesn't support animations then just resolve the deferred
2426
+ deferred.resolve();
2427
+ }
2428
+ });
2429
+
2430
+ return promise;
2431
+ };
2432
+
2433
+ })(
2434
+ // dependencies
2435
+ FooGallery.utils.$,
2436
+ FooGallery.utils,
2437
+ FooGallery.utils.is
2438
+ );
2439
+ (function($, _, _is, _animation){
2440
+ // only register methods if this version is the current version
2441
+ if (_.version !== '0.1.7') return;
2442
 
2443
  /**
2444
  * @summary Contains common utility methods and members for the CSS transition property.
2460
  /**
2461
  * @ignore
2462
  * @summary Performs a one time test to see if transitions are supported
2463
+ * @param {HTMLElement} el - An element to test with.
2464
  * @returns {boolean} `true` if transitions are supported.
2465
  */
2466
  function(el){
2492
  /**
2493
  * @ignore
2494
  * @summary Performs a one time test to determine which `transitionend` event to use for the current browser.
2495
+ * @param {HTMLElement} el - An element to test with.
2496
  * @returns {?string} The correct `transitionend` event for the current browser, `null` if the browser doesn't support transitions.
2497
  */
2498
  function(el){
2519
  if (!_is.jq($element)) return def;
2520
  // we can use jQuery.css() method to retrieve the value cross browser
2521
  var duration = $element.css('transition-duration');
2522
+ if (/^([\d.]*)+?(ms|s)$/i.test(duration)){
2523
  // if we have a valid time value
2524
+ var match = duration.match(/^([\d.]*)+?(ms|s)$/i),
2525
  value = parseFloat(match[1]),
2526
  unit = match[2].toLowerCase();
2527
  if (unit === 's'){
2555
  * @see {@link https://developer.mozilla.org/en/docs/Web/CSS/transition-duration|transition-duration - CSS | MDN} for more information on the `transition-duration` CSS property.
2556
  */
2557
  _.transition.start = function($element, classNameOrFunc, state, timeout){
2558
+ var deferred = $.Deferred(), promise = deferred.promise();
2559
 
2560
  $element = $element.first();
2561
 
2562
  if (_.transition.supported){
2563
+ $element.prop('offsetTop');
2564
  var safety = $element.data('transition_safety');
2565
  if (_is.hash(safety) && _is.number(safety.timer)){
2566
  clearTimeout(safety.timer);
2588
  });
2589
  }
2590
 
2591
+ _animation.requestFrame(function() {
 
2592
  if (_is.fn(classNameOrFunc)){
2593
  classNameOrFunc.apply($element.get(0), [$element]);
2594
  } else {
2598
  // If the browser doesn't support transitions then just resolve the deferred
2599
  deferred.resolve();
2600
  }
2601
+ });
2602
 
2603
+ return promise;
2604
  };
2605
 
2606
  })(
2607
  // dependencies
2608
  FooGallery.utils.$,
2609
  FooGallery.utils,
2610
+ FooGallery.utils.is,
2611
+ FooGallery.utils.animation
2612
  );
2613
  (function ($, _, _is, _obj, _fn) {
2614
  // only register methods if this version is the current version
2615
+ if (_.version !== '0.1.7') return;
2616
 
2617
  /**
2618
  * @summary A base class providing some helper methods for prototypal inheritance.
2749
  FooGallery.utils.obj,
2750
  FooGallery.utils.fn
2751
  );
2752
+ (function (_, _is, _str) {
2753
  // only register methods if this version is the current version
2754
+ if (_.version !== '0.1.7') return;
2755
 
2756
  _.Event = _.Class.extend(/** @lends FooGallery.utils.Event */{
2757
  /**
2775
  * eventClass.trigger(event);
2776
  */
2777
  construct: function(type){
2778
+ if (_is.empty(type))
2779
+ throw new SyntaxError('FooGallery.utils.Event objects must be supplied a `type`.');
2780
+
2781
+ var namespaced = _str.contains(type, ".");
2782
  /**
2783
  * @summary The type of event.
2784
  * @memberof FooGallery.utils.Event#
2786
  * @type {string}
2787
  * @readonly
2788
  */
2789
+ this.type = namespaced ? _str.until(type, ".") : type;
2790
+ /**
2791
+ * @summary The namespace of the event.
2792
+ * @memberof FooGallery.utils.Event#
2793
+ * @name namespace
2794
+ * @type {string}
2795
+ * @readonly
2796
+ */
2797
+ this.namespace = namespaced ? _str.from(type, ".") : null;
2798
  /**
2799
  * @summary Whether the default action should be taken or not.
2800
  * @memberof FooGallery.utils.Event#
2803
  * @readonly
2804
  */
2805
  this.defaultPrevented = false;
2806
+ /**
2807
+ * @summary The {@link FooGallery.utils.EventClass} that triggered this event.
2808
+ * @memberof FooGallery.utils.Event#
2809
+ * @name target
2810
+ * @type {FooGallery.utils.EventClass}
2811
+ * @readonly
2812
+ */
2813
+ this.target = null;
2814
  },
2815
  /**
2816
  * @summary Informs the class that raised this event that its default action should not be taken.
2819
  */
2820
  preventDefault: function(){
2821
  this.defaultPrevented = true;
2822
+ },
2823
+ /**
2824
+ * @summary Gets whether the default action should be taken or not.
2825
+ * @memberof FooGallery.utils.Event#
2826
+ * @function isDefaultPrevented
2827
+ * @returns {boolean}
2828
+ */
2829
+ isDefaultPrevented: function(){
2830
+ return this.defaultPrevented;
2831
  }
2832
  });
2833
 
2856
  this.__handlers = {};
2857
  },
2858
  /**
2859
+ * @summary Attach multiple event handler functions for one or more events to the class.
2860
+ * @memberof FooGallery.utils.EventClass#
2861
+ * @function on
2862
+ * @param {object} events - An object containing an event name to handler mapping.
2863
+ * @param {*} [thisArg] - The value of `this` within the `handler` function. Defaults to the `EventClass` raising the event.
2864
+ * @returns {this}
2865
+ *//**
2866
  * @summary Attach an event handler function for one or more events to the class.
2867
  * @memberof FooGallery.utils.EventClass#
2868
  * @function on
2872
  * @returns {this}
2873
  */
2874
  on: function(events, handler, thisArg){
2875
+ var self = this;
2876
+ if (_is.object(events)){
2877
+ thisArg = _is.undef(handler) ? this : handler;
2878
+ Object.keys(events).forEach(function(key){
2879
+ key.split(" ").forEach(function(type){
2880
+ self.__on(type, events[key], thisArg);
 
 
 
 
 
 
 
 
2881
  });
2882
+ });
2883
+ } else if (_is.string(events) && _is.fn(handler)) {
2884
+ thisArg = _is.undef(thisArg) ? this : thisArg;
2885
+ events.split(" ").forEach(function(type){
2886
+ self.__on(type, handler, thisArg);
2887
+ });
2888
+ }
2889
+
2890
  return self;
2891
  },
2892
+ __on: function(event, handler, thisArg){
2893
+ var self = this,
2894
+ namespaced = _str.contains(event, "."),
2895
+ type = namespaced ? _str.until(event, ".") : event,
2896
+ namespace = namespaced ? _str.from(event, ".") : null;
2897
+
2898
+ if (!_is.array(self.__handlers[type])){
2899
+ self.__handlers[type] = [];
2900
+ }
2901
+ var exists = self.__handlers[type].some(function(h){
2902
+ return h.namespace === namespace && h.fn === handler && h.thisArg === thisArg;
2903
+ });
2904
+ if (!exists){
2905
+ self.__handlers[type].push({
2906
+ namespace: namespace,
2907
+ fn: handler,
2908
+ thisArg: thisArg
2909
+ });
2910
+ }
2911
+ },
2912
  /**
2913
+ * @summary Remove multiple event handler functions for one or more events from the class.
2914
+ * @memberof FooGallery.utils.EventClass#
2915
+ * @function off
2916
+ * @param {object} events - An object containing an event name to handler mapping.
2917
+ * @param {*} [thisArg] - The value of `this` within the `handler` function. Defaults to the `EventClass` raising the event.
2918
+ * @returns {this}
2919
+ *//**
2920
  * @summary Remove an event handler function for one or more events from the class.
2921
  * @memberof FooGallery.utils.EventClass#
2922
  * @function off
2923
  * @param {string} events - One or more space-separated event types.
2924
  * @param {function} handler - The handler to remove.
2925
  * @param {*} [thisArg] - The value of `this` within the `handler` function.
2926
+ * @returns {this}
2927
  */
2928
  off: function(events, handler, thisArg){
2929
+ var self = this;
2930
+ if (_is.object(events)){
2931
+ thisArg = _is.undef(handler) ? this : handler;
2932
+ Object.keys(events).forEach(function(key){
2933
+ key.split(" ").forEach(function(type){
2934
+ self.__off(type, _is.fn(events[key]) ? events[key] : null, thisArg);
2935
+ });
2936
+ });
2937
+ } else if (_is.string(events)) {
2938
+ handler = _is.fn(handler) ? handler : null;
2939
+ thisArg = _is.undef(thisArg) ? this : thisArg;
2940
+ events.split(" ").forEach(function(type){
2941
+ self.__off(type, handler, thisArg);
2942
+ });
2943
+ }
2944
+
2945
+ return self;
2946
+ },
2947
+ __off: function(event, handler, thisArg){
2948
+ var self = this,
2949
+ type = _str.until(event, ".") || null,
2950
+ namespace = _str.from(event, ".") || null,
2951
+ types = [];
2952
+
2953
+ if (!_is.empty(type)){
2954
+ types.push(type);
2955
+ } else if (!_is.empty(namespace)){
2956
+ types.push.apply(types, Object.keys(self.__handlers));
2957
+ }
2958
+
2959
+ types.forEach(function(type){
2960
+ if (!_is.array(self.__handlers[type])) return;
2961
+ self.__handlers[type] = self.__handlers[type].filter(function (h) {
2962
  if (handler != null){
2963
+ return !(h.namespace === namespace && h.fn === handler && h.thisArg === thisArg);
 
 
 
 
 
 
 
2964
  }
2965
+ if (namespace != null){
2966
+ return h.namespace !== namespace;
2967
+ }
2968
+ return false;
2969
+ });
2970
+ if (self.__handlers[type].length === 0){
2971
+ delete self.__handlers[type];
2972
  }
2973
  });
 
2974
  },
2975
  /**
2976
  * @summary Trigger an event on the current class.
2981
  * @returns {(FooGallery.utils.Event|FooGallery.utils.Event[]|null)} Returns the {@link FooGallery.utils.Event|event object} of the triggered event. If more than one event was triggered an array of {@link FooGallery.utils.Event|event objects} is returned. If no `event` was supplied or triggered `null` is returned.
2982
  */
2983
  trigger: function(event, args){
 
 
2984
  args = _is.array(args) ? args : [];
2985
+ var self = this, result = [];
2986
+ if (event instanceof _.Event){
2987
+ result.push(event);
2988
+ self.__trigger(event, args);
2989
+ } else if (_is.string(event)) {
 
 
 
 
 
 
 
 
 
2990
  event.split(" ").forEach(function(type){
2991
+ var index = result.push(new _.Event(type)) - 1;
2992
+ self.__trigger(result[index], args);
2993
  });
2994
  }
2995
  return _is.empty(result) ? null : (result.length === 1 ? result[0] : result);
2996
+ },
2997
+ __trigger: function(event, args){
2998
+ var self = this;
2999
+ event.target = self;
3000
+ if (!_is.array(self.__handlers[event.type])) return;
3001
+ self.__handlers[event.type].forEach(function (h) {
3002
+ if (event.namespace != null && h.namespace !== event.namespace) return;
3003
+ h.fn.apply(h.thisArg, [event].concat(args));
3004
+ });
3005
  }
3006
  });
3007
 
3008
  })(
3009
  // dependencies
3010
  FooGallery.utils,
3011
+ FooGallery.utils.is,
3012
+ FooGallery.utils.str
3013
  );
3014
  (function($, _, _is){
3015
  // only register methods if this version is the current version
3016
+ if (_.version !== '0.1.7') return;
3017
 
3018
  _.Bounds = _.Class.extend(/** @lends FooGallery.utils.Bounds */{
3019
  /**
3112
  FooGallery.utils,
3113
  FooGallery.utils.is
3114
  );
3115
+ (function($, _, _is, _fn, _obj){
3116
+ // only register methods if this version is the current version
3117
+ if (_.version !== '0.1.7') return;
3118
 
3119
+ _.Timer = _.EventClass.extend(/** @lends FooGallery.utils.Timer */{
3120
+ /**
3121
+ * @summary A simple timer that triggers events.
3122
+ * @constructs
3123
+ * @param {number} [interval=1000] - The internal tick interval of the timer.
3124
+ */
3125
+ construct: function(interval){
3126
+ this._super();
3127
+ /**
3128
+ * @summary The internal tick interval of the timer in milliseconds.
3129
+ * @memberof FooGallery.utils.Timer#
3130
+ * @name interval
3131
+ * @type {number}
3132
+ * @default 1000
3133
+ * @readonly
3134
+ */
3135
+ this.interval = _is.number(interval) ? interval : 1000;
3136
+ /**
3137
+ * @summary Whether the timer is currently running or not.
3138
+ * @memberof FooGallery.utils.Timer#
3139
+ * @name isRunning
3140
+ * @type {boolean}
3141
+ * @default false
3142
+ * @readonly
3143
+ */
3144
+ this.isRunning = false;
3145
+ /**
3146
+ * @summary Whether the timer is currently paused or not.
3147
+ * @memberof FooGallery.utils.Timer#
3148
+ * @name isPaused
3149
+ * @type {boolean}
3150
+ * @default false
3151
+ * @readonly
3152
+ */
3153
+ this.isPaused = false;
3154
+ /**
3155
+ * @summary Whether the timer can resume from a previous state or not.
3156
+ * @memberof FooGallery.utils.Timer#
3157
+ * @name canResume
3158
+ * @type {boolean}
3159
+ * @default false
3160
+ * @readonly
3161
+ */
3162
+ this.canResume = false;
3163
+ /**
3164
+ * @summary Whether the timer can restart or not.
3165
+ * @memberof FooGallery.utils.Timer#
3166
+ * @name canRestart
3167
+ * @type {boolean}
3168
+ * @default false
3169
+ * @readonly
3170
+ */
3171
+ this.canRestart = false;
3172
+ /**
3173
+ * @summary The internal tick timeout ID.
3174
+ * @memberof FooGallery.utils.Timer#
3175
+ * @name __timeout
3176
+ * @type {?number}
3177
+ * @default null
3178
+ * @private
3179
+ */
3180
+ this.__timeout = null;
3181
+ /**
3182
+ * @summary Whether the timer is incrementing or decrementing.
3183
+ * @memberof FooGallery.utils.Timer#
3184
+ * @name __decrement
3185
+ * @type {boolean}
3186
+ * @default false
3187
+ * @private
3188
+ */
3189
+ this.__decrement = false;
3190
+ /**
3191
+ * @summary The total time for the timer.
3192
+ * @memberof FooGallery.utils.Timer#
3193
+ * @name __time
3194
+ * @type {number}
3195
+ * @default 0
3196
+ * @private
3197
+ */
3198
+ this.__time = 0;
3199
+ /**
3200
+ * @summary The remaining time for the timer.
3201
+ * @memberof FooGallery.utils.Timer#
3202
+ * @name __remaining
3203
+ * @type {number}
3204
+ * @default 0
3205
+ * @private
3206
+ */
3207
+ this.__remaining = 0;
3208
+ /**
3209
+ * @summary The current time for the timer.
3210
+ * @memberof FooGallery.utils.Timer#
3211
+ * @name __current
3212
+ * @type {number}
3213
+ * @default 0
3214
+ * @private
3215
+ */
3216
+ this.__current = 0;
3217
+ /**
3218
+ * @summary The final time for the timer.
3219
+ * @memberof FooGallery.utils.Timer#
3220
+ * @name __finish
3221
+ * @type {number}
3222
+ * @default 0
3223
+ * @private
3224
+ */
3225
+ this.__finish = 0;
3226
+ /**
3227
+ * @summary The last arguments supplied to the {@link FooGallery.utils.Timer#start|start} method.
3228
+ * @memberof FooGallery.utils.Timer#
3229
+ * @name __restart
3230
+ * @type {Array}
3231
+ * @default []
3232
+ * @private
3233
+ */
3234
+ this.__restart = [];
3235
+ },
3236
+ /**
3237
+ * @summary Resets the timer back to a fresh starting state.
3238
+ * @memberof FooGallery.utils.Timer#
3239
+ * @function __reset
3240
+ * @private
3241
+ */
3242
+ __reset: function(){
3243
+ clearTimeout(this.__timeout);
3244
+ this.__timeout = null;
3245
+ this.__decrement = false;
3246
+ this.__time = 0;
3247
+ this.__remaining = 0;
3248
+ this.__current = 0;
3249
+ this.__finish = 0;
3250
+ this.isRunning = false;
3251
+ this.isPaused = false;
3252
+ this.canResume = false;
3253
+ },
3254
+ /**
3255
+ * @summary Generates event args to be passed to listeners of the timer events.
3256
+ * @memberof FooGallery.utils.Timer#
3257
+ * @function __eventArgs
3258
+ * @param {...*} [args] - Any number of additional arguments to pass to an event listener.
3259
+ * @return {Array} - The first 3 values of the result will always be the current time, the total time and boolean indicating if the timer is decremental.
3260
+ * @private
3261
+ */
3262
+ __eventArgs: function(args){
3263
+ return [
3264
+ this.__current,
3265
+ this.__time,
3266
+ this.__decrement
3267
+ ].concat(_fn.arg2arr(arguments));
3268
+ },
3269
+ /**
3270
+ * @summary Performs the tick for the timer checking and modifying the various internal states.
3271
+ * @memberof FooGallery.utils.Timer#
3272
+ * @function __tick
3273
+ * @private
3274
+ */
3275
+ __tick: function(){
3276
+ var self = this;
3277
+ self.trigger("tick", self.__eventArgs());
3278
+ if (self.__current === self.__finish){
3279
+ self.trigger("complete", self.__eventArgs());
3280
+ self.__reset();
3281
+ } else {
3282
+ if (self.__decrement){
3283
+ self.__current--;
3284
+ } else {
3285
+ self.__current++;
3286
+ }
3287
+ self.__remaining--;
3288
+ self.canResume = self.__remaining > 0;
3289
+ self.__timeout = setTimeout(function () {
3290
+ self.__tick();
3291
+ }, self.interval);
3292
+ }
3293
+ },
3294
+ /**
3295
+ * @summary Starts the timer using the supplied `time` and whether or not to increment or decrement from the value.
3296
+ * @memberof FooGallery.utils.Timer#
3297
+ * @function start
3298
+ * @param {number} time - The total time in seconds for the timer.
3299
+ * @param {boolean} [decrement=false] - Whether the timer should increment or decrement from or to the supplied time.
3300
+ */
3301
+ start: function(time, decrement){
3302
+ var self = this;
3303
+ if (self.isRunning) return;
3304
+ decrement = _is.boolean(decrement) ? decrement : false;
3305
+ self.__restart = [time, decrement];
3306
+ self.__decrement = decrement;
3307
+ self.__time = time;
3308
+ self.__remaining = time;
3309
+ self.__current = decrement ? time : 0;
3310
+ self.__finish = decrement ? 0 : time;
3311
+ self.canRestart = true;
3312
+ self.isRunning = true;
3313
+ self.isPaused = false;
3314
+ self.trigger("start", self.__eventArgs());
3315
+ self.__tick();
3316
+ },
3317
+ /**
3318
+ * @summary Starts the timer counting down to `0` from the supplied `time`.
3319
+ * @memberof FooGallery.utils.Timer#
3320
+ * @function countdown
3321
+ * @param {number} time - The total time in seconds for the timer.
3322
+ */
3323
+ countdown: function(time){
3324
+ this.start(time, true);
3325
+ },
3326
+ /**
3327
+ * @summary Starts the timer counting up from `0` to the supplied `time`.
3328
+ * @memberof FooGallery.utils.Timer#
3329
+ * @function countup
3330
+ * @param {number} time - The total time in seconds for the timer.
3331
+ */
3332
+ countup: function(time){
3333
+ this.start(time, false);
3334
+ },
3335
+ /**
3336
+ * @summary Stops and then restarts the timer using the last arguments supplied to the {@link FooGallery.utils.Timer#start|start} method.
3337
+ * @memberof FooGallery.utils.Timer#
3338
+ * @function restart
3339
+ */
3340
+ restart: function(){
3341
+ this.stop();
3342
+ if (this.canRestart){
3343
+ this.start.apply(this, this.__restart);
3344
+ }
3345
+ },
3346
+ /**
3347
+ * @summary Stops the timer.
3348
+ * @memberof FooGallery.utils.Timer#
3349
+ * @function stop
3350
+ */
3351
+ stop: function(){
3352
+ if (this.isRunning || this.isPaused){
3353
+ this.__reset();
3354
+ this.trigger("stop", this.__eventArgs());
3355
+ }
3356
+ },
3357
+ /**
3358
+ * @summary Pauses the timer and returns the remaining seconds.
3359
+ * @memberof FooGallery.utils.Timer#
3360
+ * @function pause
3361
+ * @return {number} - The number of seconds remaining for the timer.
3362
+ */
3363
+ pause: function(){
3364
+ var self = this;
3365
+ if (self.__timeout != null){
3366
+ clearTimeout(self.__timeout);
3367
+ self.__timeout = null;
3368
+ }
3369
+ if (self.isRunning){
3370
+ self.isRunning = false;
3371
+ self.isPaused = true;
3372
+ self.trigger("pause", self.__eventArgs());
3373
+ }
3374
+ return self.__remaining;
3375
+ },
3376
+ /**
3377
+ * @summary Resumes the timer from a previously paused state.
3378
+ * @memberof FooGallery.utils.Timer#
3379
+ * @function resume
3380
+ */
3381
+ resume: function(){
3382
+ var self = this;
3383
+ if (self.canResume){
3384
+ self.isRunning = true;
3385
+ self.isPaused = false;
3386
+ self.trigger("resume", self.__eventArgs());
3387
+ self.__tick();
3388
+ }
3389
+ },
3390
+ /**
3391
+ * @summary Resets the timer back to a fresh starting state.
3392
+ * @memberof FooGallery.utils.Timer#
3393
+ * @function reset
3394
+ */
3395
+ reset: function(){
3396
+ this.__reset();
3397
+ this.trigger("reset", this.__eventArgs());
3398
+ }
3399
+ });
3400
+
3401
+ })(
3402
+ FooGallery.utils.$,
3403
+ FooGallery.utils,
3404
+ FooGallery.utils.is,
3405
+ FooGallery.utils.fn,
3406
+ FooGallery.utils.obj
3407
+ );
3408
+
3409
+ (function($, _, _is, _fn){
3410
+ // only register methods if this version is the current version
3411
+ if (_.version !== '0.1.7') return;
3412
+
3413
+ _.Factory = _.Class.extend(/** @lends FooGallery.utils.Factory */{
3414
+ /**
3415
+ * @summary A factory for classes allowing them to be registered and created using a friendly name.
3416
+ * @constructs
3417
+ * @description This class allows other classes to register themselves for use at a later time. Depending on how you intend to use the registered classes you can also specify a load and execution order through the `priority` parameter of the {@link FooGallery.utils.Factory#register|register} method.
3418
+ * @augments FooGallery.utils.Class
3419
+ * @borrows FooGallery.utils.Class.extend as extend
3420
+ * @borrows FooGallery.utils.Class.override as override
3421
+ */
3422
+ construct: function(){
3423
+ /**
3424
+ * @summary An object containing all registered classes.
3425
+ * @memberof FooGallery.utils.Factory#
3426
+ * @name registered
3427
+ * @type {Object.<string, Object>}
3428
+ * @readonly
3429
+ * @example {@caption The following shows the structure of this object. The `<name>` placeholders would be the name the class was registered with.}
3430
+ * {
3431
+ * "<name>": {
3432
+ * "name": <string>,
3433
+ * "klass": <function>,
3434
+ * "priority": <number>
3435
+ * },
3436
+ * "<name>": {
3437
+ * "name": <string>,
3438
+ * "klass": <function>,
3439
+ * "priority": <number>
3440
+ * },
3441
+ * ...
3442
+ * }
3443
+ */
3444
+ this.registered = {};
3445
+ },
3446
+ /**
3447
+ * @summary Checks if the factory contains a class registered using the supplied `name`.
3448
+ * @memberof FooGallery.utils.Factory#
3449
+ * @function contains
3450
+ * @param {string} name - The name of the class to check.
3451
+ * @returns {boolean}
3452
+ * @example {@run true}
3453
+ * // create a new instance of the factory, this is usually exposed by the class that will be using the factory.
3454
+ * var factory = new FooGallery.utils.Factory();
3455
+ *
3456
+ * // create a class to register
3457
+ * function Test(){}
3458
+ *
3459
+ * // register the class with the factory with the default priority
3460
+ * factory.register( "test", Test );
3461
+ *
3462
+ * // test if the class was registered
3463
+ * console.log( factory.contains( "test" ) ); // => true
3464
+ */
3465
+ contains: function(name){
3466
+ return !_is.undef(this.registered[name]);
3467
+ },
3468
+ /**
3469
+ * @summary Creates new instances of all registered classes using there registered priority and the supplied arguments.
3470
+ * @memberof FooGallery.utils.Factory#
3471
+ * @function load
3472
+ * @param {Object.<string, function>} overrides - An object containing classes to override any matching registered classes with, if no overrides are required you can pass `false` or `null`.
3473
+ * @param {*} arg1 - The first argument to supply when creating new instances of all registered classes.
3474
+ * @param {...*} [argN] - Any number of additional arguments to supply when creating new instances of all registered classes.
3475
+ * @returns {Array.<Object>} An array containing new instances of all registered classes.
3476
  * @description The class indexes within the result array are determined by the `priority` they were registered with, the higher the `priority` the lower the index.
3477
  *
3478
  * This method is designed to be used when all registered classes share a common interface or base type and constructor arguments.
3731
  );
3732
  (function(_, _fn, _str){
3733
  // only register methods if this version is the current version
3734
+ if (_.version !== '0.1.7') return;
3735
 
3736
  // this is done to handle Content Security in Chrome and other browsers blocking access to the localStorage object under certain configurations.
3737
  // see: https://www.chromium.org/for-testers/bug-reporting-guidelines/uncaught-securityerror-failed-to-read-the-localstorage-property-from-window-access-is-denied-for-this-document
3835
  FooGallery.utils.fn,
3836
  FooGallery.utils.str
3837
  );
3838
+ (function($, _, _fn){
3839
+ // only register methods if this version is the current version
3840
+ if (_.version !== '0.1.7') return;
3841
+
3842
+ _.FullscreenAPI = _.EventClass.extend(/** @lends FooGallery.utils.FullscreenAPI */{
3843
+ /**
3844
+ * @summary A wrapper around the fullscreen API to ensure cross browser compatibility.
3845
+ * @constructs
3846
+ */
3847
+ construct: function(){
3848
+ this._super();
3849
+ /**
3850
+ * @summary An object containing a single browsers various methods and events needed for this wrapper.
3851
+ * @typedef {Object} FooGallery.utils.FullscreenAPI~BrowserAPI
3852
+ * @property {string} enabled
3853
+ * @property {string} element
3854
+ * @property {string} request
3855
+ * @property {string} exit
3856
+ * @property {Object} events
3857
+ * @property {string} events.change
3858
+ * @property {string} events.error
3859
+ */
3860
+
3861
+ /**
3862
+ * @summary Contains the various browser specific method and event names.
3863
+ * @memberof FooGallery.utils.FullscreenAPI#
3864
+ * @name apis
3865
+ * @type {{w3: BrowserAPI, ms: BrowserAPI, moz: BrowserAPI, webkit: BrowserAPI}}
3866
+ */
3867
+ this.apis = {
3868
+ w3: {
3869
+ enabled: "fullscreenEnabled",
3870
+ element: "fullscreenElement",
3871
+ request: "requestFullscreen",
3872
+ exit: "exitFullscreen",
3873
+ events: {
3874
+ change: "fullscreenchange",
3875
+ error: "fullscreenerror"
3876
+ }
3877
+ },
3878
+ webkit: {
3879
+ enabled: "webkitFullscreenEnabled",
3880
+ element: "webkitCurrentFullScreenElement",
3881
+ request: "webkitRequestFullscreen",
3882
+ exit: "webkitExitFullscreen",
3883
+ events: {
3884
+ change: "webkitfullscreenchange",
3885
+ error: "webkitfullscreenerror"
3886
+ }
3887
+ },
3888
+ moz: {
3889
+ enabled: "mozFullScreenEnabled",
3890
+ element: "mozFullScreenElement",
3891
+ request: "mozRequestFullScreen",
3892
+ exit: "mozCancelFullScreen",
3893
+ events: {
3894
+ change: "mozfullscreenchange",
3895
+ error: "mozfullscreenerror"
3896
+ }
3897
+ },
3898
+ ms: {
3899
+ enabled: "msFullscreenEnabled",
3900
+ element: "msFullscreenElement",
3901
+ request: "msRequestFullscreen",
3902
+ exit: "msExitFullscreen",
3903
+ events: {
3904
+ change: "MSFullscreenChange",
3905
+ error: "MSFullscreenError"
3906
+ }
3907
+ }
3908
+ };
3909
+ /**
3910
+ * @summary The current browsers specific method and event names.
3911
+ * @memberof FooGallery.utils.FullscreenAPI#
3912
+ * @name api
3913
+ * @type {?BrowserAPI}
3914
+ */
3915
+ this.api = this.getAPI();
3916
+ /**
3917
+ * @summary Whether or not the fullscreen API is supported in the current browser.
3918
+ * @memberof FooGallery.utils.FullscreenAPI#
3919
+ * @name supported
3920
+ * @type {boolean}
3921
+ */
3922
+ this.supported = this.api != null;
3923
+ this.__listen();
3924
+ },
3925
+ /**
3926
+ * @summary Destroys the current wrapper unbinding events and freeing up resources.
3927
+ * @memberof FooGallery.utils.FullscreenAPI#
3928
+ * @function destroy
3929
+ * @returns {boolean}
3930
+ */
3931
+ destroy: function(){
3932
+ this.__stopListening();
3933
+ return this._super();
3934
+ },
3935
+ /**
3936
+ * @summary Fetches the correct API for the current browser.
3937
+ * @memberof FooGallery.utils.FullscreenAPI#
3938
+ * @function getAPI
3939
+ * @return {?BrowserAPI} If the fullscreen API is not supported `null` is returned.
3940
+ */
3941
+ getAPI: function(){
3942
+ for (var vendor in this.apis) {
3943
+ if (!this.apis.hasOwnProperty(vendor)) continue;
3944
+ // Check if document has the "enabled" property
3945
+ if (this.apis[vendor].enabled in document) {
3946
+ // It seems this browser supports the fullscreen API
3947
+ return this.apis[vendor];
3948
+ }
3949
+ }
3950
+ return null;
3951
+ },
3952
+ /**
3953
+ * @summary Gets the current fullscreen element or null.
3954
+ * @memberof FooGallery.utils.FullscreenAPI#
3955
+ * @function element
3956
+ * @returns {?Element}
3957
+ */
3958
+ element: function(){
3959
+ return this.supported ? document[this.api.element] : null;
3960
+ },
3961
+ /**
3962
+ * @summary Requests the browser to place the specified element into fullscreen mode.
3963
+ * @memberof FooGallery.utils.FullscreenAPI#
3964
+ * @function request
3965
+ * @param {Element} element - The element to place into fullscreen mode.
3966
+ * @returns {Promise} A Promise which is resolved once the element is placed into fullscreen mode.
3967
+ */
3968
+ request: function(element){
3969
+ if (this.supported && !!element[this.api.request]){
3970
+ var result = element[this.api.request]();
3971
+ return !result ? $.Deferred(this.__resolver(this.api.request)).promise() : result;
3972
+ }
3973
+ return _fn.rejected;
3974
+ },
3975
+ /**
3976
+ * @summary Requests that the browser switch from fullscreen mode back to windowed mode.
3977
+ * @memberof FooGallery.utils.FullscreenAPI#
3978
+ * @function exit
3979
+ * @returns {Promise} A Promise which is resolved once fullscreen mode is exited.
3980
+ */
3981
+ exit: function(){
3982
+ if (this.supported && !!this.element()){
3983
+ var result = document[this.api.exit]();
3984
+ return !result ? $.Deferred(this.__resolver(this.api.exit)).promise() : result;
3985
+ }
3986
+ return _fn.rejected;
3987
+ },
3988
+ /**
3989
+ * @summary Toggles the supplied element between fullscreen and windowed modes.
3990
+ * @memberof FooGallery.utils.FullscreenAPI#
3991
+ * @function toggle
3992
+ * @param {Element} element - The element to switch between modes.
3993
+ * @returns {Promise} A Promise that is resolved once fullscreen mode is either entered or exited.
3994
+ */
3995
+ toggle: function(element){
3996
+ return !!this.element() ? this.exit() : this.request(element);
3997
+ },
3998
+ /**
3999
+ * @summary Starts listening to the document level fullscreen events and triggers an abbreviated version on this class.
4000
+ * @memberof FooGallery.utils.FullscreenAPI#
4001
+ * @function __listen
4002
+ * @private
4003
+ */
4004
+ __listen: function(){
4005
+ var self = this;
4006
+ if (!self.supported) return;
4007
+ $(document).on(self.api.events.change + ".utils", function() {
4008
+ self.trigger("change");
4009
+ }).on(self.api.events.error + ".utils", function() {
4010
+ self.trigger("error");
4011
+ });
4012
+ },
4013
+ /**
4014
+ * @summary Stops listening to the document level fullscreen events.
4015
+ * @memberof FooGallery.utils.FullscreenAPI#
4016
+ * @function __stopListening
4017
+ * @private
4018
+ */
4019
+ __stopListening: function(){
4020
+ var self = this;
4021
+ if (!self.supported) return;
4022
+ $(document).off(self.api.events.change + ".utils")
4023
+ .off(self.api.events.error + ".utils");
4024
+ },
4025
+ /**
4026
+ * @summary Creates a resolver function to patch browsers which do not return a Promise from there request and exit methods.
4027
+ * @memberof FooGallery.utils.FullscreenAPI#
4028
+ * @function __resolver
4029
+ * @param {string} method - The request or exit method the resolver is being created for.
4030
+ * @returns {resolver}
4031
+ * @private
4032
+ */
4033
+ __resolver: function(method){
4034
+ var self = this;
4035
+ /**
4036
+ * @summary Binds to the fullscreen change and error events and resolves or rejects the supplied deferred accordingly.
4037
+ * @callback FooGallery.utils.FullscreenAPI~resolver
4038
+ * @param {jQuery.Deferred} def - The jQuery.Deferred object to resolve.
4039
+ */
4040
+ return function resolver(def) {
4041
+ // Reject the promise if asked to exitFullscreen and there is no element currently in fullscreen
4042
+ if (method === self.api.exit && !!self.element()) {
4043
+ setTimeout(function() {
4044
+ def.reject(new TypeError());
4045
+ }, 1);
4046
+ return;
4047
+ }
4048
+
4049
+ // When receiving an internal fullscreenchange event, fulfill the promise
4050
+ function change() {
4051
+ def.resolve();
4052
+ $(document).off(self.api.events.change, change)
4053
+ .off(self.api.events.error, error);
4054
+ }
4055
+
4056
+ // When receiving an internal fullscreenerror event, reject the promise
4057
+ function error() {
4058
+ def.reject(new TypeError());
4059
+ $(document).off(self.api.events.change, change)
4060
+ .off(self.api.events.error, error);
4061
+ }
4062
+
4063
+ $(document).on(self.api.events.change, change)
4064
+ .on(self.api.events.error, error);
4065
+ };
4066
+ }
4067
+ });
4068
+
4069
+ /**
4070
+ * @summary A cross browser wrapper for the fullscreen API.
4071
+ * @memberof FooGallery.utils
4072
+ * @name fullscreen
4073
+ * @type {FooGallery.utils.FullscreenAPI}
4074
+ */
4075
+ _.fullscreen = new _.FullscreenAPI();
4076
+
4077
+ })(
4078
+ FooGallery.utils.$,
4079
+ FooGallery.utils,
4080
+ FooGallery.utils.fn
4081
+ );
4082
  (function ($, _, _utils, _is, _fn) {
4083
 
4084
  _.debug = new _utils.Debugger("__FooGallery__");
4086
  /**
4087
  * @summary The url of an empty 1x1 pixel image used as the default value for the `placeholder` and `error` {@link FooGallery.defaults|options}.
4088
  * @memberof FooGallery
4089
+ * @name EMPTY_IMAGE
4090
  * @type {string}
4091
  * @default "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
4092
  */
4093
+ _.EMPTY_IMAGE = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
4094
 
4095
  /**
4096
  * @summary The name to use when getting or setting an instance of a {@link FooGallery.Template|template} on an element using jQuery's `.data()` method.
4097
  * @memberof FooGallery
4098
+ * @name DATA_TEMPLATE
4099
  * @type {string}
4100
  * @default "__FooGallery__"
4101
  */
4102
+ _.DATA_TEMPLATE = "__FooGallery__";
4103
 
4104
  /**
4105
  * @summary The name to use when getting or setting an instance of a {@link FooGallery.Item|item} on an element using jQuery's `.data()` method.
4106
  * @memberof FooGallery
4107
+ * @name DATA_ITEM
4108
  * @type {string}
4109
  * @default "__FooGalleryItem__"
4110
  */
4111
+ _.DATA_ITEM = "__FooGalleryItem__";
4112
+
4113
+ _.get = function(selector){
4114
+ return $(selector).data(_.DATA_TEMPLATE);
4115
+ };
4116
 
4117
  _.init = function (options, element) {
4118
+ element = _is.jq(element) ? element : $(element);
4119
+ if (element.length > 0){
4120
+ var current = element.data(_.DATA_TEMPLATE);
4121
+ if (current instanceof _.Template) {
4122
+ return current.destroy(true).then(function(){
4123
+ return _.template.make(options, element).initialize();
4124
+ });
4125
+ }
4126
+ }
4127
  return _.template.make(options, element).initialize();
4128
  };
4129
 
4183
  * </script>
4184
  */
4185
  $.fn.foogallery = function (options, ready) {
4186
+ ready = _is.fn(ready) ? ready : $.noop;
4187
  return this.each(function (i, element) {
 
4188
  if (_is.string(options)) {
4189
+ var template = $.data(element, _.DATA_TEMPLATE);
4190
  if (template instanceof _.Template) {
4191
  switch (options) {
4192
  case "layout":
4198
  }
4199
  }
4200
  } else {
4201
+ _.init( options, element ).then( ready );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4202
  }
4203
  });
4204
  };
4847
 
4848
  var instance = 0;
4849
 
4850
+ _.Template = _utils.EventClass.extend(/** @lends FooGallery.Template */{
4851
  /**
4852
  * @summary The primary class for FooGallery, this controls the flow of the plugin across all templates.
4853
  * @memberof FooGallery
4860
  */
4861
  construct: function (options, element) {
4862
  var self = this;
4863
+ self._super();
4864
  /**
4865
  * @summary An instance specific namespace to use when binding events to global objects that could be shared across multiple galleries.
4866
  * @memberof FooGallery.Template#
4960
  * @private
4961
  */
4962
  self._initialize = null;
4963
+ self._checkTimeout = null;
4964
  self.initializing = false;
4965
  self.initialized = false;
4966
  self.destroying = false;
5044
  } else {
5045
  self.$scrollParent = $(document);
5046
  }
5047
+ self.$el.data(_.DATA_TEMPLATE, self);
5048
 
5049
  // at this point we have our container element free of pre-existing instances so let's bind any event listeners supplied by the .on option
5050
  if (!_is.empty(self.opt.on)) {
5204
  */
5205
  var e = self.raise("post-init");
5206
  if (e.isDefaultPrevented()) return false;
5207
+ self.state.init();
 
5208
  self.$scrollParent.on("scroll" + self.namespace, {self: self}, _fn.throttle(function () {
5209
  self.loadAvailable();
5210
  }, 50));
5306
  * @summary Destroy the template.
5307
  * @memberof FooGallery.Template#
5308
  * @function destroy
5309
+ * @param {boolean} [preserveState=false] - If set to true any existing state is left intact on the URL.
5310
  * @returns {Promise}
5311
  * @description Once this method is called it can not be stopped and the template will be destroyed.
5312
  * @fires FooGallery.Template~"destroy.foogallery"
5313
  */
5314
+ destroy: function (preserveState) {
5315
+ var self = this, _super = self._super.bind(self);
5316
  if (self.destroyed) return _fn.resolved;
5317
  self.destroying = true;
5318
  return $.Deferred(function (def) {
5319
  if (self.initializing && _is.promise(self._initialize)) {
5320
  self._initialize.always(function () {
5321
  self.destroying = false;
5322
+ self.doDestroy(preserveState);
5323
  def.resolve();
5324
  });
5325
  } else {
5326
  self.destroying = false;
5327
+ self.doDestroy(preserveState);
5328
  def.resolve();
5329
  }
5330
+ }).then(function(){
5331
+ _super();
5332
+ }).promise();
5333
  },
5334
+ doDestroy: function(preserveState){
5335
  var self = this;
5336
  if (self.destroyed) return;
5337
  /**
5350
  * });
5351
  */
5352
  self.raise("destroy");
5353
+ if (self._checkTimeout) clearTimeout(self._checkTimeout);
5354
  self.$scrollParent.off(self.namespace);
5355
  $(window).off(self.namespace);
5356
+ self.state.destroy(preserveState);
5357
  if (self.filter) self.filter.destroy();
5358
  if (self.pages) self.pages.destroy();
5359
  self.items.destroy();
5376
  * });
5377
  */
5378
  self.raise("destroyed");
5379
+ self.$el.removeData(_.DATA_TEMPLATE);
5380
 
5381
  if (_is.empty(self._undo.classes)) self.$el.removeAttr("class");
5382
  else self.$el.attr("class", self._undo.classes);
5443
  _check: function (delay) {
5444
  delay = _is.number(delay) ? delay : 0;
5445
  var self = this;
5446
+ if (self._checkTimeout) clearTimeout(self._checkTimeout);
5447
+ return self._checkTimeout = setTimeout(function () {
5448
+ self._checkTimeout = null;
5449
  if (self.initialized && (!self.destroying || !self.destroyed)) {
5450
  self.loadAvailable();
5451
  }
5472
  * });
5473
  */
5474
  raise: function (eventName, args) {
5475
+ if (this.destroying || this.destroyed || !_is.string(eventName) || _is.empty(eventName)) return null;
5476
  args = _is.array(args) ? args : [];
5477
  var self = this,
5478
  name = eventName.split(".")[0],
5479
  listener = _str.camel("on-" + name),
5480
  event = $.Event(name + ".foogallery");
5481
  args.unshift(self); // add self
5482
+ var e = self.trigger(name, args);
5483
+ if (e.defaultPrevented) event.preventDefault();
5484
  self.$el.trigger(event, args);
5485
  _.debug.logf("{id}|{name}:", {id: self.id, name: name}, args);
5486
  if (_is.fn(self[listener])) {
5515
  /**
5516
  * @summary Gets the width of the FooGallery container.
5517
  * @memberof FooGallery.Template#
5518
+ * @function
5519
  * @name getContainerWidth
5520
  * @returns {number}
5521
  */
5527
  return self.$el.width();
5528
  },
5529
 
5530
+ /**
5531
+ * @summary Gets a specific type of CSS class from the template.
5532
+ * @memberof FooGallery.Template#
5533
+ * @function
5534
+ * @name getCSSClass
5535
+ * @param {string} type - The specific type of CSS class to retrieve.
5536
+ * @returns {string}
5537
+ */
5538
+ getCSSClass: function(type){
5539
+ var regex = type instanceof RegExp ? type : (_is.string(type) && this.opt.regex.hasOwnProperty(type) ? this.opt.regex[type] : null),
5540
+ className = (this.$el.prop("className") || ''),
5541
+ match = regex != null ? className.match(regex) : null;
5542
+ return match != null && match.length >= 2 ? match[1] : "";
5543
+ },
5544
+
5545
  // ###############
5546
  // ## Listeners ##
5547
  // ###############
5577
  timeout: 60000,
5578
  srcset: "data-srcset-fg",
5579
  src: "data-src-fg",
5580
+ template: {},
5581
+ regex: {
5582
+ theme: /(?:\s|^)(fg-(?:light|dark|custom))(?:\s|$)/,
5583
+ loadingIcon: /(?:\s|^)(fg-loading-(?:default|bars|dots|partial|pulse|trail))(?:\s|$)/,
5584
+ hoverIcon: /(?:\s|^)(fg-hover-(?:zoom|zoom2|zoom3|plus|circle-plus|eye|external|tint))(?:\s|$)/,
5585
+ videoIcon: /(?:\s|^)(fg-video-(?:default|1|2|3|4))(?:\s|$)/,
5586
+ hoverColor: /(?:\s|^)(fg-hover-(?:colorize|grayscale))(?:\s|$)/,
5587
+ hoverScale: /(?:\s|^)(fg-hover-scale)(?:\s|$)/,
5588
+ stickyVideoIcon: /(?:\s|^)(fg-video-sticky)(?:\s|$)/,
5589
+ insetShadow: /(?:\s|^)(fg-shadow-inset-(?:small|medium|large))(?:\s|$)/,
5590
+ filter: /(?:\s|^)(fg-filter-(?:1977|amaro|brannan|clarendon|earlybird|lofi|poprocket|reyes|toaster|walden|xpro2|xtreme))(?:\s|$)/
5591
+ }
5592
  }, {
5593
  container: "foogallery"
5594
  }, {}, -100);
5647
  FooGallery.utils.fn,
5648
  FooGallery.utils.str
5649
  );
5650
+ (function(_, _utils, _is){
5651
 
5652
  _.Component = _utils.Class.extend(/** @lend FooGallery.Component */{
5653
  /**
5678
  }
5679
  });
5680
 
5681
+ _.EventComponent = _utils.EventClass.extend(/** @lend FooGallery.EventComponent */{
5682
+ /**
5683
+ * @summary The base class for all child components of a {@link FooGallery.Template|template} that raise there own events.
5684
+ * @constructs
5685
+ * @param {FooGallery.Template} template - The template creating the component.
5686
+ * @param {string} prefix - A prefix to prepend to any events bubbled up to the template.
5687
+ * @augments FooGallery.utils.EventClass
5688
+ * @borrows FooGallery.utils.Class.extend as extend
5689
+ * @borrows FooGallery.utils.Class.override as override
5690
+ */
5691
+ construct: function(template, prefix){
5692
+ this._super(template);
5693
+ /**
5694
+ * @summary The template that created this component.
5695
+ * @memberof FooGallery.EventComponent#
5696
+ * @name tmpl
5697
+ * @type {FooGallery.Template}
5698
+ */
5699
+ this.tmpl = template;
5700
+ /**
5701
+ * @summary A prefix to prepend to any events bubbled up to the template.
5702
+ * @memberof FooGallery.EventComponent#
5703
+ * @name tmplEventPrefix
5704
+ * @type {string}
5705
+ */
5706
+ this.tmplEventPrefix = prefix;
5707
+ },
5708
+ /**
5709
+ * @summary Destroy the component making it ready for garbage collection.
5710
+ * @memberof FooGallery.EventComponent#
5711
+ * @function destroy
5712
+ */
5713
+ destroy: function(){
5714
+ this._super();
5715
+ this.tmpl = null;
5716
+ },
5717
+ /**
5718
+ * @summary Trigger an event on the current component.
5719
+ * @memberof FooGallery.EventComponent#
5720
+ * @function trigger
5721
+ * @param {(string|FooGallery.utils.Event)} event - Either a space-separated string of event types or a custom event object to raise.
5722
+ * @param {Array} [args] - An array of additional arguments to supply to the handlers after the event object.
5723
+ * @returns {(FooGallery.utils.Event|FooGallery.utils.Event[]|null)} Returns the {@link FooGallery.utils.Event|event object} of the triggered event. If more than one event was triggered an array of {@link FooGallery.utils.Event|event objects} is returned. If no `event` was supplied or triggered `null` is returned.
5724
+ */
5725
+ trigger: function(event, args){
5726
+ var self = this, result = self._super(event, args), name, e;
5727
+ if (self.tmpl != null){
5728
+ if (result instanceof _utils.Event && !result.isDefaultPrevented()){
5729
+ name = result.namespace != null ? [result.type, result.namespace].join(".") : result.type;
5730
+ e = self.tmpl.raise(self.tmplEventPrefix + name, args);
5731
+ if (!!e && e.isDefaultPrevented()) result.preventDefault();
5732
+ } else if (_is.array(result)){
5733
+ result.forEach(function (evt) {
5734
+ if (!evt.isDefaultPrevented()){
5735
+ name = evt.namespace != null ? [evt.type, evt.namespace].join(".") : evt.type;
5736
+ e = self.tmpl.raise(self.tmplEventPrefix + name, args);
5737
+ if (!!e && e.isDefaultPrevented()) evt.preventDefault();
5738
+ }
5739
+ });
5740
+ }
5741
+ }
5742
+ return _is.empty(result) ? null : (result.length === 1 ? result[0] : result);
5743
+ }
5744
+ });
5745
+
5746
+ /**
5747
+ * @summary A factory for registering and creating basic gallery components.
5748
  * @memberof FooGallery
5749
  * @name components
5750
  * @type {FooGallery.utils.Factory}
5753
 
5754
  })(
5755
  FooGallery,
5756
+ FooGallery.utils,
5757
+ FooGallery.utils.is
5758
  );
5759
+ (function($, _, _is, _str, _obj){
5760
 
5761
  _.State = _.Component.extend(/** @lends FooGallery.State */{
5762
  /**
5798
  * @type {boolean}
5799
  */
5800
  self.enabled = self.opt.enabled;
5801
+ /**
5802
+ * @summary The current state of the template.
5803
+ * @memberof FooGallery.State#
5804
+ * @name current
5805
+ * @type {{item: null, page: number, filter: []}}
5806
+ */
5807
+ self.current = {
5808
+ filter: [],
5809
+ page: 0,
5810
+ item: null
5811
+ };
5812
  /**
5813
  * @summary Which method of the history API to use by default when updating the state.
5814
  * @memberof FooGallery.State#
5818
  */
5819
  self.pushOrReplace = self.isPushOrReplace(self.opt.pushOrReplace) ? self.opt.pushOrReplace : "replace";
5820
 
5821
+ self.defaultMask = "foogallery-gallery-{id}";
5822
+
5823
  var id = _str.escapeRegExp(self.tmpl.id),
5824
+ masked = _str.escapeRegExp(self.getMasked()),
5825
  values = _str.escapeRegExp(self.opt.values),
5826
  pair = _str.escapeRegExp(self.opt.pair);
5827
  /**
5828
  * @summary An object containing regular expressions used to test and parse a hash value into a state object.
5829
  * @memberof FooGallery.State#
5830
  * @name regex
5831
+ * @type {{exists: RegExp, masked: RegExp, values: RegExp}}
5832
  * @readonly
5833
  * @description The regular expressions contained within this object are specific to this template and are created using the template {@link FooGallery.Template#id|id} and the delimiters from the {@link FooGallery.State#opt|options}.
5834
  */
5835
  self.regex = {
5836
  exists: new RegExp("^#"+id+"\\"+values+".+?"),
5837
+ masked: new RegExp("^#"+masked+"\\"+values+".+?"),
5838
  values: new RegExp("(\\w+)"+pair+"([^"+values+"]+)", "g")
5839
  };
5840
  },
5842
  * @summary Destroy the component clearing any current state from the url and preparing it for garbage collection.
5843
  * @memberof FooGallery.State#
5844
  * @function destroy
5845
+ * @param {boolean} [preserve=false] - If set to true any existing state is left intact on the URL.
5846
  */
5847
+ destroy: function(preserve){
5848
  var self = this;
5849
+ if (!preserve) self.clear();
5850
  self.opt = self.regex = {};
5851
  self._super();
5852
  },
5853
+ init: function(){
5854
+ this.set(this.initial());
5855
+ },
5856
+ getIdNumber: function(){
5857
+ return this.tmpl.id.match(/\d+/g)[0];
5858
+ },
5859
+ getMasked: function(){
5860
+ var self = this, mask = _str.contains(self.opt.mask, "{id}") ? self.opt.mask : self.defaultMask;
5861
+ return _str.format(mask, {id: self.getIdNumber()});
5862
+ },
5863
  /**
5864
  * @summary Check if the supplied value is `"push"` or `"replace"`.
5865
  * @memberof FooGallery.State#
5877
  * @returns {boolean}
5878
  */
5879
  exists: function(){
5880
+ this.regex.values.lastIndex = 0; // reset the index as we use the g flag
5881
+ return (this.regex.exists.test(location.hash) || this.regex.masked.test(location.hash)) && this.regex.values.test(location.hash);
5882
  },
5883
  /**
5884
  * @summary Parse the current url returning an object containing all values for the template.
5888
  * @description This method always returns an object, if successful the object contains properties otherwise it is just a plain empty object. For this method to be successful the current template {@link FooGallery.Template#id|id} must match the one from the url.
5889
  */
5890
  parse: function(){
5891
+ var self = this, tmpl = self.tmpl, state = {};
5892
  if (self.exists()){
5893
  if (self.enabled){
5894
  state.id = self.tmpl.id;
5895
+ self.regex.values.lastIndex = 0;
5896
  var pairs = location.hash.match(self.regex.values);
5897
  $.each(pairs, function(i, pair){
5898
+ var parts = pair.split(self.opt.pair), val;
5899
  if (parts.length === 2){
5900
+ switch(parts[0]){
5901
+ case self.opt.itemKey:
5902
+ val = tmpl.items.fromHash(parts[1]);
5903
+ if (val !== null) state.item = val;
5904
+ break;
5905
+ case self.opt.pageKey:
5906
+ if (tmpl.pages){
5907
+ val = tmpl.pages.fromHash(parts[1]);
5908
+ if (val !== null) state.page = val;
5909
+ }
5910
+ break;
5911
+ case self.opt.filterKey:
5912
+ if (tmpl.filter){
5913
+ val = tmpl.filter.fromHash(parts[1]);
5914
+ if (val !== null) state.filter = val;
5915
+ }
5916
+ break;
5917
  }
5918
  }
5919
  });
5936
  * @returns {string}
5937
  */
5938
  hashify: function(state){
5939
+ var self = this, tmpl = self.tmpl;
5940
  if (_is.hash(state)){
5941
+ var hash = [], val = tmpl.items.toHash(state.item);
5942
+ if (val !== null) hash.push(self.opt.itemKey + self.opt.pair + val);
5943
+
5944
+ if (!!tmpl.filter){
5945
+ val = tmpl.filter.toHash(state.filter);
5946
+ if (val !== null) hash.push(self.opt.filterKey + self.opt.pair + val);
5947
+ }
5948
+ if (!!tmpl.pages){
5949
+ val = tmpl.pages.toHash(state.page);
5950
+ if (val !== null) hash.push(self.opt.pageKey + self.opt.pair + val);
5951
+ }
5952
  if (hash.length > 0){
5953
+ hash.unshift("#"+self.getMasked());
5954
  }
5955
  return hash.join(self.opt.values);
5956
  }
5966
  var self = this;
5967
  if (self.enabled && self.apiEnabled){
5968
  state.id = self.tmpl.id;
5969
+ var hash = self.hashify(state), empty = _is.empty(hash), hs = _obj.extend({}, state, {item: state.item instanceof _.Item ? state.item.id : state.item});
5970
+ history.replaceState(empty ? null : hs, "", empty ? location.pathname + location.search : hash);
5971
  }
5972
  },
5973
  /**
5980
  var self = this;
5981
  if (self.enabled && self.apiEnabled){
5982
  state.id = self.tmpl.id;
5983
+ var hash = self.hashify(state), empty = _is.empty(hash), hs = _obj.extend({}, state, {item: state.item instanceof _.Item ? state.item.id : state.item});
5984
+ history.pushState(empty ? null : hs, "", empty ? location.pathname + location.search : hash);
5985
  }
5986
  },
5987
  /**
6014
  * @description This method returns an initial start up state from the template options.
6015
  */
6016
  initial: function(){
6017
+ var self = this, state = self.parse();
6018
+ if (_is.empty(state)){
6019
+ return self.get();
6020
+ }
6021
+ return _obj.extend({ filter: [], page: 1, item: null }, state);
6022
  },
6023
  /**
6024
  * @summary Get the current state of the template.
6029
  * @description This method does not parse the history or url it returns the current state of the template itself. To parse the current url use the {@link FooGallery.State#parse|parse} method instead.
6030
  */
6031
  get: function(item){
6032
+ var self = this, tmpl = self.tmpl, state = {}, val;
6033
+ if (item instanceof _.Item) state.item = item;
6034
+ if (!!tmpl.filter){
6035
+ val = tmpl.filter.getState();
6036
+ if (val !== null) state.filter = val;
6037
  }
6038
+ if (!!tmpl.pages){
6039
+ val = tmpl.pages.getState();
6040
+ if (val !== null) state.page = val;
6041
  }
6042
+ return _obj.extend({ filter: [], page: 1, item: null }, state);
6043
  },
6044
  /**
6045
  * @summary Set the current state of the template.
6051
  set: function(state){
6052
  var self = this, tmpl = self.tmpl;
6053
  if (_is.hash(state)){
6054
+ var obj = _obj.extend({ filter: [], page: 1, item: null }, state);
6055
  tmpl.items.reset();
6056
+ var e = tmpl.raise("before-state", [obj]);
6057
+ if (!e.isDefaultPrevented()){
6058
+ if (!!tmpl.filter){
6059
+ tmpl.filter.setState(obj);
 
 
 
 
 
 
 
 
6060
  }
6061
+ if (!!tmpl.pages){
6062
+ tmpl.pages.setState(obj);
6063
+ } else {
6064
+ tmpl.items.detach(tmpl.items.all());
6065
+ tmpl.items.create(tmpl.items.available(), true);
6066
  }
6067
+ if (obj.item){
6068
+ if (self.opt.scrollTo) {
6069
+ obj.item.scrollTo();
6070
+ }
6071
+ if (!_is.empty(state.item)){
6072
+ state.item = null;
6073
+ self.replace(state);
6074
+ }
6075
  }
6076
+ self.current = obj;
6077
+ tmpl.raise("after-state", [obj]);
 
 
6078
  }
6079
  }
6080
  },
6083
  _.template.configure("core", {
6084
  state: {
6085
  enabled: false,
6086
+ scrollTo: true,
6087
  pushOrReplace: "replace",
6088
+ mask: "foogallery-gallery-{id}",
6089
  values: "/",
6090
  pair: ":",
6091
+ array: "+",
6092
+ arraySeparator: ",",
6093
+ itemKey: "i",
6094
+ filterKey: "f",
6095
+ pageKey: "p"
6096
  }
6097
  });
6098
 
6112
  /**
6113
  * @summary An object used to store the state of a template.
6114
  * @typedef {object} FooGallery~State
6115
+ * @property {number} [page] - The current page number.
6116
+ * @property {string[]} [filter] - The current filter array.
6117
+ * @property {?FooGallery.Item} [item] - The currently selected item.
6118
  */
6119
 
6120
  })(
6121
  FooGallery.$,
6122
  FooGallery,
6123
  FooGallery.utils.is,
6124
+ FooGallery.utils.str,
6125
+ FooGallery.utils.obj
6126
  );
6127
  (function ($, _, _utils, _is, _fn, _obj) {
6128
 
6129
+ _.Items = _.Component.extend(/** @lends FooGallery.Items */{
6130
  /**
6131
+ * @summary This class controls everything related to items and serves as the base class for the various paging types.
6132
  * @memberof FooGallery
6133
+ * @constructs Items
6134
+ * @param {FooGallery.Template} template - The template for this component.
 
6135
  * @augments FooGallery.Component
6136
  * @borrows FooGallery.utils.Class.extend as extend
6137
  * @borrows FooGallery.utils.Class.override as override
6138
  */
6139
+ construct: function (template) {
6140
  var self = this;
6141
+ self.ALLOW_CREATE = true;
6142
+ self.ALLOW_APPEND = true;
6143
+ self.ALLOW_LOAD = true;
6144
  /**
6145
  * @ignore
6146
+ * @memberof FooGallery.Items#
6147
  * @function _super
6148
  */
6149
  self._super(template);
6150
+ self.maps = {};
6151
+ self._fetched = null;
6152
+ self._arr = [];
6153
+ self._available = [];
6154
+ // add the .all caption selector
6155
+ var cls = self.tmpl.cls.item.caption;
6156
+ self.tmpl.sel.item.caption.all = _utils.selectify([cls.elem, cls.inner, cls.title, cls.description]);
6157
+ },
6158
+ fromHash: function(hash){
6159
+ return this.get(hash);
6160
+ },
6161
+ toHash: function(value){
6162
+ return value instanceof _.Item ? value.id : null;
6163
+ },
6164
+ destroy: function () {
6165
+ var self = this, items = self.all(), destroyed = [];
6166
+ if (items.length > 0) {
6167
+ /**
6168
+ * @summary Raised before the template destroys its' items.
6169
+ * @event FooGallery.Template~"destroy-items.foogallery"
6170
+ * @type {jQuery.Event}
6171
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6172
+ * @param {FooGallery.Template} template - The template raising the event.
6173
+ * @param {FooGallery.Item[]} items - The array of items about to be destroyed.
6174
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6175
+ * $(".foogallery").foogallery({
6176
+ * on: {
6177
+ * "destroy-items.foogallery": function(event, template, items){
6178
+ * // do something
6179
+ * }
6180
+ * }
6181
+ * });
6182
+ */
6183
+ self.tmpl.raise("destroy-items", [items]);
6184
+ destroyed = $.map(items, function (item) {
6185
+ return item.destroy() ? item : null;
6186
+ });
6187
+ /**
6188
+ * @summary Raised after the template has destroyed items.
6189
+ * @event FooGallery.Template~"destroyed-items.foogallery"
6190
+ * @type {jQuery.Event}
6191
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6192
+ * @param {FooGallery.Template} template - The template raising the event.
6193
+ * @param {FooGallery.Item[]} items - The array of items destroyed.
6194
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6195
+ * $(".foogallery").foogallery({
6196
+ * on: {
6197
+ * "destroyed-items.foogallery": function(event, template, items){
6198
+ * // do something
6199
+ * }
6200
+ * }
6201
+ * });
6202
+ */
6203
+ if (destroyed.length > 0) self.tmpl.raise("destroyed-items", [destroyed]);
6204
+ // should we handle a case where the destroyed.length != items.length??
6205
+ }
6206
+ self.maps = {};
6207
+ self._fetched = null;
6208
+ self._arr = [];
6209
+ self._available = [];
6210
+ self._super();
6211
+ },
6212
+ fetch: function (refresh) {
6213
+ var self = this;
6214
+ if (!refresh && _is.promise(self._fetched)) return self._fetched;
6215
+ var fg = self.tmpl, selectors = fg.sel,
6216
+ option = fg.opt.items,
6217
+ def = $.Deferred();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6218
 
6219
+ var items = self.make(fg.$el.find(selectors.item.elem));
 
 
 
 
 
6220
 
6221
+ if (!_is.empty(option)) {
6222
+ if (_is.array(option)) {
6223
+ items.push.apply(items, self.make(option));
6224
+ def.resolve(items);
6225
+ } else if (_is.string(option)) {
6226
+ $.get(option).then(function (response) {
6227
+ items.push.apply(items, self.make(response));
6228
+ def.resolve(items);
6229
+ }, function (jqXHR, textStatus, errorThrown) {
6230
+ console.log("FooGallery: GET items error.", option, jqXHR, textStatus, errorThrown);
6231
+ def.resolve(items);
6232
+ });
6233
+ } else {
6234
+ def.resolve(items);
6235
+ }
6236
+ } else {
6237
+ items.push.apply(items, self.make(window[fg.id + "-items"]));
6238
+ def.resolve(items);
6239
+ }
6240
+ def.then(function (items) {
6241
+ self.setAll(items);
6242
+ });
6243
+ return self._fetched = def.promise();
6244
+ },
6245
+ toJSON: function(all){
6246
+ var items = all ? this.all() : this.available();
6247
+ return items.map(function(item){
6248
+ return item.toJSON();
6249
+ });
6250
+ },
6251
+ all: function () {
6252
+ return this._arr.slice();
6253
+ },
6254
+ count: function (all) {
6255
+ return all ? this.all().length : this.available().length;
6256
+ },
6257
+ available: function () {
6258
+ return this._available.slice();
6259
+ },
6260
+ get: function (idOrIndex) {
6261
+ var map = _is.number(idOrIndex) ? 'index' : 'id';
6262
+ return !!this.maps[map][idOrIndex] ? this.maps[map][idOrIndex] : null;
6263
+ },
6264
+ setAll: function (items) {
6265
+ this._arr = _is.array(items) ? items : [];
6266
+ this.maps = this.createMaps(this._arr);
6267
+ this._available = this.all();
6268
+ },
6269
+ setAvailable: function (items) {
6270
+ this.maps = this.createMaps(this._arr);
6271
+ this._available = _is.array(items) ? items : [];
6272
+ },
6273
+ reset: function () {
6274
+ this.setAvailable(this.all());
6275
+ },
6276
+ first: function(){
6277
+ return this._available.length > 0 ? this._available[0] : null;
6278
+ },
6279
+ last: function(){
6280
+ return this._available.length > 0 ? this._available[this._available.length - 1] : null;
6281
+ },
6282
+ next: function(item, loop){
6283
+ if (!(item instanceof _.Item)) return null;
6284
+ loop = _is.boolean(loop) ? loop : false;
6285
+ var index = this._available.indexOf(item);
6286
+ if (index !== -1){
6287
+ index++;
6288
+ if (index >= this._available.length){
6289
+ if (!loop) return null;
6290
+ index = 0;
6291
+ }
6292
+ return this._available[index];
6293
+ }
6294
+ return null;
6295
+ },
6296
+ prev: function(item, loop){
6297
+ if (!(item instanceof _.Item)) return null;
6298
+ loop = _is.boolean(loop) ? loop : false;
6299
+ var index = this._available.indexOf(item);
6300
+ if (index !== -1){
6301
+ index--;
6302
+ if (index < 0){
6303
+ if (!loop) return null;
6304
+ index = this._available.length - 1;
6305
+ }
6306
+ return this._available[index];
6307
+ }
6308
+ return null;
6309
+ },
6310
+ createMaps: function(items){
6311
+ items = _is.array(items) ? items : [];
6312
+ var maps = {
6313
+ id: {},
6314
+ index: {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6315
  };
6316
+ $.each(items, function (i, item) {
6317
+ if (_is.empty(item.id)) item.id = "" + (i + 1);
6318
+ item.index = i;
6319
+ maps.id[item.id] = item;
6320
+ maps.index[item.index] = item;
6321
+ });
6322
+ return maps;
6323
  },
6324
  /**
6325
+ * @summary Filter the supplied `items` and return only those that can be loaded.
6326
+ * @memberof FooGallery.Items#
6327
+ * @function loadable
6328
+ * @param {FooGallery.Item[]} items - The items to filter.
6329
+ * @returns {FooGallery.Item[]}
6330
  */
6331
+ loadable: function (items) {
6332
+ var self = this, opt = self.tmpl.opt, viewport;
6333
+ if (opt.lazy) {
6334
+ viewport = _utils.getViewportBounds(opt.viewport);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6335
  }
6336
+ return self.ALLOW_LOAD && _is.array(items) ? $.map(items, function (item) {
6337
+ return item.isCreated && item.isAttached && !item.isLoading && !item.isLoaded && !item.isError && (!opt.lazy || (opt.lazy && item.intersects(viewport))) ? item : null;
6338
+ }) : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6339
  },
6340
  /**
6341
+ * @summary Filter the supplied `items` and return only those that can be created.
6342
+ * @memberof FooGallery.Items#
6343
+ * @function creatable
6344
+ * @param {FooGallery.Item[]} items - The items to filter.
6345
+ * @returns {FooGallery.Item[]}
6346
  */
6347
+ creatable: function (items) {
6348
+ return this.ALLOW_CREATE && _is.array(items) ? $.map(items, function (item) {
6349
+ return item instanceof _.Item && !item.isCreated ? item : null;
6350
+ }) : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6351
  },
6352
  /**
6353
+ * @summary Filter the supplied `items` and return only those that can be appended.
6354
+ * @memberof FooGallery.Items#
6355
+ * @function appendable
6356
+ * @param {FooGallery.Item[]} items - The items to filter.
6357
+ * @returns {FooGallery.Item[]}
 
 
6358
  */
6359
+ appendable: function (items) {
6360
+ return this.ALLOW_APPEND && _is.array(items) ? $.map(items, function (item) {
6361
+ return item instanceof _.Item && item.isCreated && !item.isAttached ? item : null;
6362
+ }) : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6363
  },
6364
  /**
6365
+ * @summary Filter the supplied `items` and return only those that can be detached.
6366
+ * @memberof FooGallery.Items#
6367
+ * @function detachable
6368
+ * @param {FooGallery.Item[]} items - The items to filter.
6369
+ * @returns {FooGallery.Item[]}
6370
  */
6371
+ detachable: function (items) {
6372
+ return _is.array(items) ? $.map(items, function (item) {
6373
+ return item instanceof _.Item && item.isCreated && item.isAttached ? item : null;
6374
+ }) : [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6375
  },
6376
  /**
6377
+ * @summary Get a single jQuery object containing all the supplied items' elements.
6378
+ * @memberof FooGallery.Items#
6379
+ * @function jquerify
6380
+ * @param {FooGallery.Item[]} items - The items to get a jQuery object for.
6381
+ * @returns {jQuery}
 
6382
  */
6383
+ jquerify: function (items) {
6384
+ return $($.map(items, function (item) {
6385
+ return item.$el.get();
6386
+ }));
6387
+ },
6388
+ /**
6389
+ * @summary Makes a jQuery object, NodeList or an array of elements or item options, into an array of {@link FooGallery.Item|item} objects.
6390
+ * @memberof FooGallery.Items#
6391
+ * @function make
6392
+ * @param {(jQuery|NodeList|Node[]|FooGallery.Item~Options[])} items - The value to convert into an array of items.
6393
+ * @returns {FooGallery.Item[]} The array of items successfully made.
6394
+ * @fires FooGallery.Template~"make-items.foogallery"
6395
+ * @fires FooGallery.Template~"made-items.foogallery"
6396
+ * @fires FooGallery.Template~"parsed-items.foogallery"
6397
+ */
6398
+ make: function (items) {
6399
+ var self = this, made = [];
6400
+ if (_is.jq(items) || _is.array(items)) {
6401
+ var parsed = [], arr = $.makeArray(items);
6402
+ if (arr.length === 0) return made;
6403
  /**
6404
+ * @summary Raised before the template makes an array of elements or item options into an array of {@link FooGallery.Item|item} objects.
6405
+ * @event FooGallery.Template~"make-items.foogallery"
6406
  * @type {jQuery.Event}
6407
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6408
  * @param {FooGallery.Template} template - The template raising the event.
6409
+ * @param {(HTMLElement[]|FooGallery.Item~Options[])} items - The array of Nodes or item options.
6410
+ * @returns {(HTMLElement[]|FooGallery.Item~Options[])} A filtered list of items to make.
6411
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6412
  * $(".foogallery").foogallery({
6413
  * on: {
6414
+ * "make-items.foogallery": function(event, template, items){
6415
  * // do something
6416
  * }
6417
  * }
6418
  * });
6419
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being made.}
6420
  * $(".foogallery").foogallery({
6421
  * on: {
6422
+ * "make-items.foogallery": function(event, template, items){
6423
  * if ("some condition"){
6424
+ * // stop any items being made
6425
  * event.preventDefault();
6426
  * }
6427
  * }
6428
  * }
6429
  * });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6430
  */
6431
+ var e = self.tmpl.raise("make-items", [arr]);
6432
  if (!e.isDefaultPrevented()) {
6433
+ made = $.map(arr, function (obj) {
6434
+ var type = self.type(obj), opt = _obj.extend(_is.hash(obj) ? obj : {}, {type: type});
6435
+ var item = _.components.make(type, self.tmpl, opt);
6436
+ if (_is.element(obj)) {
6437
+ if (item.parse(obj)) {
6438
+ parsed.push(item);
6439
+ return item;
6440
+ }
6441
+ return null;
6442
+ }
6443
+ return item;
6444
+ });
 
 
 
 
 
 
 
 
6445
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6446
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6447
  /**
6448
+ * @summary Raised after the template has made an array of {@link FooGallery.Item|item} objects.
6449
+ * @event FooGallery.Template~"made-items.foogallery"
6450
  * @type {jQuery.Event}
6451
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6452
  * @param {FooGallery.Template} template - The template raising the event.
6453
+ * @param {FooGallery.Item[]} items - The array of items made, this includes parsed items.
6454
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6455
  * $(".foogallery").foogallery({
6456
  * on: {
6457
+ * "made-items.foogallery": function(event, template, items){
6458
  * // do something
6459
  * }
6460
  * }
6461
  * });
6462
+ */
6463
+ if (made.length > 0) self.tmpl.raise("made-items", [made]);
6464
+
6465
+ /**
6466
+ * @summary Raised after the template has parsed any elements into an array of {@link FooGallery.Item|item} objects.
6467
+ * @event FooGallery.Template~"parsed-items.foogallery"
6468
+ * @type {jQuery.Event}
6469
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6470
+ * @param {FooGallery.Template} template - The template raising the event.
6471
+ * @param {FooGallery.Item[]} items - The array of items parsed.
6472
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
 
6473
  * $(".foogallery").foogallery({
6474
  * on: {
6475
+ * "parsed-items.foogallery": function(event, template, items){
6476
+ * // do something
 
 
 
 
 
 
6477
  * }
6478
  * }
6479
  * });
6480
  */
6481
+ if (parsed.length > 0) self.tmpl.raise("parsed-items", [parsed]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6482
  }
6483
+ return made;
6484
+ },
6485
+ type: function (objOrElement) {
6486
+ var type;
6487
+ if (_is.hash(objOrElement)) {
6488
+ type = objOrElement.type;
6489
+ } else if (_is.element(objOrElement)) {
6490
+ var $el = $(objOrElement), item = this.tmpl.sel.item;
6491
+ type = $el.find(item.anchor).data("type");
6492
+ }
6493
+ return _is.string(type) && _.components.contains(type) ? type : "image";
6494
  },
6495
  /**
6496
+ * @summary Create each of the supplied {@link FooGallery.Item|`items`} elements.
6497
+ * @memberof FooGallery.Items#
6498
+ * @function create
6499
+ * @param {FooGallery.Item[]} items - The array of items to create.
6500
+ * @param {boolean} [append=false] - Whether or not to automatically append the item after it is created.
6501
+ * @returns {FooGallery.Item[]} The array of items that were created or if `append` is `true` the array of items that were appended.
6502
+ * @description This will only create and/or append items that are not already created and/or appended so it is safe to call without worrying about the items' pre-existing state.
6503
+ * @fires FooGallery.Template~"create-items.foogallery"
6504
+ * @fires FooGallery.Template~"created-items.foogallery"
6505
+ * @fires FooGallery.Template~"append-items.foogallery"
6506
+ * @fires FooGallery.Template~"appended-items.foogallery"
6507
  */
6508
+ create: function (items, append) {
6509
+ var self = this, created = [], creatable = self.creatable(items);
6510
+ if (creatable.length > 0) {
6511
  /**
6512
+ * @summary Raised before the template creates the `items` elements.
6513
+ * @event FooGallery.Template~"create-items.foogallery"
6514
  * @type {jQuery.Event}
6515
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6516
  * @param {FooGallery.Template} template - The template raising the event.
6517
+ * @param {FooGallery.Item[]} items - The array of items to create.
6518
+ * @param {boolean} [append=false] - Whether or not to automatically append the item after it is created.
6519
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6520
  * $(".foogallery").foogallery({
6521
  * on: {
6522
+ * "create-items.foogallery": function(event, template, items){
6523
  * // do something
6524
  * }
6525
  * }
6526
  * });
6527
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being created.}
6528
  * $(".foogallery").foogallery({
6529
  * on: {
6530
+ * "create-items.foogallery": function(event, template, items){
6531
  * if ("some condition"){
6532
+ * // stop any items being created
6533
  * event.preventDefault();
6534
  * }
6535
  * }
6536
  * }
6537
  * });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6538
  */
6539
+ var e = self.tmpl.raise("create-items", [creatable]);
6540
  if (!e.isDefaultPrevented()) {
6541
+ created = $.map(creatable, function (item) {
6542
+ return item.create() ? item : null;
6543
+ });
6544
  }
6545
+ /**
6546
+ * @summary Raised after the template has created the `items` elements.
6547
+ * @event FooGallery.Template~"created-items.foogallery"
6548
+ * @type {jQuery.Event}
6549
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6550
+ * @param {FooGallery.Template} template - The template raising the event.
6551
+ * @param {FooGallery.Item[]} items - The array of items created.
6552
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6553
+ * $(".foogallery").foogallery({
6554
+ * on: {
6555
+ * "created-items.foogallery": function(event, template, items){
6556
+ * // do something
6557
+ * }
6558
+ * }
6559
+ * });
6560
+ */
6561
+ if (created.length > 0) self.tmpl.raise("created-items", [created]);
6562
+ }
6563
+ if (_is.boolean(append) ? append : false) return self.append(items);
6564
+ return created;
6565
+ },
6566
+ /**
6567
+ * @summary Append each of the supplied {@link FooGallery.Item|`items`} to the template.
6568
+ * @memberof FooGallery.Items#
6569
+ * @function append
6570
+ * @param {FooGallery.Item[]} items - The array of items to append.
6571
+ * @returns {FooGallery.Item[]} The array of items that were appended.
6572
+ * @fires FooGallery.Template~"append-items.foogallery"
6573
+ * @fires FooGallery.Template~"appended-items.foogallery"
6574
+ */
6575
+ append: function (items) {
6576
+ var self = this, appended = [], appendable = self.appendable(items);
6577
+ if (appendable.length > 0) {
6578
+ /**
6579
+ * @summary Raised before the template appends any items to itself.
6580
+ * @event FooGallery.Template~"append-items.foogallery"
6581
+ * @type {jQuery.Event}
6582
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6583
+ * @param {FooGallery.Template} template - The template raising the event.
6584
+ * @param {FooGallery.Item[]} items - The array of items to append.
6585
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6586
+ * $(".foogallery").foogallery({
6587
+ * on: {
6588
+ * "append-items.foogallery": function(event, template, items){
6589
+ * // do something
6590
+ * }
6591
+ * }
6592
+ * });
6593
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being appended.}
6594
+ * $(".foogallery").foogallery({
6595
+ * on: {
6596
+ * "append-items.foogallery": function(event, template, items){
6597
+ * if ("some condition"){
6598
+ * // stop any items being appended
6599
+ * event.preventDefault();
6600
+ * }
6601
+ * }
6602
+ * }
6603
+ * });
6604
+ */
6605
+ var e = self.tmpl.raise("append-items", [appendable]);
6606
+ if (!e.isDefaultPrevented()) {
6607
+ appended = $.map(appendable, function (item) {
6608
+ return item.append() ? item : null;
6609
+ });
6610
+ }
6611
+ /**
6612
+ * @summary Raised after the template has appended items to itself.
6613
+ * @event FooGallery.Template~"appended-items.foogallery"
6614
+ * @type {jQuery.Event}
6615
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6616
+ * @param {FooGallery.Template} template - The template raising the event.
6617
+ * @param {FooGallery.Item[]} items - The array of items appended.
6618
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6619
+ * $(".foogallery").foogallery({
6620
  * on: {
6621
+ * "appended-items.foogallery": function(event, template, items){
6622
  * // do something
6623
  * }
6624
  * }
6625
  * });
6626
+ */
6627
+ if (appended.length > 0) self.tmpl.raise("appended-items", [appended]);
 
6628
  }
6629
+ return appended;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6630
  },
6631
  /**
6632
+ * @summary Detach each of the supplied {@link FooGallery.Item|`items`} from the template.
6633
+ * @memberof FooGallery.Items#
6634
+ * @function detach
6635
+ * @param {FooGallery.Item[]} items - The array of items to detach.
6636
+ * @returns {FooGallery.Item[]} The array of items that were detached.
6637
+ * @fires FooGallery.Template~"detach-items.foogallery"
6638
+ * @fires FooGallery.Template~"detached-items.foogallery"
6639
  */
6640
+ detach: function (items) {
6641
+ var self = this, detached = [], detachable = self.detachable(items);
6642
+ if (detachable.length > 0) {
6643
+ /**
6644
+ * @summary Raised before the template detaches any items from itself.
6645
+ * @event FooGallery.Template~"detach-items.foogallery"
6646
+ * @type {jQuery.Event}
6647
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6648
+ * @param {FooGallery.Template} template - The template raising the event.
6649
+ * @param {FooGallery.Item[]} items - The array of items to detach.
6650
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6651
+ * $(".foogallery").foogallery({
6652
+ * on: {
6653
+ * "detach-items.foogallery": function(event, template, items){
6654
+ * // do something
6655
+ * }
6656
+ * }
6657
+ * });
6658
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any items being detached.}
6659
+ * $(".foogallery").foogallery({
6660
+ * on: {
6661
+ * "detach-items.foogallery": function(event, template, items){
6662
+ * if ("some condition"){
6663
+ * // stop any items being detached
6664
+ * event.preventDefault();
6665
+ * }
6666
+ * }
6667
+ * }
6668
+ * });
6669
+ */
6670
+ var e = self.tmpl.raise("detach-items", [detachable]);
6671
+ if (!e.isDefaultPrevented()) {
6672
+ detached = $.map(detachable, function (item) {
6673
+ return item.detach() ? item : null;
6674
+ });
6675
  }
6676
+ /**
6677
+ * @summary Raised after the template has detached items from itself.
6678
+ * @event FooGallery.Template~"detached-items.foogallery"
6679
+ * @type {jQuery.Event}
6680
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6681
+ * @param {FooGallery.Template} template - The template raising the event.
6682
+ * @param {FooGallery.Item[]} items - The array of items detached.
6683
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6684
+ * $(".foogallery").foogallery({
6685
+ * on: {
6686
+ * "detached-items.foogallery": function(event, template, items){
6687
+ * // do something
6688
+ * }
6689
+ * }
6690
+ * });
6691
+ */
6692
+ if (detached.length > 0) self.tmpl.raise("detached-items", [detached]);
6693
  }
6694
+ return detached;
 
 
 
 
 
 
 
 
 
 
 
 
6695
  },
6696
  /**
6697
+ * @summary Load each of the supplied `items` images.
6698
+ * @memberof FooGallery.Items#
6699
+ * @function load
6700
+ * @param {FooGallery.Item[]} items - The array of items to load.
6701
+ * @returns {Promise<FooGallery.Item[]>} Resolved with an array of {@link FooGallery.Item|items} as the first argument. If no items are loaded this array is empty.
6702
+ * @fires FooGallery.Template~"load-items.foogallery"
6703
+ * @fires FooGallery.Template~"loaded-items.foogallery"
6704
  */
6705
+ load: function (items) {
 
6706
  var self = this;
6707
+ items = self.loadable(items);
6708
+ if (items.length > 0) {
6709
+ /**
6710
+ * @summary Raised before the template loads any items.
6711
+ * @event FooGallery.Template~"load-items.foogallery"
6712
+ * @type {jQuery.Event}
6713
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6714
+ * @param {FooGallery.Template} template - The template raising the event.
6715
+ * @param {FooGallery.Item[]} items - The array of items to load.
6716
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6717
+ * $(".foogallery").foogallery({
6718
+ * on: {
6719
+ * "load-items.foogallery": function(event, template, items){
6720
+ * // do something
6721
+ * }
6722
+ * }
6723
+ * });
6724
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent any `items` being loaded.}
6725
+ * $(".foogallery").foogallery({
6726
+ * on: {
6727
+ * "load-items.foogallery": function(event, template, items){
6728
+ * if ("some condition"){
6729
+ * // stop any items being loaded
6730
+ * event.preventDefault();
6731
+ * }
6732
+ * }
6733
+ * }
6734
+ * });
6735
+ */
6736
+ var e = self.tmpl.raise("load-items", [items]);
6737
+ if (!e.isDefaultPrevented()) {
6738
+ var loading = $.map(items, function (item) {
6739
+ return item.load();
6740
+ });
6741
+ return _fn.when(loading).done(function (loaded) {
6742
+ /**
6743
+ * @summary Raised after the template has loaded items.
6744
+ * @event FooGallery.Template~"loaded-items.foogallery"
6745
+ * @type {jQuery.Event}
6746
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
6747
+ * @param {FooGallery.Template} template - The template raising the event.
6748
+ * @param {FooGallery.Item[]} items - The array of items that were loaded.
6749
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
6750
+ * $(".foogallery").foogallery({
6751
+ * on: {
6752
+ * "loaded-items.foogallery": function(event, template, items){
6753
+ * // do something
6754
+ * }
6755
+ * }
6756
+ * });
6757
+ */
6758
+ self.tmpl.raise("loaded-items", [loaded]);
6759
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6760
  }
6761
  }
6762
+ return _fn.resolveWith([]);
6763
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6764
  });
6765
 
6766
+ _.components.register("items", _.Items);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6767
 
6768
  })(
6769
  FooGallery.$,
6773
  FooGallery.utils.fn,
6774
  FooGallery.utils.obj
6775
  );
6776
+ (function ($, _, _utils, _is, _fn, _obj, _str) {
6777
 
6778
+ _.Item = _.Component.extend(/** @lends FooGallery.Item */{
6779
  /**
6780
+ * @summary The base class for an item.
6781
  * @memberof FooGallery
6782
+ * @constructs Item
6783
+ * @param {FooGallery.Template} template - The template this item belongs to.
6784
+ * @param {FooGallery.Item~Options} [options] - The options to initialize the item with.
6785
  * @augments FooGallery.Component
6786
  * @borrows FooGallery.utils.Class.extend as extend
6787
  * @borrows FooGallery.utils.Class.override as override
6788
  */
6789
+ construct: function (template, options) {
6790
  var self = this;
6791
  /**
6792
  * @ignore
6793
+ * @memberof FooGallery.Item#
6794
  * @function _super
6795
  */
6796
  self._super(template);
6797
+ self.cls = template.cls.item;
6798
+ self.il8n = template.il8n.item;
6799
+ self.sel = template.sel.item;
6800
+ self.opt = _obj.extend({}, template.opt.item, options);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6801
 
6802
+ /**
6803
+ * @summary Whether or not the items' elements are appended to the template.
6804
+ * @memberof FooGallery.Item#
6805
+ * @name isAttached
6806
+ * @type {boolean}
6807
+ * @readonly
6808
+ */
6809
+ self.isAttached = false;
6810
+ /**
6811
+ * @summary Whether or not the items' elements are created and can be used.
6812
+ * @memberof FooGallery.Item#
6813
+ * @name isCreated
6814
+ * @type {boolean}
6815
+ * @readonly
6816
+ */
6817
+ self.isCreated = false;
6818
+ /**
6819
+ * @summary Whether or not the item has been destroyed and can not be used.
6820
+ * @memberof FooGallery.Item#
6821
+ * @name isDestroyed
6822
+ * @type {boolean}
6823
+ * @readonly
6824
+ */
6825
+ self.isDestroyed = false;
6826
+ /**
6827
+ * @summary Whether or not the items' image is currently loading.
6828
+ * @memberof FooGallery.Item#
6829
+ * @name isLoading
6830
+ * @type {boolean}
6831
+ * @readonly
6832
+ */
6833
+ self.isLoading = false;
6834
+ /**
6835
+ * @summary Whether or not the items' image has been loaded.
6836
+ * @memberof FooGallery.Item#
6837
+ * @name isLoaded
6838
+ * @type {boolean}
6839
+ * @readonly
6840
+ */
6841
+ self.isLoaded = false;
6842
+ /**
6843
+ * @summary Whether or not the items' image threw an error while loading.
6844
+ * @memberof FooGallery.Item#
6845
+ * @name isError
6846
+ * @type {boolean}
6847
+ * @readonly
6848
+ */
6849
+ self.isError = false;
6850
+ /**
6851
+ * @summary Whether or not this item was parsed from an existing DOM element.
6852
+ * @memberof FooGallery.Item#
6853
+ * @name isParsed
6854
+ * @type {boolean}
6855
+ * @readonly
6856
+ */
6857
+ self.isParsed = false;
6858
+ /**
6859
+ * @memberof FooGallery.Item#
6860
+ * @name $el
6861
+ * @type {?jQuery}
6862
+ */
6863
+ self.$el = null;
6864
+ /**
6865
+ * @memberof FooGallery.Item#
6866
+ * @name $inner
6867
+ * @type {?jQuery}
6868
+ */
6869
+ self.$inner = null;
6870
+ /**
6871
+ * @memberof FooGallery.Item#
6872
+ * @name $anchor
6873
+ * @type {?jQuery}
6874
+ */
6875
+ self.$anchor = null;
6876
+ /**
6877
+ * @memberof FooGallery.Item#
6878
+ * @name $overlay
6879
+ * @type {?jQuery}
6880
+ */
6881
+ self.$overlay = null;
6882
+ /**
6883
+ * @memberof FooGallery.Item#
6884
+ * @name $wrap
6885
+ * @type {?jQuery}
6886
+ */
6887
+ self.$wrap = null;
6888
+ /**
6889
+ * @memberof FooGallery.Item#
6890
+ * @name $image
6891
+ * @type {?jQuery}
6892
+ */
6893
+ self.$image = null;
6894
+ /**
6895
+ * @memberof FooGallery.Item#
6896
+ * @name $caption
6897
+ * @type {?jQuery}
6898
+ */
6899
+ self.$caption = null;
6900
 
6901
+ /**
6902
+ * @memberof FooGallery.Item#
6903
+ * @name fixLayout
6904
+ * @type {boolean}
6905
+ */
6906
+ self.fixLayout = self.tmpl.opt.fixLayout;
6907
+
6908
+ /**
6909
+ * @memberof FooGallery.Item#
6910
+ * @name index
6911
+ * @type {number}
6912
+ * @default -1
6913
+ */
6914
+ self.index = -1;
6915
+ /**
6916
+ * @memberof FooGallery.Item#
6917
+ * @name type
6918
+ * @type {string}
6919
+ */
6920
+ self.type = self.opt.type;
6921
+ /**
6922
+ * @memberof FooGallery.Item#
6923
+ * @name id
6924
+ * @type {string}
6925
+ */
6926
+ self.id = self.opt.id;
6927
+ /**
6928
+ * @memberof FooGallery.Item#
6929
+ * @name productId
6930
+ * @type {string}
6931
+ */
6932
+ self.productId = self.opt.productId;
6933
+ /**
6934
+ * @memberof FooGallery.Item#
6935
+ * @name href
6936
+ * @type {string}
6937
+ */
6938
+ self.href = self.opt.href;
6939
+ /**
6940
+ * @memberof FooGallery.Item#
6941
+ * @name src
6942
+ * @type {string}
6943
+ */
6944
+ self.src = self.opt.src;
6945
+ /**
6946
+ * @memberof FooGallery.Item#
6947
+ * @name srcset
6948
+ * @type {string}
6949
+ */
6950
+ self.srcset = self.opt.srcset;
6951
+ /**
6952
+ * @memberof FooGallery.Item#
6953
+ * @name width
6954
+ * @type {number}
6955
+ */
6956
+ self.width = self.opt.width;
6957
+ /**
6958
+ * @memberof FooGallery.Item#
6959
+ * @name height
6960
+ * @type {number}
6961
+ */
6962
+ self.height = self.opt.height;
6963
+ /**
6964
+ * @memberof FooGallery.Item#
6965
+ * @name title
6966
+ * @type {string}
6967
+ */
6968
+ self.title = self.opt.title;
6969
+ /**
6970
+ * @memberof FooGallery.Item#
6971
+ * @name alt
6972
+ * @type {string}
6973
+ */
6974
+ self.alt = self.opt.alt;
6975
+ /**
6976
+ * @memberof FooGallery.Item#
6977
+ * @name caption
6978
+ * @type {string}
6979
+ */
6980
+ self.caption = _is.empty(self.opt.caption) ? self.title : self.opt.caption;
6981
+ /**
6982
+ * @memberof FooGallery.Item#
6983
+ * @name description
6984
+ * @type {string}
6985
+ */
6986
+ self.description = _is.empty(self.opt.description) ? self.alt : self.opt.description;
6987
+ /**
6988
+ * @memberof FooGallery.Item#
6989
+ * @name attrItem
6990
+ * @type {FooGallery.Item~Attributes}
6991
+ */
6992
+ self.attr = self.opt.attr;
6993
+ /**
6994
+ * @memberof FooGallery.Item#
6995
+ * @name tags
6996
+ * @type {string[]}
6997
+ */
6998
+ self.tags = self.opt.tags;
6999
+ /**
7000
+ * @memberof FooGallery.Item#
7001
+ * @name maxWidth
7002
+ * @type {?FooGallery.Item~maxWidthCallback}
7003
+ */
7004
+ self.maxWidth = self.opt.maxWidth;
7005
+ /**
7006
+ * @memberof FooGallery.Item#
7007
+ * @name maxCaptionLength
7008
+ * @type {number}
7009
+ */
7010
+ self.maxCaptionLength = self.opt.maxCaptionLength;
7011
+ /**
7012
+ * @memberof FooGallery.Item#
7013
+ * @name maxDescriptionLength
7014
+ * @type {number}
7015
+ */
7016
+ self.maxDescriptionLength = self.opt.maxDescriptionLength;
7017
+ /**
7018
+ * @memberof FooGallery.Item#
7019
+ * @name showCaptionTitle
7020
+ * @type {boolean}
7021
+ */
7022
+ self.showCaptionTitle = self.opt.showCaptionTitle;
7023
+ /**
7024
+ * @memberof FooGallery.Item#
7025
+ * @name showCaptionDescription
7026
+ * @type {boolean}
7027
+ */
7028
+ self.showCaptionDescription = self.opt.showCaptionDescription;
7029
+ /**
7030
+ * @summary The cached result of the last call to the {@link FooGallery.Item#getThumbUrl|getThumbUrl} method.
7031
+ * @memberof FooGallery.Item#
7032
+ * @name _thumbUrl
7033
+ * @type {?string}
7034
+ * @private
7035
+ */
7036
+ self._thumbUrl = null;
7037
+ /**
7038
+ * @summary This property is used to store the promise created when loading an item for the first time.
7039
+ * @memberof FooGallery.Item#
7040
+ * @name _load
7041
+ * @type {?Promise}
7042
+ * @private
7043
+ */
7044
+ self._load = null;
7045
+ /**
7046
+ * @summary This property is used to store the init state of an item the first time it is parsed and is used to reset state during destroy.
7047
+ * @memberof FooGallery.Item#
7048
+ * @name _undo
7049
+ * @type {Object}
7050
+ * @private
7051
+ */
7052
+ self._undo = {
7053
+ classes: "",
7054
+ style: "",
7055
+ loader: false,
7056
+ wrap: false,
7057
+ overlay: false,
7058
+ placeholder: false
7059
+ };
7060
+ },
7061
+ /**
7062
+ * @summary Destroy the item preparing it for garbage collection.
7063
+ * @memberof FooGallery.Item#
7064
+ * @function destroy
7065
  */
7066
+ destroy: function () {
7067
+ var self = this;
7068
+ /**
7069
+ * @summary Raised when a template destroys an item.
7070
+ * @event FooGallery.Template~"destroy-item.foogallery"
7071
+ * @type {jQuery.Event}
7072
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7073
+ * @param {FooGallery.Template} template - The template raising the event.
7074
+ * @param {FooGallery.Item} item - The item to destroy.
7075
+ * @returns {boolean} `true` if the {@link FooGallery.Item|`item`} has been successfully destroyed.
7076
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7077
+ * $(".foogallery").foogallery({
7078
+ * on: {
7079
+ * "destroy-item.foogallery": function(event, template, item){
7080
+ * // do something
7081
+ * }
7082
+ * }
7083
+ * });
7084
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being destroyed.}
7085
+ * $(".foogallery").foogallery({
7086
+ * on: {
7087
+ * "destroy-item.foogallery": function(event, template, item){
7088
+ * if ("some condition"){
7089
+ * // stop the item being destroyed
7090
+ * event.preventDefault();
7091
+ * }
7092
+ * }
7093
+ * }
7094
+ * });
7095
+ * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
7096
+ * $(".foogallery").foogallery({
7097
+ * on: {
7098
+ * "destroy-item.foogallery": function(event, template, item){
7099
+ * // stop the default logic
7100
+ * event.preventDefault();
7101
+ * // replacing it with your own destroying the item yourself
7102
+ * item.$el.off(".foogallery").remove();
7103
+ * item.$el = null;
7104
+ * ...
7105
+ * // once all destroy work is complete you must set isDestroyed to true
7106
+ * item.isDestroyed = true;
7107
+ * }
7108
+ * }
7109
+ * });
7110
+ */
7111
+ var e = self.tmpl.raise("destroy-item", [self]);
7112
+ if (!e.isDefaultPrevented()) {
7113
+ self.isDestroyed = self.doDestroyItem();
7114
+ }
7115
+ if (self.isDestroyed) {
7116
  /**
7117
+ * @summary Raised after an item has been destroyed.
7118
+ * @event FooGallery.Template~"destroyed-item.foogallery"
7119
  * @type {jQuery.Event}
7120
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7121
  * @param {FooGallery.Template} template - The template raising the event.
7122
+ * @param {FooGallery.Item} item - The item that was destroyed.
 
7123
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7124
  * $(".foogallery").foogallery({
7125
+ * on: {
7126
+ * "destroyed-item.foogallery": function(event, template, item){
7127
+ * // do something
7128
+ * }
7129
+ * }
7130
+ * });
 
 
 
 
 
 
 
 
 
 
 
7131
  */
7132
+ self.tmpl.raise("destroyed-item", [self]);
7133
+ // call the original method that simply nulls the tmpl property
7134
+ self._super();
7135
+ }
7136
+ return self.isDestroyed;
7137
+ },
7138
+ /**
7139
+ * @summary Performs the actual destroy logic for the item.
7140
+ * @memberof FooGallery.Item#
7141
+ * @function doDestroyItem
7142
+ * @returns {boolean}
7143
+ */
7144
+ doDestroyItem: function () {
7145
+ var self = this;
7146
+ if (self.isParsed) {
7147
+ self.$anchor.add(self.$caption).off("click.foogallery");
7148
+ self.append();
7149
+ if (_is.empty(self._undo.classes)) self.$el.removeAttr("class");
7150
+ else self.$el.attr("class", self._undo.classes);
7151
 
7152
+ if (_is.empty(self._undo.style)) self.$el.removeAttr("style");
7153
+ else self.$el.attr("style", self._undo.style);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7154
 
7155
+ if (self._undo.overlay) {
7156
+ self.$overlay.remove();
7157
+ }
7158
+ if (self._undo.wrap) {
7159
+ self.$anchor.append(self.$image);
7160
+ self.$wrap.remove();
7161
+ }
7162
+ if (self._undo.loader) {
7163
+ self.$el.find(self.sel.loader).remove();
7164
+ }
7165
+ if (self._undo.placeholder && self.$image.prop("src") === _.EMPTY_IMAGE) {
7166
+ self.$image.removeAttr("src");
7167
+ }
7168
+ } else if (self.isCreated) {
7169
+ self.detach();
7170
+ self.$el.remove();
7171
+ }
7172
+ return true;
7173
+ },
7174
+ /**
7175
+ * @summary Parse the supplied element updating the current items' properties.
7176
+ * @memberof FooGallery.Item#
7177
+ * @function parse
7178
+ * @param {(jQuery|HTMLElement|string)} element - The element to parse.
7179
+ * @returns {boolean}
7180
+ * @fires FooGallery.Template~"parse-item.foogallery"
7181
+ * @fires FooGallery.Template~"parsed-item.foogallery"
7182
+ */
7183
+ parse: function (element) {
7184
+ var self = this, $el = $(element);
7185
+ /**
7186
+ * @summary Raised when an item needs to parse properties from an element.
7187
+ * @event FooGallery.Template~"parse-item.foogallery"
7188
+ * @type {jQuery.Event}
7189
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7190
+ * @param {FooGallery.Template} template - The template raising the event.
7191
+ * @param {FooGallery.Item} item - The item to populate.
7192
+ * @param {jQuery} $element - The jQuery object of the element to parse.
7193
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7194
+ * $(".foogallery").foogallery({
7195
+ * on: {
7196
+ * "parse-item.foogallery": function(event, template, item, $element){
7197
+ * // do something
7198
+ * }
7199
+ * }
7200
+ * });
7201
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` properties being parsed from the `element`.}
7202
+ * $(".foogallery").foogallery({
7203
+ * on: {
7204
+ * "parse-item.foogallery": function(event, template, item, $element){
7205
+ * if ("some condition"){
7206
+ * // stop the item being parsed
7207
+ * event.preventDefault();
7208
+ * }
7209
+ * }
7210
+ * }
7211
+ * });
7212
+ * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object and then populating the `item` properties from the `element`.}
7213
+ * $(".foogallery").foogallery({
7214
+ * on: {
7215
+ * "parse-item.foogallery": function(event, template, item, $element){
7216
+ * // stop the default logic
7217
+ * event.preventDefault();
7218
+ * // replacing it with your own setting each property of the item yourself
7219
+ * item.$el = $element;
7220
+ * ...
7221
+ * // once all properties are set you must set isParsed to true
7222
+ * item.isParsed = true;
7223
+ * }
7224
+ * }
7225
+ * });
7226
+ */
7227
+ var e = self.tmpl.raise("parse-item", [self, $el]);
7228
+ if (!e.isDefaultPrevented() && (self.isCreated = $el.is(self.sel.elem))) {
7229
+ self.isParsed = self.doParseItem($el);
7230
+ if (self.fixLayout) self.fix();
7231
+ // We don't load the attributes when parsing as they are only ever used to create an item and if you're parsing it's already created.
7232
+ }
7233
+ if (self.isParsed) {
7234
  /**
7235
+ * @summary Raised after an item has been parsed from an element.
7236
+ * @event FooGallery.Template~"parsed-item.foogallery"
7237
  * @type {jQuery.Event}
7238
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7239
  * @param {FooGallery.Template} template - The template raising the event.
7240
+ * @param {FooGallery.Item} item - The item that was parsed.
7241
+ * @param {jQuery} $element - The jQuery object of the element that was parsed.
7242
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7243
  * $(".foogallery").foogallery({
7244
  * on: {
7245
+ * "parsed-item.foogallery": function(event, template, item, $element){
7246
  * // do something
7247
  * }
7248
  * }
7249
  * });
7250
  */
7251
+ self.tmpl.raise("parsed-item", [self]);
7252
+ }
7253
+ return self.isParsed;
7254
+ },
7255
+ /**
7256
+ * @summary Performs the actual parse logic for the item.
7257
+ * @memberof FooGallery.Item#
7258
+ * @function doParseItem
7259
+ * @param {jQuery} $el - The jQuery element to parse.
7260
+ * @returns {boolean}
7261
+ */
7262
+ doParseItem: function ($el) {
7263
+ var self = this, o = self.tmpl.opt, cls = self.cls, sel = self.sel;
7264
+
7265
+ self._undo.classes = $el.attr("class") || "";
7266
+ self._undo.style = $el.attr("style") || "";
7267
+
7268
+ self.$el = $el.data(_.DATA_ITEM, self);
7269
+ self.$inner = self.$el.children(sel.inner);
7270
+ self.$anchor = self.$inner.children(sel.anchor).on("click.foogallery", {self: self}, self.onAnchorClick);
7271
+ self.$image = self.$anchor.find(sel.image);
7272
+ self.$caption = self.$inner.children(sel.caption.elem).on("click.foogallery", {self: self}, self.onCaptionClick);
7273
+
7274
+ if ( !self.$el.length || !self.$inner.length || !self.$anchor.length || !self.$image.length ){
7275
+ console.error("FooGallery Error: Invalid HTML markup. Check the item markup for additional elements or malformed HTML in the title or description.", self);
7276
+ self.isError = true;
7277
+ self.tmpl.raise("error-item", [self]);
7278
+ if (self.$el.length !== 0){
7279
+ self.$el.remove();
7280
+ }
7281
+ return false;
7282
  }
7283
+
7284
+ self.isAttached = self.$el.parent().length > 0;
7285
+ self.isLoading = self.$el.is(sel.loading);
7286
+ self.isLoaded = self.$el.is(sel.loaded);
7287
+ self.isError = self.$el.is(sel.error);
7288
+
7289
+ var data = self.$anchor.attr("data-type", self.type).data();
7290
+ self.id = data.id || self.id;
7291
+ self.productId = data.productId || self.productId;
7292
+ self.tags = data.tags || self.tags;
7293
+ self.href = data.href || self.$anchor.attr('href') || self.href;
7294
+ self.src = self.$image.attr(o.src) || self.src;
7295
+ self.srcset = self.$image.attr(o.srcset) || self.srcset;
7296
+ self.width = parseInt(self.$image.attr("width")) || self.width;
7297
+ self.height = parseInt(self.$image.attr("height")) || self.height;
7298
+ self.title = self.$image.attr("title") || self.title;
7299
+ self.alt = self.$image.attr("alt") || self.alt;
7300
+ self.caption = data.title || data.captionTitle || self.caption || self.title;
7301
+ self.description = data.description || data.captionDesc || self.description || self.alt;
7302
+ // if the caption or description are not set yet try fetching it from the html
7303
+ if (_is.empty(self.caption)) self.caption = $.trim(self.$caption.find(sel.caption.title).html());
7304
+ if (_is.empty(self.description)) self.description = $.trim(self.$caption.find(sel.caption.description).html());
7305
+ // enforce the max lengths for the caption and description
7306
+ if (_is.number(self.maxCaptionLength) && self.maxCaptionLength > 0 && !_is.empty(self.caption) && _is.string(self.caption) && self.caption.length > self.maxCaptionLength) {
7307
+ self.$caption.find(sel.caption.title).html(self.caption.substr(0, self.maxCaptionLength) + "&hellip;");
7308
  }
7309
+ if (_is.number(self.maxDescriptionLength) && self.maxDescriptionLength > 0 && !_is.empty(self.description) && _is.string(self.description) && self.description.length > self.maxDescriptionLength) {
7310
+ self.$caption.find(sel.caption.description).html(self.description.substr(0, self.maxDescriptionLength) + "&hellip;");
7311
+ }
7312
+ // check if the item has an overlay
7313
+ self.$overlay = self.$anchor.children(sel.overlay);
7314
+ if (self.$overlay.length === 0) {
7315
+ self.$overlay = $("<span/>", {"class": cls.overlay});
7316
+ self.$anchor.append(self.$overlay);
7317
+ self._undo.overlay = true;
7318
+ }
7319
+ // check if the item has a wrap
7320
+ self.$wrap = self.$anchor.children(sel.wrap);
7321
+ if (self.$wrap.length === 0) {
7322
+ self.$wrap = $("<span/>", {"class": cls.wrap});
7323
+ self.$anchor.append(self.$wrap.append(self.$image));
7324
+ self._undo.wrap = true;
7325
+ }
7326
+ // check if the item has a loader
7327
+ if (self.$el.children(sel.loader).length === 0) {
7328
+ self.$el.append($("<div/>", {"class": cls.loader}));
7329
+ self._undo.loader = true;
7330
+ }
7331
+ // if the image has no src url then set the placeholder
7332
+ var img = self.$image.get(0);
7333
+ if (_is.empty(img.src)) {
7334
+ img.src = _.EMPTY_IMAGE;
7335
+ self._undo.placeholder = true;
7336
+ }
7337
+ self.$el.addClass(self.getTypeClass());
7338
+ if (self.isCreated && self.isAttached && !self.isLoading && !self.isLoaded && !self.isError) {
7339
+ self.$el.addClass(cls.idle);
7340
+ }
7341
+ return true;
7342
  },
7343
  /**
7344
+ * @summary Create the items' DOM elements and populate the corresponding properties.
7345
+ * @memberof FooGallery.Item#
7346
  * @function create
7347
+ * @returns {boolean}
7348
+ * @fires FooGallery.Template~"create-item.foogallery"
7349
+ * @fires FooGallery.Template~"created-item.foogallery"
 
 
 
 
 
7350
  */
7351
+ create: function () {
7352
+ var self = this;
7353
+ if (!self.isCreated && _is.string(self.href) && _is.string(self.src) && _is.number(self.width) && _is.number(self.height)) {
7354
  /**
7355
+ * @summary Raised when an item needs to create its' elements.
7356
+ * @event FooGallery.Template~"create-item.foogallery"
7357
  * @type {jQuery.Event}
7358
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7359
  * @param {FooGallery.Template} template - The template raising the event.
7360
+ * @param {FooGallery.Item} item - The item to create the elements for.
 
7361
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7362
  * $(".foogallery").foogallery({
7363
  * on: {
7364
+ * "create-item.foogallery": function(event, template, item){
7365
  * // do something
7366
  * }
7367
  * }
7368
  * });
7369
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being created.}
7370
  * $(".foogallery").foogallery({
7371
  * on: {
7372
+ * "create-item.foogallery": function(event, template, item){
7373
  * if ("some condition"){
7374
+ * // stop the item being created
7375
  * event.preventDefault();
7376
  * }
7377
  * }
7378
  * }
7379
  * });
7380
+ * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7381
  * $(".foogallery").foogallery({
7382
  * on: {
7383
+ * "create-item.foogallery": function(event, template, item){
7384
+ * // stop the default logic
7385
+ * event.preventDefault();
7386
+ * // replacing it with your own creating each element property of the item yourself
7387
+ * item.$el = $("<div/>");
7388
+ * ...
7389
+ * // once all elements are created you must set isCreated to true
7390
+ * item.isCreated = true;
7391
  * }
7392
  * }
7393
  * });
7394
  */
7395
+ var e = self.tmpl.raise("create-item", [self]);
7396
+ if (!e.isDefaultPrevented()) {
7397
+ self.isCreated = self.doCreateItem();
7398
+ }
7399
+ if (self.isCreated) {
7400
+ /**
7401
+ * @summary Raised after an items' elements have been created.
7402
+ * @event FooGallery.Template~"created-item.foogallery"
7403
+ * @type {jQuery.Event}
7404
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7405
+ * @param {FooGallery.Template} template - The template raising the event.
7406
+ * @param {FooGallery.Item} item - The item that was created.
7407
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7408
+ * $(".foogallery").foogallery({
7409
+ * on: {
7410
+ * "created-item.foogallery": function(event, template, item){
7411
+ * // do something
7412
+ * }
7413
+ * }
7414
+ * });
7415
+ */
7416
+ self.tmpl.raise("created-item", [self]);
7417
+ }
7418
  }
7419
+ return self.isCreated;
 
7420
  },
7421
  /**
7422
+ * @summary Performs the actual create logic for the item.
7423
+ * @memberof FooGallery.Item#
7424
+ * @function doCreateItem
7425
+ * @returns {boolean}
7426
+ */
7427
+ doCreateItem: function () {
7428
+ var self = this, o = self.tmpl.opt, cls = self.cls, attr = self.attr, type = self.getTypeClass();
7429
+ attr.elem["class"] = [cls.elem, type, cls.idle].join(" ");
7430
+
7431
+ attr.inner["class"] = cls.inner;
7432
+
7433
+ attr.anchor["class"] = cls.anchor;
7434
+ attr.anchor["href"] = self.href;
7435
+ attr.anchor["data-type"] = self.type;
7436
+ attr.anchor["data-id"] = self.id;
7437
+ attr.anchor["data-title"] = self.caption;
7438
+ attr.anchor["data-description"] = self.description;
7439
+ if (!_is.empty(self.tags)) {
7440
+ attr.anchor["data-tags"] = JSON.stringify(self.tags);
7441
+ }
7442
+ if (!_is.empty(self.productId)) {
7443
+ attr.anchor["data-product-id"] = self.productId;
7444
+ }
7445
+
7446
+ attr.image["class"] = cls.image;
7447
+ attr.image[o.src] = self.src;
7448
+ attr.image[o.srcset] = self.srcset;
7449
+ attr.image["width"] = self.width;
7450
+ attr.image["height"] = self.height;
7451
+ attr.image["title"] = self.title;
7452
+ attr.image["alt"] = self.alt;
7453
+
7454
+ self.$el = $("<div/>").attr(attr.elem).data(_.DATA_ITEM, self);
7455
+ self.$inner = $("<figure/>").attr(attr.inner).appendTo(self.$el);
7456
+ self.$anchor = $("<a/>").attr(attr.anchor).appendTo(self.$inner).on("click.foogallery", {self: self}, self.onAnchorClick);
7457
+ self.$overlay = $("<span/>", {"class": cls.overlay}).appendTo(self.$anchor);
7458
+ self.$wrap = $("<span/>", {"class": cls.wrap}).appendTo(self.$anchor);
7459
+ self.$image = $("<img/>").attr(attr.image).appendTo(self.$wrap);
7460
+
7461
+ cls = self.cls.caption;
7462
+ attr = self.attr.caption;
7463
+ attr.elem["class"] = cls.elem;
7464
+ self.$caption = $("<figcaption/>").attr(attr.elem).on("click.foogallery", {self: self}, self.onCaptionClick);
7465
+ attr.inner["class"] = cls.inner;
7466
+ var $inner = $("<div/>").attr(attr.inner).appendTo(self.$caption);
7467
+ var hasTitle = self.showCaptionTitle && !_is.empty(self.caption), hasDesc = self.showCaptionDescription && !_is.empty(self.description);
7468
+ if (hasTitle || hasDesc) {
7469
+ attr.title["class"] = cls.title;
7470
+ attr.description["class"] = cls.description;
7471
+ if (hasTitle) {
7472
+ var $title = $("<div/>").attr(attr.title), titleHtml = self.caption;
7473
+ // enforce the max length for the caption
7474
+ if (_is.number(self.maxCaptionLength) && self.maxCaptionLength > 0 && _is.string(self.caption) && self.caption.length > self.maxCaptionLength) {
7475
+ titleHtml = self.caption.substr(0, self.maxCaptionLength) + "&hellip;";
7476
+ }
7477
+ $title.get(0).innerHTML = titleHtml;
7478
+ $inner.append($title);
7479
+ }
7480
+ if (hasDesc) {
7481
+ var $desc = $("<div/>").attr(attr.description), descHtml = self.description;
7482
+ // enforce the max length for the description
7483
+ if (_is.number(self.maxDescriptionLength) && self.maxDescriptionLength > 0 && _is.string(self.description) && self.description.length > self.maxDescriptionLength) {
7484
+ descHtml = self.description.substr(0, self.maxDescriptionLength) + "&hellip;";
7485
+ }
7486
+ $desc.get(0).innerHTML = descHtml;
7487
+ $inner.append($desc);
7488
+ }
7489
+ }
7490
+ self.$caption.appendTo(self.$inner);
7491
+ // check if the item has a loader
7492
+ if (self.$el.find(self.sel.loader).length === 0) {
7493
+ self.$el.append($("<div/>", {"class": self.cls.loader}));
7494
+ }
7495
+ return true;
7496
+ },
7497
+ /**
7498
+ * @summary Append the item to the current template.
7499
+ * @memberof FooGallery.Item#
7500
  * @function append
7501
+ * @returns {boolean}
7502
+ * @fires FooGallery.Template~"append-item.foogallery"
7503
+ * @fires FooGallery.Template~"appended-item.foogallery"
 
7504
  */
7505
+ append: function () {
7506
+ var self = this;
7507
+ if (self.isCreated && !self.isAttached) {
7508
  /**
7509
+ * @summary Raised when an item needs to append its elements to the template.
7510
+ * @event FooGallery.Template~"append-item.foogallery"
7511
  * @type {jQuery.Event}
7512
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7513
  * @param {FooGallery.Template} template - The template raising the event.
7514
+ * @param {FooGallery.Item} item - The item to append to the template.
7515
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7516
  * $(".foogallery").foogallery({
7517
  * on: {
7518
+ * "append-item.foogallery": function(event, template, item){
7519
  * // do something
7520
  * }
7521
  * }
7522
  * });
7523
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being appended.}
7524
  * $(".foogallery").foogallery({
7525
  * on: {
7526
+ * "append-item.foogallery": function(event, template, item){
7527
  * if ("some condition"){
7528
+ * // stop the item being appended
7529
  * event.preventDefault();
7530
  * }
7531
  * }
7532
  * }
7533
  * });
7534
+ * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
7535
+ * $(".foogallery").foogallery({
7536
+ * on: {
7537
+ * "append-item.foogallery": function(event, template, item){
7538
+ * // stop the default logic
7539
+ * event.preventDefault();
7540
+ * // replacing it with your own appending the item to the template
7541
+ * item.$el.appendTo(template.$el);
7542
+ * ...
7543
+ * // once the item is appended you must set isAttached to true
7544
+ * item.isAttached = true;
7545
+ * }
7546
+ * }
7547
+ * });
7548
  */
7549
+ var e = self.tmpl.raise("append-item", [self]);
7550
  if (!e.isDefaultPrevented()) {
7551
+ self.tmpl.$el.append(self.$el);
7552
+ if (self.fixLayout || !self.isParsed) self.fix();
7553
+ self.isAttached = true;
7554
  }
7555
+ if (self.isAttached) {
7556
+ /**
7557
+ * @summary Raised after an item has appended its' elements to the template.
7558
+ * @event FooGallery.Template~"appended-item.foogallery"
7559
+ * @type {jQuery.Event}
7560
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7561
+ * @param {FooGallery.Template} template - The template raising the event.
7562
+ * @param {FooGallery.Item} item - The item that was appended.
7563
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7564
+ * $(".foogallery").foogallery({
7565
  * on: {
7566
+ * "appended-item.foogallery": function(event, template, item){
7567
  * // do something
7568
  * }
7569
  * }
7570
  * });
7571
+ */
7572
+ self.tmpl.raise("appended-item", [self]);
7573
+ }
7574
  }
7575
+ return self.isAttached;
7576
  },
7577
  /**
7578
+ * @summary Detach the item from the current template preserving its' data and events.
7579
+ * @memberof FooGallery.Item#
7580
  * @function detach
7581
+ * @returns {boolean}
 
 
 
7582
  */
7583
+ detach: function () {
7584
+ var self = this;
7585
+ if (self.isCreated && self.isAttached) {
7586
  /**
7587
+ * @summary Raised when an item needs to detach its' elements from the template.
7588
+ * @event FooGallery.Template~"detach-item.foogallery"
7589
  * @type {jQuery.Event}
7590
  * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7591
  * @param {FooGallery.Template} template - The template raising the event.
7592
+ * @param {FooGallery.Item} item - The item to detach from the template.
7593
  * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7594
  * $(".foogallery").foogallery({
7595
  * on: {
7596
+ * "detach-item.foogallery": function(event, template, item){
7597
  * // do something
7598
  * }
7599
  * }
7600
  * });
7601
+ * @example {@caption Calling the `preventDefault` method on the `event` object will prevent the `item` being detached.}
7602
  * $(".foogallery").foogallery({
7603
  * on: {
7604
+ * "detach-item.foogallery": function(event, template, item){
7605
  * if ("some condition"){
7606
+ * // stop the item being detached
7607
  * event.preventDefault();
7608
  * }
7609
  * }
7610
  * }
7611
  * });
7612
+ * @example {@caption You can also prevent the default logic and replace it with your own by calling the `preventDefault` method on the `event` object.}
7613
+ * $(".foogallery").foogallery({
7614
+ * on: {
7615
+ * "detach-item.foogallery": function(event, template, item){
7616
+ * // stop the default logic
7617
+ * event.preventDefault();
7618
+ * // replacing it with your own detaching the item from the template
7619
+ * item.$el.detach();
7620
+ * ...
7621
+ * // once the item is detached you must set isAttached to false
7622
+ * item.isAttached = false;
7623
+ * }
7624
+ * }
7625
+ * });
7626
  */
7627
+ var e = self.tmpl.raise("detach-item", [self]);
7628
  if (!e.isDefaultPrevented()) {
7629
+ self.$el.detach();
7630
+ if (self.fixLayout || !self.isParsed) self.unfix();
7631
+ self.isAttached = false;
7632
  }
7633
+ if (!self.isAttached) {
7634
+ /**
7635
+ * @summary Raised after an item has detached its' elements from the template.
7636
+ * @event FooGallery.Template~"detached-item.foogallery"
7637
+ * @type {jQuery.Event}
7638
+ * @param {jQuery.Event} event - The jQuery.Event object for the current event.
7639
+ * @param {FooGallery.Template} template - The template raising the event.
7640
+ * @param {FooGallery.Item} item - The item that was detached.
7641
+ * @example {@caption To listen for this event and perform some action when it occurs you would bind to it as follows.}
7642
+ * $(".foogallery").foogallery({
7643
  * on: {
7644
+ * "detached-item.foogallery": function(event, template, item){
7645
  * // do something
7646
  * }
7647
  * }
7648
  * });
7649
+ */
7650
+ self.tmpl.raise("detached-item", [self]);
7651
+ }
7652
+ }
7653
+ return !self.isAttached;
7654
+ },
7655
+ /**
7656
+ * @summary Load the items' {@link FooGallery.Item#$image|$image}.
7657
+ * @memberof FooGallery.Item#
7658
+ * @function load
7659
+ * @returns {Promise.<FooGallery.Item>}
7660
+ */
7661
+ load: function () {
7662
+ var self = this;
7663
+ if (_is.promise(self._load)) return self._load;
7664
+ if (!self.isCreated || !self.isAttached) return _fn.rejectWith("not created or attached");
7665
+ var e = self.tmpl.raise("load-item", [self]);
7666
+ if (e.isDefaultPrevented()) return _fn.rejectWith("default prevented");
7667
+ var cls = self.cls, img = self.$image.get(0), placeholder = img.src;
7668
+ self.isLoading = true;
7669
+ self.$el.removeClass(cls.idle).removeClass(cls.loaded).removeClass(cls.error).addClass(cls.loading);
7670
+ return self._load = $.Deferred(function (def) {
7671
+ img.onload = function () {
7672
+ img.onload = img.onerror = null;
7673
+ self.isLoading = false;
7674
+ self.isLoaded = true;
7675
+ self.$el.removeClass(cls.loading).addClass(cls.loaded);
7676
+ if (self.fixLayout || !self.isParsed) self.unfix();
7677
+ self.tmpl.raise("loaded-item", [self]);
7678
+ def.resolve(self);
7679
+ };
7680
+ img.onerror = function () {
7681
+ img.onload = img.onerror = null;
7682
+ self.isLoading = false;
7683
+ self.isError = true;
7684
+ self.$el.removeClass(cls.loading).addClass(cls.error);
7685
+ if (_is.string(placeholder)) {
7686
+ self.$image.prop("src", placeholder);
7687
+ }
7688
+ self.tmpl.raise("error-item", [self]);
7689
+ def.reject(self);
7690
+ };
7691
+ // set everything in motion by setting the src
7692
+ img.src = self.getThumbUrl();
7693
+ if (img.complete){
7694
+ img.onload();
7695
+ }
7696
+ }).promise();
7697
+ },
7698
+ /**
7699
+ * @summary Attempts to set a inline width and height on the {@link FooGallery.Item#$image|$image} to prevent layout jumps.
7700
+ * @memberof FooGallery.Item#
7701
+ * @function fix
7702
+ * @returns {FooGallery.Item}
7703
+ */
7704
+ fix: function () {
7705
+ var self = this;
7706
+ if (self.tmpl == null) return self;
7707
+ if (self.isCreated && !self.isLoading && !self.isLoaded && !self.isError) {
7708
+ var w = self.width, h = self.height, img = self.$image.get(0);
7709
+ // if we have a base width and height to work with
7710
+ if (!isNaN(w) && !isNaN(h) && !!img) {
7711
+ // figure out the max image width and calculate the height the image should be displayed as
7712
+ var width = _is.fn(self.maxWidth) ? self.maxWidth(self) : self.$image.width();
7713
+ if (width <= 0) width = w;
7714
+ var ratio = width / w, height = h * ratio;
7715
+ // actually set the inline css on the image
7716
+ self.$image.css({width: width, height: height});
7717
+ }
7718
+ }
7719
+ return self;
7720
+ },
7721
+ /**
7722
+ * @summary Removes any inline width and height values set on the {@link FooGallery.Item#$image|$image}.
7723
+ * @memberof FooGallery.Item#
7724
+ * @function unfix
7725
+ * @returns {FooGallery.Item}
7726
+ */
7727
+ unfix: function () {
7728
+ var self = this;
7729
+ if (self.tmpl == null) return self;
7730
+ if (self.isCreated) self.$image.css({width: '', height: ''});
7731
+ return self;
7732
+ },
7733
+ /**
7734
+ * @summary Inspect the `src` and `srcset` properties to determine which url to load for the thumb.
7735
+ * @memberof FooGallery.Item#
7736
+ * @function getThumbSrc
7737
+ * @param {number} renderWidth - The rendered width of the image to fetch the url for.
7738
+ * @param {number} renderHeight - The rendered height of the image to fetch the url for.
7739
+ * @returns {string}
7740
+ */
7741
+ getThumbSrc: function(renderWidth, renderHeight){
7742
+ return _utils.src(this.src, this.srcset, this.width, this.height, renderWidth, renderHeight);
7743
+ },
7744
+ /**
7745
+ * @summary Inspect the `src` and `srcset` properties to determine which url to load for the thumb.
7746
+ * @memberof FooGallery.Item#
7747
+ * @function getThumbUrl
7748
+ * @param {boolean} [refresh=false] - Whether or not to force refreshing of the cached value.
7749
+ * @returns {string}
7750
+ */
7751
+ getThumbUrl: function (refresh) {
7752
+ refresh = _is.boolean(refresh) ? refresh : false;
7753
+ var self = this;
7754
+ if (!refresh && _is.string(self._thumbUrl)) return self._thumbUrl;
7755
+ return self._thumbUrl = self.getThumbSrc(self.$anchor.innerWidth(), self.$anchor.innerHeight());
7756
+ },
7757
+ /**
7758
+ * @summary Gets the type specific CSS class for the item.
7759
+ * @memberof FooGallery.Item#
7760
+ * @function getTypeClass
7761
+ * @returns {string}
7762
+ */
7763
+ getTypeClass: function(){
7764
+ return this.cls.types.hasOwnProperty(this.type) ? this.cls.types[this.type] : "";
7765
+ },
7766
+ /**
7767
+ * @summary Scroll the item into the center of the viewport.
7768
+ * @memberof FooGallery.Item#
7769
+ * @function scrollTo
7770
+ */
7771
+ scrollTo: function (align) {
7772
+ var self = this;
7773
+ if (self.isAttached) {
7774
+ var ib = self.bounds(), vb = _utils.getViewportBounds();
7775
+ switch (align) {
7776
+ case "top": // attempts to center the item horizontally but aligns the top with the middle of the viewport
7777
+ ib.left += (ib.width / 2) - (vb.width / 2);
7778
+ ib.top -= (vb.height / 5);
7779
+ break;
7780
+ default: // attempts to center the item in the viewport
7781
+ ib.left += (ib.width / 2) - (vb.width / 2);
7782
+ ib.top += (ib.height / 2) - (vb.height / 2);
7783
+ break;
7784
+ }
7785
+ window.scrollTo(ib.left, ib.top);
7786
+ }
7787
+ return self;
7788
+ },
7789
+ /**
7790
+ * @summary Get the bounds for the item.
7791
+ * @memberof FooGallery.Item#
7792
+ * @function bounds
7793
+ * @returns {?FooGallery.utils.Bounds}
7794
+ */
7795
+ bounds: function () {
7796
+ return this.isAttached ? _utils.getElementBounds(this.$el) : null;
7797
+ },
7798
+ /**
7799
+ * @summary Checks if the item bounds intersects the supplied bounds.
7800
+ * @memberof FooGallery.Item#
7801
+ * @function intersects
7802
+ * @param {FooGallery.utils.Bounds} bounds - The bounds to check.
7803
+ * @returns {boolean}
7804
+ */
7805
+ intersects: function (bounds) {
7806
+ return this.isAttached ? this.bounds().intersects(bounds) : false;
7807
+ },
7808
+ /**
7809
+ * @summary Updates the current state to this item.
7810
+ * @memberof FooGallery.Item#
7811
+ * @function updateState
7812
+ */
7813
+ updateState: function(){
7814
+ this.tmpl.state.update(this.tmpl.state.get(this));
7815
+ },
7816
+ /**
7817
+ * @summary Converts the item to a JSON object.
7818
+ * @memberof FooGallery.Item#
7819
+ * @function toJSON
7820
+ * @returns {object}
7821
+ */
7822
+ toJSON: function(){
7823
+ return {
7824
+ "type": this.type,
7825
+ "href": this.href,
7826
+ "src": this.src,
7827
+ "srcset": this.srcset,
7828
+ "width": this.width,
7829
+ "height": this.height,
7830
+ "alt": this.alt,
7831
+ "title": this.title,
7832
+ "caption": this.caption,
7833
+ "description": this.description,
7834
+ "tags": this.tags.slice(),
7835
+ "maxCaptionLength": this.maxCaptionLength,
7836
+ "maxDescriptionLength": this.maxDescriptionLength,
7837
+ "showCaptionTitle": this.showCaptionTitle,
7838
+ "showCaptionDescription": this.showCaptionDescription,
7839
+ "attr": _obj.extend({}, this.attr)
7840
+ };
7841
+ },
7842
+ /**
7843
+ * @summary Listens for the click event on the {@link FooGallery.Item#$anchor|$anchor} element and updates the state if enabled.
7844
+ * @memberof FooGallery.Item#
7845
+ * @function onAnchorClick
7846
+ * @param {jQuery.Event} e - The jQuery.Event object for the click event.
7847
+ * @private
7848
+ */
7849
+ onAnchorClick: function (e) {
7850
+ var self = e.data.self, evt = self.tmpl.raise("anchor-click-item", [self]);
7851
+ if (evt.isDefaultPrevented()) {
7852
+ e.preventDefault();
7853
+ } else {
7854
+ self.updateState();
7855
  }
 
7856
  },
7857
  /**
7858
+ * @summary Listens for the click event on the {@link FooGallery.Item#$caption|$caption} element and redirects it to the anchor if required.
7859
+ * @memberof FooGallery.Item#
7860
+ * @function onCaptionClick
7861
+ * @param {jQuery.Event} e - The jQuery.Event object for the click event.
7862
+ * @private
 
 
7863
  */
7864
+ onCaptionClick: function (e) {
7865
+ var self = e.data.self, evt = self.tmpl.raise("caption-click-item", [self]);
7866
+ if (!evt.isDefaultPrevented() && self.$anchor.length > 0 && !$(e.target).is("a,:input")) {
7867
+ self.$anchor.get(0).click();
7868
+ }
7869
+ }
7870
+ });
7871
+
7872
+ /**
7873
+ * @summary Called when setting an items' image size to prevent layout jumps.
7874
+ * @callback FooGallery.Item~maxWidthCallback
7875
+ * @param {FooGallery.Item} item - The item to determine the maxWidth for.
7876
+ * @returns {number} Returns the maximum width allowed for the {@link FooGallery.Item#$image|$image} element.
7877
+ * @example {@caption An example of the default behavior this callback replaces would look like the below.}
7878
+ * {
7879
+ * "maxWidth": function(item){
7880
+ * return item.$image.outerWidth();
7881
+ * }
7882
+ * }
7883
+ */
7884
+
7885
+ /**
7886
+ * @summary A simple object containing an items' default values.
7887
+ * @typedef {object} FooGallery.Item~Options
7888
+ * @property {?string} [type="item"] - The `data-type` attribute for the anchor element.
7889
+ * @property {?string} [id=null] - The `data-id` attribute for the outer element.
7890
+ * @property {?string} [href=null] - The `href` attribute for the anchor element.
7891
+ * @property {?string} [src=null] - The `src` attribute for the image element.
7892
+ * @property {?string} [srcset=null] - The `srcset` attribute for the image element.
7893
+ * @property {number} [width=0] - The width of the image.
7894
+ * @property {number} [height=0] - The height of the image.
7895
+ * @property {?string} [title=null] - The title for the image. This should be plain text.
7896
+ * @property {?string} [alt=null] - The alt for the image. This should be plain text.
7897
+ * @property {?string} [caption=null] - The caption for the image. This can contain HTML content.
7898
+ * @property {?string} [description=null] - The description for the image. This can contain HTML content.
7899
+ * @property {string[]} [tags=[]] - The `data-tags` attribute for the outer element.
7900
+ * @property {?FooGallery.Item~maxWidthCallback} [maxWidth=null] - Called when setting an items' image size. If not supplied the images outer width is used.
7901
+ * @property {number} [maxCaptionLength=0] - The max length of the title for the caption.
7902
+ * @property {number} [maxDescriptionLength=0] - The max length of the description for the caption.
7903
+ * @property {boolean} [showCaptionTitle=true] - Whether or not the caption title should be displayed.
7904
+ * @property {boolean} [showCaptionDescription=true] - Whether or not the caption description should be displayed.
7905
+ * @property {FooGallery.Item~Attributes} [attr] - Additional attributes to apply to the items' elements.
7906
+ */
7907
+ _.template.configure("core", {
7908
+ item: {
7909
+ type: "item",
7910
+ id: "",
7911
+ href: "",
7912
+ src: "",
7913
+ srcset: "",
7914
+ width: 0,
7915
+ height: 0,
7916
+ title: "",
7917
+ alt: "",
7918
+ caption: "",
7919
+ description: "",
7920
+ tags: [],
7921
+ maxWidth: null,
7922
+ maxCaptionLength: 0,
7923
+ maxDescriptionLength: 0,
7924
+ showCaptionTitle: true,
7925
+ showCaptionDescription: true,
7926
+ attr: {
7927
+ elem: {},
7928
+ inner: {},
7929
+ anchor: {},
7930
+ image: {},
7931
+ caption: {
7932
+ elem: {},
7933
+ inner: {},
7934
+ title: {},
7935
+ description: {}
7936
  }
7937
  }
 
 
 
 
 
 
 
 
 
7938
  }
7939
+ }, {
7940
+ item: {
7941
+ elem: "fg-item",
7942
+ inner: "fg-item-inner",
7943
+ anchor: "fg-thumb",
7944
+ overlay: "fg-image-overlay",
7945
+ wrap: "fg-image-wrap",
7946
+ image: "fg-image",
7947
+ loader: "fg-loader",
7948
+ idle: "fg-idle",
7949
+ loading: "fg-loading",
7950
+ loaded: "fg-loaded",
7951
+ error: "fg-error",
7952
+ types: {
7953
+ item: "fg-type-unknown"
7954
+ },
7955
+ caption: {
7956
+ elem: "fg-caption",
7957
+ inner: "fg-caption-inner",
7958
+ title: "fg-caption-title",
7959
+ description: "fg-caption-desc"
7960
+ }
7961
+ }
7962
+ }, {
7963
+ item: {}
7964
  });
7965
 
7966
+ _.components.register("item", _.Item);
7967
+
7968
+ // ######################
7969
+ // ## Type Definitions ##
7970
+ // ######################
7971
+
7972
+ /**
7973
+ * @summary A simple object containing the CSS classes used by an item.
7974
+ * @typedef {object} FooGallery.Item~CSSClasses
7975
+ * @property {string} [elem="fg-item"] - The CSS class for the outer containing `div` element of an item.
7976
+ * @property {string} [inner="fg-item-inner"] - The CSS class for the inner containing `div` element of an item.
7977
+ * @property {string} [anchor="fg-thumb"] - The CSS class for the `a` element of an item.
7978
+ * @property {string} [image="fg-image"] - The CSS class for the `img` element of an item.
7979
+ * @property {string} [loading="fg-idle"] - The CSS class applied to an item that is waiting to be loaded.
7980
+ * @property {string} [loading="fg-loading"] - The CSS class applied to an item while it is loading.
7981
+ * @property {string} [loaded="fg-loaded"] - The CSS class applied to an item once it is loaded.
7982
+ * @property {string} [error="fg-error"] - The CSS class applied to an item if it throws an error while loading.
7983
+ * @property {object} [caption] - A simple object containing the CSS classes used by an items' caption.
7984
+ * @property {string} [caption.elem="fg-caption"] - The CSS class for the outer containing `div` element of a caption.
7985
+ * @property {string} [caption.inner="fg-caption-inner"] - The CSS class for the inner containing `div` element of a caption.
7986
+ * @property {string} [caption.title="fg-caption-title"] - The CSS class for the title `div` element of a caption.
7987
+ * @property {string} [caption.description="fg-caption-desc"] - The CSS class for the description `div` element of a caption.
7988
+ */
7989
+ /**
7990
+ * @summary A simple object used to store any additional attributes to apply to an items' elements.
7991
+ * @typedef {object} FooGallery.Item~Attributes
7992
+ * @property {object} [elem={}] - The attributes to apply to the items' outer `<div/>` element.
7993
+ * @property {object} [inner={}] - The attributes to apply to the items' inner element.
7994
+ * @property {object} [anchor={}] - The attributes to apply to the items' anchor element.
7995
+ * @property {object} [image={}] - The attributes to apply to the items' image element.
7996
+ * @property {object} [caption] - A simple object used to store any additional attributes to apply to an items' caption elements.
7997
+ * @property {object} [caption.elem={}] - The attributes to apply to the captions' outer `<div/>` element.
7998
+ * @property {object} [caption.inner={}] - The attributes to apply to the captions' inner element.
7999
+ * @property {object} [caption.title={}] - The attributes to apply to the captions' title element.
8000
+ * @property {object} [caption.description={}] - The attributes to apply to the captions' description element.
8001
+ */
8002
 
8003
  })(
8004
+ FooGallery.$,
8005
+ FooGallery,
8006
+ FooGallery.utils,
8007
+ FooGallery.utils.is,
8008
+ FooGallery.utils.fn,
8009
+ FooGallery.utils.obj,
8010
+ FooGallery.utils.str
8011
+ );
8012
+ (function($, _, _utils, _is){
8013
+
8014
+ _.Image = _.Item.extend({});
8015
+
8016
+ _.template.configure("core", null,{
8017
+ item: {
8018
+ types: {
8019
+ image: "fg-type-image"
8020
+ }
8021
+ }
8022
+ });
8023
+
8024
+ _.components.register("image", _.Image);
8025
+
8026
+ })(
8027
+ FooGallery.$,
8028
+ FooGallery,
8029
+ FooGallery.utils,
8030
+ FooGallery.utils.is
8031
  );
8032
  (function ($, _, _utils, _is) {
8033
 
8055
  self.ctrls = [];
8056
  self._arr = [];
8057
  },
8058
+ fromHash: function(hash){
8059
+ var parsed = parseInt(hash);
8060
+ return isNaN(parsed) ? null : parsed;
8061
+ },
8062
+ toHash: function(value){
8063
+ return _is.number(value) && value > 0 ? value.toString() : null;
8064
+ },
8065
+ getState: function(){
8066
+ return this.isValid(this.current) ? this.current : null;
8067
+ },
8068
+ setState: function(state){
8069
+ this.rebuild();
8070
+ if (!!state.item && !this.contains(state.page, state.item)){
8071
+ state.page = this.find(state.item);
8072
+ state.page = state.page !== 0 ? state.page : 1;
8073
+ }
8074
+ this.set(state.page, false, false, true);
8075
+ },
8076
  destroy: function () {
8077
  var self = this;
8078
  self._arr.splice(0, self._arr.length);
8551
  }
8552
  return self.style.sheet;
8553
  },
8554
+ delayedLayout: function(){
8555
+ var self = this;
8556
+ if (self._delayedLayout) clearTimeout(self._delayedLayout);
8557
+ self._delayedLayout = setTimeout(function () {
8558
+ self._delayedLayout = null;
8559
+ self.masonry.layout();
8560
+ }, 20);
8561
+ },
8562
  /**
8563
  * @summary Listens for the {@link FooGallery.Template~event:"pre-init.foogallery"|`pre-init.foogallery`} event.
8564
  * @memberof FooGallery.MasonryTemplate#
8635
  self.masonry.layout();
8636
  },
8637
  onReady: function(event, self){
8638
+ self.delayedLayout();
8639
  },
8640
  onDestroy: function(event, self){
8641
+ if (self._delayedLayout) clearTimeout(self._delayedLayout);
8642
  self.$el.find(self.sel.columnWidth).remove();
8643
  self.$el.find(self.sel.gutterWidth).remove();
8644
  if (self.style && self.style.parentNode){
8723
  });
8724
 
8725
  _.template.register("masonry", _.MasonryTemplate, {
8726
+ fixLayout: true,
8727
  template: {
8728
  initLayout: false,
8729
  isInitLayout: false,
9092
  maxRowHeight: "200%",
9093
  margins: 0,
9094
  lastRow: "center",
9095
+ justifyThreshold: 1,
9096
  refreshInterval: 250
9097
  };
9098
 
9539
  }
9540
  };
9541
 
9542
+ _.autoEnabled = true;
9543
+
9544
  _.auto = function (options) {
9545
  _.autoDefaults = _obj.merge(_.autoDefaults, options);
9546
  };
9548
  _.load = _.reload = function(){
9549
  // this automatically initializes all templates on page load
9550
  $(function () {
9551
+ if (_.autoEnabled){
9552
+ $('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(_.autoDefaults);
9553
+ }
9554
  });
9555
 
9556
  _utils.ready(function () {
9557
+ if (_.autoEnabled){
9558
+ $('[id^="foogallery-gallery-"].fg-ready').foogallery(_.autoDefaults);
9559
+ }
9560
  });
9561
  };
9562
 
extensions/default-templates/shared/js/foogallery.min.js CHANGED
@@ -1,11 +1,11 @@
1
  /*
2
  * FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
3
- * @version 1.3.4
4
  * @link
5
  * @copyright Steven Usher & Brad Vincent 2015
6
  * @license Released under the GPLv3 license.
7
  */
8
 
9
- !function(a,b){b.$=a}(jQuery,window.FooGallery=window.FooGallery||{}),function(a){if(!a)return void console.warn("jQuery must be included in the page prior to the FooGallery.utils library.");var b={$:a,version:"0.1.3"};b.versionCompare=function(a,b){function c(a){for(var b=a.split("."),c=[],d=0,e=b.length;d<e;d++)c[d]=parseInt(b[d]),isNaN(c[d])&&(c[d]=0);return c}if(!/[\d.]/.test(a)||!/[\d.]/.test(b))return NaN;for(var d=c(a),e=c(b);d.length<e.length;)d.push(0);for(;e.length<d.length;)e.push(0);for(var f=0;f<d.length;++f){if(e.length===f)return 1;if(d[f]!==e[f])return d[f]>e[f]?1:-1}return d.length!==e.length?-1:0},!function(){try{return!!window.FooGallery.utils}catch(a){return!1}}()?window.FooGallery.utils=b:b.versionCompare(b.version,window.FooGallery.utils.version)>0?(console.warn("An older version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will override it."),window.FooGallery.utils=b):console.warn("A newer version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will not register itself.")}(jQuery),function(a,b){"0.1.3"===b.version&&(b.is={},b.is.array=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b.is.boolean=function(a){return"[object Boolean]"===Object.prototype.toString.call(a)},b.is.element=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:!!a&&"object"==typeof a&&1===a.nodeType&&"string"==typeof a.nodeName},b.is.empty=function(a){if(b.is.undef(a)||null===a)return!0;if(b.is.number(a)&&0===a)return!0;if(b.is.boolean(a)&&!1===a)return!0;if(b.is.string(a)&&0===a.length)return!0;if(b.is.array(a)&&0===a.length)return!0;if(b.is.jq(a)&&0===a.length)return!0;if(b.is.hash(a)){for(var c in a)if(a.hasOwnProperty(c))return!1;return!0}return!1},b.is.error=function(a){return"[object Error]"===Object.prototype.toString.call(a)},b.is.fn=function(a){return a===window.alert||"[object Function]"===Object.prototype.toString.call(a)},b.is.hash=function(a){return b.is.object(a)&&a.constructor===Object&&!a.nodeType&&!a.setInterval},b.is.jq=function(c){return!b.is.undef(a)&&c instanceof a},b.is.number=function(a){return"[object Number]"===Object.prototype.toString.call(a)&&!isNaN(a)},b.is.object=function(a){return"[object Object]"===Object.prototype.toString.call(a)&&!b.is.undef(a)&&null!==a},b.is.promise=function(a){return b.is.object(a)&&b.is.fn(a.then)&&b.is.fn(a.promise)},b.is.size=function(a){return!!(b.is.string(a)&&!b.is.empty(a)||b.is.number(a))&&/^(auto|none|(?:[\d.]*)+?(?:%|px|mm|q|cm|in|pt|pc|em|ex|ch|rem|vh|vw|vmin|vmax)?)$/.test(a)},b.is.string=function(a){return"[object String]"===Object.prototype.toString.call(a)},b.is.undef=function(a){return void 0===a})}(FooGallery.utils.$,FooGallery.utils),function(a,b,c){if("0.1.3"===b.version){b.fn={};var d=Function.prototype.toString;b.fn.CONTAINS_SUPER=/xyz/.test(d.call(function(){xyz}))?/\b_super\b/:/.*/,b.fn.addOrOverride=function(a,e,f){if(c.object(a)&&c.string(e)&&!c.empty(e)&&c.fn(f)){var g=a[e],h=c.fn(g)&&b.fn.CONTAINS_SUPER.test(d.call(f));a[e]=h?function(a,b){return function(){var c=this._super;this._super=a;var d=b.apply(this,arguments);return this._super=c,d}}(g,f):f}},b.fn.apply=function(a,b){function d(){return a.apply(this,b)}return b=c.array(b)?b:[],d.prototype=a.prototype,new d},b.fn.arg2arr=function(a){return Array.prototype.slice.call(a)},b.fn.debounce=function(a,c){var d;return function(){var e=this,f=b.fn.arg2arr(arguments);clearTimeout(d),d=setTimeout(function(){a.apply(e,f)},c)}},b.fn.throttle=function(a,c){var d,e;return function(){var f=this,g=b.fn.arg2arr(arguments);d?(clearTimeout(e),e=setTimeout(function(){Date.now()-d>=c&&(a.apply(f,g),d=Date.now())},c-(Date.now()-d))):(a.apply(f,g),d=Date.now())}},b.fn.check=function(d,e,f,g){function h(a){return function(){return a.apply(d,arguments)}}return f=c.fn(f)?f:a.noop,d=c.object(d)?d:window,e=c.string(e)?b.fn.fetch(e,g):e,h(c.fn(e)?e:f)},b.fn.fetch=function(b,d){return!c.string(b)||c.empty(b)?null:(d=c.object(d)?d:window,a.each(b.split("."),function(a,b){if(!d[b])return!1;d=d[b]}),c.fn(d)?d:null)},b.fn.enqueue=function(d,e,f,g){function h(a,b){try{return n.push(a),b.apply(a,i)}catch(a){return j.reject(a,n),j}}var i=b.fn.arg2arr(arguments),j=a.Deferred(),k=a.Deferred(),l=k.promise(),m=[],n=[],o=!0;return d=i.shift(),e=i.shift(),a.each(d,function(a,d){c.fn(d[e])&&(l=l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}return o=!1,h(d,d[e])}))}),l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}o=!1,j.resolve(m)}),l.fail(function(){var a=b.fn.arg2arr(arguments);a.push(n),j.reject.apply(j,a)}),k.resolve(),j.promise()},b.fn.when=function(b){if(!c.array(b)||c.empty(b))return a.when();for(var d=a.Deferred(),e=[],f=b.length,g=0;g<b.length;g++)b[g].then(function(a){e.push(a)}).always(function(){--f||d.resolve(e)});return d.promise()},b.fn.rejectWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.reject.apply(e,f).promise()},b.fn.resolveWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.resolve.apply(e,f).promise()},b.fn.resolved=a.Deferred().resolve().promise(),b.fn.rejected=a.Deferred().reject().promise()}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b){if("0.1.3"===a.version){a.url={};var c=document.createElement("a");a.url.parts=function(a){return c.href=a,{hash:c.hash,host:c.host,hostname:c.hostname,href:c.href,origin:c.origin,pathname:c.pathname,port:c.port,protocol:c.protocol,search:c.search}},a.url.full=function(a){return!b.string(a)||b.empty(a)?null:(c.href=a,c.href)},a.url.param=function(a,c,d){if(!b.string(a)||!b.string(c)||b.empty(c))return a;var e,f,g,h;return b.undef(d)?(e=new RegExp("[?|&]"+c+"=([^&;]+?)(&|#|;|$)"),f=e.exec(a)||[,""],g=f[1].replace(/\+/g,"%20"),b.string(g)&&!b.empty(g)?decodeURIComponent(g):null):(""===d||null===d?(e=new RegExp("^([^#]*?)(([^#]*)&)?"+c+"(=[^&#]*)?(&|#|$)"),g=a.replace(e,"$1$3$5").replace(/^([^#]*)((\?)&|\?(#|$))/,"$1$3$4")):(e=new RegExp("([?&])"+c+"[^&]*"),h=c+"="+encodeURIComponent(d),(g=a.replace(e,"$1"+h))!==a||e.test(g)||(g+=(-1!==g.indexOf("?")?"&":"?")+h)),g)}}}(FooGallery.utils,FooGallery.utils.is),function(a,b,c){"0.1.3"===a.version&&(a.str={},a.str.camel=function(a){return b.empty(a)?a:a.toUpperCase()===a?a.toLowerCase():a.replace(/^([A-Z])|[-\s_]+(\w)/g,function(a,c,d){return b.string(d)?d.toUpperCase():c.toLowerCase()})},a.str.contains=function(a,c,d){return!(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c))&&(c.length<=a.length&&-1!==(d?a.toUpperCase().indexOf(c.toUpperCase()):a.indexOf(c)))},a.str.containsWord=function(a,c,d){if(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)||a.length<c.length)return!1;for(var e=a.split(/\W/),f=0,g=e.length;f<g;f++)if(d?e[f].toUpperCase()==c.toUpperCase():e[f]==c)return!0;return!1},a.str.endsWith=function(a,c){return!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)?a==c:a.slice(a.length-c.length)==c},a.str.escapeRegExp=function(a){return b.empty(a)?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},a.str.fnv1a=function(a){if(!b.string(a)||b.empty(a))return null;var c,d,e=2166136261;for(c=0,d=a.length;c<d;c++)e^=a.charCodeAt(c),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return e>>>0},a.str.from=function(c,d){return!b.string(c)||b.empty(c)||!b.string(d)||b.empty(d)?null:a.str.contains(c,d)?c.substring(c.indexOf(d)+d.length):null},a.str.join=function(d,e,f){if(!b.string(d)||!b.string(e))return null;var g=c.arg2arr(arguments);d=g.shift();var h,i,j=g.shift();for(h=0,i=g.length;h<i;h++)e=g[h],b.empty(e)||(a.str.endsWith(j,d)&&(j=j.slice(0,j.length-d.length)),a.str.startsWith(e,d)&&(e=e.slice(d.length)),j+=d+e);return j},a.str.startsWith=function(a,c){return!b.empty(a)&&!b.empty(c)&&a.slice(0,c.length)==c},a.str.until=function(c,d){return b.empty(c)||b.empty(d)?c:a.str.contains(c,d)?c.substring(0,c.indexOf(d)):c},a.str.format=function(a,d,e){var f=c.arg2arr(arguments);if(a=f.shift(),b.empty(a)||b.empty(f))return a;1===f.length&&(b.array(f[0])||b.object(f[0]))&&(f=f[0]);for(var g in f)a=a.replace(new RegExp("\\{"+g+"\\}","gi"),f[g]);return a})}(FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){if("0.1.3"===b.version){b.obj={};var f=function(){};b.obj.create=function(a){if(!c.object(a))throw TypeError("Argument must be an object");f.prototype=a;var b=new f;return f.prototype=null,b},b.obj.extend=function(e,f,g){e=c.object(e)?e:{};var h=d.arg2arr(arguments);return h.shift(),a.each(h,function(a,c){b.obj.merge(e,c)}),e},b.obj.merge=function(a,d){a=c.hash(a)?a:{},d=c.hash(d)?d:{};for(var e in d)d.hasOwnProperty(e)&&(c.hash(d[e])?(a[e]=c.hash(a[e])?a[e]:{},b.obj.merge(a[e],d[e])):c.array(d[e])?a[e]=d[e].slice():a[e]=d[e]);return a},b.obj.mergeValid=function(d,e,f,g){if(!c.hash(f)||!c.hash(e))return d;e=c.hash(e)?e:{},g=c.hash(g)?g:{};var h,i,j;for(h in e)e.hasOwnProperty(h)&&c.fn(e[h])&&(i=c.array(g[h])?g[h]:c.string(g[h])?[g[h]]:[h],a.each(i,function(a,g){if(j=b.obj.prop(f,g),!c.undef(j))return e[h](j)?(b.obj.prop(d,h,j),!1):void 0}));return d},b.obj.prop=function(b,d,f){if(c.object(b)&&!c.empty(d)){var g,h;if(c.undef(f))return e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){if(a===h)f=b[d];else{if(!c.hash(b[d]))return!1;b=b[d]}})):c.undef(b[d])||(f=b[d]),f;e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){a===h?b[d]=f:b=c.hash(b[d])?b[d]:b[d]={}})):c.undef(b[d])||(b[d]=f)}}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){if("0.1.3"===b.version){b.ready=function(a){function c(){try{a.call(window,b.$)}catch(a){console.error(a)}}(Function("/*@cc_on return true@*/")()?"complete"===document.readyState:"loading"!==document.readyState)?c():document.addEventListener("DOMContentLoaded",c,!1)};var d=0;b.uniqueId=function(a,b){var e=a.attr("id");return c.empty(e)&&(b=c.string(b)&&!c.empty(b)?b:"uid-",e=b+ ++d,a.attr("id",e).data("__uniqueId__",!0)),e},b.removeUniqueId=function(a){a.data("__uniqueId__")&&a.removeAttr("id").removeData("__uniqueId__")},b.selectify=function(a){if(c.empty(a))return null;if(c.hash(a)){var d,e={};for(var f in a)a.hasOwnProperty(f)&&(d=b.selectify(a[f]))&&(e[f]=d);return e}return c.string(a)||c.array(a)?(c.string(a)&&(a=[a]),a.map(function(a){return c.string(a)?"."+a.split(/\s/g).join("."):null}).join(",")):null},b.src=function(a,b,d,e,f,g,h){if(!c.string(a))return null;if(!c.string(b))return a;var i=b.replace(/(\s[\d.]+[whx]),/g,"$1 @,@ ").split(" @,@ "),j=i.map(function(a){return{url:/^\s*(\S*)/.exec(a)[1],w:parseFloat((/\S\s+(\d+)w/.exec(a)||[0,1/0])[1]),h:parseFloat((/\S\s+(\d+)h/.exec(a)||[0,1/0])[1]),x:parseFloat((/\S\s+([\d.]+)x/.exec(a)||[0,1])[1])}});if(!j.length)return a;j.unshift({url:a,w:j[0].w!==1/0&&j[0].h===1/0?d:1/0,h:j[0].h!==1/0&&j[0].w===1/0?e:1/0,x:1});var k=c.number(h)?h:window.devicePixelRatio||1,l={w:f*k,h:g*k,x:k},m=["w","h","x"];return m.forEach(function(a){var b=Math.max.apply(null,j.map(function(b){return b[a]}));j=j.filter(function(c){return c[a]>=l[a]||c[a]===b})}),m.forEach(function(a){var b=Math.min.apply(null,j.map(function(b){return b[a]}));j=j.filter(function(c){return c[a]===b})}),j[0].url},b.scrollParent=function(b,d,e){b=c.jq(b)?b:a(b),d=c.string(d)&&/^(x|y|xy|yx)$/i.test(d)?d:"xy";var f=a(!!b.length&&b[0].ownerDocument||document);if(e=c.jq(e)?e:f,!b.length)return e;var g=b.css("position"),h="absolute"===g,i=/(auto|scroll)/i,j=/x/i,k=/y/i,l=b.parentsUntil(e).filter(function(b,c){var e=a(this);if(h&&"static"===e.css("position"))return!1;var f=k.test(d)&&c.scrollHeight>c.clientHeight&&i.test(e.css("overflow-y")),g=j.test(d)&&c.scrollWidth>c.clientWidth&&i.test(e.css("overflow-x"));return f||g}).eq(0);return l.is("html")&&(l=f),"fixed"!==g&&l.length?l:e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c){if("0.1.3"===b.version){b.transition={};var d=document.createElement("div");b.transition.supported=function(a){var b=a.style;return c.string(b.transition)||c.string(b.WebkitTransition)||c.string(b.MozTransition)||c.string(b.msTransition)||c.string(b.OTransition)}(d),b.transition.end=function(a){var b=a.style;return c.string(b.transition)?"transitionend":c.string(b.WebkitTransition)?"webkitTransitionEnd":c.string(b.MozTransition)?"transitionend":c.string(b.msTransition)?"msTransitionEnd":c.string(b.OTransition)?"oTransitionEnd":null}(d),b.transition.duration=function(a,b){if(b=c.number(b)?b:0,!c.jq(a))return b;var d=a.css("transition-duration");if(/^([\d\.]*)+?(ms|s)$/i.test(d)){var e=d.match(/^([\d\.]*)+?(ms|s)$/i),f=parseFloat(e[1]);return"s"===e[2].toLowerCase()&&(f*=1e3),f}return b},b.transition.start=function(d,e,f,g){var h=a.Deferred();if(d=d.first(),b.transition.supported){var i=d.data("transition_safety");c.hash(i)&&c.number(i.timer)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),i.deferred.reject()),g=c.number(g)?g:b.transition.duration(d)+50,i={deferred:h,timer:setTimeout(function(){d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve()},g)},d.data("transition_safety",i),d.on(b.transition.end+".utils",function(a){d.is(a.target)&&(clearTimeout(i.timer),d.removeData("transition_safety").off(b.transition.end+".utils"),h.resolve())})}return setTimeout(function(){c.fn(e)?e.apply(d.get(0),[d]):d.toggleClass(e,f),b.transition.supported||h.resolve()},20),h.promise()}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){"0.1.3"===b.version&&(b.Class=function(){},b.Class.extend=function(a){function f(){if(!c.fn(this.construct))throw new SyntaxError('FooGallery.utils.Class objects must be constructed with the "new" keyword.');this.construct.apply(this,arguments)}a=c.hash(a)?a:{};var g=d.create(this.prototype);for(var h in a)a.hasOwnProperty(h)&&e.addOrOverride(g,h,a[h]);return g.construct=c.fn(g.construct)?g.construct:function(){},f.prototype=g,f.prototype.constructor=c.fn(g.__ctor__)?g.__ctor__:f,f.extend=b.Class.extend,f.override=b.Class.override,f},b.Class.override=function(a,b){e.addOrOverride(this.prototype,a,b)})}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj,FooGallery.utils.fn),function(a,b){"0.1.3"===a.version&&(a.Event=a.Class.extend({construct:function(a){this.type=a,this.defaultPrevented=!1},preventDefault:function(){this.defaultPrevented=!0}}),a.EventClass=a.Class.extend({construct:function(){this.__handlers={}},destroy:function(){this.__handlers={}},on:function(a,c,d){if(!b.string(a)||!b.fn(c))return this;d=b.undef(d)?this:d;var e,f=this,g=f.__handlers;return a.split(" ").forEach(function(a){b.array(g[a])||(g[a]=[]),(e=g[a].some(function(a){return a.fn===c&&a.thisArg===d}))||g[a].push({fn:c,thisArg:d})}),f},off:function(a,c,d){if(!b.string(a))return this;c=b.fn(c)?c:null,d=b.undef(d)?this:d;var e=this,f=e.__handlers;return a.split(" ").forEach(function(a){b.array(f[a])&&(null!=c?(f[a]=f[a].filter(function(a){return!(a.fn===c&&a.thisArg===d)}),0===f[a].length&&delete f[a]):delete f[a])}),e},trigger:function(c,d){var e=c instanceof a.Event;if(!e&&!b.string(c))return null;d=b.array(d)?d:[];var f=this,g=f.__handlers,h=[],i=function(a){h.push(a),b.array(g[a.type])&&g[a.type].forEach(function(b){b.fn.apply(b.thisArg,[a].concat(d))})};return e?i(c):c.split(" ").forEach(function(b){i(new a.Event(b))}),b.empty(h)?null:1===h.length?h[0]:h}}))}(FooGallery.utils,FooGallery.utils.is),function(a,b,c){if("0.1.3"===b.version){b.Bounds=b.Class.extend({construct:function(){var a=this;a.top=0,a.right=0,a.bottom=0,a.left=0,a.width=0,a.height=0},inflate:function(a){var b=this;return c.number(a)&&(b.top-=a,b.right+=a,b.bottom+=a,b.left-=a,b.width+=2*a,b.height+=2*a),b},intersects:function(a){var b=this;return b.left<=a.right&&a.left<=b.right&&b.top<=a.bottom&&a.top<=b.bottom}});var d;b.getViewportBounds=function(c){d||(d=a(window));var e=new b.Bounds;return e.top=d.scrollTop(),e.left=d.scrollLeft(),e.width=d.width(),e.height=d.height(),e.right=e.left+e.width,e.bottom=e.top+e.height,e.inflate(c),e},b.getElementBounds=function(d){c.jq(d)||(d=a(d));var e=new b.Bounds;if(0!==d.length){var f=d.offset();e.top=f.top,e.left=f.left,e.width=d.width(),e.height=d.height()}return e.right=e.left+e.width,e.bottom=e.top+e.height,e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){"0.1.3"===b.version&&(b.Factory=b.Class.extend({construct:function(){this.registered={}},contains:function(a){return!c.undef(this.registered[a])},load:function(b,e,f){var g,h,i=this,j=d.arg2arr(arguments),k=[],l=[];b=j.shift()||{};for(g in i.registered)if(i.registered.hasOwnProperty(g)){var m=i.registered[g];b.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&(m={name:g,klass:h,priority:i.registered[g].priority})),k.push(m)}for(g in b)b.hasOwnProperty(g)&&!i.registered.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&k.push({name:g,klass:h,priority:0}));return k.sort(function(a,b){return b.priority-a.priority}),a.each(k,function(a,b){c.fn(b.klass)&&l.push(d.apply(b.klass,j))}),l},make:function(a,b,e){var f,g=this,h=d.arg2arr(arguments);return a=h.shift(),f=g.registered[a],c.hash(f)&&c.fn(f.klass)?d.apply(f.klass,h):null},names:function(b){b=!!c.boolean(b)&&b;var d,e=[];if(b){var f=[];for(d in this.registered)this.registered.hasOwnProperty(d)&&f.push(this.registered[d]);f.sort(function(a,b){return b.priority-a.priority}),a.each(f,function(a,b){e.push(b.name)})}else for(d in this.registered)this.registered.hasOwnProperty(d)&&e.push(d);return e},register:function(a,b,d){if(!c.string(a)||c.empty(a)||!c.fn(b))return!1;d=c.number(d)?d:0;var e=this.registered[a];return this.registered[a]={name:a,klass:b,priority:c.undef(e)?d:e.priority},!0}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c){if("0.1.3"===a.version){var d=!1;try{d=!!window.localStorage}catch(a){d=!1}a.Debugger=a.Class.extend({construct:function(a){this.key=a,this.enabled=!!d&&!!localStorage.getItem(this.key)},enable:function(){d&&(this.enabled=!0,localStorage.setItem(this.key,this.enabled))},disable:function(){d&&(this.enabled=!1,localStorage.removeItem(this.key))},log:function(a,c){this.enabled&&console.log.apply(console,b.arg2arr(arguments))},logf:function(a,d,e){if(this.enabled){var f=b.arg2arr(arguments);a=f.shift(),d=f.shift(),f.unshift(c.format(a,d)),this.log.apply(this,f)}}})}}(FooGallery.utils,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c,d,e){b.debug=new c.Debugger("__FooGallery__"),b.emptyImage="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",b.dataTemplate="__FooGallery__",b.dataItem="__FooGalleryItem__",b.init=function(a,c){return b.template.make(a,c).initialize()},b.initAll=function(c){return e.when(a(".foogallery").map(function(a,d){return b.init(c,d)}).get())},a.fn.foogallery=function(c,e){return this.each(function(f,g){var h=a.data(g,b.dataTemplate);if(d.string(c)){if(h instanceof b.Template)switch(c){case"layout":return void h.layout();case"destroy":return void h.destroy()}}else h instanceof b.Template?h.destroy().then(function(){b.template.make(c,g).initialize().then(function(a){d.fn(e)&&e(a)})}):b.template.make(c,g).initialize().then(function(a){d.fn(e)&&e(a)})})},b.isCached=function(a){var b=new Image;b.src=a;var c=b.complete;return b.src="",b=null,c}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){var f="__FooGallerySwipe__",g="ontouchstart"in window,h=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled&&!g,i=(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&!g,j=g||i;b.Swipe=c.Class.extend({construct:function(b,c){var d=this,f=".fgswipe";d.$el=a(b),d.opt=e.extend({threshold:20,allowPageScroll:!1,swipe:a.noop,data:{}},c),d.active=!1,d.startPoint=null,d.endPoint=null,d.events={start:(j?i?h?"MSPointerDown":"pointerdown":"touchstart":"mousedown")+f,move:(j?i?h?"MSPointerMove":"pointermove":"touchmove":"mousemove")+f,end:(j?i?h?"MSPointerUp":"pointerup":"touchend":"mouseup")+f,leave:(j?i?"mouseleave":null:"mouseleave")+f}},init:function(){var a=this;a.$el.on(a.events.start,{self:a},a.onStart),a.$el.on(a.events.move,{self:a},a.onMove),a.$el.on(a.events.end,{self:a},a.onEnd),d.string(a.events.leave)&&a.$el.on(a.events.leave,{self:a},a.onEnd),a.$el.data(f,a)},destroy:function(){var a=this;a.$el.off(a.events.start,a.onStart),a.$el.off(a.events.move,a.onMove),a.$el.off(a.events.end,a.onEnd),d.string(a.events.leave)&&a.$el.off(a.events.leave,a.onEnd),a.$el.removeData(f)},getAngle:function(a,b){var c=Math.atan2(a.x-b.x,a.y-b.y),d=Math.round(180*c/Math.PI);return 360-(d<0?360-Math.abs(d):d)},getDistance:function(a,b){var c=b.x-a.x,d=b.y-a.y;return c*=c,d*=d,Math.sqrt(c+d)},getDirection:function(a,b){var c=this,d=c.getAngle(a,b);return d>337.5||d<=22.5?"N":d>22.5&&d<=67.5?"NE":d>67.5&&d<=112.5?"E":d>112.5&&d<=157.5?"SE":d>157.5&&d<=202.5?"S":d>202.5&&d<=247.5?"SW":d>247.5&&d<=292.5?"W":d>292.5&&d<=337.5?"NW":"NONE"},getPoint:function(a){var b;return j&&!d.empty(b=a.originalEvent.touches||a.touches)?{x:b[0].pageX,y:b[0].pageY}:d.number(a.pageX)&&d.number(a.pageY)?{x:a.pageX,y:a.pageY}:null},getOffset:function(a){var b=this,c=b.$el.offset();return{left:a.x-c.left,top:a.y-c.top}},onStart:function(a){var b=a.data.self,c=b.getPoint(a);d.empty(c)||(b.active=!0,b.startPoint=b.endPoint=c)},onMove:function(b){var c=b.data.self,e=c.getPoint(b);if(c.active&&!d.empty(e))if(c.endPoint=e,c.opt.allowPageScroll){if(d.hash(c.opt.allowPageScroll)){var f=c.getDirection(c.startPoint,c.endPoint);c.opt.allowPageScroll.x||-1===a.inArray(f,["NE","E","SE","NW","W","SW"])||b.preventDefault(),c.opt.allowPageScroll.y||-1===a.inArray(f,["NW","N","NE","SW","S","SE"])||b.preventDefault()}}else b.preventDefault()},onEnd:function(a){var b=a.data.self;if(b.active){b.active=!1;var c={startPoint:b.startPoint,endPoint:b.endPoint,startOffset:b.getOffset(b.startPoint),endOffset:b.getOffset(b.endPoint),angle:b.getAngle(b.startPoint,b.endPoint),distance:b.getDistance(b.startPoint,b.endPoint),direction:b.getDirection(b.startPoint,b.endPoint)};if(b.opt.threshold>0&&c.distance<b.opt.threshold)return;b.opt.swipe.apply(this,[c,b.opt.data]),b.startPoint=null,b.endPoint=null}}}),a.fn.fgswipe=function(c){return this.each(function(){var e=a(this),g=e.data(f);if(g instanceof b.Swipe){if(d.string(c)&&d.fn(g[c]))return void g[c]();g.destroy()}d.hash(c)&&(g=new b.Swipe(this,c),g.init())})}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj),function(a,b,c,d,e,f){b.TemplateFactory=c.Factory.extend({construct:function(){this.registered={}},register:function(a,b,c,e,f,g){var h=this,i=h._super(a,b,g);if(i){var j=h.registered;j[a].opt=d.hash(c)?c:{},j[a].cls=d.hash(e)?e:{},j[a].il8n=d.hash(f)?f:{}}return i},make:function(b,c){c=d.jq(c)?c:a(c),b=f.extend({},b,c.data("foogallery"));var e=this,g=e.type(b,c);return e.contains(g)?(b=e.options(g,b),e._super(g,b,c)):null},type:function(b,e){e=d.jq(e)?e:a(e);var f=this,g=d.hash(b)&&d.hash(b)&&d.string(b.type)&&f.contains(b.type)?b.type:"core";if("core"===g&&e.length>0)for(var h=f.registered,i=f.names(!0),j=0,k=i.length;j<k;j++)if(h.hasOwnProperty(i[j])){var l=i[j],m=h[l].cls;if(d.string(m.container)){var n=c.selectify(m.container);if(e.is(n)){g=i[j];break}}}return g},configure:function(a,b,c,d){var e=this;if(e.contains(a)){var g=e.registered;f.extend(g[a].opt,b),f.extend(g[a].cls,c),f.extend(g[a].il8n,d)}},options:function(a,c){c=f.extend({type:a},c);var e=this,g=e.registered,h=g.core.opt,i=g.core.cls,j=g.core.il8n;return d.hash(c.cls)||(c.cls={}),d.hash(c.il8n)||(c.il8n={}),d.undef(b.filtering)||(c=b.filtering.merge(c)),d.undef(b.paging)||(c=b.paging.merge(c)),"core"!==a&&e.contains(a)?(c=f.extend({},h,g[a].opt,c),c.cls=f.extend({},i,g[a].cls,c.cls),c.il8n=f.extend({},j,g[a].il8n,c.il8n)):(c=f.extend({},h,c),c.cls=f.extend({},i,c.cls),c.il8n=f.extend({},j,c.il8n)),c}}),b.template=new b.TemplateFactory}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e){a.PagingFactory=b.Factory.extend({construct:function(){this.registered={}},register:function(a,b,d,e,f,g,h){var i=this,j=i._super(a,b,h);if(j){var k=i.registered;k[a].ctrl=c.fn(d)?d:null,k[a].opt=c.hash(e)?e:{},k[a].cls=c.hash(f)?f:{},k[a].il8n=c.hash(g)?g:{}}return j},type:function(a){var b,d=this;return c.hash(a)&&c.hash(b=a.paging)&&c.string(b.type)&&d.contains(b.type)?b.type:null},merge:function(a){a=e.extend({},a);var b=this,d=b.type(a),f=b.registered,g=f.default.opt,h=f.default.cls,i=f.default.il8n,j=c.hash(a.paging)?a.paging:{},k=c.hash(a.cls)&&c.hash(a.cls.paging)?e.extend({},a.cls.paging):{},l=c.hash(a.il8n)&&c.hash(a.il8n.paging)?e.extend({},a.il8n.paging):{};return c.hash(a.cls)||(a.cls={}),c.hash(a.il8n)||(a.il8n={}),"default"!==d&&b.contains(d)?(a.paging=e.extend({},g,f[d].opt,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:f[d].cls},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:f[d].il8n},{paging:l})):(a.paging=e.extend({},g,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:l})),a},configure:function(a,b,c,d){var f=this;if(f.contains(a)){var g=f.registered;e.extend(g[a].opt,b),e.extend(g[a].cls,c),e.extend(g[a].il8n,d)}},hasCtrl:function(a){var b=this,d=b.registered[a];return c.hash(d)&&c.fn(d.ctrl)},makeCtrl:function(a,b,d,e){var f=this,g=f.registered[a];return c.hash(g)&&c.fn(g.ctrl)?new g.ctrl(b,d,e):null}}),a.paging=new a.PagingFactory}(FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){var g=0;b.Template=c.Class.extend({construct:function(e,f){var h=this;h.namespace=".foogallery-"+ ++g,h.$el=d.jq(f)?f:a(f),h.$scrollParent=null,h.opt=e,h.template=e.template,h.id=h.$el.prop("id")||e.id,h.cls=e.cls,h.il8n=e.il8n,h.sel=c.selectify(h.cls),h.items=b.components.make("items",h),h.pages=d.undef(b.paging)?null:b.paging.make(e.paging.type,h),h.filter=d.undef(b.filtering)?null:b.filtering.make(e.filtering.type,h),h.state=b.components.make("state",h),h._initialize=null,h.initializing=!1,h.initialized=!1,h.destroying=!1,h.destroyed=!1,h._undo={classes:"",style:"",create:!1,children:!1}},initialize:function(b){var c=this;return d.promise(c._initialize)?c._initialize:c._initialize=a.Deferred(function(a){c.preInit(b)?c.init().then(function(){c.postInit()?c.firstLoad().then(function(){c.ready(),a.resolve(c)}).fail(a.reject):a.reject("post-init failed")}).fail(a.reject):a.reject("pre-init failed")}).fail(function(a){console.log("initialize failed",c,a),c.destroy()}).promise()},preInit:function(e){var f=this;if(f.destroying)return!1;if(e=d.jq(e)?e:a(e),f.initializing=!0,0===e.length&&0===f.$el.parent().length)return!1;0===f.$el.length&&(f.$el=f.create(),f._undo.create=!0),e.length>0&&f.$el.appendTo(e);var g;d.empty(f.opt.scrollParent)||0===(g=a(f.opt.scrollParent)).length?f.$scrollParent=a(document):f.$scrollParent=g.is("html")?a(document):g,f.$el.data(b.dataTemplate,f),d.empty(f.opt.on)||f.$el.on(f.opt.on),f._undo.classes=f.$el.attr("class"),f._undo.style=f.$el.attr("style"),f.$el.is(f.sel.container)||f.$el.addClass(f.cls.container);var h=c.selectify(f.opt.classes);return null==h||f.$el.is(h)||f.$el.addClass(f.opt.classes),0===f.$el.children().not(f.sel.item.elem).length&&(f.$el.append(f.createChildren()),f._undo.children=!0),!f.raise("pre-init").isDefaultPrevented()},init:function(){var a=this;return a.raise("init").isDefaultPrevented()?e.rejectWith("init default prevented"):a.items.fetch()},postInit:function(){var b=this;if(b.destroying)return!1;if(b.raise("post-init").isDefaultPrevented())return!1;var c=b.state.parse();return b.state.set(d.empty(c)?b.state.initial():c),b.$scrollParent.on("scroll"+b.namespace,{self:b},e.throttle(function(){b.loadAvailable()},50)),a(window).on("popstate"+b.namespace,{self:b},b.onWindowPopState),!0},firstLoad:function(){var a=this;return a.destroying?e.rejected:(a.raise("first-load"),a.loadAvailable())},ready:function(){var a=this;return!a.destroying&&(a.initializing=!1,a.initialized=!0,a._check(1e3),a.raise("ready"),!0)},create:function(){var b=this;return a("<div/>",{id:b.id,class:b.cls.container}).addClass(b.opt.classes)},createChildren:function(){return a()},destroy:function(){var b=this;return b.destroyed?e.resolved:(b.destroying=!0,a.Deferred(function(a){b.initializing&&d.promise(b._initialize)?b._initialize.always(function(){b.destroying=!1,b.doDestroy(),a.resolve()}):(b.destroying=!1,b.doDestroy(),a.resolve())}).promise())},doDestroy:function(){var c=this;c.destroyed||(c.raise("destroy"),c.$scrollParent.off(c.namespace),a(window).off(c.namespace),c.state.destroy(),c.filter&&c.filter.destroy(),c.pages&&c.pages.destroy(),c.items.destroy(),d.empty(c.opt.on)||c.$el.off(c.opt.on),c.raise("destroyed"),c.$el.removeData(b.dataTemplate),d.empty(c._undo.classes)?c.$el.removeAttr("class"):c.$el.attr("class",c._undo.classes),d.empty(c._undo.style)?c.$el.removeAttr("style"):c.$el.attr("style",c._undo.style),c._undo.children&&c.destroyChildren(),c._undo.create&&c.$el.remove(),c.$el=c.state=c.items=c.pages=null,c.destroyed=!0,c.initializing=!1,c.initialized=!1)},destroyChildren:function(){},getAvailable:function(){return this.pages?this.pages.available():this.items.available()},loadAvailable:function(){return this.items.load(this.getAvailable())},getItems:function(){return this.pages?this.pages.items():this.items.available()},_check:function(a){a=d.number(a)?a:0;var b=this;setTimeout(function(){!b.initialized||b.destroying&&b.destroyed||b.loadAvailable()},a)},raise:function(c,e){if(!d.string(c)||d.empty(c))return null;e=d.array(e)?e:[];var g=this,h=c.split(".")[0],i=f.camel("on-"+h),j=a.Event(h+".foogallery");return e.unshift(g),g.$el.trigger(j,e),b.debug.logf("{id}|{name}:",{id:g.id,name:h},e),d.fn(g[i])&&(e.unshift(j),g[i].apply(g.$el.get(0),e)),j},layout:function(){var a=this;null!==a._initialize&&a.raise("layout")},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},onWindowPopState:function(a){var b=a.data.self,c=a.originalEvent.state;d.empty(c)||c.id!==b.id||(b.state.set(c),b.loadAvailable())}}),b.template.register("core",b.Template,{id:null,type:"core",classes:"",on:{},lazy:!0,viewport:200,items:[],fixLayout:!0,scrollParent:null,delay:0,throttle:50,timeout:6e4,srcset:"data-srcset-fg",src:"data-src-fg",template:{}},{container:"foogallery"},{},-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b){a.Component=b.Class.extend({construct:function(a){this.tmpl=a},destroy:function(){this.tmpl=null}}),a.components=new b.Factory}(FooGallery,FooGallery.utils),function(a,b,c,d){b.State=b.Component.extend({construct:function(a){var b=this;b._super(a),b.apiEnabled=!!window.history&&!!history.replaceState,b.opt=b.tmpl.opt.state,b.enabled=b.opt.enabled,b.pushOrReplace=b.isPushOrReplace(b.opt.pushOrReplace)?b.opt.pushOrReplace:"replace";var c=d.escapeRegExp(b.tmpl.id),e=d.escapeRegExp(b.opt.values),f=d.escapeRegExp(b.opt.pair);b.regex={exists:new RegExp("^#"+c+"\\"+e+".+?"),values:new RegExp("(\\w+)"+f+"([^"+e+"]+)","g")}},destroy:function(){var a=this;a.clear(),a.opt=a.regex={},a._super()},isPushOrReplace:function(b){return-1!==a.inArray(b,["push","replace"])},exists:function(){return this.regex.exists.test(location.hash)&&this.regex.values.test(location.hash)},parse:function(){var b=this,d={};if(b.exists())if(b.enabled){d.id=b.tmpl.id;var e=location.hash.match(b.regex.values);a.each(e,function(e,f){var g=f.split(b.opt.pair);2===g.length&&(d[g[0]]=-1===g[1].indexOf(b.opt.array)?decodeURIComponent(g[1].replace(/\+/g,"%20")):a.map(g[1].split(b.opt.array),function(a){return decodeURIComponent(a.replace(/\+/g,"%20"))}),c.string(d[g[0]])&&!isNaN(d[g[0]])&&(d[g[0]]=parseInt(d[g[0]])))})
10
- }else b.apiEnabled?history.replaceState(null,"",location.pathname+location.search):location.hash="#";return d},hashify:function(b){var d=this;if(c.hash(b)){var e=[];return a.each(b,function(b,f){c.empty(f)||"id"===b||(f=c.array(f)?a.map(f,function(a){return encodeURIComponent(a)}).join(d.opt.array):encodeURIComponent(f),e.push(b+d.opt.pair+f))}),e.length>0&&e.unshift("#"+d.tmpl.id),e.join(d.opt.values)}return""},replace:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.replaceState(e?null:a,"",e?location.pathname+location.search:d)}},push:function(a){var b=this;if(b.enabled&&b.apiEnabled){a.id=b.tmpl.id;var d=b.hashify(a),e=c.empty(d);history.pushState(e?null:a,"",e?location.pathname+location.search:d)}},update:function(a,b){var c=this;c.enabled&&c.apiEnabled&&(b=c.isPushOrReplace(b)?b:c.pushOrReplace,c[b](a))},clear:function(){this.exists()&&this.replace({})},initial:function(){var a=this,b=a.tmpl,d={};return b.filter&&!c.empty(b.filter.current)&&(d.f=b.filter.current),b.pages&&b.pages.current>1&&(d.p=b.pages.current),d},get:function(a){var d=this,e=d.tmpl,f={};return a instanceof b.Item&&(f.i=a.id),e.filter&&!c.empty(e.filter.current)&&(f.f=e.filter.current),e.pages&&e.pages.isValid(e.pages.current)&&(f.p=e.pages.current),f},set:function(a){var b=this,d=b.tmpl;if(c.hash(a)){d.items.reset();var e=d.items.get(a.i);if(d.filter){d.filter.rebuild();var f=c.empty(a.f)?[]:a.f;d.filter.set(f,!1)}if(d.pages){d.pages.rebuild();var g=d.pages.number(a.p);e&&!d.pages.contains(g,e)&&(g=d.pages.find(e),g=0!==g?g:1),d.pages.set(g,!c.empty(a),!1,!0),e&&d.pages.contains(g,e)&&e.scrollTo()}else d.items.detach(d.items.all()),d.items.create(d.items.available(),!0),e&&e.scrollTo();c.empty(a.i)||(a.i=null,b.replace(a))}}}),b.template.configure("core",{state:{enabled:!1,pushOrReplace:"replace",values:"/",pair:":",array:"+"}}),b.components.register("state",b.State)}(FooGallery.$,FooGallery,FooGallery.utils.is,FooGallery.utils.str),function(a,b,c,d,e,f){b.Item=b.Component.extend({construct:function(a,b){var c=this;c._super(a),c.cls=a.cls.item,c.il8n=a.il8n.item,c.sel=a.sel.item,c.opt=f.extend({},a.opt.item,b),c.isAttached=!1,c.isCreated=!1,c.isDestroyed=!1,c.isLoading=!1,c.isLoaded=!1,c.isError=!1,c.isParsed=!1,c.$el=null,c.$inner=null,c.$anchor=null,c.$wrap=null,c.$image=null,c.$caption=null,c.fixLayout=c.tmpl.opt.fixLayout,c.type=c.opt.type,c.id=c.opt.id,c.href=c.opt.href,c.src=c.opt.src,c.srcset=c.opt.srcset,c.width=c.opt.width,c.height=c.opt.height,c.title=c.opt.title,c.alt=c.opt.alt,c.caption=d.empty(c.opt.caption)?c.title:c.opt.caption,c.description=d.empty(c.opt.description)?c.alt:c.opt.description,c.attr=c.opt.attr,c.tags=c.opt.tags,c.maxWidth=c.opt.maxWidth,c.maxCaptionLength=c.opt.maxCaptionLength,c.maxDescriptionLength=c.opt.maxDescriptionLength,c.showCaptionTitle=c.opt.showCaptionTitle,c.showCaptionDescription=c.opt.showCaptionDescription,c._thumbUrl=null,c._load=null,c._undo={classes:"",style:"",loader:!1,wrap:!1,placeholder:!1}},destroy:function(){var a=this;return a.tmpl.raise("destroy-item",[a]).isDefaultPrevented()||(a.isDestroyed=a.doDestroyItem()),a.isDestroyed&&(a.tmpl.raise("destroyed-item",[a]),a._super()),a.isDestroyed},doDestroyItem:function(){var a=this;return a.isParsed?(a.append(),d.empty(a._undo.classes)?a.$el.removeAttr("class"):a.$el.attr("class",a._undo.classes),d.empty(a._undo.style)?a.$el.removeAttr("style"):a.$el.attr("style",a._undo.style),a._undo.wrap&&a.$image.unwrap(),a._undo.loader&&a.$el.find(a.sel.loader).remove(),a._undo.placeholder&&a.$image.prop("src")==b.emptyImage&&a.$image.removeAttr("src")):a.isCreated&&(a.detach(),a.$el.remove()),!0},parse:function(b){var c=this,d=a(b);return!c.tmpl.raise("parse-item",[c,d]).isDefaultPrevented()&&(c.isCreated=d.is(c.sel.elem))&&(c.isParsed=c.doParseItem(d),c.fixLayout&&c.fix()),c.isParsed&&c.tmpl.raise("parsed-item",[c]),c.isParsed},doParseItem:function(c){var e=this,f=e.tmpl.opt,g=e.cls,h=e.sel;if(e._undo.classes=c.attr("class")||"",e._undo.style=c.attr("style")||"",e.$el=c.data(b.dataItem,e),e.$inner=e.$el.children(h.inner),e.$anchor=e.$inner.children(h.anchor).on("click.foogallery",{self:e},e.onAnchorClick),e.$image=e.$anchor.find(h.image),e.$caption=e.$inner.children(h.caption.elem).on("click.foogallery",{self:e},e.onCaptionClick),!(e.$el.length&&e.$inner.length&&e.$anchor.length&&e.$image.length))return console.error("FooGallery Error: Invalid HTML markup. Check the item markup for additional elements or malformed HTML in the title or description.",e),e.isError=!0,e.tmpl.raise("error-item",[e]),0!==e.$el.length&&e.$el.remove(),!1;e.isAttached=e.$el.parent().length>0,e.isLoading=e.$el.is(h.loading),e.isLoaded=e.$el.is(h.loaded),e.isError=e.$el.is(h.error);var i=e.$anchor.data();if(e.id=i.id||e.id,e.tags=i.tags||e.tags,e.href=i.href||e.$anchor.attr("href")||e.href,e.src=e.$image.attr(f.src)||e.src,e.srcset=e.$image.attr(f.srcset)||e.srcset,e.width=parseInt(e.$image.attr("width"))||e.width,e.height=parseInt(e.$image.attr("height"))||e.height,e.title=e.$image.attr("title")||e.title,e.alt=e.$image.attr("alt")||e.alt,e.caption=i.title||i.captionTitle||e.caption||e.title,e.description=i.description||i.captionDesc||e.description||e.alt,d.empty(e.caption)&&(e.caption=a.trim(e.$caption.find(h.caption.title).html())),d.empty(e.description)&&(e.description=a.trim(e.$caption.find(h.caption.description).html())),d.number(e.maxCaptionLength)&&e.maxCaptionLength>0&&!d.empty(e.caption)&&d.string(e.caption)&&e.caption.length>e.maxCaptionLength&&e.$caption.find(h.caption.title).html(e.caption.substr(0,e.maxCaptionLength)+"&hellip;"),d.number(e.maxDescriptionLength)&&e.maxDescriptionLength>0&&!d.empty(e.description)&&d.string(e.description)&&e.description.length>e.maxDescriptionLength&&e.$caption.find(h.caption.description).html(e.description.substr(0,e.maxDescriptionLength)+"&hellip;"),0===e.$anchor.children(h.wrap).length){var j=a("<span/>",{class:g.wrap});e.$anchor.append(j.append(e.$image)),e._undo.wrap=!0}0===e.$el.children(h.loader).length&&(e.$el.append(a("<div/>",{class:g.loader})),e._undo.loader=!0);var k=e.$image.get(0);return d.empty(k.src)&&(k.src=b.emptyImage,e._undo.placeholder=!0),!e.isCreated||!e.isAttached||e.isLoading||e.isLoaded||e.isError||e.$el.addClass(g.idle),!0},create:function(){var a=this;if(!a.isCreated&&d.string(a.href)&&d.string(a.src)&&d.number(a.width)&&d.number(a.height)){a.tmpl.raise("create-item",[a]).isDefaultPrevented()||(a.isCreated=a.doCreateItem()),a.isCreated&&a.tmpl.raise("created-item",[a])}return a.isCreated},doCreateItem:function(){var c=this,e=c.tmpl.opt,f=c.cls,g=c.attr;g.elem.class=f.elem+" "+f.idle,g.inner.class=f.inner,g.anchor.class=f.anchor,g.anchor.href=c.href,g.anchor["data-id"]=c.id,g.anchor["data-title"]=c.caption,g.anchor["data-description"]=c.description,d.empty(c.tags)||(g.anchor["data-tags"]=JSON.stringify(c.tags)),g.image.class=f.image,g.image.src=b.emptyImage,g.image[e.src]=c.src,g.image[e.srcset]=c.srcset,g.image.width=c.width,g.image.height=c.height,g.image.title=c.title,g.image.alt=c.alt,c.$el=a("<div/>").attr(g.elem).data(b.dataItem,c),c.$inner=a("<figure/>").attr(g.inner).appendTo(c.$el),c.$anchor=a("<a/>").attr(g.anchor).appendTo(c.$inner).on("click.foogallery",{self:c},c.onAnchorClick);var h=a("<span/>",{class:f.wrap}).appendTo(c.$anchor);c.$image=a("<img/>").attr(g.image).appendTo(h),f=c.cls.caption,g=c.attr.caption,g.elem.class=f.elem,c.$caption=a("<figcaption/>").attr(g.elem).on("click.foogallery",{self:c},c.onCaptionClick),g.inner.class=f.inner;var i=a("<div/>").attr(g.inner).appendTo(c.$caption),j=c.showCaptionTitle&&!d.empty(c.caption),k=c.showCaptionDescription&&!d.empty(c.description);if(j||k){if(g.title.class=f.title,g.description.class=f.description,j){var l=a("<div/>").attr(g.title),m=c.caption;d.number(c.maxCaptionLength)&&c.maxCaptionLength>0&&d.string(c.caption)&&c.caption.length>c.maxCaptionLength&&(m=c.caption.substr(0,c.maxCaptionLength)+"&hellip;"),l.get(0).innerHTML=m,i.append(l)}if(k){var n=a("<div/>").attr(g.description),o=c.description;d.number(c.maxDescriptionLength)&&c.maxDescriptionLength>0&&d.string(c.description)&&c.description.length>c.maxDescriptionLength&&(o=c.description.substr(0,c.maxDescriptionLength)+"&hellip;"),n.get(0).innerHTML=o,i.append(n)}}return c.$caption.appendTo(c.$inner),0===c.$el.find(c.sel.loader).length&&c.$el.append(a("<div/>",{class:c.cls.loader})),!0},append:function(){var a=this;if(a.isCreated&&!a.isAttached){a.tmpl.raise("append-item",[a]).isDefaultPrevented()||(a.tmpl.$el.append(a.$el),a.fixLayout&&a.fix(),a.isAttached=!0),a.isAttached&&a.tmpl.raise("appended-item",[a])}return a.isAttached},detach:function(){var a=this;if(a.isCreated&&a.isAttached){a.tmpl.raise("detach-item",[a]).isDefaultPrevented()||(a.$el.detach(),a.fixLayout&&a.unfix(),a.isAttached=!1),a.isAttached||a.tmpl.raise("detached-item",[a])}return!a.isAttached},load:function(){var b=this;if(d.promise(b._load))return b._load;if(!b.isCreated||!b.isAttached)return e.rejectWith("not created or attached");if(b.tmpl.raise("load-item",[b]).isDefaultPrevented())return e.rejectWith("default prevented");var c=b.cls,f=b.$image.get(0),g=f.src;return b.isLoading=!0,b.$el.removeClass(c.idle).removeClass(c.loaded).removeClass(c.error).addClass(c.loading),b._load=a.Deferred(function(a){f.onload=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isLoaded=!0,b.$el.removeClass(c.loading).addClass(c.loaded),b.fixLayout&&b.unfix(),b.tmpl.raise("loaded-item",[b]),a.resolve(b)},f.onerror=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isError=!0,b.$el.removeClass(c.loading).addClass(c.error),d.string(g)&&b.$image.prop("src",g),b.tmpl.raise("error-item",[b]),a.reject(b)},f.src=b.getThumbUrl(),f.complete&&f.onload()}).promise()},fix:function(){var a=this;if(null==a.tmpl)return a;if(a.isCreated&&!a.isLoading&&!a.isLoaded&&!a.isError){var b=a.width,c=a.height,e=a.$image.get(0);if(!isNaN(b)&&!isNaN(c)&&e){var f=d.fn(a.maxWidth)?a.maxWidth(a):a.$image.width();f<=0&&(f=b);var g=f/b,h=c*g;a.$image.css({width:f,height:h})}}return a},unfix:function(){var a=this;return null==a.tmpl?a:(a.isCreated&&a.$image.css({width:"",height:""}),a)},getThumbUrl:function(a){a=!!d.boolean(a)&&a;var b=this;return!a&&d.string(b._thumbUrl)?b._thumbUrl:b._thumbUrl=c.src(b.src,b.srcset,b.width,b.height,b.$anchor.innerWidth(),b.$anchor.innerHeight())},scrollTo:function(a){var b=this;if(b.isAttached){var d=b.bounds(),e=c.getViewportBounds();switch(a){case"top":d.left+=d.width/2-e.width/2,d.top-=e.height/5;break;default:d.left+=d.width/2-e.width/2,d.top+=d.height/2-e.height/2}window.scrollTo(d.left,d.top)}return b},bounds:function(){return this.isAttached?c.getElementBounds(this.$el):null},intersects:function(a){return!!this.isAttached&&this.bounds().intersects(a)},onAnchorClick:function(a){var b=a.data.self,c=b.tmpl.state.get(b);b.tmpl.state.update(c)},onCaptionClick:function(a){var b=a.data.self;b.$anchor.length>0&&b.$anchor.get(0).click()}}),b.template.configure("core",{item:{type:"item",id:"",href:"",src:"",srcset:"",width:0,height:0,title:"",alt:"",caption:"",description:"",tags:[],maxWidth:null,maxCaptionLength:0,maxDescriptionLength:0,showCaptionTitle:!0,showCaptionDescription:!0,attr:{elem:{},inner:{},anchor:{},image:{},caption:{elem:{},inner:{},title:{},description:{}}}}},{item:{elem:"fg-item",inner:"fg-item-inner",anchor:"fg-thumb",wrap:"fg-image-wrap",image:"fg-image",loader:"fg-loader",idle:"fg-idle",loading:"fg-loading",loaded:"fg-loaded",error:"fg-error",caption:{elem:"fg-caption",inner:"fg-caption-inner",title:"fg-caption-title",description:"fg-caption-desc"}}},{item:{}}),b.components.register("item",b.Item)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){b.Items=b.Component.extend({construct:function(a){var b=this;b._super(a),b.idMap={},b._fetched=null,b._arr=[],b._available=[],b._canvas=document.createElement("canvas");var d=b.tmpl.cls.item.caption;b.tmpl.sel.item.caption.all=c.selectify([d.elem,d.inner,d.title,d.description])},destroy:function(){var b=this,c=b.all(),d=[];c.length>0&&(b.tmpl.raise("destroy-items",[c]),d=a.map(c,function(a){return a.destroy()?a:null}),d.length>0&&b.tmpl.raise("destroyed-items",[d])),b.idMap={},b._canvas=b._fetched=null,b._arr=[],b._available=[],b._super()},fetch:function(b){var c=this;if(!b&&d.promise(c._fetched))return c._fetched;var e=c.tmpl,f=e.sel,g=e.opt.items,h=a.Deferred(),i=c.make(e.$el.find(f.item.elem));return d.empty(g)?(i.push.apply(i,c.make(window[e.id+"-items"])),h.resolve(i)):d.array(g)?(i.push.apply(i,c.make(g)),h.resolve(i)):d.string(g)?a.get(g).then(function(a){i.push.apply(i,c.make(a)),h.resolve(i)},function(a,b,c){console.log("FooGallery: GET items error.",g,a,b,c),h.resolve(i)}):h.resolve(i),h.then(function(a){c.setAll(a)}),c._fetched=h.promise()},all:function(){return this._arr.slice()},count:function(a){return a?this.all().length:this.available().length},available:function(){return this._available.slice()},get:function(a){return!d.empty(a)&&this.idMap[a]?this.idMap[a]:null},setAll:function(a){this._arr=d.array(a)?a:[],this.idMap=this.createIdMap(a),this._available=this.all()},setAvailable:function(a){this._available=d.array(a)?a:[]},reset:function(){this.setAvailable(this.all())},loadable:function(b){var e,f=this,g=f.tmpl.opt;return g.lazy&&(e=c.getViewportBounds(g.viewport)),d.array(b)?a.map(b,function(a){return a.isCreated&&a.isAttached&&!a.isLoading&&!a.isLoaded&&!a.isError&&(!g.lazy||g.lazy&&a.intersects(e))?a:null}):[]},creatable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&!a.isCreated?a:null}):[]},appendable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&!a.isAttached?a:null}):[]},detachable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&a.isAttached?a:null}):[]},jquerify:function(b){return a(a.map(b,function(a){return a.$el.get()}))},make:function(c){var e=this,g=[];if(d.jq(c)||d.array(c)){var h=[],i=a.makeArray(c);if(0===i.length)return g;e.tmpl.raise("make-items",[i]).isDefaultPrevented()||(g=a.map(i,function(a){var c=e.type(a),g=f.extend(d.hash(a)?a:{},{type:c}),i=b.components.make(c,e.tmpl,g);return d.element(a)?i.parse(a)?(h.push(i),i):null:i})),g.length>0&&e.tmpl.raise("made-items",[g]),h.length>0&&e.tmpl.raise("parsed-items",[h])}return g},type:function(c){var e;if(d.hash(c))e=c.type;else if(d.element(c)){var f=a(c),g=this.tmpl.sel.item;e=f.find(g.anchor).data("type")}return d.string(e)&&b.components.contains(e)?e:"item"},create:function(b,c){var e=this,f=[],g=e.creatable(b);if(g.length>0){e.tmpl.raise("create-items",[g]).isDefaultPrevented()||(f=a.map(g,function(a){return a.create()?a:null})),f.length>0&&e.tmpl.raise("created-items",[f])}return d.boolean(c)&&c?e.append(b):f},append:function(b){var c=this,d=[],e=c.appendable(b);if(e.length>0){c.tmpl.raise("append-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.append()?a:null})),d.length>0&&c.tmpl.raise("appended-items",[d])}return d},detach:function(b){var c=this,d=[],e=c.detachable(b);if(e.length>0){c.tmpl.raise("detach-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.detach()?a:null})),d.length>0&&c.tmpl.raise("detached-items",[d])}return d},load:function(b){var c=this;if(b=c.loadable(b),b.length>0){if(!c.tmpl.raise("load-items",[b]).isDefaultPrevented()){var d=a.map(b,function(a){return a.load()});return e.when(d).done(function(a){c.tmpl.raise("loaded-items",[a])})}}return e.resolveWith([])},createIdMap:function(b){var c={};return a.each(b,function(a,b){d.empty(b.id)&&(b.id=""+(a+1)),c[b.id]=b}),c}}),b.components.register("items",b.Items)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d){b.Paging=b.Component.extend({construct:function(a){var b=this;b._super(a),b.opt=b.tmpl.opt.paging,b.cls=b.tmpl.cls.paging,b.il8n=b.tmpl.il8n.paging,b.sel=b.tmpl.sel.paging,b.pushOrReplace=b.opt.pushOrReplace,b.type=b.opt.type,b.theme=b.opt.theme,b.size=b.opt.size,b.position=b.opt.position,b.scrollToTop=b.opt.scrollToTop,b.current=0,b.total=0,b.ctrls=[],b._arr=[]},destroy:function(){var b=this;b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b._super()},build:function(){var a=this,c=a.tmpl.items.available();a.total=a.size>0&&c.length>0?Math.ceil(c.length/a.size):1;for(var d=0;d<a.total;d++)a._arr.push(c.splice(0,a.size));if(a.total>1&&b.paging.hasCtrl(a.type)){var e,f,g=a.position;"both"!==g&&"top"!==g||(e=b.paging.makeCtrl(a.type,a.tmpl,a,"top"),e.create()&&(e.append(),a.ctrls.push(e))),"both"!==g&&"bottom"!==g||(f=b.paging.makeCtrl(a.type,a.tmpl,a,"bottom"),f.create()&&(f.append(),a.ctrls.push(f)))}},rebuild:function(){var b=this;b.current=0,b.total=0,b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b.build()},all:function(){return this._arr.slice()},available:function(){return this.get(this.current)},items:function(){return this.get(this.current)},controls:function(b){var c=this;c.isValid(b)&&a.each(c.ctrls,function(a,c){c.update(b)})},isValid:function(a){return d.number(a)&&a>0&&a<=this.total},number:function(a){return this.isValid(a)?a:0===this.current?1:this.current},create:function(a,b){var c=this;a=c.number(a);var d=a-1;c.tmpl.items.detach(c.tmpl.items.all()),c.current=a,c.tmpl.items.create(c._arr[d],!0)},get:function(a){var b=this;return b.isValid(a)?(a=b.number(a),b._arr[a-1]):[]},set:function(a,b,c,e){var f=this;if(f.isValid(a)){var g,h=f.number(a);if(h!==f.current){var i=f.current,j=function(){if(c=!d.boolean(c)||c,e=!!d.boolean(e)&&e,c&&1===f.current&&!f.tmpl.state.exists()&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.controls(a),f.create(h,e),c&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.scrollToTop&&d.boolean(b)&&b){var j=f.get(f.current);j.length>0&&j[0].scrollTo("top")}f.tmpl.raise("after-page-change",[f.current,i,e])};return!f.tmpl.raise("before-page-change",[f.current,h,j,e]).isDefaultPrevented()&&(j(),!0)}}return!1},find:function(b){for(var c=this,d=0,e=c._arr.length;d<e;d++)if(-1!==a.inArray(b,c._arr[d]))return d+1;return 0},contains:function(b,c){var d=this.get(b);return-1!==a.inArray(c,d)},first:function(){this.goto(1)},last:function(){this.goto(this._arr.length)},prev:function(){this.goto(this.current-1)},next:function(){this.goto(this.current+1)},goto:function(a){var b=this;b.set(a,!0)&&b.tmpl.loadAvailable()}}),b.PagingControl=b.Component.extend({construct:function(a,b,c){var d=this;d._super(a),d.pages=b,d.position=c,d.$container=null},create:function(){var b=this;return b.$container=a("<nav/>",{class:b.pages.cls.container}).addClass(b.pages.theme),!0},destroy:function(){var a=this;a.$container.remove(),a.$container=null},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},update:function(a){}}),b.paging.register("default",b.Paging,null,{type:"none",theme:"fg-light",size:30,pushOrReplace:"push",position:"none",scrollToTop:!0},{container:"fg-paging-container"},null,-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Dots=b.Paging.extend({}),b.DotsControl=b.PagingControl.extend({construct:function(b,c,d){this._super(b,c,d),this.$container=a(),this.$list=a(),this.$items=a()},create:function(){for(var b,c=this,d=c.pages.cls,e=c.pages.il8n,f=[],g=a("<ul/>",{class:d.list}),h=0,i=c.pages.total;h<i;h++)f.push(b=c.createItem(h+1,e.page)),g.append(b);return c.$list=g,c.$container=a("<nav/>",{class:d.container}).addClass(c.pages.theme).append(g),c.$items=a(a.map(f,function(a){return a.get()})),!0},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},destroy:function(){var b=this,c=b.pages.sel;b.$list.find(c.link).off("click.foogallery",b.onLinkClick),b.$container.remove(),b.$container=a(),b.$list=a(),b.$items=a()},update:function(a){this.setSelected(a-1)},setSelected:function(b){var c=this,e=c.pages.cls,f=c.pages.il8n,g=c.pages.sel;c.$items.filter(g.selected).removeClass(e.selected).each(function(b,c){var e=a(c),f=e.data("label"),h=e.find(g.reader);d.string(f)&&0!==h.length&&h.html(f)}),c.$items.eq(b).addClass(e.selected).each(function(b,c){var e=a(c),h=e.find(g.reader),i=h.html();d.string(i)&&0!==h.length&&(e.data("label",i),h.html(f.current))})},createItem:function(b,c,e,f,g){e=d.string(e)?e:b,c=d.string(c)?c:"";var h=this,i=h.pages.opt,j=h.pages.cls,k=a("<a/>",{class:j.link,href:"#page-"+b}).html(e).on("click.foogallery",{self:h,page:b},h.onLinkClick);d.empty(c)||k.attr("title",c.replace(/\{PAGE}/g,b).replace(/\{LIMIT}/g,i.limit+"")),g=d.string(g)?g:c,d.empty(g)||k.prepend(a("<span/>",{class:j.reader,text:g.replace(/\{PAGE}/g,"").replace(/\{LIMIT}/g,i.limit+"")}));var l=a("<li/>",{class:j.item}).append(k);return f=d.string(f)?f:"",d.empty(f)||l.addClass(f),l},onLinkClick:function(b){b.preventDefault();var c=b.data.self,d=b.data.page,e=c.pages.sel;a(this).closest(e.item).is(e.disabled)||(c.pages.set(d,!0),c.tmpl.loadAvailable())}}),b.paging.register("dots",b.Dots,b.DotsControl,{type:"dots",position:"both",pushOrReplace:"push"},{list:"fg-dots",item:"fg-dot-item",link:"fg-dot-link",disabled:"fg-disabled",selected:"fg-selected",visible:"fg-visible",reader:"fg-sr-only"},{current:"Current page",page:"Page {PAGE}"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.DefaultTemplate=b.Template.extend({}),b.template.register("default",b.DefaultTemplate,null,{container:"foogallery fg-default"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.MasonryTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.masonry=null,this.style=null,this.$columnWidth=null},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},onPreInit:function(b,c){var e=c.sel,f=c.cls;f.layouts=a.map(f.layout,function(a){return a}).join(" ");for(var g=a.map(f.layout,function(a,b){return{key:b,value:a}}),h=0,i=g.length;h<i;h++)if(c.$el.hasClass(g[h].value)){c.template.layout=g[h].key;break}d.string(f.layout[c.template.layout])||(c.template.layout="col4");var j,k,l="fixed"===c.template.layout;if(c.template.isFitWidth=l,c.template.percentPosition=!l,c.template.transitionDuration=0,c.template.itemSelector=e.item.elem,c.$el.removeClass(f.layouts).addClass(f.layout[c.template.layout]),l||(0===c.$el.find(e.gutterWidth).length&&c.$el.prepend(a("<div/>").addClass(f.gutterWidth)),c.template.gutter=e.gutterWidth),0===c.$el.find(e.columnWidth).length&&c.$el.prepend(a("<div/>").addClass(f.columnWidth)),l&&d.number(c.template.columnWidth)){var m=c.$el.find(e.columnWidth).width(c.template.columnWidth);j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { width: "+m.outerWidth()+"px; }",j.insertRule(k,0)}c.template.columnWidth=e.columnWidth,l&&d.number(c.template.gutter)&&(j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { margin-bottom: "+c.template.gutter+"px; }",j.insertRule(k,0)),c.masonry=new Masonry(c.$el.get(0),c.template)},onPostInit:function(a,b){b.masonry.layout()},onFirstLoad:function(a,b){b.masonry.layout()},onReady:function(a,b){b.masonry.layout()},onDestroy:function(a,b){b.$el.find(b.sel.columnWidth).remove(),b.$el.find(b.sel.gutterWidth).remove(),b.style&&b.style.parentNode&&b.style.parentNode.removeChild(b.style)},onDestroyed:function(a,b){b.masonry instanceof Masonry&&b.masonry.destroy()},onLayout:function(a,b){b.masonry.layout()},onParsedItems:function(a,b,c){b.masonry.layout()},onAppendedItems:function(a,b,c){c=b.items.jquerify(c),c=b.masonry.addItems(c),b.masonry.layoutItems(c,!0)},onDetachItem:function(a,b,c){a.isDefaultPrevented()||(a.preventDefault(),b.masonry.remove(c.$el),c.isAttached=!1,c.unfix())},onDetachedItems:function(a,b,c){b.masonry.layout()},onLoadedItems:function(a,b,c){b.masonry.layout()}}),b.template.register("masonry",b.MasonryTemplate,{template:{initLayout:!1,isInitLayout:!1,layout:"col4"}},{container:"foogallery fg-masonry",columnWidth:"fg-column-width",gutterWidth:"fg-gutter-width",layout:{fixed:"fg-masonry-fixed",col2:"fg-masonry-2col",col3:"fg-masonry-3col",col4:"fg-masonry-4col",col5:"fg-masonry-5col"}})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Justified=c.Class.extend({construct:function(c,d){this.tmpl=c,this.$el=c.$el,this.options=a.extend(!0,{},b.Justified.defaults,d),this._items=[],this._lastRefresh=0,this._refresh=null},init:function(){var b=this;d.string(b.options.maxRowHeight)&&(b.options.maxRowHeight.indexOf("%")?b.options.maxRowHeight=b.options.rowHeight*(parseInt(b.options.maxRowHeight)/100):b.options.maxRowHeight=parseInt(b.options.maxRowHeight)),a(window).on("resize.justified",{self:b},b.onWindowResize),this._refresh=setInterval(function(){b.refresh()},b.options.refreshInterval)},destroy:function(){this._refresh&&clearInterval(this._refresh),a(window).off("resize.justified"),this.$el.removeAttr("style")},refresh:function(){var a=this.getContainerWidth();a!=this._lastRefresh&&(this.layout(),this._lastRefresh=a)},parse:function(){var b=this;return b._items=a.map(b.tmpl.getItems(),function(a,b){return{index:b,width:a.width,height:a.height,top:0,left:0,$item:a.$el}})},getMaxRowHeight:function(){var a=this;return d.string(a.options.maxRowHeight)&&(a.options.maxRowHeight.indexOf("%")?a.options.maxRowHeight=a.options.rowHeight*(parseInt(a.options.maxRowHeight)/100):a.options.maxRowHeight=parseInt(a.options.maxRowHeight)),d.number(a.options.maxRowHeight)?a.options.maxRowHeight:a.options.rowHeight},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(b,c){b=!!d.boolean(b)&&b,c=!d.boolean(c)||c,(b||0===this._items.length)&&this.parse();var e=this,f=0,g=e.getContainerWidth(),h=e.getMaxRowHeight(),i=e.rows(g,h);a.each(i,function(a,b){b.visible&&(a>0&&(f+=e.options.margins),f+=b.height),e.render(b)}),e.$el.height(f),c&&e.getContainerWidth()<g&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:b.height,top:b.top,left:b.left,display:"",maxHeight:this.options.maxRowHeight>0?this.options.maxRowHeight:""}).addClass("fg-positioned"):b.$item.css("display","none")},justify:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=g/a.width;a.width=a.width*h,a.height=a.height*h,a.top=b,a.height>d&&(a.height=d),a.left=0,a.width<g&&(a.left=(g-a.width)/2),a.width+=f;for(var i,j=a.left,k=0,l=a.items.length;k<l;k++)k>0&&(j+=e.options.margins),i=a.items[k],i.left=j,i.top=b,i.width=i.width*h,i.height=i.height*h,i.height>d&&(i.height=d),j+=i.width;return a.height},position:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f;if(a.top=b,a.left=0,a.width<g)switch(d){case"center":a.left=(g-a.width)/2;break;case"right":a.left=g-a.width}a.width+=f;for(var h,i=a.left,j=0,k=a.items.length;j<k;j++)j>0&&(i+=e.options.margins),h=a.items[j],h.left=i,h.top=b,i+=h.width;return a.height},lastRow:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=a.width/g>e.options.justifyThreshold;switch(e.options.lastRow){case"hide":h?e.justify(a,b,c,d):a.visible=!1;break;case"justify":e.justify(a,b,c,d);break;case"nojustify":h?e.justify(a,b,c,d):e.position(a,b,c,"left");break;case"left":case"center":case"right":h?e.justify(a,b,c,d):e.position(a,b,c,e.options.lastRow)}},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,top:a.top,left:a.left}})},rows:function(a,b){function c(){var a={index:++h,visible:!0,width:0,height:e.options.rowHeight,top:0,left:0,items:[]};return g.push(a),a}for(var d,e=this,f=e.items(),g=[],h=-1,i=c(),j=0,k=0,l=0,m=f.length;l<m;l++){if(d=f[l],d.height!=e.options.rowHeight){var n=e.options.rowHeight/d.height;d.height=d.height*n,d.width=d.width*n}k+d.width>a&&l>0&&(g.length>1&&(j+=e.options.margins),j+=e.justify(i,j,a,b),i=c(),k=0),i.items.length>0&&(k+=e.options.margins),k+=d.width,i.width+=d.width,i.items.push(d)}return g.length>1&&(j+=e.options.margins),e.lastRow(i,j,a,b),g},onWindowResize:function(a){a.data.self.layout(!0)}}),b.Justified.defaults={itemSelector:".fg-item",rowHeight:150,maxRowHeight:"200%",margins:0,lastRow:"center",justifyThreshold:.5,refreshInterval:250}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.JustifiedTemplate=b.Template.extend({onPreInit:function(a,c){c.justified=new b.Justified(c,c.template)},onInit:function(a,b){b.justified.init()},onFirstLoad:function(a,b){b.justified.layout(!0)},onReady:function(a,b){b.justified.layout(!0)},onDestroy:function(a,b){b.justified.destroy()},onLayout:function(a,b){b.justified.layout(!0)},onAfterPageChange:function(a,b,c,d,e){e||b.justified.layout(!0)},onAfterFilterChange:function(a,b){b.justified.layout(!0)}}),b.template.register("justified",b.JustifiedTemplate,null,{container:"foogallery fg-justified"})}(FooGallery.$,FooGallery,FooGallery.utils.is),function(a,b,c,d,e){b.PortfolioTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.style=null,this.fullWidth=!1},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},onPreInit:function(a,b){b.appendCSS()},onPostInit:function(b,c){c.checkCSS(),a(window).on("resize"+c.namespace,{self:c},e.debounce(function(){c.checkCSS()},50))},onDestroy:function(b,c){c.removeCSS(),a(window).off("resize"+c.namespace)},checkCSS:function(){var a=this,b=a.getContainerWidth();b<a.template.columnWidth!==a.fullWidth&&a.appendCSS(b)},appendCSS:function(a){var b=this;a=d.number(a)?a:b.getContainerWidth(),b.removeCSS();var c,e=b.getStylesheet(),f="#"+b.id+b.sel.container,g=f+" "+b.sel.item.elem,h=b.template.columnWidth,i=Math.ceil(b.template.gutter/2);switch(b.template.align){case"center":c=f+" { justify-content: center; }",e.insertRule(c,0);break;case"left":c=f+" { justify-content: flex-start; }",e.insertRule(c,0);break;case"right":c=f+" { justify-content: flex-end; }",e.insertRule(c,0)}b.fullWidth=a<h,b.fullWidth?(c=g+" { max-width: 100%; margin: "+i+"px; }",e.insertRule(c,0)):(c=g+" { max-width: "+h+"px; min-width: "+h+"px; margin: "+i+"px; }",e.insertRule(c,0))},removeCSS:function(){var a=this;a.style&&a.style.parentNode&&(a.style.parentNode.removeChild(a.style),a.style=null,a.fullWidth=!1)}}),b.template.register("simple_portfolio",b.PortfolioTemplate,{template:{gutter:40,align:"center",columnWidth:250}},{container:"foogallery fg-simple_portfolio"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d){b.ImageViewerTemplate=b.Template.extend({construct:function(b,c){this._super(d.extend({},b,{paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),c),this.$inner=a(),this.$current=a(),this.$total=a(),this.$prev=a(),this.$next=a()},createChildren:function(){var b=this;return a("<div/>",{class:b.cls.inner}).append(a("<div/>",{class:b.cls.innerContainer}),a("<div/>",{class:b.cls.controls}).append(a("<div/>",{class:b.cls.prev}).append(a("<span/>",{text:b.il8n.prev})),a("<label/>",{class:b.cls.count,text:b.il8n.count}).prepend(a("<span/>",{class:b.cls.countCurrent,text:"0"})).append(a("<span/>",{class:b.cls.countTotal,text:"0"})),a("<div/>",{class:b.cls.next}).append(a("<span/>",{text:b.il8n.next}))))},destroyChildren:function(){var a=this;a.$el.find(a.sel.inner).remove()},onPreInit:function(a,b){b.$inner=b.$el.find(b.sel.innerContainer),b.$current=b.$el.find(b.sel.countCurrent),
11
- b.$total=b.$el.find(b.sel.countTotal),b.$prev=b.$el.find(b.sel.prev),b.$next=b.$el.find(b.sel.next)},onInit:function(a,b){b.template.attachFooBox&&b.$el.on("foobox.previous",{self:b},b.onFooBoxPrev).on("foobox.next",{self:b},b.onFooBoxNext),b.$prev.on("click",{self:b},b.onPrevClick),b.$next.on("click",{self:b},b.onNextClick)},onFirstLoad:function(a,b){b.update()},onDestroy:function(a,b){b.template.attachFooBox&&b.$el.off({"foobox.previous":b.onFooBoxPrev,"foobox.next":b.onFooBoxNext}),b.$prev.off("click",b.onPrevClick),b.$next.off("click",b.onNextClick)},onAppendItem:function(a,b,c){a.preventDefault(),b.$inner.append(c.$el),c.fix(),c.isAttached=!0},onAfterPageChange:function(a,b,c,d,e){e||b.update()},onAfterFilterChange:function(a,b){b.update()},update:function(){this.pages&&(this.$current.text(this.pages.current),this.$total.text(this.pages.total))},prev:function(){this.pages&&(this.template.loop&&1===this.pages.current?this.pages.last():this.pages.prev(),this.update())},next:function(){this.pages&&(this.template.loop&&this.pages.current===this.pages.total?this.pages.first():this.pages.next(),this.update())},onFooBoxPrev:function(a){a.data.self.prev()},onFooBoxNext:function(a){a.data.self.next()},onPrevClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.prev()},onNextClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.next()}}),b.template.register("image-viewer",b.ImageViewerTemplate,{template:{attachFooBox:!1,loop:!1}},{container:"foogallery fg-image-viewer",inner:"fiv-inner",innerContainer:"fiv-inner-container",controls:"fiv-ctrls",prev:"fiv-prev",next:"fiv-next",count:"fiv-count",countCurrent:"fiv-count-current",countTotal:"fiv-count-total"},{prev:"Prev",next:"Next",count:"of"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj),function(a,b,c){b.ThumbnailTemplate=b.Template.extend({construct:function(a,b){this._super(c.extend({},a,{filtering:{type:"none"},paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),b)}}),b.template.register("thumbnail",b.ThumbnailTemplate,null,{container:"foogallery fg-thumbnail"})}(FooGallery.$,FooGallery,FooGallery.utils.obj),function(a,b,c,d){b.triggerPostLoad=function(b,c,d,e,f){if("first-load"===b.type||c.initialized&&("after-page-change"===b.type&&!f||"after-filter-change"===b.type))try{if(c.$el.parents(".fbx-item").length>0)return;c.$el.hasClass("fbx-instance")&&window.FOOBOX&&a.fn.foobox?c.$el.foobox(window.FOOBOX.o):a("body").trigger("post-load")}catch(a){console.error(a)}},b.autoDefaults={on:{"first-load.foogallery after-page-change.foogallery after-filter-change.foogallery":b.triggerPostLoad}},b.auto=function(a){b.autoDefaults=d.merge(b.autoDefaults,a)},b.load=b.reload=function(){a(function(){a('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(b.autoDefaults)}),c.ready(function(){a('[id^="foogallery-gallery-"].fg-ready').foogallery(b.autoDefaults)})},b.load()}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj);
1
  /*
2
  * FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
3
+ * @version 1.4.1
4
  * @link
5
  * @copyright Steven Usher & Brad Vincent 2015
6
  * @license Released under the GPLv3 license.
7
  */
8
 
9
+ !function(a,b){b.$=a}(jQuery,window.FooGallery=window.FooGallery||{}),function(a){if(!a)return void console.warn("jQuery must be included in the page prior to the FooGallery.utils library.");var b={$:a,version:"0.1.7"};b.versionCompare=function(a,b){function c(a){for(var b=a.split("."),c=[],d=0,e=b.length;d<e;d++)c[d]=parseInt(b[d]),isNaN(c[d])&&(c[d]=0);return c}if(!/[\d.]/.test(a)||!/[\d.]/.test(b))return NaN;for(var d=c(a),e=c(b);d.length<e.length;)d.push(0);for(;e.length<d.length;)e.push(0);for(var f=0;f<d.length;++f){if(e.length===f)return 1;if(d[f]!==e[f])return d[f]>e[f]?1:-1}return d.length!==e.length?-1:0},!function(){try{return!!window.FooGallery.utils}catch(a){return!1}}()?window.FooGallery.utils=b:b.versionCompare(b.version,window.FooGallery.utils.version)>0?(console.warn("An older version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will override it."),window.FooGallery.utils=b):console.warn("A newer version of FooGallery.utils ("+window.FooGallery.utils.version+") already exists in the page, version "+b.version+" will not register itself.")}(jQuery),function(a,b){"0.1.7"===b.version&&(b.is={},b.is.array=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b.is.boolean=function(a){return"[object Boolean]"===Object.prototype.toString.call(a)},b.is.element=function(a){return"object"==typeof HTMLElement?a instanceof HTMLElement:!!a&&"object"==typeof a&&1===a.nodeType&&"string"==typeof a.nodeName},b.is.empty=function(a){if(b.is.undef(a)||null===a)return!0;if(b.is.number(a)&&0===a)return!0;if(b.is.boolean(a)&&!1===a)return!0;if(b.is.string(a)&&0===a.length)return!0;if(b.is.array(a)&&0===a.length)return!0;if(b.is.jq(a)&&0===a.length)return!0;if(b.is.hash(a)){for(var c in a)if(a.hasOwnProperty(c))return!1;return!0}return!1},b.is.error=function(a){return"[object Error]"===Object.prototype.toString.call(a)},b.is.fn=function(a){return a===window.alert||"[object Function]"===Object.prototype.toString.call(a)},b.is.hash=function(a){return b.is.object(a)&&a.constructor===Object&&!a.nodeType&&!a.setInterval},b.is.jq=function(c){return!b.is.undef(a)&&c instanceof a},b.is.number=function(a){return"[object Number]"===Object.prototype.toString.call(a)&&!isNaN(a)},b.is.object=function(a){return"[object Object]"===Object.prototype.toString.call(a)&&!b.is.undef(a)&&null!==a},b.is.promise=function(a){return b.is.object(a)&&b.is.fn(a.then)&&b.is.fn(a.promise)},b.is.size=function(a){return!!(b.is.string(a)&&!b.is.empty(a)||b.is.number(a))&&/^(auto|none|(?:[\d.]*)+?(?:%|px|mm|q|cm|in|pt|pc|em|ex|ch|rem|vh|vw|vmin|vmax)?)$/.test(a)},b.is.string=function(a){return"[object String]"===Object.prototype.toString.call(a)},b.is.undef=function(a){return void 0===a})}(FooGallery.utils.$,FooGallery.utils),function(a,b,c){if("0.1.7"===b.version){b.fn={};var d=Function.prototype.toString;b.fn.CONTAINS_SUPER=/xyz/.test(d.call(function(){xyz}))?/\b_super\b/:/.*/,b.fn.addOrOverride=function(a,e,f){if(c.object(a)&&c.string(e)&&!c.empty(e)&&c.fn(f)){var g=a[e],h=c.fn(g)&&b.fn.CONTAINS_SUPER.test(d.call(f));a[e]=h?function(a,b){return function(){var c=this._super;this._super=a;var d=b.apply(this,arguments);return this._super=c,d}}(g,f):f}},b.fn.apply=function(a,b){function d(){return a.apply(this,b)}return b=c.array(b)?b:[],d.prototype=a.prototype,new d},b.fn.arg2arr=function(a){return Array.prototype.slice.call(a)},b.fn.debounce=function(a,c){var d;return function(){var e=this,f=b.fn.arg2arr(arguments);clearTimeout(d),d=setTimeout(function(){a.apply(e,f)},c)}},b.fn.throttle=function(a,c){var d,e;return function(){var f=this,g=b.fn.arg2arr(arguments);d?(clearTimeout(e),e=setTimeout(function(){Date.now()-d>=c&&(a.apply(f,g),d=Date.now())},c-(Date.now()-d))):(a.apply(f,g),d=Date.now())}},b.fn.check=function(d,e,f,g){function h(a){return function(){return a.apply(d,arguments)}}return f=c.fn(f)?f:a.noop,d=c.object(d)?d:window,e=c.string(e)?b.fn.fetch(e,g):e,h(c.fn(e)?e:f)},b.fn.fetch=function(b,d){return!c.string(b)||c.empty(b)?null:(d=c.object(d)?d:window,a.each(b.split("."),function(a,b){if(!d[b])return!1;d=d[b]}),c.fn(d)?d:null)},b.fn.enqueue=function(d,e,f,g){function h(a,b){try{return n.push(a),b.apply(a,i)}catch(a){return j.reject(a,n),j}}var i=b.fn.arg2arr(arguments),j=a.Deferred(),k=a.Deferred(),l=k.promise(),m=[],n=[],o=!0;return d=i.shift(),e=i.shift(),a.each(d,function(a,d){c.fn(d[e])&&(l=l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}return o=!1,h(d,d[e])}))}),l.then(function(){if(!o){var a=b.fn.arg2arr(arguments);m.push(a)}o=!1,j.resolve(m)}),l.fail(function(){var a=b.fn.arg2arr(arguments);a.push(n),j.reject.apply(j,a)}),k.resolve(),j.promise()},b.fn.when=function(b){if(!c.array(b)||c.empty(b))return a.when();for(var d=a.Deferred(),e=[],f=b.length,g=0;g<b.length;g++)b[g].then(function(a){e.push(a)}).always(function(){--f||d.resolve(e)});return d.promise()},b.fn.rejectWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.reject.apply(e,f).promise()},b.fn.resolveWith=function(c,d){var e=a.Deferred(),f=b.fn.arg2arr(arguments);return e.resolve.apply(e,f).promise()},b.fn.resolved=a.Deferred().resolve().promise(),b.fn.rejected=a.Deferred().reject().promise()}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b){if("0.1.7"===a.version){a.url={};var c=document.createElement("a");a.url.parts=function(a){c.href=a;var b=c.port?c.port:-1!==["http:","https:"].indexOf(c.protocol)?"https:"===c.protocol?"443":"80":"",d=c.hostname+(b?":"+b:""),e=c.origin?c.origin:c.protocol+"//"+d,f="/"===c.pathname.slice(0,1)?c.pathname:"/"+c.pathname;return{hash:c.hash,host:d,hostname:c.hostname,href:c.href,origin:e,pathname:f,port:b,protocol:c.protocol,search:c.search}},a.url.full=function(a){return!b.string(a)||b.empty(a)?null:(c.href=a,c.href)},a.url.param=function(a,c,d){if(!b.string(a)||!b.string(c)||b.empty(c))return a;var e,f,g,h;return b.undef(d)?(e=new RegExp("[?|&]"+c+"=([^&;]+?)(&|#|;|$)"),f=e.exec(a)||["",""],g=f[1].replace(/\+/g,"%20"),b.string(g)&&!b.empty(g)?decodeURIComponent(g):null):(b.empty(d)?(e=new RegExp("^([^#]*?)(([^#]*)&)?"+c+"(=[^&#]*)?(&|#|$)"),g=a.replace(e,"$1$3$5").replace(/^([^#]*)((\?)&|\?(#|$))/,"$1$3$4")):(e=new RegExp("([?&])"+c+"[^&]*"),h=c+"="+encodeURIComponent(d),(g=a.replace(e,"$1"+h))!==a||e.test(g)||(g+=(-1!==g.indexOf("?")?"&":"?")+h)),g)}}}(FooGallery.utils,FooGallery.utils.is),function(a,b,c){"0.1.7"===a.version&&(a.str={},a.str.camel=function(a){return b.empty(a)?a:a.toUpperCase()===a?a.toLowerCase():a.replace(/^([A-Z])|[-\s_]+(\w)/g,function(a,c,d){return b.string(d)?d.toUpperCase():c.toLowerCase()})},a.str.contains=function(a,c,d){return!(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c))&&(c.length<=a.length&&-1!==(d?a.toUpperCase().indexOf(c.toUpperCase()):a.indexOf(c)))},a.str.containsWord=function(a,c,d){if(!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)||a.length<c.length)return!1;for(var e=a.split(/\W/),f=0,g=e.length;f<g;f++)if(d?e[f].toUpperCase()===c.toUpperCase():e[f]===c)return!0;return!1},a.str.endsWith=function(a,c){return!b.string(a)||b.empty(a)||!b.string(c)||b.empty(c)?a===c:a.slice(a.length-c.length)===c},a.str.escapeRegExp=function(a){return b.empty(a)?a:a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")},a.str.fnv1a=function(a){if(!b.string(a)||b.empty(a))return null;var c,d,e=2166136261;for(c=0,d=a.length;c<d;c++)e^=a.charCodeAt(c),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return e>>>0},a.str.from=function(c,d){return!b.string(c)||b.empty(c)||!b.string(d)||b.empty(d)?null:a.str.contains(c,d)?c.substring(c.indexOf(d)+d.length):null},a.str.join=function(d,e,f){if(!b.string(d)||!b.string(e))return null;var g=c.arg2arr(arguments);d=g.shift();var h,i,j=g.shift();for(h=0,i=g.length;h<i;h++)e=g[h],b.empty(e)||(a.str.endsWith(j,d)&&(j=j.slice(0,j.length-d.length)),a.str.startsWith(e,d)&&(e=e.slice(d.length)),j+=d+e);return j},a.str.startsWith=function(a,c){return!b.empty(a)&&!b.empty(c)&&a.slice(0,c.length)===c},a.str.until=function(c,d){return b.empty(c)||b.empty(d)?c:a.str.contains(c,d)?c.substring(0,c.indexOf(d)):c},a.str.format=function(a,d,e){var f=c.arg2arr(arguments);if(a=f.shift(),b.empty(a)||b.empty(f))return a;1===f.length&&(b.array(f[0])||b.object(f[0]))&&(f=f[0]);for(var g in f)a=a.replace(new RegExp("\\{"+g+"\\}","gi"),f[g]);return a})}(FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){if("0.1.7"===b.version){b.obj={};var f=function(){};b.obj.create=function(a){if(!c.object(a))throw TypeError("Argument must be an object");f.prototype=a;var b=new f;return f.prototype=null,b},b.obj.extend=function(e,f,g){e=c.object(e)?e:{};var h=d.arg2arr(arguments);return h.shift(),a.each(h,function(a,c){b.obj.merge(e,c)}),e},b.obj.merge=function(a,d){a=c.hash(a)?a:{},d=c.hash(d)?d:{};for(var e in d)d.hasOwnProperty(e)&&(c.hash(d[e])?(a[e]=c.hash(a[e])?a[e]:{},b.obj.merge(a[e],d[e])):c.array(d[e])?a[e]=d[e].slice():a[e]=d[e]);return a},b.obj.mergeValid=function(d,e,f,g){if(!c.hash(f)||!c.hash(e))return d;e=c.hash(e)?e:{},g=c.hash(g)?g:{};var h,i,j;for(h in e)e.hasOwnProperty(h)&&c.fn(e[h])&&(i=c.array(g[h])?g[h]:c.string(g[h])?[g[h]]:[h],a.each(i,function(a,g){if(j=b.obj.prop(f,g),!c.undef(j))return e[h](j)?(b.obj.prop(d,h,j),!1):void 0}));return d},b.obj.prop=function(b,d,f){if(c.object(b)&&!c.empty(d)){var g,h;if(c.undef(f))return e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){if(a===h)f=b[d];else{if(!c.hash(b[d]))return!1;b=b[d]}})):c.undef(b[d])||(f=b[d]),f;e.contains(d,".")?(g=d.split("."),h=g.length-1,a.each(g,function(a,d){a===h?b[d]=f:b=c.hash(b[d])?b[d]:b[d]={}})):c.undef(b[d])||(b[d]=f)}}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){if("0.1.7"===b.version){b.ready=function(a){function c(){try{a.call(window,b.$)}catch(a){console.error(a)}}(Function("/*@cc_on return true@*/")()?"complete"===document.readyState:"loading"!==document.readyState)?c():document.addEventListener("DOMContentLoaded",c,!1)};var d=0;b.uniqueId=function(a,b){var e=a.attr("id");return c.empty(e)&&(b=c.string(b)&&!c.empty(b)?b:"uid-",e=b+ ++d,a.attr("id",e).data("__uniqueId__",!0)),e},b.removeUniqueId=function(a){a.data("__uniqueId__")&&a.removeAttr("id").removeData("__uniqueId__")},b.selectify=function(a){if(c.empty(a))return null;if(c.hash(a)){var d,e={};for(var f in a)a.hasOwnProperty(f)&&(d=b.selectify(a[f]))&&(e[f]=d);return e}return c.string(a)||c.array(a)?(c.string(a)&&(a=[a]),a.map(function(a){return c.string(a)?"."+a.split(/\s/g).join("."):null}).join(",")):null},b.src=function(a,b,d,e,f,g,h){if(!c.string(a))return null;if(!c.string(b))return a;var i=b.replace(/(\s[\d.]+[whx]),/g,"$1 @,@ ").split(" @,@ "),j=i.map(function(a){return{url:/^\s*(\S*)/.exec(a)[1],w:parseFloat((/\S\s+(\d+)w/.exec(a)||[0,1/0])[1]),h:parseFloat((/\S\s+(\d+)h/.exec(a)||[0,1/0])[1]),x:parseFloat((/\S\s+([\d.]+)x/.exec(a)||[0,1])[1])}});if(!j.length)return a;j.unshift({url:a,w:j[0].w!==1/0&&j[0].h===1/0?d:1/0,h:j[0].h!==1/0&&j[0].w===1/0?e:1/0,x:1});var k=c.number(h)?h:window.devicePixelRatio||1,l={w:f*k,h:g*k,x:k},m=["w","h","x"];return m.forEach(function(a){var b=Math.max.apply(null,j.map(function(b){return b[a]}));j=j.filter(function(c){return c[a]>=l[a]||c[a]===b})}),m.forEach(function(a){var b=Math.min.apply(null,j.map(function(b){return b[a]}));j=j.filter(function(c){return c[a]===b})}),j[0].url},b.scrollParent=function(b,d,e){b=c.jq(b)?b:a(b),d=c.string(d)&&/^(x|y|xy|yx)$/i.test(d)?d:"xy";var f=a(!!b.length&&b[0].ownerDocument||document);if(e=c.jq(e)?e:f,!b.length)return e;var g=b.css("position"),h="absolute"===g,i=/(auto|scroll)/i,j=/x/i,k=/y/i,l=b.parentsUntil(e).filter(function(b,c){var e=a(this);if(h&&"static"===e.css("position"))return!1;var f=k.test(d)&&c.scrollHeight>c.clientHeight&&i.test(e.css("overflow-y")),g=j.test(d)&&c.scrollWidth>c.clientWidth&&i.test(e.css("overflow-x"));return f||g}).eq(0);return l.is("html")&&(l=f),"fixed"!==g&&l.length?l:e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c){function d(a){return setTimeout(a,1)}function e(a){clearTimeout(a)}if("0.1.7"===b.version){b.animation={},b.animation.requestFrame=(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||d).bind(window),b.animation.cancelFrame=(window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame||e).bind(window);var f=document.createElement("div");b.animation.supported=function(a){var b=a.style;return c.string(b.animation)||c.string(b.WebkitAnimation)||c.string(b.MozAnimation)||c.string(b.msAnimation)||c.string(b.OAnimation)}(f),b.animation.end=function(a){var b=a.style;return c.string(b.animation)?"animationend":c.string(b.WebkitAnimation)?"webkitAnimationEnd":c.string(b.MozAnimation)?"animationend":c.string(b.msAnimation)?"msAnimationEnd":c.string(b.OAnimation)?"oAnimationEnd":null}(f),b.animation.duration=function(a,b){if(b=c.number(b)?b:0,!c.jq(a))return b;var d=a.css("animation-duration");if(/^([\d.]*)+?(ms|s)$/i.test(d)){var e=d.match(/^([\d.]*)+?(ms|s)$/i),f=parseFloat(e[1]);return"s"===e[2].toLowerCase()&&(f*=1e3),f}return b},b.animation.iterations=function(a,b){if(b=c.number(b)?b:1,!c.jq(a))return b;var d=a.css("animation-iteration-count");return/^(\d+|infinite)$/i.test(d)?"infinite"===d?1/0:parseInt(d):b},b.animation.start=function(d,e,f,g){var h=a.Deferred(),i=h.promise();if(d=d.first(),b.animation.supported){d.prop("offsetTop");var j=d.data("animation_safety");if(c.hash(j)&&c.number(j.timer)&&(clearTimeout(j.timer),d.removeData("animation_safety").off(b.animation.end+".utils"),j.deferred.reject()),!c.number(g)){var k=b.animation.iterations(d);if(k===1/0)return h.reject("No timeout supplied with an infinite animation."),i;g=b.animation.duration(d)*k+50}j={deferred:h,timer:setTimeout(function(){d.removeData("animation_safety").off(b.animation.end+".utils"),h.resolve()},g)},d.data("animation_safety",j),d.on(b.animation.end+".utils",function(a){d.is(a.target)&&(clearTimeout(j.timer),d.removeData("animation_safety").off(b.animation.end+".utils"),h.resolve())})}return b.animation.requestFrame(function(){c.fn(e)?e.apply(d.get(0),[d]):d.toggleClass(e,f),b.animation.supported||h.resolve()}),i}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){if("0.1.7"===b.version){b.transition={};var e=document.createElement("div");b.transition.supported=function(a){var b=a.style;return c.string(b.transition)||c.string(b.WebkitTransition)||c.string(b.MozTransition)||c.string(b.msTransition)||c.string(b.OTransition)}(e),b.transition.end=function(a){var b=a.style;return c.string(b.transition)?"transitionend":c.string(b.WebkitTransition)?"webkitTransitionEnd":c.string(b.MozTransition)?"transitionend":c.string(b.msTransition)?"msTransitionEnd":c.string(b.OTransition)?"oTransitionEnd":null}(e),b.transition.duration=function(a,b){if(b=c.number(b)?b:0,!c.jq(a))return b;var d=a.css("transition-duration");if(/^([\d.]*)+?(ms|s)$/i.test(d)){var e=d.match(/^([\d.]*)+?(ms|s)$/i),f=parseFloat(e[1]);return"s"===e[2].toLowerCase()&&(f*=1e3),f}return b},b.transition.start=function(e,f,g,h){var i=a.Deferred(),j=i.promise();if(e=e.first(),b.transition.supported){e.prop("offsetTop");var k=e.data("transition_safety");c.hash(k)&&c.number(k.timer)&&(clearTimeout(k.timer),e.removeData("transition_safety").off(b.transition.end+".utils"),k.deferred.reject()),h=c.number(h)?h:b.transition.duration(e)+50,k={deferred:i,timer:setTimeout(function(){e.removeData("transition_safety").off(b.transition.end+".utils"),i.resolve()},h)},e.data("transition_safety",k),e.on(b.transition.end+".utils",function(a){e.is(a.target)&&(clearTimeout(k.timer),e.removeData("transition_safety").off(b.transition.end+".utils"),i.resolve())})}return d.requestFrame(function(){c.fn(f)?f.apply(e.get(0),[e]):e.toggleClass(f,g),b.transition.supported||i.resolve()}),j}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.animation),function(a,b,c,d,e){"0.1.7"===b.version&&(b.Class=function(){},b.Class.extend=function(a){function f(){if(!c.fn(this.construct))throw new SyntaxError('FooGallery.utils.Class objects must be constructed with the "new" keyword.');this.construct.apply(this,arguments)}a=c.hash(a)?a:{};var g=d.create(this.prototype);for(var h in a)a.hasOwnProperty(h)&&e.addOrOverride(g,h,a[h]);return g.construct=c.fn(g.construct)?g.construct:function(){},f.prototype=g,f.prototype.constructor=c.fn(g.__ctor__)?g.__ctor__:f,f.extend=b.Class.extend,f.override=b.Class.override,f},b.Class.override=function(a,b){e.addOrOverride(this.prototype,a,b)})}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj,FooGallery.utils.fn),function(a,b,c){"0.1.7"===a.version&&(a.Event=a.Class.extend({construct:function(a){if(b.empty(a))throw new SyntaxError("FooGallery.utils.Event objects must be supplied a `type`.");var d=c.contains(a,".");this.type=d?c.until(a,"."):a,this.namespace=d?c.from(a,"."):null,this.defaultPrevented=!1,this.target=null},preventDefault:function(){this.defaultPrevented=!0},isDefaultPrevented:function(){return this.defaultPrevented}}),a.EventClass=a.Class.extend({construct:function(){this.__handlers={}},destroy:function(){this.__handlers={}},on:function(a,c,d){var e=this;return b.object(a)?(d=b.undef(c)?this:c,Object.keys(a).forEach(function(b){b.split(" ").forEach(function(c){e.__on(c,a[b],d)})})):b.string(a)&&b.fn(c)&&(d=b.undef(d)?this:d,a.split(" ").forEach(function(a){e.__on(a,c,d)})),e},__on:function(a,d,e){var f=this,g=c.contains(a,"."),h=g?c.until(a,"."):a,i=g?c.from(a,"."):null;b.array(f.__handlers[h])||(f.__handlers[h]=[]),f.__handlers[h].some(function(a){return a.namespace===i&&a.fn===d&&a.thisArg===e})||f.__handlers[h].push({namespace:i,fn:d,thisArg:e})},off:function(a,c,d){var e=this;return b.object(a)?(d=b.undef(c)?this:c,Object.keys(a).forEach(function(c){c.split(" ").forEach(function(f){e.__off(f,b.fn(a[c])?a[c]:null,d)})})):b.string(a)&&(c=b.fn(c)?c:null,d=b.undef(d)?this:d,a.split(" ").forEach(function(a){e.__off(a,c,d)})),e},__off:function(a,d,e){var f=this,g=c.until(a,".")||null,h=c.from(a,".")||null,i=[];b.empty(g)?b.empty(h)||i.push.apply(i,Object.keys(f.__handlers)):i.push(g),i.forEach(function(a){b.array(f.__handlers[a])&&(f.__handlers[a]=f.__handlers[a].filter(function(a){return null!=d?!(a.namespace===h&&a.fn===d&&a.thisArg===e):null!=h&&a.namespace!==h}),0===f.__handlers[a].length&&delete f.__handlers[a])})},trigger:function(c,d){d=b.array(d)?d:[];var e=this,f=[];return c instanceof a.Event?(f.push(c),e.__trigger(c,d)):b.string(c)&&c.split(" ").forEach(function(b){var c=f.push(new a.Event(b))-1;e.__trigger(f[c],d)}),b.empty(f)?null:1===f.length?f[0]:f},__trigger:function(a,c){var d=this;a.target=d,b.array(d.__handlers[a.type])&&d.__handlers[a.type].forEach(function(b){null!=a.namespace&&b.namespace!==a.namespace||b.fn.apply(b.thisArg,[a].concat(c))})}}))}(FooGallery.utils,FooGallery.utils.is,FooGallery.utils.str),function(a,b,c){if("0.1.7"===b.version){b.Bounds=b.Class.extend({construct:function(){var a=this;a.top=0,a.right=0,a.bottom=0,a.left=0,a.width=0,a.height=0},inflate:function(a){var b=this;return c.number(a)&&(b.top-=a,b.right+=a,b.bottom+=a,b.left-=a,b.width+=2*a,b.height+=2*a),b},intersects:function(a){var b=this;return b.left<=a.right&&a.left<=b.right&&b.top<=a.bottom&&a.top<=b.bottom}});var d;b.getViewportBounds=function(c){d||(d=a(window));var e=new b.Bounds;return e.top=d.scrollTop(),e.left=d.scrollLeft(),e.width=d.width(),e.height=d.height(),e.right=e.left+e.width,e.bottom=e.top+e.height,e.inflate(c),e},b.getElementBounds=function(d){c.jq(d)||(d=a(d));var e=new b.Bounds;if(0!==d.length){var f=d.offset();e.top=f.top,e.left=f.left,e.width=d.width(),e.height=d.height()}return e.right=e.left+e.width,e.bottom=e.top+e.height,e}}}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){"0.1.7"===b.version&&(b.Timer=b.EventClass.extend({construct:function(a){this._super(),this.interval=c.number(a)?a:1e3,this.isRunning=!1,this.isPaused=!1,this.canResume=!1,this.canRestart=!1,this.__timeout=null,this.__decrement=!1,this.__time=0,this.__remaining=0,this.__current=0,this.__finish=0,this.__restart=[]},__reset:function(){clearTimeout(this.__timeout),this.__timeout=null,this.__decrement=!1,this.__time=0,this.__remaining=0,this.__current=0,this.__finish=0,this.isRunning=!1,this.isPaused=!1,this.canResume=!1},__eventArgs:function(a){return[this.__current,this.__time,this.__decrement].concat(d.arg2arr(arguments))},__tick:function(){var a=this;a.trigger("tick",a.__eventArgs()),a.__current===a.__finish?(a.trigger("complete",a.__eventArgs()),a.__reset()):(a.__decrement?a.__current--:a.__current++,a.__remaining--,a.canResume=a.__remaining>0,a.__timeout=setTimeout(function(){a.__tick()},a.interval))},start:function(a,b){var d=this;d.isRunning||(b=!!c.boolean(b)&&b,d.__restart=[a,b],d.__decrement=b,d.__time=a,d.__remaining=a,d.__current=b?a:0,d.__finish=b?0:a,d.canRestart=!0,d.isRunning=!0,d.isPaused=!1,d.trigger("start",d.__eventArgs()),d.__tick())},countdown:function(a){this.start(a,!0)},countup:function(a){this.start(a,!1)},restart:function(){this.stop(),this.canRestart&&this.start.apply(this,this.__restart)},stop:function(){(this.isRunning||this.isPaused)&&(this.__reset(),this.trigger("stop",this.__eventArgs()))},pause:function(){var a=this;return null!=a.__timeout&&(clearTimeout(a.__timeout),a.__timeout=null),a.isRunning&&(a.isRunning=!1,a.isPaused=!0,a.trigger("pause",a.__eventArgs())),a.__remaining},resume:function(){var a=this;a.canResume&&(a.isRunning=!0,a.isPaused=!1,a.trigger("resume",a.__eventArgs()),a.__tick())},reset:function(){this.__reset(),this.trigger("reset",this.__eventArgs())}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d){"0.1.7"===b.version&&(b.Factory=b.Class.extend({construct:function(){this.registered={}},contains:function(a){return!c.undef(this.registered[a])},load:function(b,e,f){var g,h,i=this,j=d.arg2arr(arguments),k=[],l=[];b=j.shift()||{};for(g in i.registered)if(i.registered.hasOwnProperty(g)){var m=i.registered[g];b.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&(m={name:g,klass:h,priority:i.registered[g].priority})),k.push(m)}for(g in b)b.hasOwnProperty(g)&&!i.registered.hasOwnProperty(g)&&(h=b[g],c.string(h)&&(h=d.fetch(b[g])),c.fn(h)&&k.push({name:g,klass:h,priority:0}));return k.sort(function(a,b){return b.priority-a.priority}),a.each(k,function(a,b){c.fn(b.klass)&&l.push(d.apply(b.klass,j))}),l},make:function(a,b,e){var f,g=this,h=d.arg2arr(arguments);return a=h.shift(),f=g.registered[a],c.hash(f)&&c.fn(f.klass)?d.apply(f.klass,h):null},names:function(b){b=!!c.boolean(b)&&b;var d,e=[];if(b){var f=[];for(d in this.registered)this.registered.hasOwnProperty(d)&&f.push(this.registered[d]);f.sort(function(a,b){return b.priority-a.priority}),a.each(f,function(a,b){e.push(b.name)})}else for(d in this.registered)this.registered.hasOwnProperty(d)&&e.push(d);return e},register:function(a,b,d){if(!c.string(a)||c.empty(a)||!c.fn(b))return!1;d=c.number(d)?d:0;var e=this.registered[a];return this.registered[a]={name:a,klass:b,priority:c.undef(e)?d:e.priority},!0}}))}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c){if("0.1.7"===a.version){var d=!1;try{d=!!window.localStorage}catch(a){d=!1}a.Debugger=a.Class.extend({construct:function(a){this.key=a,this.enabled=!!d&&!!localStorage.getItem(this.key)},enable:function(){d&&(this.enabled=!0,localStorage.setItem(this.key,this.enabled))},disable:function(){d&&(this.enabled=!1,localStorage.removeItem(this.key))},log:function(a,c){this.enabled&&console.log.apply(console,b.arg2arr(arguments))},logf:function(a,d,e){if(this.enabled){var f=b.arg2arr(arguments);a=f.shift(),d=f.shift(),f.unshift(c.format(a,d)),this.log.apply(this,f)}}})}}(FooGallery.utils,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){"0.1.7"===b.version&&(b.FullscreenAPI=b.EventClass.extend({construct:function(){this._super(),this.apis={w3:{enabled:"fullscreenEnabled",element:"fullscreenElement",request:"requestFullscreen",exit:"exitFullscreen",events:{change:"fullscreenchange",error:"fullscreenerror"}},webkit:{enabled:"webkitFullscreenEnabled",element:"webkitCurrentFullScreenElement",request:"webkitRequestFullscreen",exit:"webkitExitFullscreen",events:{change:"webkitfullscreenchange",error:"webkitfullscreenerror"}},moz:{enabled:"mozFullScreenEnabled",element:"mozFullScreenElement",request:"mozRequestFullScreen",exit:"mozCancelFullScreen",events:{change:"mozfullscreenchange",error:"mozfullscreenerror"}},ms:{enabled:"msFullscreenEnabled",element:"msFullscreenElement",request:"msRequestFullscreen",exit:"msExitFullscreen",events:{change:"MSFullscreenChange",error:"MSFullscreenError"}}},this.api=this.getAPI(),this.supported=null!=this.api,this.__listen()},destroy:function(){return this.__stopListening(),this._super()},getAPI:function(){for(var a in this.apis)if(this.apis.hasOwnProperty(a)&&this.apis[a].enabled in document)return this.apis[a];return null},element:function(){return this.supported?document[this.api.element]:null},request:function(b){if(this.supported&&b[this.api.request]){var d=b[this.api.request]();return d||a.Deferred(this.__resolver(this.api.request)).promise()}return c.rejected},exit:function(){if(this.supported&&this.element()){var b=document[this.api.exit]();return b||a.Deferred(this.__resolver(this.api.exit)).promise()}return c.rejected},toggle:function(a){return this.element()?this.exit():this.request(a)},__listen:function(){var b=this;b.supported&&a(document).on(b.api.events.change+".utils",function(){b.trigger("change")}).on(b.api.events.error+".utils",function(){b.trigger("error")})},__stopListening:function(){var b=this;b.supported&&a(document).off(b.api.events.change+".utils").off(b.api.events.error+".utils")},__resolver:function(b){var c=this;return function(d){function e(){d.resolve(),a(document).off(c.api.events.change,e).off(c.api.events.error,f)}function f(){d.reject(new TypeError),a(document).off(c.api.events.change,e).off(c.api.events.error,f)}if(b===c.api.exit&&c.element())return void setTimeout(function(){d.reject(new TypeError)},1);a(document).on(c.api.events.change,e).on(c.api.events.error,f)}}}),b.fullscreen=new b.FullscreenAPI)}(FooGallery.utils.$,FooGallery.utils,FooGallery.utils.fn),function(a,b,c,d,e){b.debug=new c.Debugger("__FooGallery__"),b.EMPTY_IMAGE="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",b.DATA_TEMPLATE="__FooGallery__",b.DATA_ITEM="__FooGalleryItem__",b.get=function(c){return a(c).data(b.DATA_TEMPLATE)},b.init=function(c,e){if(e=d.jq(e)?e:a(e),e.length>0){var f=e.data(b.DATA_TEMPLATE);if(f instanceof b.Template)return f.destroy(!0).then(function(){return b.template.make(c,e).initialize()})}return b.template.make(c,e).initialize()},b.initAll=function(c){return e.when(a(".foogallery").map(function(a,d){return b.init(c,d)}).get())},a.fn.foogallery=function(c,e){return e=d.fn(e)?e:a.noop,this.each(function(f,g){if(d.string(c)){var h=a.data(g,b.DATA_TEMPLATE);if(h instanceof b.Template)switch(c){case"layout":return void h.layout();case"destroy":return void h.destroy()}}else b.init(c,g).then(e)})},b.isCached=function(a){var b=new Image;b.src=a;var c=b.complete;return b.src="",b=null,c}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d,e){var f="__FooGallerySwipe__",g="ontouchstart"in window,h=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled&&!g,i=(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&!g,j=g||i;b.Swipe=c.Class.extend({construct:function(b,c){var d=this,f=".fgswipe";d.$el=a(b),d.opt=e.extend({threshold:20,allowPageScroll:!1,swipe:a.noop,data:{}},c),d.active=!1,d.startPoint=null,d.endPoint=null,d.events={start:(j?i?h?"MSPointerDown":"pointerdown":"touchstart":"mousedown")+f,move:(j?i?h?"MSPointerMove":"pointermove":"touchmove":"mousemove")+f,end:(j?i?h?"MSPointerUp":"pointerup":"touchend":"mouseup")+f,leave:(j?i?"mouseleave":null:"mouseleave")+f}},init:function(){var a=this;a.$el.on(a.events.start,{self:a},a.onStart),a.$el.on(a.events.move,{self:a},a.onMove),a.$el.on(a.events.end,{self:a},a.onEnd),d.string(a.events.leave)&&a.$el.on(a.events.leave,{self:a},a.onEnd),a.$el.data(f,a)},destroy:function(){var a=this;a.$el.off(a.events.start,a.onStart),a.$el.off(a.events.move,a.onMove),a.$el.off(a.events.end,a.onEnd),d.string(a.events.leave)&&a.$el.off(a.events.leave,a.onEnd),a.$el.removeData(f)},getAngle:function(a,b){var c=Math.atan2(a.x-b.x,a.y-b.y),d=Math.round(180*c/Math.PI);return 360-(d<0?360-Math.abs(d):d)},getDistance:function(a,b){var c=b.x-a.x,d=b.y-a.y;return c*=c,d*=d,Math.sqrt(c+d)},getDirection:function(a,b){var c=this,d=c.getAngle(a,b);return d>337.5||d<=22.5?"N":d>22.5&&d<=67.5?"NE":d>67.5&&d<=112.5?"E":d>112.5&&d<=157.5?"SE":d>157.5&&d<=202.5?"S":d>202.5&&d<=247.5?"SW":d>247.5&&d<=292.5?"W":d>292.5&&d<=337.5?"NW":"NONE"},getPoint:function(a){var b;return j&&!d.empty(b=a.originalEvent.touches||a.touches)?{x:b[0].pageX,y:b[0].pageY}:d.number(a.pageX)&&d.number(a.pageY)?{x:a.pageX,y:a.pageY}:null},getOffset:function(a){var b=this,c=b.$el.offset();return{left:a.x-c.left,top:a.y-c.top}},onStart:function(a){var b=a.data.self,c=b.getPoint(a);d.empty(c)||(b.active=!0,b.startPoint=b.endPoint=c)},onMove:function(b){var c=b.data.self,e=c.getPoint(b);if(c.active&&!d.empty(e))if(c.endPoint=e,c.opt.allowPageScroll){if(d.hash(c.opt.allowPageScroll)){var f=c.getDirection(c.startPoint,c.endPoint);c.opt.allowPageScroll.x||-1===a.inArray(f,["NE","E","SE","NW","W","SW"])||b.preventDefault(),c.opt.allowPageScroll.y||-1===a.inArray(f,["NW","N","NE","SW","S","SE"])||b.preventDefault()}}else b.preventDefault()},onEnd:function(a){var b=a.data.self;if(b.active){b.active=!1;var c={startPoint:b.startPoint,endPoint:b.endPoint,startOffset:b.getOffset(b.startPoint),endOffset:b.getOffset(b.endPoint),angle:b.getAngle(b.startPoint,b.endPoint),distance:b.getDistance(b.startPoint,b.endPoint),direction:b.getDirection(b.startPoint,b.endPoint)};if(b.opt.threshold>0&&c.distance<b.opt.threshold)return;b.opt.swipe.apply(this,[c,b.opt.data]),b.startPoint=null,b.endPoint=null}}}),a.fn.fgswipe=function(c){return this.each(function(){var e=a(this),g=e.data(f);if(g instanceof b.Swipe){if(d.string(c)&&d.fn(g[c]))return void g[c]();g.destroy()}d.hash(c)&&(g=new b.Swipe(this,c),g.init())})}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.obj),function(a,b,c,d,e,f){b.TemplateFactory=c.Factory.extend({construct:function(){this.registered={}},register:function(a,b,c,e,f,g){var h=this,i=h._super(a,b,g);if(i){var j=h.registered;j[a].opt=d.hash(c)?c:{},j[a].cls=d.hash(e)?e:{},j[a].il8n=d.hash(f)?f:{}}return i},make:function(b,c){c=d.jq(c)?c:a(c),b=f.extend({},b,c.data("foogallery"));var e=this,g=e.type(b,c);return e.contains(g)?(b=e.options(g,b),e._super(g,b,c)):null},type:function(b,e){e=d.jq(e)?e:a(e);var f=this,g=d.hash(b)&&d.hash(b)&&d.string(b.type)&&f.contains(b.type)?b.type:"core";if("core"===g&&e.length>0)for(var h=f.registered,i=f.names(!0),j=0,k=i.length;j<k;j++)if(h.hasOwnProperty(i[j])){var l=i[j],m=h[l].cls;if(d.string(m.container)){var n=c.selectify(m.container);if(e.is(n)){g=i[j];break}}}return g},configure:function(a,b,c,d){var e=this;if(e.contains(a)){var g=e.registered;f.extend(g[a].opt,b),f.extend(g[a].cls,c),f.extend(g[a].il8n,d)}},options:function(a,c){c=f.extend({type:a},c);var e=this,g=e.registered,h=g.core.opt,i=g.core.cls,j=g.core.il8n;return d.hash(c.cls)||(c.cls={}),d.hash(c.il8n)||(c.il8n={}),d.undef(b.filtering)||(c=b.filtering.merge(c)),d.undef(b.paging)||(c=b.paging.merge(c)),"core"!==a&&e.contains(a)?(c=f.extend({},h,g[a].opt,c),c.cls=f.extend({},i,g[a].cls,c.cls),
10
+ c.il8n=f.extend({},j,g[a].il8n,c.il8n)):(c=f.extend({},h,c),c.cls=f.extend({},i,c.cls),c.il8n=f.extend({},j,c.il8n)),c}}),b.template=new b.TemplateFactory}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e){a.PagingFactory=b.Factory.extend({construct:function(){this.registered={}},register:function(a,b,d,e,f,g,h){var i=this,j=i._super(a,b,h);if(j){var k=i.registered;k[a].ctrl=c.fn(d)?d:null,k[a].opt=c.hash(e)?e:{},k[a].cls=c.hash(f)?f:{},k[a].il8n=c.hash(g)?g:{}}return j},type:function(a){var b,d=this;return c.hash(a)&&c.hash(b=a.paging)&&c.string(b.type)&&d.contains(b.type)?b.type:null},merge:function(a){a=e.extend({},a);var b=this,d=b.type(a),f=b.registered,g=f.default.opt,h=f.default.cls,i=f.default.il8n,j=c.hash(a.paging)?a.paging:{},k=c.hash(a.cls)&&c.hash(a.cls.paging)?e.extend({},a.cls.paging):{},l=c.hash(a.il8n)&&c.hash(a.il8n.paging)?e.extend({},a.il8n.paging):{};return c.hash(a.cls)||(a.cls={}),c.hash(a.il8n)||(a.il8n={}),"default"!==d&&b.contains(d)?(a.paging=e.extend({},g,f[d].opt,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:f[d].cls},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:f[d].il8n},{paging:l})):(a.paging=e.extend({},g,j,{type:d}),a.cls=e.extend(a.cls,{paging:h},{paging:k}),a.il8n=e.extend(a.il8n,{paging:i},{paging:l})),a},configure:function(a,b,c,d){var f=this;if(f.contains(a)){var g=f.registered;e.extend(g[a].opt,b),e.extend(g[a].cls,c),e.extend(g[a].il8n,d)}},hasCtrl:function(a){var b=this,d=b.registered[a];return c.hash(d)&&c.fn(d.ctrl)},makeCtrl:function(a,b,d,e){var f=this,g=f.registered[a];return c.hash(g)&&c.fn(g.ctrl)?new g.ctrl(b,d,e):null}}),a.paging=new a.PagingFactory}(FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f){var g=0;b.Template=c.EventClass.extend({construct:function(e,f){var h=this;h._super(),h.namespace=".foogallery-"+ ++g,h.$el=d.jq(f)?f:a(f),h.$scrollParent=null,h.opt=e,h.template=e.template,h.id=h.$el.prop("id")||e.id,h.cls=e.cls,h.il8n=e.il8n,h.sel=c.selectify(h.cls),h.items=b.components.make("items",h),h.pages=d.undef(b.paging)?null:b.paging.make(e.paging.type,h),h.filter=d.undef(b.filtering)?null:b.filtering.make(e.filtering.type,h),h.state=b.components.make("state",h),h._initialize=null,h._checkTimeout=null,h.initializing=!1,h.initialized=!1,h.destroying=!1,h.destroyed=!1,h._undo={classes:"",style:"",create:!1,children:!1}},initialize:function(b){var c=this;return d.promise(c._initialize)?c._initialize:c._initialize=a.Deferred(function(a){c.preInit(b)?c.init().then(function(){c.postInit()?c.firstLoad().then(function(){c.ready(),a.resolve(c)}).fail(a.reject):a.reject("post-init failed")}).fail(a.reject):a.reject("pre-init failed")}).fail(function(a){console.log("initialize failed",c,a),c.destroy()}).promise()},preInit:function(e){var f=this;if(f.destroying)return!1;if(e=d.jq(e)?e:a(e),f.initializing=!0,0===e.length&&0===f.$el.parent().length)return!1;0===f.$el.length&&(f.$el=f.create(),f._undo.create=!0),e.length>0&&f.$el.appendTo(e);var g;d.empty(f.opt.scrollParent)||0===(g=a(f.opt.scrollParent)).length?f.$scrollParent=a(document):f.$scrollParent=g.is("html")?a(document):g,f.$el.data(b.DATA_TEMPLATE,f),d.empty(f.opt.on)||f.$el.on(f.opt.on),f._undo.classes=f.$el.attr("class"),f._undo.style=f.$el.attr("style"),f.$el.is(f.sel.container)||f.$el.addClass(f.cls.container);var h=c.selectify(f.opt.classes);return null==h||f.$el.is(h)||f.$el.addClass(f.opt.classes),0===f.$el.children().not(f.sel.item.elem).length&&(f.$el.append(f.createChildren()),f._undo.children=!0),!f.raise("pre-init").isDefaultPrevented()},init:function(){var a=this;return a.raise("init").isDefaultPrevented()?e.rejectWith("init default prevented"):a.items.fetch()},postInit:function(){var b=this;return!b.destroying&&(!b.raise("post-init").isDefaultPrevented()&&(b.state.init(),b.$scrollParent.on("scroll"+b.namespace,{self:b},e.throttle(function(){b.loadAvailable()},50)),a(window).on("popstate"+b.namespace,{self:b},b.onWindowPopState),!0))},firstLoad:function(){var a=this;return a.destroying?e.rejected:(a.raise("first-load"),a.loadAvailable())},ready:function(){var a=this;return!a.destroying&&(a.initializing=!1,a.initialized=!0,a._check(1e3),a.raise("ready"),!0)},create:function(){var b=this;return a("<div/>",{id:b.id,class:b.cls.container}).addClass(b.opt.classes)},createChildren:function(){return a()},destroy:function(b){var c=this,f=c._super.bind(c);return c.destroyed?e.resolved:(c.destroying=!0,a.Deferred(function(a){c.initializing&&d.promise(c._initialize)?c._initialize.always(function(){c.destroying=!1,c.doDestroy(b),a.resolve()}):(c.destroying=!1,c.doDestroy(b),a.resolve())}).then(function(){f()}).promise())},doDestroy:function(c){var e=this;e.destroyed||(e.raise("destroy"),e._checkTimeout&&clearTimeout(e._checkTimeout),e.$scrollParent.off(e.namespace),a(window).off(e.namespace),e.state.destroy(c),e.filter&&e.filter.destroy(),e.pages&&e.pages.destroy(),e.items.destroy(),d.empty(e.opt.on)||e.$el.off(e.opt.on),e.raise("destroyed"),e.$el.removeData(b.DATA_TEMPLATE),d.empty(e._undo.classes)?e.$el.removeAttr("class"):e.$el.attr("class",e._undo.classes),d.empty(e._undo.style)?e.$el.removeAttr("style"):e.$el.attr("style",e._undo.style),e._undo.children&&e.destroyChildren(),e._undo.create&&e.$el.remove(),e.$el=e.state=e.items=e.pages=null,e.destroyed=!0,e.initializing=!1,e.initialized=!1)},destroyChildren:function(){},getAvailable:function(){return this.pages?this.pages.available():this.items.available()},loadAvailable:function(){return this.items.load(this.getAvailable())},getItems:function(){return this.pages?this.pages.items():this.items.available()},_check:function(a){a=d.number(a)?a:0;var b=this;return b._checkTimeout&&clearTimeout(b._checkTimeout),b._checkTimeout=setTimeout(function(){b._checkTimeout=null,!b.initialized||b.destroying&&b.destroyed||b.loadAvailable()},a)},raise:function(c,e){if(this.destroying||this.destroyed||!d.string(c)||d.empty(c))return null;e=d.array(e)?e:[];var g=this,h=c.split(".")[0],i=f.camel("on-"+h),j=a.Event(h+".foogallery");return e.unshift(g),g.trigger(h,e).defaultPrevented&&j.preventDefault(),g.$el.trigger(j,e),b.debug.logf("{id}|{name}:",{id:g.id,name:h},e),d.fn(g[i])&&(e.unshift(j),g[i].apply(g.$el.get(0),e)),j},layout:function(){var a=this;null!==a._initialize&&a.raise("layout")},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},getCSSClass:function(a){var b=a instanceof RegExp?a:d.string(a)&&this.opt.regex.hasOwnProperty(a)?this.opt.regex[a]:null,c=this.$el.prop("className")||"",e=null!=b?c.match(b):null;return null!=e&&e.length>=2?e[1]:""},onWindowPopState:function(a){var b=a.data.self,c=a.originalEvent.state;d.empty(c)||c.id!==b.id||(b.state.set(c),b.loadAvailable())}}),b.template.register("core",b.Template,{id:null,type:"core",classes:"",on:{},lazy:!0,viewport:200,items:[],fixLayout:!0,scrollParent:null,delay:0,throttle:50,timeout:6e4,srcset:"data-srcset-fg",src:"data-src-fg",template:{},regex:{theme:/(?:\s|^)(fg-(?:light|dark|custom))(?:\s|$)/,loadingIcon:/(?:\s|^)(fg-loading-(?:default|bars|dots|partial|pulse|trail))(?:\s|$)/,hoverIcon:/(?:\s|^)(fg-hover-(?:zoom|zoom2|zoom3|plus|circle-plus|eye|external|tint))(?:\s|$)/,videoIcon:/(?:\s|^)(fg-video-(?:default|1|2|3|4))(?:\s|$)/,hoverColor:/(?:\s|^)(fg-hover-(?:colorize|grayscale))(?:\s|$)/,hoverScale:/(?:\s|^)(fg-hover-scale)(?:\s|$)/,stickyVideoIcon:/(?:\s|^)(fg-video-sticky)(?:\s|$)/,insetShadow:/(?:\s|^)(fg-shadow-inset-(?:small|medium|large))(?:\s|$)/,filter:/(?:\s|^)(fg-filter-(?:1977|amaro|brannan|clarendon|earlybird|lofi|poprocket|reyes|toaster|walden|xpro2|xtreme))(?:\s|$)/}},{container:"foogallery"},{},-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.str),function(a,b,c){a.Component=b.Class.extend({construct:function(a){this.tmpl=a},destroy:function(){this.tmpl=null}}),a.EventComponent=b.EventClass.extend({construct:function(a,b){this._super(a),this.tmpl=a,this.tmplEventPrefix=b},destroy:function(){this._super(),this.tmpl=null},trigger:function(a,d){var e,f,g=this,h=g._super(a,d);return null!=g.tmpl&&(h instanceof b.Event&&!h.isDefaultPrevented()?(e=null!=h.namespace?[h.type,h.namespace].join("."):h.type,(f=g.tmpl.raise(g.tmplEventPrefix+e,d))&&f.isDefaultPrevented()&&h.preventDefault()):c.array(h)&&h.forEach(function(a){a.isDefaultPrevented()||(e=null!=a.namespace?[a.type,a.namespace].join("."):a.type,(f=g.tmpl.raise(g.tmplEventPrefix+e,d))&&f.isDefaultPrevented()&&a.preventDefault())})),c.empty(h)?null:1===h.length?h[0]:h}}),a.components=new b.Factory}(FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d,e){b.State=b.Component.extend({construct:function(a){var b=this;b._super(a),b.apiEnabled=!!window.history&&!!history.replaceState,b.opt=b.tmpl.opt.state,b.enabled=b.opt.enabled,b.current={filter:[],page:0,item:null},b.pushOrReplace=b.isPushOrReplace(b.opt.pushOrReplace)?b.opt.pushOrReplace:"replace",b.defaultMask="foogallery-gallery-{id}";var c=d.escapeRegExp(b.tmpl.id),e=d.escapeRegExp(b.getMasked()),f=d.escapeRegExp(b.opt.values),g=d.escapeRegExp(b.opt.pair);b.regex={exists:new RegExp("^#"+c+"\\"+f+".+?"),masked:new RegExp("^#"+e+"\\"+f+".+?"),values:new RegExp("(\\w+)"+g+"([^"+f+"]+)","g")}},destroy:function(a){var b=this;a||b.clear(),b.opt=b.regex={},b._super()},init:function(){this.set(this.initial())},getIdNumber:function(){return this.tmpl.id.match(/\d+/g)[0]},getMasked:function(){var a=this,b=d.contains(a.opt.mask,"{id}")?a.opt.mask:a.defaultMask;return d.format(b,{id:a.getIdNumber()})},isPushOrReplace:function(b){return-1!==a.inArray(b,["push","replace"])},exists:function(){return this.regex.values.lastIndex=0,(this.regex.exists.test(location.hash)||this.regex.masked.test(location.hash))&&this.regex.values.test(location.hash)},parse:function(){var b=this,c=b.tmpl,d={};if(b.exists())if(b.enabled){d.id=b.tmpl.id,b.regex.values.lastIndex=0;var e=location.hash.match(b.regex.values);a.each(e,function(a,e){var f,g=e.split(b.opt.pair);if(2===g.length)switch(g[0]){case b.opt.itemKey:f=c.items.fromHash(g[1]),null!==f&&(d.item=f);break;case b.opt.pageKey:c.pages&&null!==(f=c.pages.fromHash(g[1]))&&(d.page=f);break;case b.opt.filterKey:c.filter&&null!==(f=c.filter.fromHash(g[1]))&&(d.filter=f)}})}else b.apiEnabled?history.replaceState(null,"",location.pathname+location.search):location.hash="#";return d},hashify:function(a){var b=this,d=b.tmpl;if(c.hash(a)){var e=[],f=d.items.toHash(a.item);return null!==f&&e.push(b.opt.itemKey+b.opt.pair+f),d.filter&&null!==(f=d.filter.toHash(a.filter))&&e.push(b.opt.filterKey+b.opt.pair+f),d.pages&&null!==(f=d.pages.toHash(a.page))&&e.push(b.opt.pageKey+b.opt.pair+f),e.length>0&&e.unshift("#"+b.getMasked()),e.join(b.opt.values)}return""},replace:function(a){var d=this;if(d.enabled&&d.apiEnabled){a.id=d.tmpl.id;var f=d.hashify(a),g=c.empty(f),h=e.extend({},a,{item:a.item instanceof b.Item?a.item.id:a.item});history.replaceState(g?null:h,"",g?location.pathname+location.search:f)}},push:function(a){var d=this;if(d.enabled&&d.apiEnabled){a.id=d.tmpl.id;var f=d.hashify(a),g=c.empty(f),h=e.extend({},a,{item:a.item instanceof b.Item?a.item.id:a.item});history.pushState(g?null:h,"",g?location.pathname+location.search:f)}},update:function(a,b){var c=this;c.enabled&&c.apiEnabled&&(b=c.isPushOrReplace(b)?b:c.pushOrReplace,c[b](a))},clear:function(){this.exists()&&this.replace({})},initial:function(){var a=this,b=a.parse();return c.empty(b)?a.get():e.extend({filter:[],page:1,item:null},b)},get:function(a){var c,d=this,f=d.tmpl,g={};return a instanceof b.Item&&(g.item=a),f.filter&&null!==(c=f.filter.getState())&&(g.filter=c),f.pages&&null!==(c=f.pages.getState())&&(g.page=c),e.extend({filter:[],page:1,item:null},g)},set:function(a){var b=this,d=b.tmpl;if(c.hash(a)){var f=e.extend({filter:[],page:1,item:null},a);d.items.reset();d.raise("before-state",[f]).isDefaultPrevented()||(d.filter&&d.filter.setState(f),d.pages?d.pages.setState(f):(d.items.detach(d.items.all()),d.items.create(d.items.available(),!0)),f.item&&(b.opt.scrollTo&&f.item.scrollTo(),c.empty(a.item)||(a.item=null,b.replace(a))),b.current=f,d.raise("after-state",[f]))}}}),b.template.configure("core",{state:{enabled:!1,scrollTo:!0,pushOrReplace:"replace",mask:"foogallery-gallery-{id}",values:"/",pair:":",array:"+",arraySeparator:",",itemKey:"i",filterKey:"f",pageKey:"p"}}),b.components.register("state",b.State)}(FooGallery.$,FooGallery,FooGallery.utils.is,FooGallery.utils.str,FooGallery.utils.obj),function(a,b,c,d,e,f){b.Items=b.Component.extend({construct:function(a){var b=this;b.ALLOW_CREATE=!0,b.ALLOW_APPEND=!0,b.ALLOW_LOAD=!0,b._super(a),b.maps={},b._fetched=null,b._arr=[],b._available=[];var d=b.tmpl.cls.item.caption;b.tmpl.sel.item.caption.all=c.selectify([d.elem,d.inner,d.title,d.description])},fromHash:function(a){return this.get(a)},toHash:function(a){return a instanceof b.Item?a.id:null},destroy:function(){var b=this,c=b.all(),d=[];c.length>0&&(b.tmpl.raise("destroy-items",[c]),d=a.map(c,function(a){return a.destroy()?a:null}),d.length>0&&b.tmpl.raise("destroyed-items",[d])),b.maps={},b._fetched=null,b._arr=[],b._available=[],b._super()},fetch:function(b){var c=this;if(!b&&d.promise(c._fetched))return c._fetched;var e=c.tmpl,f=e.sel,g=e.opt.items,h=a.Deferred(),i=c.make(e.$el.find(f.item.elem));return d.empty(g)?(i.push.apply(i,c.make(window[e.id+"-items"])),h.resolve(i)):d.array(g)?(i.push.apply(i,c.make(g)),h.resolve(i)):d.string(g)?a.get(g).then(function(a){i.push.apply(i,c.make(a)),h.resolve(i)},function(a,b,c){console.log("FooGallery: GET items error.",g,a,b,c),h.resolve(i)}):h.resolve(i),h.then(function(a){c.setAll(a)}),c._fetched=h.promise()},toJSON:function(a){return(a?this.all():this.available()).map(function(a){return a.toJSON()})},all:function(){return this._arr.slice()},count:function(a){return a?this.all().length:this.available().length},available:function(){return this._available.slice()},get:function(a){var b=d.number(a)?"index":"id";return this.maps[b][a]?this.maps[b][a]:null},setAll:function(a){this._arr=d.array(a)?a:[],this.maps=this.createMaps(this._arr),this._available=this.all()},setAvailable:function(a){this.maps=this.createMaps(this._arr),this._available=d.array(a)?a:[]},reset:function(){this.setAvailable(this.all())},first:function(){return this._available.length>0?this._available[0]:null},last:function(){return this._available.length>0?this._available[this._available.length-1]:null},next:function(a,c){if(!(a instanceof b.Item))return null;c=!!d.boolean(c)&&c;var e=this._available.indexOf(a);if(-1!==e){if(++e>=this._available.length){if(!c)return null;e=0}return this._available[e]}return null},prev:function(a,c){if(!(a instanceof b.Item))return null;c=!!d.boolean(c)&&c;var e=this._available.indexOf(a);if(-1!==e){if(--e<0){if(!c)return null;e=this._available.length-1}return this._available[e]}return null},createMaps:function(b){b=d.array(b)?b:[];var c={id:{},index:{}};return a.each(b,function(a,b){d.empty(b.id)&&(b.id=""+(a+1)),b.index=a,c.id[b.id]=b,c.index[b.index]=b}),c},loadable:function(b){var e,f=this,g=f.tmpl.opt;return g.lazy&&(e=c.getViewportBounds(g.viewport)),f.ALLOW_LOAD&&d.array(b)?a.map(b,function(a){return a.isCreated&&a.isAttached&&!a.isLoading&&!a.isLoaded&&!a.isError&&(!g.lazy||g.lazy&&a.intersects(e))?a:null}):[]},creatable:function(c){return this.ALLOW_CREATE&&d.array(c)?a.map(c,function(a){return a instanceof b.Item&&!a.isCreated?a:null}):[]},appendable:function(c){return this.ALLOW_APPEND&&d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&!a.isAttached?a:null}):[]},detachable:function(c){return d.array(c)?a.map(c,function(a){return a instanceof b.Item&&a.isCreated&&a.isAttached?a:null}):[]},jquerify:function(b){return a(a.map(b,function(a){return a.$el.get()}))},make:function(c){var e=this,g=[];if(d.jq(c)||d.array(c)){var h=[],i=a.makeArray(c);if(0===i.length)return g;e.tmpl.raise("make-items",[i]).isDefaultPrevented()||(g=a.map(i,function(a){var c=e.type(a),g=f.extend(d.hash(a)?a:{},{type:c}),i=b.components.make(c,e.tmpl,g);return d.element(a)?i.parse(a)?(h.push(i),i):null:i})),g.length>0&&e.tmpl.raise("made-items",[g]),h.length>0&&e.tmpl.raise("parsed-items",[h])}return g},type:function(c){var e;if(d.hash(c))e=c.type;else if(d.element(c)){var f=a(c),g=this.tmpl.sel.item;e=f.find(g.anchor).data("type")}return d.string(e)&&b.components.contains(e)?e:"image"},create:function(b,c){var e=this,f=[],g=e.creatable(b);if(g.length>0){e.tmpl.raise("create-items",[g]).isDefaultPrevented()||(f=a.map(g,function(a){return a.create()?a:null})),f.length>0&&e.tmpl.raise("created-items",[f])}return d.boolean(c)&&c?e.append(b):f},append:function(b){var c=this,d=[],e=c.appendable(b);if(e.length>0){c.tmpl.raise("append-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.append()?a:null})),d.length>0&&c.tmpl.raise("appended-items",[d])}return d},detach:function(b){var c=this,d=[],e=c.detachable(b);if(e.length>0){c.tmpl.raise("detach-items",[e]).isDefaultPrevented()||(d=a.map(e,function(a){return a.detach()?a:null})),d.length>0&&c.tmpl.raise("detached-items",[d])}return d},load:function(b){var c=this;if(b=c.loadable(b),b.length>0){if(!c.tmpl.raise("load-items",[b]).isDefaultPrevented()){var d=a.map(b,function(a){return a.load()});return e.when(d).done(function(a){c.tmpl.raise("loaded-items",[a])})}}return e.resolveWith([])}}),b.components.register("items",b.Items)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj),function(a,b,c,d,e,f,g){b.Item=b.Component.extend({construct:function(a,b){var c=this;c._super(a),c.cls=a.cls.item,c.il8n=a.il8n.item,c.sel=a.sel.item,c.opt=f.extend({},a.opt.item,b),c.isAttached=!1,c.isCreated=!1,c.isDestroyed=!1,c.isLoading=!1,c.isLoaded=!1,c.isError=!1,c.isParsed=!1,c.$el=null,c.$inner=null,c.$anchor=null,c.$overlay=null,c.$wrap=null,c.$image=null,c.$caption=null,c.fixLayout=c.tmpl.opt.fixLayout,c.index=-1,c.type=c.opt.type,c.id=c.opt.id,c.productId=c.opt.productId,c.href=c.opt.href,c.src=c.opt.src,c.srcset=c.opt.srcset,c.width=c.opt.width,c.height=c.opt.height,c.title=c.opt.title,c.alt=c.opt.alt,c.caption=d.empty(c.opt.caption)?c.title:c.opt.caption,c.description=d.empty(c.opt.description)?c.alt:c.opt.description,c.attr=c.opt.attr,c.tags=c.opt.tags,c.maxWidth=c.opt.maxWidth,c.maxCaptionLength=c.opt.maxCaptionLength,c.maxDescriptionLength=c.opt.maxDescriptionLength,c.showCaptionTitle=c.opt.showCaptionTitle,c.showCaptionDescription=c.opt.showCaptionDescription,c._thumbUrl=null,c._load=null,c._undo={classes:"",style:"",loader:!1,wrap:!1,overlay:!1,placeholder:!1}},destroy:function(){var a=this;return a.tmpl.raise("destroy-item",[a]).isDefaultPrevented()||(a.isDestroyed=a.doDestroyItem()),a.isDestroyed&&(a.tmpl.raise("destroyed-item",[a]),a._super()),a.isDestroyed},doDestroyItem:function(){var a=this;return a.isParsed?(a.$anchor.add(a.$caption).off("click.foogallery"),a.append(),d.empty(a._undo.classes)?a.$el.removeAttr("class"):a.$el.attr("class",a._undo.classes),d.empty(a._undo.style)?a.$el.removeAttr("style"):a.$el.attr("style",a._undo.style),a._undo.overlay&&a.$overlay.remove(),a._undo.wrap&&(a.$anchor.append(a.$image),a.$wrap.remove()),a._undo.loader&&a.$el.find(a.sel.loader).remove(),a._undo.placeholder&&a.$image.prop("src")===b.EMPTY_IMAGE&&a.$image.removeAttr("src")):a.isCreated&&(a.detach(),a.$el.remove()),!0},parse:function(b){var c=this,d=a(b);return!c.tmpl.raise("parse-item",[c,d]).isDefaultPrevented()&&(c.isCreated=d.is(c.sel.elem))&&(c.isParsed=c.doParseItem(d),c.fixLayout&&c.fix()),c.isParsed&&c.tmpl.raise("parsed-item",[c]),c.isParsed},doParseItem:function(c){var e=this,f=e.tmpl.opt,g=e.cls,h=e.sel;if(e._undo.classes=c.attr("class")||"",e._undo.style=c.attr("style")||"",e.$el=c.data(b.DATA_ITEM,e),e.$inner=e.$el.children(h.inner),e.$anchor=e.$inner.children(h.anchor).on("click.foogallery",{self:e},e.onAnchorClick),e.$image=e.$anchor.find(h.image),e.$caption=e.$inner.children(h.caption.elem).on("click.foogallery",{self:e},e.onCaptionClick),!(e.$el.length&&e.$inner.length&&e.$anchor.length&&e.$image.length))return console.error("FooGallery Error: Invalid HTML markup. Check the item markup for additional elements or malformed HTML in the title or description.",e),e.isError=!0,e.tmpl.raise("error-item",[e]),0!==e.$el.length&&e.$el.remove(),!1;e.isAttached=e.$el.parent().length>0,e.isLoading=e.$el.is(h.loading),e.isLoaded=e.$el.is(h.loaded),e.isError=e.$el.is(h.error);var i=e.$anchor.attr("data-type",e.type).data();e.id=i.id||e.id,e.productId=i.productId||e.productId,e.tags=i.tags||e.tags,e.href=i.href||e.$anchor.attr("href")||e.href,e.src=e.$image.attr(f.src)||e.src,e.srcset=e.$image.attr(f.srcset)||e.srcset,e.width=parseInt(e.$image.attr("width"))||e.width,e.height=parseInt(e.$image.attr("height"))||e.height,e.title=e.$image.attr("title")||e.title,e.alt=e.$image.attr("alt")||e.alt,e.caption=i.title||i.captionTitle||e.caption||e.title,e.description=i.description||i.captionDesc||e.description||e.alt,d.empty(e.caption)&&(e.caption=a.trim(e.$caption.find(h.caption.title).html())),d.empty(e.description)&&(e.description=a.trim(e.$caption.find(h.caption.description).html())),d.number(e.maxCaptionLength)&&e.maxCaptionLength>0&&!d.empty(e.caption)&&d.string(e.caption)&&e.caption.length>e.maxCaptionLength&&e.$caption.find(h.caption.title).html(e.caption.substr(0,e.maxCaptionLength)+"&hellip;"),d.number(e.maxDescriptionLength)&&e.maxDescriptionLength>0&&!d.empty(e.description)&&d.string(e.description)&&e.description.length>e.maxDescriptionLength&&e.$caption.find(h.caption.description).html(e.description.substr(0,e.maxDescriptionLength)+"&hellip;"),e.$overlay=e.$anchor.children(h.overlay),0===e.$overlay.length&&(e.$overlay=a("<span/>",{class:g.overlay}),e.$anchor.append(e.$overlay),e._undo.overlay=!0),e.$wrap=e.$anchor.children(h.wrap),0===e.$wrap.length&&(e.$wrap=a("<span/>",{class:g.wrap}),e.$anchor.append(e.$wrap.append(e.$image)),e._undo.wrap=!0),0===e.$el.children(h.loader).length&&(e.$el.append(a("<div/>",{class:g.loader})),e._undo.loader=!0);var j=e.$image.get(0);return d.empty(j.src)&&(j.src=b.EMPTY_IMAGE,e._undo.placeholder=!0),e.$el.addClass(e.getTypeClass()),!e.isCreated||!e.isAttached||e.isLoading||e.isLoaded||e.isError||e.$el.addClass(g.idle),!0},create:function(){var a=this;if(!a.isCreated&&d.string(a.href)&&d.string(a.src)&&d.number(a.width)&&d.number(a.height)){a.tmpl.raise("create-item",[a]).isDefaultPrevented()||(a.isCreated=a.doCreateItem()),a.isCreated&&a.tmpl.raise("created-item",[a])}return a.isCreated},doCreateItem:function(){var c=this,e=c.tmpl.opt,f=c.cls,g=c.attr,h=c.getTypeClass();g.elem.class=[f.elem,h,f.idle].join(" "),g.inner.class=f.inner,g.anchor.class=f.anchor,g.anchor.href=c.href,g.anchor["data-type"]=c.type,g.anchor["data-id"]=c.id,g.anchor["data-title"]=c.caption,g.anchor["data-description"]=c.description,d.empty(c.tags)||(g.anchor["data-tags"]=JSON.stringify(c.tags)),d.empty(c.productId)||(g.anchor["data-product-id"]=c.productId),g.image.class=f.image,g.image[e.src]=c.src,g.image[e.srcset]=c.srcset,g.image.width=c.width,g.image.height=c.height,g.image.title=c.title,g.image.alt=c.alt,c.$el=a("<div/>").attr(g.elem).data(b.DATA_ITEM,c),c.$inner=a("<figure/>").attr(g.inner).appendTo(c.$el),c.$anchor=a("<a/>").attr(g.anchor).appendTo(c.$inner).on("click.foogallery",{self:c},c.onAnchorClick),c.$overlay=a("<span/>",{class:f.overlay}).appendTo(c.$anchor),c.$wrap=a("<span/>",{class:f.wrap}).appendTo(c.$anchor),c.$image=a("<img/>").attr(g.image).appendTo(c.$wrap),f=c.cls.caption,g=c.attr.caption,g.elem.class=f.elem,c.$caption=a("<figcaption/>").attr(g.elem).on("click.foogallery",{self:c},c.onCaptionClick),g.inner.class=f.inner;var i=a("<div/>").attr(g.inner).appendTo(c.$caption),j=c.showCaptionTitle&&!d.empty(c.caption),k=c.showCaptionDescription&&!d.empty(c.description);if(j||k){if(g.title.class=f.title,g.description.class=f.description,j){var l=a("<div/>").attr(g.title),m=c.caption;d.number(c.maxCaptionLength)&&c.maxCaptionLength>0&&d.string(c.caption)&&c.caption.length>c.maxCaptionLength&&(m=c.caption.substr(0,c.maxCaptionLength)+"&hellip;"),l.get(0).innerHTML=m,i.append(l)}if(k){var n=a("<div/>").attr(g.description),o=c.description;d.number(c.maxDescriptionLength)&&c.maxDescriptionLength>0&&d.string(c.description)&&c.description.length>c.maxDescriptionLength&&(o=c.description.substr(0,c.maxDescriptionLength)+"&hellip;"),n.get(0).innerHTML=o,i.append(n)}}return c.$caption.appendTo(c.$inner),0===c.$el.find(c.sel.loader).length&&c.$el.append(a("<div/>",{class:c.cls.loader})),!0},append:function(){var a=this;if(a.isCreated&&!a.isAttached){a.tmpl.raise("append-item",[a]).isDefaultPrevented()||(a.tmpl.$el.append(a.$el),!a.fixLayout&&a.isParsed||a.fix(),a.isAttached=!0),a.isAttached&&a.tmpl.raise("appended-item",[a])}return a.isAttached},detach:function(){var a=this;if(a.isCreated&&a.isAttached){a.tmpl.raise("detach-item",[a]).isDefaultPrevented()||(a.$el.detach(),!a.fixLayout&&a.isParsed||a.unfix(),a.isAttached=!1),a.isAttached||a.tmpl.raise("detached-item",[a])}return!a.isAttached},load:function(){var b=this;if(d.promise(b._load))return b._load;if(!b.isCreated||!b.isAttached)return e.rejectWith("not created or attached");if(b.tmpl.raise("load-item",[b]).isDefaultPrevented())return e.rejectWith("default prevented");var c=b.cls,f=b.$image.get(0),g=f.src;return b.isLoading=!0,b.$el.removeClass(c.idle).removeClass(c.loaded).removeClass(c.error).addClass(c.loading),b._load=a.Deferred(function(a){f.onload=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isLoaded=!0,b.$el.removeClass(c.loading).addClass(c.loaded),!b.fixLayout&&b.isParsed||b.unfix(),b.tmpl.raise("loaded-item",[b]),a.resolve(b)},f.onerror=function(){f.onload=f.onerror=null,b.isLoading=!1,b.isError=!0,b.$el.removeClass(c.loading).addClass(c.error),d.string(g)&&b.$image.prop("src",g),b.tmpl.raise("error-item",[b]),a.reject(b)},f.src=b.getThumbUrl(),f.complete&&f.onload()}).promise()},fix:function(){var a=this;if(null==a.tmpl)return a;if(a.isCreated&&!a.isLoading&&!a.isLoaded&&!a.isError){var b=a.width,c=a.height,e=a.$image.get(0);if(!isNaN(b)&&!isNaN(c)&&e){var f=d.fn(a.maxWidth)?a.maxWidth(a):a.$image.width();f<=0&&(f=b);var g=f/b,h=c*g;a.$image.css({width:f,height:h})}}return a},unfix:function(){var a=this;return null==a.tmpl?a:(a.isCreated&&a.$image.css({width:"",height:""}),a)},getThumbSrc:function(a,b){return c.src(this.src,this.srcset,this.width,this.height,a,b)},getThumbUrl:function(a){a=!!d.boolean(a)&&a;var b=this;return!a&&d.string(b._thumbUrl)?b._thumbUrl:b._thumbUrl=b.getThumbSrc(b.$anchor.innerWidth(),b.$anchor.innerHeight())},getTypeClass:function(){return this.cls.types.hasOwnProperty(this.type)?this.cls.types[this.type]:""},scrollTo:function(a){var b=this;if(b.isAttached){var d=b.bounds(),e=c.getViewportBounds();switch(a){case"top":d.left+=d.width/2-e.width/2,d.top-=e.height/5;break;default:d.left+=d.width/2-e.width/2,d.top+=d.height/2-e.height/2}window.scrollTo(d.left,d.top)}return b},bounds:function(){return this.isAttached?c.getElementBounds(this.$el):null},intersects:function(a){return!!this.isAttached&&this.bounds().intersects(a)},updateState:function(){this.tmpl.state.update(this.tmpl.state.get(this))},toJSON:function(){return{type:this.type,href:this.href,src:this.src,srcset:this.srcset,width:this.width,height:this.height,alt:this.alt,title:this.title,caption:this.caption,description:this.description,tags:this.tags.slice(),maxCaptionLength:this.maxCaptionLength,maxDescriptionLength:this.maxDescriptionLength,showCaptionTitle:this.showCaptionTitle,showCaptionDescription:this.showCaptionDescription,attr:f.extend({},this.attr)}},onAnchorClick:function(a){var b=a.data.self;b.tmpl.raise("anchor-click-item",[b]).isDefaultPrevented()?a.preventDefault():b.updateState()},onCaptionClick:function(b){var c=b.data.self;!c.tmpl.raise("caption-click-item",[c]).isDefaultPrevented()&&c.$anchor.length>0&&!a(b.target).is("a,:input")&&c.$anchor.get(0).click()}}),b.template.configure("core",{item:{type:"item",id:"",href:"",src:"",srcset:"",width:0,height:0,title:"",alt:"",caption:"",description:"",tags:[],maxWidth:null,maxCaptionLength:0,maxDescriptionLength:0,showCaptionTitle:!0,showCaptionDescription:!0,attr:{elem:{},inner:{},anchor:{},image:{},caption:{elem:{},inner:{},title:{},description:{}}}}},{item:{elem:"fg-item",inner:"fg-item-inner",anchor:"fg-thumb",overlay:"fg-image-overlay",wrap:"fg-image-wrap",image:"fg-image",loader:"fg-loader",idle:"fg-idle",loading:"fg-loading",loaded:"fg-loaded",error:"fg-error",types:{item:"fg-type-unknown"},caption:{elem:"fg-caption",inner:"fg-caption-inner",title:"fg-caption-title",description:"fg-caption-desc"}}},{item:{}}),b.components.register("item",b.Item)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn,FooGallery.utils.obj,FooGallery.utils.str),function(a,b,c,d){b.Image=b.Item.extend({}),b.template.configure("core",null,{item:{types:{image:"fg-type-image"}}}),b.components.register("image",b.Image)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Paging=b.Component.extend({construct:function(a){var b=this;b._super(a),b.opt=b.tmpl.opt.paging,b.cls=b.tmpl.cls.paging,b.il8n=b.tmpl.il8n.paging,b.sel=b.tmpl.sel.paging,b.pushOrReplace=b.opt.pushOrReplace,b.type=b.opt.type,b.theme=b.opt.theme,b.size=b.opt.size,b.position=b.opt.position,b.scrollToTop=b.opt.scrollToTop,b.current=0,b.total=0,b.ctrls=[],b._arr=[]},fromHash:function(a){var b=parseInt(a);return isNaN(b)?null:b},toHash:function(a){return d.number(a)&&a>0?a.toString():null},getState:function(){return this.isValid(this.current)?this.current:null},setState:function(a){this.rebuild(),a.item&&!this.contains(a.page,a.item)&&(a.page=this.find(a.item),a.page=0!==a.page?a.page:1),this.set(a.page,!1,!1,!0)},destroy:function(){var b=this;b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b._super()},build:function(){var a=this,c=a.tmpl.items.available();a.total=a.size>0&&c.length>0?Math.ceil(c.length/a.size):1;for(var d=0;d<a.total;d++)a._arr.push(c.splice(0,a.size));if(a.total>1&&b.paging.hasCtrl(a.type)){var e,f,g=a.position;"both"!==g&&"top"!==g||(e=b.paging.makeCtrl(a.type,a.tmpl,a,"top"),e.create()&&(e.append(),a.ctrls.push(e))),"both"!==g&&"bottom"!==g||(f=b.paging.makeCtrl(a.type,a.tmpl,a,"bottom"),f.create()&&(f.append(),a.ctrls.push(f)))}},rebuild:function(){var b=this;b.current=0,b.total=0,b._arr.splice(0,b._arr.length),a.each(b.ctrls.splice(0,b.ctrls.length),function(a,b){b.destroy()}),b.build()},all:function(){return this._arr.slice()},available:function(){return this.get(this.current)},items:function(){return this.get(this.current)},controls:function(b){var c=this;c.isValid(b)&&a.each(c.ctrls,function(a,c){c.update(b)})},isValid:function(a){return d.number(a)&&a>0&&a<=this.total},number:function(a){return this.isValid(a)?a:0===this.current?1:this.current},create:function(a,b){var c=this;a=c.number(a);var d=a-1;c.tmpl.items.detach(c.tmpl.items.all()),c.current=a,c.tmpl.items.create(c._arr[d],!0)},get:function(a){var b=this;return b.isValid(a)?(a=b.number(a),b._arr[a-1]):[]},set:function(a,b,c,e){var f=this;if(f.isValid(a)){var g,h=f.number(a);if(h!==f.current){var i=f.current,j=function(){if(c=!d.boolean(c)||c,e=!!d.boolean(e)&&e,c&&1===f.current&&!f.tmpl.state.exists()&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.controls(a),f.create(h,e),c&&(g=f.tmpl.state.get(),f.tmpl.state.update(g,f.pushOrReplace)),f.scrollToTop&&d.boolean(b)&&b){var j=f.get(f.current);j.length>0&&j[0].scrollTo("top")}f.tmpl.raise("after-page-change",[f.current,i,e])};return!f.tmpl.raise("before-page-change",[f.current,h,j,e]).isDefaultPrevented()&&(j(),!0)}}return!1},find:function(b){
11
+ for(var c=this,d=0,e=c._arr.length;d<e;d++)if(-1!==a.inArray(b,c._arr[d]))return d+1;return 0},contains:function(b,c){var d=this.get(b);return-1!==a.inArray(c,d)},first:function(){this.goto(1)},last:function(){this.goto(this._arr.length)},prev:function(){this.goto(this.current-1)},next:function(){this.goto(this.current+1)},goto:function(a){var b=this;b.set(a,!0)&&b.tmpl.loadAvailable()}}),b.PagingControl=b.Component.extend({construct:function(a,b,c){var d=this;d._super(a),d.pages=b,d.position=c,d.$container=null},create:function(){var b=this;return b.$container=a("<nav/>",{class:b.pages.cls.container}).addClass(b.pages.theme),!0},destroy:function(){var a=this;a.$container.remove(),a.$container=null},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},update:function(a){}}),b.paging.register("default",b.Paging,null,{type:"none",theme:"fg-light",size:30,pushOrReplace:"push",position:"none",scrollToTop:!0},{container:"fg-paging-container"},null,-100)}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Dots=b.Paging.extend({}),b.DotsControl=b.PagingControl.extend({construct:function(b,c,d){this._super(b,c,d),this.$container=a(),this.$list=a(),this.$items=a()},create:function(){for(var b,c=this,d=c.pages.cls,e=c.pages.il8n,f=[],g=a("<ul/>",{class:d.list}),h=0,i=c.pages.total;h<i;h++)f.push(b=c.createItem(h+1,e.page)),g.append(b);return c.$list=g,c.$container=a("<nav/>",{class:d.container}).addClass(c.pages.theme).append(g),c.$items=a(a.map(f,function(a){return a.get()})),!0},append:function(){var a=this;"top"===a.position?a.$container.insertBefore(a.tmpl.$el):a.$container.insertAfter(a.tmpl.$el)},destroy:function(){var b=this,c=b.pages.sel;b.$list.find(c.link).off("click.foogallery",b.onLinkClick),b.$container.remove(),b.$container=a(),b.$list=a(),b.$items=a()},update:function(a){this.setSelected(a-1)},setSelected:function(b){var c=this,e=c.pages.cls,f=c.pages.il8n,g=c.pages.sel;c.$items.filter(g.selected).removeClass(e.selected).each(function(b,c){var e=a(c),f=e.data("label"),h=e.find(g.reader);d.string(f)&&0!==h.length&&h.html(f)}),c.$items.eq(b).addClass(e.selected).each(function(b,c){var e=a(c),h=e.find(g.reader),i=h.html();d.string(i)&&0!==h.length&&(e.data("label",i),h.html(f.current))})},createItem:function(b,c,e,f,g){e=d.string(e)?e:b,c=d.string(c)?c:"";var h=this,i=h.pages.opt,j=h.pages.cls,k=a("<a/>",{class:j.link,href:"#page-"+b}).html(e).on("click.foogallery",{self:h,page:b},h.onLinkClick);d.empty(c)||k.attr("title",c.replace(/\{PAGE}/g,b).replace(/\{LIMIT}/g,i.limit+"")),g=d.string(g)?g:c,d.empty(g)||k.prepend(a("<span/>",{class:j.reader,text:g.replace(/\{PAGE}/g,"").replace(/\{LIMIT}/g,i.limit+"")}));var l=a("<li/>",{class:j.item}).append(k);return f=d.string(f)?f:"",d.empty(f)||l.addClass(f),l},onLinkClick:function(b){b.preventDefault();var c=b.data.self,d=b.data.page,e=c.pages.sel;a(this).closest(e.item).is(e.disabled)||(c.pages.set(d,!0),c.tmpl.loadAvailable())}}),b.paging.register("dots",b.Dots,b.DotsControl,{type:"dots",position:"both",pushOrReplace:"push"},{list:"fg-dots",item:"fg-dot-item",link:"fg-dot-link",disabled:"fg-disabled",selected:"fg-selected",visible:"fg-visible",reader:"fg-sr-only"},{current:"Current page",page:"Page {PAGE}"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.DefaultTemplate=b.Template.extend({}),b.template.register("default",b.DefaultTemplate,null,{container:"foogallery fg-default"})}(FooGallery.$,FooGallery,FooGallery.utils),function(a,b,c,d){b.MasonryTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.masonry=null,this.style=null,this.$columnWidth=null},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},delayedLayout:function(){var a=this;a._delayedLayout&&clearTimeout(a._delayedLayout),a._delayedLayout=setTimeout(function(){a._delayedLayout=null,a.masonry.layout()},20)},onPreInit:function(b,c){var e=c.sel,f=c.cls;f.layouts=a.map(f.layout,function(a){return a}).join(" ");for(var g=a.map(f.layout,function(a,b){return{key:b,value:a}}),h=0,i=g.length;h<i;h++)if(c.$el.hasClass(g[h].value)){c.template.layout=g[h].key;break}d.string(f.layout[c.template.layout])||(c.template.layout="col4");var j,k,l="fixed"===c.template.layout;if(c.template.isFitWidth=l,c.template.percentPosition=!l,c.template.transitionDuration=0,c.template.itemSelector=e.item.elem,c.$el.removeClass(f.layouts).addClass(f.layout[c.template.layout]),l||(0===c.$el.find(e.gutterWidth).length&&c.$el.prepend(a("<div/>").addClass(f.gutterWidth)),c.template.gutter=e.gutterWidth),0===c.$el.find(e.columnWidth).length&&c.$el.prepend(a("<div/>").addClass(f.columnWidth)),l&&d.number(c.template.columnWidth)){var m=c.$el.find(e.columnWidth).width(c.template.columnWidth);j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { width: "+m.outerWidth()+"px; }",j.insertRule(k,0)}c.template.columnWidth=e.columnWidth,l&&d.number(c.template.gutter)&&(j=c.getStylesheet(),k="#"+c.id+e.container+" "+e.item.elem+" { margin-bottom: "+c.template.gutter+"px; }",j.insertRule(k,0)),c.masonry=new Masonry(c.$el.get(0),c.template)},onPostInit:function(a,b){b.masonry.layout()},onFirstLoad:function(a,b){b.masonry.layout()},onReady:function(a,b){b.delayedLayout()},onDestroy:function(a,b){b._delayedLayout&&clearTimeout(b._delayedLayout),b.$el.find(b.sel.columnWidth).remove(),b.$el.find(b.sel.gutterWidth).remove(),b.style&&b.style.parentNode&&b.style.parentNode.removeChild(b.style)},onDestroyed:function(a,b){b.masonry instanceof Masonry&&b.masonry.destroy()},onLayout:function(a,b){b.masonry.layout()},onParsedItems:function(a,b,c){b.masonry.layout()},onAppendedItems:function(a,b,c){c=b.items.jquerify(c),c=b.masonry.addItems(c),b.masonry.layoutItems(c,!0)},onDetachItem:function(a,b,c){a.isDefaultPrevented()||(a.preventDefault(),b.masonry.remove(c.$el),c.isAttached=!1,c.unfix())},onDetachedItems:function(a,b,c){b.masonry.layout()},onLoadedItems:function(a,b,c){b.masonry.layout()}}),b.template.register("masonry",b.MasonryTemplate,{fixLayout:!0,template:{initLayout:!1,isInitLayout:!1,layout:"col4"}},{container:"foogallery fg-masonry",columnWidth:"fg-column-width",gutterWidth:"fg-gutter-width",layout:{fixed:"fg-masonry-fixed",col2:"fg-masonry-2col",col3:"fg-masonry-3col",col4:"fg-masonry-4col",col5:"fg-masonry-5col"}})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c,d){b.Justified=c.Class.extend({construct:function(c,d){this.tmpl=c,this.$el=c.$el,this.options=a.extend(!0,{},b.Justified.defaults,d),this._items=[],this._lastRefresh=0,this._refresh=null},init:function(){var b=this;d.string(b.options.maxRowHeight)&&(b.options.maxRowHeight.indexOf("%")?b.options.maxRowHeight=b.options.rowHeight*(parseInt(b.options.maxRowHeight)/100):b.options.maxRowHeight=parseInt(b.options.maxRowHeight)),a(window).on("resize.justified",{self:b},b.onWindowResize),this._refresh=setInterval(function(){b.refresh()},b.options.refreshInterval)},destroy:function(){this._refresh&&clearInterval(this._refresh),a(window).off("resize.justified"),this.$el.removeAttr("style")},refresh:function(){var a=this.getContainerWidth();a!=this._lastRefresh&&(this.layout(),this._lastRefresh=a)},parse:function(){var b=this;return b._items=a.map(b.tmpl.getItems(),function(a,b){return{index:b,width:a.width,height:a.height,top:0,left:0,$item:a.$el}})},getMaxRowHeight:function(){var a=this;return d.string(a.options.maxRowHeight)&&(a.options.maxRowHeight.indexOf("%")?a.options.maxRowHeight=a.options.rowHeight*(parseInt(a.options.maxRowHeight)/100):a.options.maxRowHeight=parseInt(a.options.maxRowHeight)),d.number(a.options.maxRowHeight)?a.options.maxRowHeight:a.options.rowHeight},getContainerWidth:function(){var a=this;return a.$el.is(":visible")?a.$el.width():a.$el.parents(":visible:first").innerWidth()},layout:function(b,c){b=!!d.boolean(b)&&b,c=!d.boolean(c)||c,(b||0===this._items.length)&&this.parse();var e=this,f=0,g=e.getContainerWidth(),h=e.getMaxRowHeight(),i=e.rows(g,h);a.each(i,function(a,b){b.visible&&(a>0&&(f+=e.options.margins),f+=b.height),e.render(b)}),e.$el.height(f),c&&e.getContainerWidth()<g&&e.layout(!1,!1)},render:function(a){for(var b,c=0,d=a.items.length;c<d;c++)b=a.items[c],a.visible?b.$item.css({width:b.width,height:b.height,top:b.top,left:b.left,display:"",maxHeight:this.options.maxRowHeight>0?this.options.maxRowHeight:""}).addClass("fg-positioned"):b.$item.css("display","none")},justify:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=g/a.width;a.width=a.width*h,a.height=a.height*h,a.top=b,a.height>d&&(a.height=d),a.left=0,a.width<g&&(a.left=(g-a.width)/2),a.width+=f;for(var i,j=a.left,k=0,l=a.items.length;k<l;k++)k>0&&(j+=e.options.margins),i=a.items[k],i.left=j,i.top=b,i.width=i.width*h,i.height=i.height*h,i.height>d&&(i.height=d),j+=i.width;return a.height},position:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f;if(a.top=b,a.left=0,a.width<g)switch(d){case"center":a.left=(g-a.width)/2;break;case"right":a.left=g-a.width}a.width+=f;for(var h,i=a.left,j=0,k=a.items.length;j<k;j++)j>0&&(i+=e.options.margins),h=a.items[j],h.left=i,h.top=b,i+=h.width;return a.height},lastRow:function(a,b,c,d){var e=this,f=e.options.margins*(a.items.length-1),g=c-f,h=a.width/g>e.options.justifyThreshold;switch(e.options.lastRow){case"hide":h?e.justify(a,b,c,d):a.visible=!1;break;case"justify":e.justify(a,b,c,d);break;case"nojustify":h?e.justify(a,b,c,d):e.position(a,b,c,"left");break;case"left":case"center":case"right":h?e.justify(a,b,c,d):e.position(a,b,c,e.options.lastRow)}},items:function(){return a.map(this._items,function(a){return{index:a.index,width:a.width,height:a.height,$item:a.$item,top:a.top,left:a.left}})},rows:function(a,b){function c(){var a={index:++h,visible:!0,width:0,height:e.options.rowHeight,top:0,left:0,items:[]};return g.push(a),a}for(var d,e=this,f=e.items(),g=[],h=-1,i=c(),j=0,k=0,l=0,m=f.length;l<m;l++){if(d=f[l],d.height!=e.options.rowHeight){var n=e.options.rowHeight/d.height;d.height=d.height*n,d.width=d.width*n}k+d.width>a&&l>0&&(g.length>1&&(j+=e.options.margins),j+=e.justify(i,j,a,b),i=c(),k=0),i.items.length>0&&(k+=e.options.margins),k+=d.width,i.width+=d.width,i.items.push(d)}return g.length>1&&(j+=e.options.margins),e.lastRow(i,j,a,b),g},onWindowResize:function(a){a.data.self.layout(!0)}}),b.Justified.defaults={itemSelector:".fg-item",rowHeight:150,maxRowHeight:"200%",margins:0,lastRow:"center",justifyThreshold:1,refreshInterval:250}}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is),function(a,b,c){b.JustifiedTemplate=b.Template.extend({onPreInit:function(a,c){c.justified=new b.Justified(c,c.template)},onInit:function(a,b){b.justified.init()},onFirstLoad:function(a,b){b.justified.layout(!0)},onReady:function(a,b){b.justified.layout(!0)},onDestroy:function(a,b){b.justified.destroy()},onLayout:function(a,b){b.justified.layout(!0)},onAfterPageChange:function(a,b,c,d,e){e||b.justified.layout(!0)},onAfterFilterChange:function(a,b){b.justified.layout(!0)}}),b.template.register("justified",b.JustifiedTemplate,null,{container:"foogallery fg-justified"})}(FooGallery.$,FooGallery,FooGallery.utils.is),function(a,b,c,d,e){b.PortfolioTemplate=b.Template.extend({construct:function(a,b){this._super(a,b),this.style=null,this.fullWidth=!1},getStylesheet:function(){var a=this;return null===a.style&&(a.style=document.createElement("style"),a.style.appendChild(document.createTextNode("")),document.head.appendChild(a.style)),a.style.sheet},onPreInit:function(a,b){b.appendCSS()},onPostInit:function(b,c){c.checkCSS(),a(window).on("resize"+c.namespace,{self:c},e.debounce(function(){c.checkCSS()},50))},onDestroy:function(b,c){c.removeCSS(),a(window).off("resize"+c.namespace)},checkCSS:function(){var a=this,b=a.getContainerWidth();b<a.template.columnWidth!==a.fullWidth&&a.appendCSS(b)},appendCSS:function(a){var b=this;a=d.number(a)?a:b.getContainerWidth(),b.removeCSS();var c,e=b.getStylesheet(),f="#"+b.id+b.sel.container,g=f+" "+b.sel.item.elem,h=b.template.columnWidth,i=Math.ceil(b.template.gutter/2);switch(b.template.align){case"center":c=f+" { justify-content: center; }",e.insertRule(c,0);break;case"left":c=f+" { justify-content: flex-start; }",e.insertRule(c,0);break;case"right":c=f+" { justify-content: flex-end; }",e.insertRule(c,0)}b.fullWidth=a<h,b.fullWidth?(c=g+" { max-width: 100%; margin: "+i+"px; }",e.insertRule(c,0)):(c=g+" { max-width: "+h+"px; min-width: "+h+"px; margin: "+i+"px; }",e.insertRule(c,0))},removeCSS:function(){var a=this;a.style&&a.style.parentNode&&(a.style.parentNode.removeChild(a.style),a.style=null,a.fullWidth=!1)}}),b.template.register("simple_portfolio",b.PortfolioTemplate,{template:{gutter:40,align:"center",columnWidth:250}},{container:"foogallery fg-simple_portfolio"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.is,FooGallery.utils.fn),function(a,b,c,d){b.ImageViewerTemplate=b.Template.extend({construct:function(b,c){this._super(d.extend({},b,{paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),c),this.$inner=a(),this.$current=a(),this.$total=a(),this.$prev=a(),this.$next=a()},createChildren:function(){var b=this;return a("<div/>",{class:b.cls.inner}).append(a("<div/>",{class:b.cls.innerContainer}),a("<div/>",{class:b.cls.controls}).append(a("<div/>",{class:b.cls.prev}).append(a("<span/>",{text:b.il8n.prev})),a("<label/>",{class:b.cls.count,text:b.il8n.count}).prepend(a("<span/>",{class:b.cls.countCurrent,text:"0"})).append(a("<span/>",{class:b.cls.countTotal,text:"0"})),a("<div/>",{class:b.cls.next}).append(a("<span/>",{text:b.il8n.next}))))},destroyChildren:function(){var a=this;a.$el.find(a.sel.inner).remove()},onPreInit:function(a,b){b.$inner=b.$el.find(b.sel.innerContainer),b.$current=b.$el.find(b.sel.countCurrent),b.$total=b.$el.find(b.sel.countTotal),b.$prev=b.$el.find(b.sel.prev),b.$next=b.$el.find(b.sel.next)},onInit:function(a,b){b.template.attachFooBox&&b.$el.on("foobox.previous",{self:b},b.onFooBoxPrev).on("foobox.next",{self:b},b.onFooBoxNext),b.$prev.on("click",{self:b},b.onPrevClick),b.$next.on("click",{self:b},b.onNextClick)},onFirstLoad:function(a,b){b.update()},onDestroy:function(a,b){b.template.attachFooBox&&b.$el.off({"foobox.previous":b.onFooBoxPrev,"foobox.next":b.onFooBoxNext}),b.$prev.off("click",b.onPrevClick),b.$next.off("click",b.onNextClick)},onAppendItem:function(a,b,c){a.preventDefault(),b.$inner.append(c.$el),c.fix(),c.isAttached=!0},onAfterPageChange:function(a,b,c,d,e){e||b.update()},onAfterFilterChange:function(a,b){b.update()},update:function(){this.pages&&(this.$current.text(this.pages.current),this.$total.text(this.pages.total))},prev:function(){this.pages&&(this.template.loop&&1===this.pages.current?this.pages.last():this.pages.prev(),this.update())},next:function(){this.pages&&(this.template.loop&&this.pages.current===this.pages.total?this.pages.first():this.pages.next(),this.update())},onFooBoxPrev:function(a){a.data.self.prev()},onFooBoxNext:function(a){a.data.self.next()},onPrevClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.prev()},onNextClick:function(a){a.preventDefault(),a.stopPropagation(),a.data.self.next()}}),b.template.register("image-viewer",b.ImageViewerTemplate,{template:{attachFooBox:!1,loop:!1}},{container:"foogallery fg-image-viewer",inner:"fiv-inner",innerContainer:"fiv-inner-container",controls:"fiv-ctrls",prev:"fiv-prev",next:"fiv-next",count:"fiv-count",countCurrent:"fiv-count-current",countTotal:"fiv-count-total"},{prev:"Prev",next:"Next",count:"of"})}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj),function(a,b,c){b.ThumbnailTemplate=b.Template.extend({construct:function(a,b){this._super(c.extend({},a,{filtering:{type:"none"},paging:{pushOrReplace:"replace",theme:"fg-light",type:"default",size:1,position:"none",scrollToTop:!1}}),b)}}),b.template.register("thumbnail",b.ThumbnailTemplate,null,{container:"foogallery fg-thumbnail"})}(FooGallery.$,FooGallery,FooGallery.utils.obj),function(a,b,c,d){b.triggerPostLoad=function(b,c,d,e,f){if("first-load"===b.type||c.initialized&&("after-page-change"===b.type&&!f||"after-filter-change"===b.type))try{if(c.$el.parents(".fbx-item").length>0)return;c.$el.hasClass("fbx-instance")&&window.FOOBOX&&a.fn.foobox?c.$el.foobox(window.FOOBOX.o):a("body").trigger("post-load")}catch(a){console.error(a)}},b.autoDefaults={on:{"first-load.foogallery after-page-change.foogallery after-filter-change.foogallery":b.triggerPostLoad}},b.autoEnabled=!0,b.auto=function(a){b.autoDefaults=d.merge(b.autoDefaults,a)},b.load=b.reload=function(){a(function(){b.autoEnabled&&a('[id^="foogallery-gallery-"]:not(.fg-ready)').foogallery(b.autoDefaults)}),c.ready(function(){b.autoEnabled&&a('[id^="foogallery-gallery-"].fg-ready').foogallery(b.autoDefaults)})},b.load()}(FooGallery.$,FooGallery,FooGallery.utils,FooGallery.utils.obj);
extensions/default-templates/thumbnail/class-thumbnail-gallery-template.php CHANGED
@@ -115,6 +115,18 @@ if ( !class_exists( 'FooGallery_Thumbnail_Gallery_Template' ) ) {
115
  'type' => 'checkbox',
116
  'desc' => __( 'You can link your thumbnails to Custom URL\'s (if they are set on your attachments). Fallback will be to the full size image.', 'foogallery' )
117
  ),
 
 
 
 
 
 
 
 
 
 
 
 
118
  array(
119
  'id' => 'lightbox',
120
  'title' => __( 'Lightbox', 'foogallery' ),
@@ -171,6 +183,9 @@ if ( !class_exists( 'FooGallery_Thumbnail_Gallery_Template' ) ) {
171
  $args['thumbnail_dimensions'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_thumbnail_dimensions'];
172
  $args['caption_title'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_caption_title'];
173
  $args['caption_description'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_caption_description'];
 
 
 
174
  return $args;
175
  }
176
 
115
  'type' => 'checkbox',
116
  'desc' => __( 'You can link your thumbnails to Custom URL\'s (if they are set on your attachments). Fallback will be to the full size image.', 'foogallery' )
117
  ),
118
+ // array(
119
+ // 'id' => 'exclude_featured_image',
120
+ // 'title' => __( 'Exclude Featured Image', 'foogallery' ),
121
+ // 'section' => __( 'General', 'foogallery' ),
122
+ // 'default' => '',
123
+ // 'type' => 'checkbox',
124
+ // 'desc' => __( 'You can exclude the featured image from the images shown in the lightbox.', 'foogallery' ),
125
+ // 'row_data'=> array(
126
+ // 'data-foogallery-change-selector' => 'input',
127
+ // 'data-foogallery-preview' => 'shortcode'
128
+ // )
129
+ // ),
130
  array(
131
  'id' => 'lightbox',
132
  'title' => __( 'Lightbox', 'foogallery' ),
183
  $args['thumbnail_dimensions'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_thumbnail_dimensions'];
184
  $args['caption_title'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_caption_title'];
185
  $args['caption_description'] = $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_caption_description'];
186
+ // if ( isset( $post_data[FOOGALLERY_META_SETTINGS]['thumbnail_exclude_featured_image'] ) ) {
187
+ // $args['exclude_featured_image'] = $post_data[ FOOGALLERY_META_SETTINGS ]['thumbnail_exclude_featured_image'];
188
+ // }
189
  return $args;
190
  }
191
 
foogallery.php CHANGED
@@ -1,71 +1,71 @@
1
- <?php
2
-
3
  /*
4
  Plugin Name: FooGallery
5
  Description: FooGallery is the most intuitive and extensible gallery management tool ever created for WordPress
6
- Version: 1.8.18
7
  Author: FooPlugins
8
  Plugin URI: https://foo.gallery
9
  Author URI: http://fooplugins.com
10
  Text Domain: foogallery
11
  License: GPL-2.0+
12
- Domain Path: /languages
13
- */
14
- // If this file is called directly, abort.
15
- if ( !defined( 'WPINC' ) ) {
16
- die;
17
- }
18
-
19
- if ( function_exists( 'foogallery_fs' ) ) {
20
- foogallery_fs()->set_basename( false, __FILE__ );
21
- } else {
22
-
23
- if ( !class_exists( 'FooGallery_Plugin' ) ) {
24
- define( 'FOOGALLERY_SLUG', 'foogallery' );
25
- define( 'FOOGALLERY_PATH', plugin_dir_path( __FILE__ ) );
26
- define( 'FOOGALLERY_URL', plugin_dir_url( __FILE__ ) );
27
- define( 'FOOGALLERY_FILE', __FILE__ );
28
- define( 'FOOGALLERY_VERSION', '1.8.18' );
29
- define( 'FOOGALLERY_SETTINGS_VERSION', '2' );
30
- require_once FOOGALLERY_PATH . 'includes/constants.php';
31
- // Create a helper function for easy SDK access.
32
- function foogallery_fs()
33
- {
34
- global $foogallery_fs ;
35
-
36
- if ( !isset( $foogallery_fs ) ) {
37
- // Include Freemius SDK.
38
- require_once dirname( __FILE__ ) . '/freemius/start.php';
39
- $foogallery_fs = fs_dynamic_init( array(
40
- 'id' => '843',
41
- 'slug' => 'foogallery',
42
- 'type' => 'plugin',
43
- 'public_key' => 'pk_d87616455a835af1d0658699d0192',
44
- 'is_premium' => false,
45
- 'has_paid_plans' => true,
46
- 'trial' => array(
47
- 'days' => 7,
48
- 'is_require_payment' => false,
49
- ),
50
- 'menu' => array(
51
- 'slug' => 'edit.php?post_type=' . FOOGALLERY_CPT_GALLERY,
52
- 'first-path' => 'edit.php?post_type=' . FOOGALLERY_CPT_GALLERY . '&page=' . FOOGALLERY_ADMIN_MENU_HELP_SLUG,
53
- 'account' => true,
54
- 'contact' => false,
55
- 'support' => false,
56
- ),
57
- 'is_live' => true,
58
- ) );
59
- }
60
-
61
- return $foogallery_fs;
62
- }
63
-
64
- // Init Freemius.
65
- foogallery_fs();
66
- // Signal that SDK was initiated.
67
- do_action( 'foogallery_fs_loaded' );
68
- require_once FOOGALLERY_PATH . 'includes/foopluginbase/bootstrapper.php';
69
  /**
70
  * FooGallery_Plugin class
71
  *
@@ -74,211 +74,211 @@ if ( function_exists( 'foogallery_fs' ) ) {
74
  * @license GPL-2.0+
75
  * @link https://github.com/fooplugins/foogallery
76
  * @copyright 2013 FooPlugins LLC
77
- */
78
- class FooGallery_Plugin extends Foo_Plugin_Base_v2_4
79
- {
80
- private static $instance ;
81
- public static function get_instance()
82
- {
83
- if ( !isset( self::$instance ) && !self::$instance instanceof FooGallery_Plugin ) {
84
- self::$instance = new FooGallery_Plugin();
85
- }
86
- return self::$instance;
87
- }
88
-
89
  /**
90
  * Initialize the plugin by setting localization, filters, and administration functions.
91
- */
92
- private function __construct()
93
- {
94
- //include everything we need!
95
- require_once FOOGALLERY_PATH . 'includes/includes.php';
96
- register_activation_hook( __FILE__, array( 'FooGallery_Plugin', 'activate' ) );
97
- //init FooPluginBase
98
- $this->init(
99
- FOOGALLERY_FILE,
100
- FOOGALLERY_SLUG,
101
- FOOGALLERY_VERSION,
102
- 'FooGallery'
103
- );
104
- //setup text domain
105
- $this->load_plugin_textdomain();
106
- //setup gallery post type
107
- new FooGallery_PostTypes();
108
- //load any extensions
109
- new FooGallery_Extensions_Loader();
110
-
111
- if ( is_admin() ) {
112
- new FooGallery_Admin();
113
- add_action( 'wpmu_new_blog', array( $this, 'set_default_extensions_for_multisite_network_activated' ) );
114
- add_action( 'admin_page_access_denied', array( $this, 'check_for_access_denied' ) );
115
- foogallery_fs()->add_filter(
116
- 'connect_message_on_update',
117
- array( $this, 'override_connect_message_on_update' ),
118
- 10,
119
- 6
120
- );
121
- foogallery_fs()->add_filter(
122
- 'is_submenu_visible',
123
- array( $this, 'is_submenu_visible' ),
124
- 10,
125
- 2
126
- );
127
- foogallery_fs()->add_filter(
128
- 'plugin_icon',
129
- array( $this, 'freemius_plugin_icon' ),
130
- 10,
131
- 1
132
- );
133
- add_action( 'foogallery_admin_menu_before', array( $this, 'add_freemius_activation_menu' ) );
134
- } else {
135
- new FooGallery_Public();
136
- }
137
-
138
- new FooGallery_Shortcodes();
139
- new FooGallery_Thumbnails();
140
- new FooGallery_Attachment_Filters();
141
- new FooGallery_Retina();
142
- new FooGallery_WPThumb_Enhancements();
143
- new FooGallery_Animated_Gif_Support();
144
- new FooGallery_Cache();
145
- new FooGallery_Common_Fields();
146
- new FooGallery_LazyLoad();
147
- new FooGallery_Paging();
148
- new FooGallery_Thumbnail_Dimensions();
149
- new FooGallery_Attachment_Custom_Class();
150
- new FooGallery_Upgrade();
151
- new FooGallery_Compatibility();
152
- new FooGallery_Extensions_Compatibility();
153
- new FooGallery_Default_Crop_Position();
154
- new FooGallery_ForceHttps();
155
- $checker = new FooGallery_Version_Check();
156
- $checker->wire_up_checker();
157
- new FooGallery_Widget_Init();
158
- //include the default templates no matter what!
159
- new FooGallery_Default_Templates();
160
- //init the default media library datasource
161
- new FooGallery_Datasource_MediaLibrary();
162
- add_filter( 'foogallery_extensions_for_view', array( $this, 'add_foogallery_pro_extension' ) );
163
- //init Gutenberg!
164
- new FooGallery_Gutenberg();
165
- //init advanced settings
166
- new FooGallery_Advanced_Gallery_Settings();
167
- }
168
-
169
- function add_foogallery_pro_extension( $extensions )
170
- {
171
- $extension = array(
172
- 'slug' => 'foogallery-pro',
173
- 'class' => 'FooGallery_Pro',
174
- 'categories' => array( 'Featured', 'Premium' ),
175
- 'title' => 'FooGallery Pro',
176
- 'description' => 'The best gallery plugin for WordPress just got even better!',
177
- 'price' => '$49',
178
- 'author' => 'FooPlugins',
179
- 'author_url' => 'http://fooplugins.com',
180
- 'thumbnail' => 'https://s3.amazonaws.com/foogallery/extensions/foogallerypro.png',
181
- 'tags' => array( 'premium' ),
182
- 'source' => 'fooplugins',
183
- "download_button" => array(
184
- "text" => "Start FREE Trial",
185
- "target" => "_self",
186
- "href" => foogallery_fs()->checkout_url( WP_FS__PERIOD_ANNUALLY, true ),
187
- "confirm" => false,
188
- ),
189
- );
190
- array_unshift( $extensions, $extension );
191
- return $extensions;
192
- }
193
-
194
  /**
195
  * Checks for the access denied page after we have activated/updated the plugin
196
- */
197
- function check_for_access_denied()
198
- {
199
- global $plugin_page ;
200
- if ( FOOGALLERY_ADMIN_MENU_HELP_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_SETTINGS_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_EXTENSIONS_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_SYSTEMINFO_SLUG === $plugin_page ) {
201
- //fs_redirect( 'admin.php?page=' . FOOGALLERY_SLUG );
202
- }
203
- }
204
-
205
  /**
206
  *
207
- */
208
- function override_connect_message_on_update(
209
- $original,
210
- $first_name,
211
- $plugin_name,
212
- $login,
213
- $link,
214
- $freemius_link
215
- )
216
- {
217
- return sprintf( __( 'Hey %s', 'foogallery' ), $first_name ) . '<br>' . sprintf(
218
- __( '<h2>Thank you for updating to %1$s v%5$s!</h2>Our goal with this update is to make %1$s the best gallery plugin for WordPress, but we need your help!<br><br>We have introduced this opt-in so that you can help us improve %1$s by simply clicking <strong>Allow &amp; Continue</strong>.<br><br>If you opt-in, some data about your usage of %1$s will be sent to %4$s. If you skip this, that\'s okay! %1$s will still work just fine.', 'foogallery' ),
219
- '<b>' . $plugin_name . '</b>',
220
- '<b>' . $login . '</b>',
221
- $link,
222
- $freemius_link,
223
- FOOGALLERY_VERSION
224
- );
225
- }
226
-
227
- function add_freemius_activation_menu()
228
- {
229
- global $foogallery_fs ;
230
- $parent_slug = foogallery_admin_menu_parent_slug();
231
- if ( !$foogallery_fs->is_registered() ) {
232
- add_submenu_page(
233
- $parent_slug,
234
- __( 'FooGallery Opt-In', 'foogallery' ),
235
- __( 'Activation', 'foogallery' ),
236
- 'manage_options',
237
- 'foogallery-optin',
238
- array( $foogallery_fs, '_connect_page_render' )
239
- );
240
- }
241
- }
242
-
243
- function is_submenu_visible( $visible, $id )
244
- {
245
- if ( 'addons' === $id ) {
246
- //hide addons submenu for now
247
- $visible = false;
248
- }
249
- return $visible;
250
- }
251
-
252
  /**
253
  * Set Freemius plugin icon.
254
  *
255
  * @return string
256
- */
257
- public function freemius_plugin_icon( $icon )
258
- {
259
- return FOOGALLERY_PATH . 'assets/foogallery.png';
260
- }
261
-
262
  /**
263
  * Set default extensions when a new site is created in multisite and FooGallery is network activated
264
  *
265
  * @since 1.2.5
266
  *
267
  * @param int $blog_id The ID of the newly created site
268
- */
269
- public function set_default_extensions_for_multisite_network_activated( $blog_id )
270
- {
271
- switch_to_blog( $blog_id );
272
-
273
- if ( false === get_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, false ) ) {
274
- $api = new FooGallery_Extensions_API();
275
- $api->auto_activate_extensions();
276
- update_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, true );
277
- }
278
-
279
- restore_current_blog();
280
- }
281
-
282
  /**
283
  * Fired when the plugin is activated.
284
  *
@@ -288,56 +288,56 @@ if ( function_exists( 'foogallery_fs' ) ) {
288
  * "Network Activate" action, false if
289
  * WPMU is disabled or plugin is
290
  * activated on an individual blog.
291
- */
292
- public static function activate( $network_wide )
293
- {
294
-
295
- if ( function_exists( 'is_multisite' ) && is_multisite() ) {
296
-
297
- if ( $network_wide ) {
298
- // Get all blog ids
299
- $blog_ids = self::get_blog_ids();
300
-
301
- if ( is_array( $blog_ids ) ) {
302
- foreach ( $blog_ids as $blog_id ) {
303
- switch_to_blog( $blog_id );
304
- self::single_activate();
305
- }
306
- restore_current_blog();
307
- }
308
-
309
- } else {
310
- self::single_activate();
311
- }
312
-
313
- } else {
314
- self::single_activate( false );
315
- }
316
-
317
- }
318
-
319
  /**
320
  * Fired for each blog when the plugin is activated.
321
  *
322
  * @since 1.0.0
323
- */
324
- private static function single_activate( $multisite = true )
325
- {
326
-
327
- if ( false === get_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, false ) ) {
328
- $api = new FooGallery_Extensions_API();
329
- $api->auto_activate_extensions();
330
- update_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, true );
331
- }
332
-
333
- if ( false === $multisite ) {
334
- //Make sure we redirect to the welcome page
335
- set_transient( FOOGALLERY_ACTIVATION_REDIRECT_TRANSIENT_KEY, true, 30 );
336
- }
337
- //force a version check on activation to make sure housekeeping is performed
338
- foogallery_perform_version_check();
339
- }
340
-
341
  /**
342
  * Get all blog ids of blogs in the current network that are:
343
  * - not archived
@@ -347,29 +347,29 @@ if ( function_exists( 'foogallery_fs' ) ) {
347
  * @since 1.0.0
348
  *
349
  * @return array|false The blog ids, false if no matches.
350
- */
351
- private static function get_blog_ids()
352
- {
353
-
354
- if ( function_exists( 'get_sites' ) ) {
355
- $sites = get_sites();
356
- $blog_ids = array();
357
- foreach ( $sites as $site ) {
358
- $blog_ids[] = $site->blog_id;
359
- }
360
- return $blog_ids;
361
- } else {
362
- //pre WP 3.7 - do this the old way!
363
- global $wpdb ;
364
- // get an array of blog ids
365
- $sql = "SELECT blog_id FROM {$wpdb->blogs} WHERE archived = '0' AND spam = '0' AND deleted = '0'";
366
- return $wpdb->get_col( $sql );
367
- }
368
-
369
- }
370
-
371
- }
372
- }
373
-
374
- FooGallery_Plugin::get_instance();
375
- }
1
+ <?php
2
+
3
  /*
4
  Plugin Name: FooGallery
5
  Description: FooGallery is the most intuitive and extensible gallery management tool ever created for WordPress
6
+ Version: 1.9.8
7
  Author: FooPlugins
8
  Plugin URI: https://foo.gallery
9
  Author URI: http://fooplugins.com
10
  Text Domain: foogallery
11
  License: GPL-2.0+
12
+ Domain Path: /languages
13
+ */
14
+ // If this file is called directly, abort.
15
+ if ( !defined( 'WPINC' ) ) {
16
+ die;
17
+ }
18
+
19
+ if ( function_exists( 'foogallery_fs' ) ) {
20
+ foogallery_fs()->set_basename( false, __FILE__ );
21
+ } else {
22
+
23
+ if ( !class_exists( 'FooGallery_Plugin' ) ) {
24
+ define( 'FOOGALLERY_SLUG', 'foogallery' );
25
+ define( 'FOOGALLERY_PATH', plugin_dir_path( __FILE__ ) );
26
+ define( 'FOOGALLERY_URL', plugin_dir_url( __FILE__ ) );
27
+ define( 'FOOGALLERY_FILE', __FILE__ );
28
+ define( 'FOOGALLERY_VERSION', '1.9.8' );
29
+ define( 'FOOGALLERY_SETTINGS_VERSION', '2' );
30
+ require_once FOOGALLERY_PATH . 'includes/constants.php';
31
+ // Create a helper function for easy SDK access.
32
+ function foogallery_fs()
33
+ {
34
+ global $foogallery_fs ;
35
+
36
+ if ( !isset( $foogallery_fs ) ) {
37
+ // Include Freemius SDK.
38
+ require_once dirname( __FILE__ ) . '/freemius/start.php';
39
+ $foogallery_fs = fs_dynamic_init( array(
40
+ 'id' => '843',
41
+ 'slug' => 'foogallery',
42
+ 'type' => 'plugin',
43
+ 'public_key' => 'pk_d87616455a835af1d0658699d0192',
44
+ 'is_premium' => false,
45
+ 'has_paid_plans' => true,
46
+ 'trial' => array(
47
+ 'days' => 7,
48
+ 'is_require_payment' => false,
49
+ ),
50
+ 'menu' => array(
51
+ 'slug' => 'edit.php?post_type=' . FOOGALLERY_CPT_GALLERY,
52
+ 'first-path' => 'edit.php?post_type=' . FOOGALLERY_CPT_GALLERY . '&page=' . FOOGALLERY_ADMIN_MENU_HELP_SLUG,
53
+ 'account' => true,
54
+ 'contact' => false,
55
+ 'support' => false,
56
+ ),
57
+ 'is_live' => true,
58
+ ) );
59
+ }
60
+
61
+ return $foogallery_fs;
62
+ }
63
+
64
+ // Init Freemius.
65
+ foogallery_fs();
66
+ // Signal that SDK was initiated.
67
+ do_action( 'foogallery_fs_loaded' );
68
+ require_once FOOGALLERY_PATH . 'includes/foopluginbase/bootstrapper.php';
69
  /**
70
  * FooGallery_Plugin class
71
  *
74
  * @license GPL-2.0+
75
  * @link https://github.com/fooplugins/foogallery
76
  * @copyright 2013 FooPlugins LLC
77
+ */
78
+ class FooGallery_Plugin extends Foo_Plugin_Base_v2_4
79
+ {
80
+ private static $instance ;
81
+ public static function get_instance()
82
+ {
83
+ if ( !isset( self::$instance ) && !self::$instance instanceof FooGallery_Plugin ) {
84
+ self::$instance = new FooGallery_Plugin();
85
+ }
86
+ return self::$instance;
87
+ }
88
+
89
  /**
90
  * Initialize the plugin by setting localization, filters, and administration functions.
91
+ */
92
+ private function __construct()
93
+ {
94
+ //include everything we need!
95
+ require_once FOOGALLERY_PATH . 'includes/includes.php';
96
+ register_activation_hook( __FILE__, array( 'FooGallery_Plugin', 'activate' ) );
97
+ //init FooPluginBase
98
+ $this->init(
99
+ FOOGALLERY_FILE,
100
+ FOOGALLERY_SLUG,
101
+ FOOGALLERY_VERSION,
102
+ 'FooGallery'
103
+ );
104
+ //setup text domain
105
+ $this->load_plugin_textdomain();
106
+ //setup gallery post type
107
+ new FooGallery_PostTypes();
108
+ //load any extensions
109
+ new FooGallery_Extensions_Loader();
110
+
111
+ if ( is_admin() ) {
112
+ new FooGallery_Admin();
113
+ add_action( 'wpmu_new_blog', array( $this, 'set_default_extensions_for_multisite_network_activated' ) );
114
+ add_action( 'admin_page_access_denied', array( $this, 'check_for_access_denied' ) );
115
+ foogallery_fs()->add_filter(
116
+ 'connect_message_on_update',
117
+ array( $this, 'override_connect_message_on_update' ),
118
+ 10,
119
+ 6
120
+ );
121
+ foogallery_fs()->add_filter(
122
+ 'is_submenu_visible',
123
+ array( $this, 'is_submenu_visible' ),
124
+ 10,
125
+ 2
126
+ );
127
+ foogallery_fs()->add_filter(
128
+ 'plugin_icon',
129
+ array( $this, 'freemius_plugin_icon' ),
130
+ 10,
131
+ 1
132
+ );
133
+ add_action( 'foogallery_admin_menu_before', array( $this, 'add_freemius_activation_menu' ) );
134
+ } else {
135
+ new FooGallery_Public();
136
+ }
137
+
138
+ new FooGallery_Shortcodes();
139
+ new FooGallery_Thumbnails();
140
+ new FooGallery_Attachment_Filters();
141
+ new FooGallery_Retina();
142
+ new FooGallery_WPThumb_Enhancements();
143
+ new FooGallery_Animated_Gif_Support();
144
+ new FooGallery_Cache();
145
+ new FooGallery_Common_Fields();
146
+ new FooGallery_LazyLoad();
147
+ new FooGallery_Paging();
148
+ new FooGallery_Thumbnail_Dimensions();
149
+ new FooGallery_Attachment_Custom_Class();
150
+ new FooGallery_Upgrade();
151
+ new FooGallery_Compatibility();
152
+ new FooGallery_Extensions_Compatibility();
153
+ new FooGallery_Default_Crop_Position();
154
+ new FooGallery_ForceHttps();
155
+ $checker = new FooGallery_Version_Check();
156
+ $checker->wire_up_checker();
157
+ new FooGallery_Widget_Init();
158
+ //include the default templates no matter what!
159
+ new FooGallery_Default_Templates();
160
+ //init the default media library datasource
161
+ new FooGallery_Datasource_MediaLibrary();
162
+ add_filter( 'foogallery_extensions_for_view', array( $this, 'add_foogallery_pro_extension' ) );
163
+ //init Gutenberg!
164
+ new FooGallery_Gutenberg();
165
+ //init advanced settings
166
+ new FooGallery_Advanced_Gallery_Settings();
167
+ }
168
+
169
+ function add_foogallery_pro_extension( $extensions )
170
+ {
171
+ $extension = array(
172
+ 'slug' => 'foogallery-pro',
173
+ 'class' => 'FooGallery_Pro',
174
+ 'categories' => array( 'Featured', 'Premium' ),
175
+ 'title' => 'FooGallery Pro',
176
+ 'description' => 'The best gallery plugin for WordPress just got even better!',
177
+ 'price' => '$49',
178
+ 'author' => 'FooPlugins',
179
+ 'author_url' => 'http://fooplugins.com',
180
+ 'thumbnail' => 'https://s3.amazonaws.com/foogallery/extensions/foogallerypro.png',
181
+ 'tags' => array( 'premium' ),
182
+ 'source' => 'fooplugins',
183
+ "download_button" => array(
184
+ "text" => "Start FREE Trial",
185
+ "target" => "_self",
186
+ "href" => foogallery_fs()->checkout_url( WP_FS__PERIOD_ANNUALLY, true ),
187
+ "confirm" => false,
188
+ ),
189
+ );
190
+ array_unshift( $extensions, $extension );
191
+ return $extensions;
192
+ }
193
+
194
  /**
195
  * Checks for the access denied page after we have activated/updated the plugin
196
+ */
197
+ function check_for_access_denied()
198
+ {
199
+ global $plugin_page ;
200
+ if ( FOOGALLERY_ADMIN_MENU_HELP_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_SETTINGS_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_EXTENSIONS_SLUG === $plugin_page || FOOGALLERY_ADMIN_MENU_SYSTEMINFO_SLUG === $plugin_page ) {
201
+ //fs_redirect( 'admin.php?page=' . FOOGALLERY_SLUG );
202
+ }
203
+ }
204
+
205
  /**
206
  *
207
+ */
208
+ function override_connect_message_on_update(
209
+ $original,
210
+ $first_name,
211
+ $plugin_name,
212
+ $login,
213
+ $link,
214
+ $freemius_link
215
+ )
216
+ {
217
+ return sprintf( __( 'Hey %s', 'foogallery' ), $first_name ) . '<br>' . sprintf(
218
+ __( '<h2>Thank you for updating to %1$s v%5$s!</h2>Our goal with this update is to make %1$s the best gallery plugin for WordPress, but we need your help!<br><br>We have introduced this opt-in so that you can help us improve %1$s by simply clicking <strong>Allow &amp; Continue</strong>.<br><br>If you opt-in, some data about your usage of %1$s will be sent to %4$s. If you skip this, that\'s okay! %1$s will still work just fine.', 'foogallery' ),
219
+ '<b>' . $plugin_name . '</b>',
220
+ '<b>' . $login . '</b>',
221
+ $link,
222
+ $freemius_link,
223
+ FOOGALLERY_VERSION
224
+ );
225
+ }
226
+
227
+ function add_freemius_activation_menu()
228
+ {
229
+ global $foogallery_fs ;
230
+ $parent_slug = foogallery_admin_menu_parent_slug();
231
+ if ( !$foogallery_fs->is_registered() ) {
232
+ add_submenu_page(
233
+ $parent_slug,
234
+ __( 'FooGallery Opt-In', 'foogallery' ),
235
+ __( 'Activation', 'foogallery' ),
236
+ 'manage_options',
237
+ 'foogallery-optin',
238
+ array( $foogallery_fs, '_connect_page_render' )
239
+ );
240
+ }
241
+ }
242
+
243
+ function is_submenu_visible( $visible, $id )
244
+ {
245
+ if ( 'addons' === $id ) {
246
+ //hide addons submenu for now
247
+ $visible = false;
248
+ }
249
+ return $visible;
250
+ }
251
+
252
  /**
253
  * Set Freemius plugin icon.
254
  *
255
  * @return string
256
+ */
257
+ public function freemius_plugin_icon( $icon )
258
+ {
259
+ return FOOGALLERY_PATH . 'assets/foogallery.png';
260
+ }
261
+
262
  /**
263
  * Set default extensions when a new site is created in multisite and FooGallery is network activated
264
  *
265
  * @since 1.2.5
266
  *
267
  * @param int $blog_id The ID of the newly created site
268
+ */
269
+ public function set_default_extensions_for_multisite_network_activated( $blog_id )
270
+ {
271
+ switch_to_blog( $blog_id );
272
+
273
+ if ( false === get_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, false ) ) {
274
+ $api = new FooGallery_Extensions_API();
275
+ $api->auto_activate_extensions();
276
+ update_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, true );
277
+ }
278
+
279
+ restore_current_blog();
280
+ }
281
+
282
  /**
283
  * Fired when the plugin is activated.
284
  *
288
  * "Network Activate" action, false if
289
  * WPMU is disabled or plugin is
290
  * activated on an individual blog.
291
+ */
292
+ public static function activate( $network_wide )
293
+ {
294
+
295
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
296
+
297
+ if ( $network_wide ) {
298
+ // Get all blog ids
299
+ $blog_ids = self::get_blog_ids();
300
+
301
+ if ( is_array( $blog_ids ) ) {
302
+ foreach ( $blog_ids as $blog_id ) {
303
+ switch_to_blog( $blog_id );
304
+ self::single_activate();
305
+ }
306
+ restore_current_blog();
307
+ }
308
+
309
+ } else {
310
+ self::single_activate();
311
+ }
312
+
313
+ } else {
314
+ self::single_activate( false );
315
+ }
316
+
317
+ }
318
+
319
  /**
320
  * Fired for each blog when the plugin is activated.
321
  *
322
  * @since 1.0.0
323
+ */
324
+ private static function single_activate( $multisite = true )
325
+ {
326
+
327
+ if ( false === get_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, false ) ) {
328
+ $api = new FooGallery_Extensions_API();
329
+ $api->auto_activate_extensions();
330
+ update_option( FOOGALLERY_EXTENSIONS_AUTO_ACTIVATED_OPTIONS_KEY, true );
331
+ }
332
+
333
+ if ( false === $multisite ) {
334
+ //Make sure we redirect to the welcome page
335
+ set_transient( FOOGALLERY_ACTIVATION_REDIRECT_TRANSIENT_KEY, true, 30 );
336
+ }
337
+ //force a version check on activation to make sure housekeeping is performed
338
+ foogallery_perform_version_check();
339
+ }
340
+
341
  /**
342
  * Get all blog ids of blogs in the current network that are:
343
  * - not archived
347
  * @since 1.0.0
348
  *
349
  * @return array|false The blog ids, false if no matches.
350
+ */
351
+ private static function get_blog_ids()
352
+ {
353
+
354
+ if ( function_exists( 'get_sites' ) ) {
355
+ $sites = get_sites();
356
+ $blog_ids = array();
357
+ foreach ( $sites as $site ) {
358
+ $blog_ids[] = $site->blog_id;
359
+ }
360
+ return $blog_ids;
361
+ } else {
362
+ //pre WP 3.7 - do this the old way!
363
+ global $wpdb ;
364
+ // get an array of blog ids
365
+ $sql = "SELECT blog_id FROM {$wpdb->blogs} WHERE archived = '0' AND spam = '0' AND deleted = '0'";
366
+ return $wpdb->get_col( $sql );
367
+ }
368
+
369
+ }
370
+
371
+ }
372
+ }
373
+
374
+ FooGallery_Plugin::get_instance();
375
+ }
gutenberg/class-foogallery-blocks.php CHANGED
@@ -133,6 +133,9 @@ if ( ! class_exists( 'FooGallery_Blocks' ) ) {
133
  'type' => 'number',
134
  'default' => 0
135
  ),
 
 
 
136
  ),
137
  'render_callback' => array( $this, 'render_block' ),
138
  ));
@@ -146,16 +149,12 @@ if ( ! class_exists( 'FooGallery_Blocks' ) ) {
146
  * @return false|string|null
147
  */
148
  function render_block( $attributes ) {
149
- $foogallery_id = $attributes['id'];
150
- $args = array(
151
- 'id' => $foogallery_id
152
- );
153
  //create new instance of template engine
154
  $engine = new FooGallery_Template_Loader();
155
 
156
  ob_start();
157
 
158
- $engine->render_template( $args );
159
 
160
  $output_string = ob_get_contents();
161
  ob_end_clean();
133
  'type' => 'number',
134
  'default' => 0
135
  ),
136
+ 'className' => array(
137
+ 'type' => 'string'
138
+ ),
139
  ),
140
  'render_callback' => array( $this, 'render_block' ),
141
  ));
149
  * @return false|string|null
150
  */
151
  function render_block( $attributes ) {
 
 
 
 
152
  //create new instance of template engine
153
  $engine = new FooGallery_Template_Loader();
154
 
155
  ob_start();
156
 
157
+ $engine->render_template( $attributes );
158
 
159
  $output_string = ob_get_contents();
160
  ob_end_clean();
gutenberg/dist/blocks.build.js CHANGED
@@ -119,7 +119,7 @@ eval("Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true }
119
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
120
 
121
  "use strict";
122
- eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_scss__ = __webpack_require__(/*! ./style.scss */ 5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_scss___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__style_scss__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__editor_scss__ = __webpack_require__(/*! ./editor.scss */ 6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__editor_scss___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__editor_scss__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__edit__ = __webpack_require__(/*! ./edit */ 7);\n/**\r\n * BLOCK: fooplugins/foogallery\r\n *\r\n * Registering a basic FooGallery block with Gutenberg.\r\n */\n\n\n\n\n\nvar __ = wp.i18n.__; // Import __() from wp.i18n\n\nvar registerBlockType = wp.blocks.registerBlockType; // Import registerBlockType() from wp.blocks\n\n/**\r\n * Register: aa Gutenberg Block.\r\n *\r\n * Registers a new block provided a unique name and an object defining its\r\n * behavior. Once registered, the block is made editor as an option to any\r\n * editor interface where blocks are implemented.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/\r\n * @param {string} name Block name.\r\n * @param {Object} settings Block settings.\r\n * @return {?WPBlock} The block, if it has been successfully\r\n * registered; otherwise `undefined`.\r\n */\n\nregisterBlockType('fooplugins/foogallery', {\n\t// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.\n\ttitle: __('FooGallery'), // Block title.\n\tdescription: __('Insert a FooGallery into your content'),\n\ticon: 'format-gallery', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.\n\tcategory: 'common', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.\n\tkeywords: [__('foogallery'), __('gallery')],\n\tsupports: {\n\t\tmultiple: true,\n\t\thtml: false\n\t},\n\tattributes: {\n\t\tid: {\n\t\t\ttype: 'number',\n\t\t\tdefault: 0\n\t\t}\n\t},\n\t/**\r\n * The edit function describes the structure of your block in the context of the editor.\r\n * This represents what the editor will render when the block is used.\r\n *\r\n * The \"edit\" property must be a valid function.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/\r\n */\n\tedit: function edit(props) {\n\t\treturn wp.element.createElement(__WEBPACK_IMPORTED_MODULE_2__edit__[\"a\" /* default */], props);\n\t},\n\n\n\t/**\r\n * The save function defines the way in which the different attributes should be combined\r\n * into the final markup, which is then serialized by Gutenberg into post_content.\r\n *\r\n * The \"save\" property must be specified and must be a valid function.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/\r\n */\n\tsave: function save() {\n\t\t// Rendering in PHP\n\t\treturn null;\n\t}\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2d1dGVuYmVyZy9zcmMvYmxvY2svaW5kZXguanM/NTc2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQkxPQ0s6IGZvb3BsdWdpbnMvZm9vZ2FsbGVyeVxyXG4gKlxyXG4gKiBSZWdpc3RlcmluZyBhIGJhc2ljIEZvb0dhbGxlcnkgYmxvY2sgd2l0aCBHdXRlbmJlcmcuXHJcbiAqL1xuXG5pbXBvcnQgJy4vc3R5bGUuc2Nzcyc7XG5pbXBvcnQgJy4vZWRpdG9yLnNjc3MnO1xuaW1wb3J0IEZvb0dhbGxlcnlFZGl0IGZyb20gJy4vZWRpdCc7XG5cbnZhciBfXyA9IHdwLmkxOG4uX187IC8vIEltcG9ydCBfXygpIGZyb20gd3AuaTE4blxuXG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7IC8vIEltcG9ydCByZWdpc3RlckJsb2NrVHlwZSgpIGZyb20gd3AuYmxvY2tzXG5cbi8qKlxyXG4gKiBSZWdpc3RlcjogYWEgR3V0ZW5iZXJnIEJsb2NrLlxyXG4gKlxyXG4gKiBSZWdpc3RlcnMgYSBuZXcgYmxvY2sgcHJvdmlkZWQgYSB1bmlxdWUgbmFtZSBhbmQgYW4gb2JqZWN0IGRlZmluaW5nIGl0c1xyXG4gKiBiZWhhdmlvci4gT25jZSByZWdpc3RlcmVkLCB0aGUgYmxvY2sgaXMgbWFkZSBlZGl0b3IgYXMgYW4gb3B0aW9uIHRvIGFueVxyXG4gKiBlZGl0b3IgaW50ZXJmYWNlIHdoZXJlIGJsb2NrcyBhcmUgaW1wbGVtZW50ZWQuXHJcbiAqXHJcbiAqIEBsaW5rIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svYmxvY2stYXBpL1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgbmFtZSAgICAgQmxvY2sgbmFtZS5cclxuICogQHBhcmFtICB7T2JqZWN0fSAgIHNldHRpbmdzIEJsb2NrIHNldHRpbmdzLlxyXG4gKiBAcmV0dXJuIHs/V1BCbG9ja30gICAgICAgICAgVGhlIGJsb2NrLCBpZiBpdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHlcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWQ7IG90aGVyd2lzZSBgdW5kZWZpbmVkYC5cclxuICovXG5cbnJlZ2lzdGVyQmxvY2tUeXBlKCdmb29wbHVnaW5zL2Zvb2dhbGxlcnknLCB7XG5cdC8vIEJsb2NrIG5hbWUuIEJsb2NrIG5hbWVzIG11c3QgYmUgc3RyaW5nIHRoYXQgY29udGFpbnMgYSBuYW1lc3BhY2UgcHJlZml4LiBFeGFtcGxlOiBteS1wbHVnaW4vbXktY3VzdG9tLWJsb2NrLlxuXHR0aXRsZTogX18oJ0Zvb0dhbGxlcnknKSwgLy8gQmxvY2sgdGl0bGUuXG5cdGRlc2NyaXB0aW9uOiBfXygnSW5zZXJ0IGEgRm9vR2FsbGVyeSBpbnRvIHlvdXIgY29udGVudCcpLFxuXHRpY29uOiAnZm9ybWF0LWdhbGxlcnknLCAvLyBCbG9jayBpY29uIGZyb20gRGFzaGljb25zIOKGkiBodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3Jlc291cmNlL2Rhc2hpY29ucy8uXG5cdGNhdGVnb3J5OiAnY29tbW9uJywgLy8gQmxvY2sgY2F0ZWdvcnkg4oCUIEdyb3VwIGJsb2NrcyB0b2dldGhlciBiYXNlZCBvbiBjb21tb24gdHJhaXRzIEUuZy4gY29tbW9uLCBmb3JtYXR0aW5nLCBsYXlvdXQgd2lkZ2V0cywgZW1iZWQuXG5cdGtleXdvcmRzOiBbX18oJ2Zvb2dhbGxlcnknKSwgX18oJ2dhbGxlcnknKV0sXG5cdHN1cHBvcnRzOiB7XG5cdFx0bXVsdGlwbGU6IHRydWUsXG5cdFx0aHRtbDogZmFsc2Vcblx0fSxcblx0YXR0cmlidXRlczoge1xuXHRcdGlkOiB7XG5cdFx0XHR0eXBlOiAnbnVtYmVyJyxcblx0XHRcdGRlZmF1bHQ6IDBcblx0XHR9XG5cdH0sXG5cdC8qKlxyXG4gICogVGhlIGVkaXQgZnVuY3Rpb24gZGVzY3JpYmVzIHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBibG9jayBpbiB0aGUgY29udGV4dCBvZiB0aGUgZWRpdG9yLlxyXG4gICogVGhpcyByZXByZXNlbnRzIHdoYXQgdGhlIGVkaXRvciB3aWxsIHJlbmRlciB3aGVuIHRoZSBibG9jayBpcyB1c2VkLlxyXG4gICpcclxuICAqIFRoZSBcImVkaXRcIiBwcm9wZXJ0eSBtdXN0IGJlIGEgdmFsaWQgZnVuY3Rpb24uXHJcbiAgKlxyXG4gICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlL1xyXG4gICovXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KEZvb0dhbGxlcnlFZGl0LCBwcm9wcyk7XG5cdH0sXG5cblxuXHQvKipcclxuICAqIFRoZSBzYXZlIGZ1bmN0aW9uIGRlZmluZXMgdGhlIHdheSBpbiB3aGljaCB0aGUgZGlmZmVyZW50IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIGNvbWJpbmVkXHJcbiAgKiBpbnRvIHRoZSBmaW5hbCBtYXJrdXAsIHdoaWNoIGlzIHRoZW4gc2VyaWFsaXplZCBieSBHdXRlbmJlcmcgaW50byBwb3N0X2NvbnRlbnQuXHJcbiAgKlxyXG4gICogVGhlIFwic2F2ZVwiIHByb3BlcnR5IG11c3QgYmUgc3BlY2lmaWVkIGFuZCBtdXN0IGJlIGEgdmFsaWQgZnVuY3Rpb24uXHJcbiAgKlxyXG4gICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlL1xyXG4gICovXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoKSB7XG5cdFx0Ly8gUmVuZGVyaW5nIGluIFBIUFxuXHRcdHJldHVybiBudWxsO1xuXHR9XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2d1dGVuYmVyZy9zcmMvYmxvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4\n");
123
 
124
  /***/ }),
125
  /* 5 */
119
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
120
 
121
  "use strict";
122
+ eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_scss__ = __webpack_require__(/*! ./style.scss */ 5);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__style_scss___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__style_scss__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__editor_scss__ = __webpack_require__(/*! ./editor.scss */ 6);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__editor_scss___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__editor_scss__);\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__edit__ = __webpack_require__(/*! ./edit */ 7);\n/**\r\n * BLOCK: fooplugins/foogallery\r\n *\r\n * Registering a basic FooGallery block with Gutenberg.\r\n */\n\n\n\n\n\nvar __ = wp.i18n.__; // Import __() from wp.i18n\n\nvar registerBlockType = wp.blocks.registerBlockType; // Import registerBlockType() from wp.blocks\n\n/**\r\n * Register: aa Gutenberg Block.\r\n *\r\n * Registers a new block provided a unique name and an object defining its\r\n * behavior. Once registered, the block is made editor as an option to any\r\n * editor interface where blocks are implemented.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/\r\n * @param {string} name Block name.\r\n * @param {Object} settings Block settings.\r\n * @return {?WPBlock} The block, if it has been successfully\r\n * registered; otherwise `undefined`.\r\n */\n\nregisterBlockType('fooplugins/foogallery', {\n\t// Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.\n\ttitle: __('FooGallery'), // Block title.\n\tdescription: __('Insert a FooGallery into your content'),\n\ticon: 'format-gallery', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.\n\tcategory: 'common', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.\n\tkeywords: [__('foogallery'), __('gallery')],\n\tsupports: {\n\t\tmultiple: true,\n\t\thtml: false\n\t},\n\tattributes: {\n\t\tid: {\n\t\t\ttype: 'number',\n\t\t\tdefault: 0\n\t\t},\n\t\tclassName: {\n\t\t\ttype: 'string'\n\t\t}\n\t},\n\t/**\r\n * The edit function describes the structure of your block in the context of the editor.\r\n * This represents what the editor will render when the block is used.\r\n *\r\n * The \"edit\" property must be a valid function.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/\r\n */\n\tedit: function edit(props) {\n\t\treturn wp.element.createElement(__WEBPACK_IMPORTED_MODULE_2__edit__[\"a\" /* default */], props);\n\t},\n\n\n\t/**\r\n * The save function defines the way in which the different attributes should be combined\r\n * into the final markup, which is then serialized by Gutenberg into post_content.\r\n *\r\n * The \"save\" property must be specified and must be a valid function.\r\n *\r\n * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/\r\n */\n\tsave: function save() {\n\t\t// Rendering in PHP\n\t\treturn null;\n\t}\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2d1dGVuYmVyZy9zcmMvYmxvY2svaW5kZXguanM/NTc2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQkxPQ0s6IGZvb3BsdWdpbnMvZm9vZ2FsbGVyeVxyXG4gKlxyXG4gKiBSZWdpc3RlcmluZyBhIGJhc2ljIEZvb0dhbGxlcnkgYmxvY2sgd2l0aCBHdXRlbmJlcmcuXHJcbiAqL1xuXG5pbXBvcnQgJy4vc3R5bGUuc2Nzcyc7XG5pbXBvcnQgJy4vZWRpdG9yLnNjc3MnO1xuaW1wb3J0IEZvb0dhbGxlcnlFZGl0IGZyb20gJy4vZWRpdCc7XG5cbnZhciBfXyA9IHdwLmkxOG4uX187IC8vIEltcG9ydCBfXygpIGZyb20gd3AuaTE4blxuXG52YXIgcmVnaXN0ZXJCbG9ja1R5cGUgPSB3cC5ibG9ja3MucmVnaXN0ZXJCbG9ja1R5cGU7IC8vIEltcG9ydCByZWdpc3RlckJsb2NrVHlwZSgpIGZyb20gd3AuYmxvY2tzXG5cbi8qKlxyXG4gKiBSZWdpc3RlcjogYWEgR3V0ZW5iZXJnIEJsb2NrLlxyXG4gKlxyXG4gKiBSZWdpc3RlcnMgYSBuZXcgYmxvY2sgcHJvdmlkZWQgYSB1bmlxdWUgbmFtZSBhbmQgYW4gb2JqZWN0IGRlZmluaW5nIGl0c1xyXG4gKiBiZWhhdmlvci4gT25jZSByZWdpc3RlcmVkLCB0aGUgYmxvY2sgaXMgbWFkZSBlZGl0b3IgYXMgYW4gb3B0aW9uIHRvIGFueVxyXG4gKiBlZGl0b3IgaW50ZXJmYWNlIHdoZXJlIGJsb2NrcyBhcmUgaW1wbGVtZW50ZWQuXHJcbiAqXHJcbiAqIEBsaW5rIGh0dHBzOi8vd29yZHByZXNzLm9yZy9ndXRlbmJlcmcvaGFuZGJvb2svYmxvY2stYXBpL1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgbmFtZSAgICAgQmxvY2sgbmFtZS5cclxuICogQHBhcmFtICB7T2JqZWN0fSAgIHNldHRpbmdzIEJsb2NrIHNldHRpbmdzLlxyXG4gKiBAcmV0dXJuIHs/V1BCbG9ja30gICAgICAgICAgVGhlIGJsb2NrLCBpZiBpdCBoYXMgYmVlbiBzdWNjZXNzZnVsbHlcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWQ7IG90aGVyd2lzZSBgdW5kZWZpbmVkYC5cclxuICovXG5cbnJlZ2lzdGVyQmxvY2tUeXBlKCdmb29wbHVnaW5zL2Zvb2dhbGxlcnknLCB7XG5cdC8vIEJsb2NrIG5hbWUuIEJsb2NrIG5hbWVzIG11c3QgYmUgc3RyaW5nIHRoYXQgY29udGFpbnMgYSBuYW1lc3BhY2UgcHJlZml4LiBFeGFtcGxlOiBteS1wbHVnaW4vbXktY3VzdG9tLWJsb2NrLlxuXHR0aXRsZTogX18oJ0Zvb0dhbGxlcnknKSwgLy8gQmxvY2sgdGl0bGUuXG5cdGRlc2NyaXB0aW9uOiBfXygnSW5zZXJ0IGEgRm9vR2FsbGVyeSBpbnRvIHlvdXIgY29udGVudCcpLFxuXHRpY29uOiAnZm9ybWF0LWdhbGxlcnknLCAvLyBCbG9jayBpY29uIGZyb20gRGFzaGljb25zIOKGkiBodHRwczovL2RldmVsb3Blci53b3JkcHJlc3Mub3JnL3Jlc291cmNlL2Rhc2hpY29ucy8uXG5cdGNhdGVnb3J5OiAnY29tbW9uJywgLy8gQmxvY2sgY2F0ZWdvcnkg4oCUIEdyb3VwIGJsb2NrcyB0b2dldGhlciBiYXNlZCBvbiBjb21tb24gdHJhaXRzIEUuZy4gY29tbW9uLCBmb3JtYXR0aW5nLCBsYXlvdXQgd2lkZ2V0cywgZW1iZWQuXG5cdGtleXdvcmRzOiBbX18oJ2Zvb2dhbGxlcnknKSwgX18oJ2dhbGxlcnknKV0sXG5cdHN1cHBvcnRzOiB7XG5cdFx0bXVsdGlwbGU6IHRydWUsXG5cdFx0aHRtbDogZmFsc2Vcblx0fSxcblx0YXR0cmlidXRlczoge1xuXHRcdGlkOiB7XG5cdFx0XHR0eXBlOiAnbnVtYmVyJyxcblx0XHRcdGRlZmF1bHQ6IDBcblx0XHR9LFxuXHRcdGNsYXNzTmFtZToge1xuXHRcdFx0dHlwZTogJ3N0cmluZydcblx0XHR9XG5cdH0sXG5cdC8qKlxyXG4gICogVGhlIGVkaXQgZnVuY3Rpb24gZGVzY3JpYmVzIHRoZSBzdHJ1Y3R1cmUgb2YgeW91ciBibG9jayBpbiB0aGUgY29udGV4dCBvZiB0aGUgZWRpdG9yLlxyXG4gICogVGhpcyByZXByZXNlbnRzIHdoYXQgdGhlIGVkaXRvciB3aWxsIHJlbmRlciB3aGVuIHRoZSBibG9jayBpcyB1c2VkLlxyXG4gICpcclxuICAqIFRoZSBcImVkaXRcIiBwcm9wZXJ0eSBtdXN0IGJlIGEgdmFsaWQgZnVuY3Rpb24uXHJcbiAgKlxyXG4gICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlL1xyXG4gICovXG5cdGVkaXQ6IGZ1bmN0aW9uIGVkaXQocHJvcHMpIHtcblx0XHRyZXR1cm4gd3AuZWxlbWVudC5jcmVhdGVFbGVtZW50KEZvb0dhbGxlcnlFZGl0LCBwcm9wcyk7XG5cdH0sXG5cblxuXHQvKipcclxuICAqIFRoZSBzYXZlIGZ1bmN0aW9uIGRlZmluZXMgdGhlIHdheSBpbiB3aGljaCB0aGUgZGlmZmVyZW50IGF0dHJpYnV0ZXMgc2hvdWxkIGJlIGNvbWJpbmVkXHJcbiAgKiBpbnRvIHRoZSBmaW5hbCBtYXJrdXAsIHdoaWNoIGlzIHRoZW4gc2VyaWFsaXplZCBieSBHdXRlbmJlcmcgaW50byBwb3N0X2NvbnRlbnQuXHJcbiAgKlxyXG4gICogVGhlIFwic2F2ZVwiIHByb3BlcnR5IG11c3QgYmUgc3BlY2lmaWVkIGFuZCBtdXN0IGJlIGEgdmFsaWQgZnVuY3Rpb24uXHJcbiAgKlxyXG4gICogQGxpbmsgaHR0cHM6Ly93b3JkcHJlc3Mub3JnL2d1dGVuYmVyZy9oYW5kYm9vay9ibG9jay1hcGkvYmxvY2stZWRpdC1zYXZlL1xyXG4gICovXG5cdHNhdmU6IGZ1bmN0aW9uIHNhdmUoKSB7XG5cdFx0Ly8gUmVuZGVyaW5nIGluIFBIUFxuXHRcdHJldHVybiBudWxsO1xuXHR9XG59KTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2d1dGVuYmVyZy9zcmMvYmxvY2svaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4\n");
123
 
124
  /***/ }),
125
  /* 5 */
gutenberg/dist/blocks.editor.build.css CHANGED
@@ -170,9 +170,9 @@ svg.dashicon.foogallery-modal__icon-disabled {
170
  */
171
  .foogallery-inspector-controls__button-container {
172
  text-align: center;
173
- margin: -16px;
174
  padding: 16px; }
175
 
176
  .foogallery-inspector-controls__button-container button {
177
  display: -ms-inline-flexbox;
178
- display: inline-flex; }
 
170
  */
171
  .foogallery-inspector-controls__button-container {
172
  text-align: center;
 
173
  padding: 16px; }
174
 
175
  .foogallery-inspector-controls__button-container button {
176
  display: -ms-inline-flexbox;
177
+ display: inline-flex;
178
+ vertical-align: middle; }
gutenberg/src/block/edit/components/inspector-controls/editor.scss CHANGED
@@ -1,9 +1,9 @@
1
  .foogallery-inspector-controls__button-container {
2
  text-align: center;
3
- margin: -16px;
4
  padding: 16px;
5
  }
6
 
7
  .foogallery-inspector-controls__button-container button {
8
  display: inline-flex;
 
9
  }
1
  .foogallery-inspector-controls__button-container {
2
  text-align: center;
 
3
  padding: 16px;
4
  }
5
 
6
  .foogallery-inspector-controls__button-container button {
7
  display: inline-flex;
8
+ vertical-align: middle;
9
  }
gutenberg/src/block/index.js CHANGED
@@ -42,6 +42,9 @@ registerBlockType( 'fooplugins/foogallery', {
42
  id: {
43
  type: 'number',
44
  default: 0
 
 
 
45
  }
46
  },
47
  /**
42
  id: {
43
  type: 'number',
44
  default: 0
45
+ },
46
+ className: {
47
+ type: 'string'
48
  }
49
  },
50
  /**
includes/admin/class-gallery-metabox-items.php CHANGED
@@ -117,6 +117,10 @@ if ( ! class_exists( 'FooGallery_Admin_Gallery_MetaBox_Items' ) ) {
117
  $args = apply_filters( 'foogallery_preview_arguments', $args, $_POST, $template );
118
  $args = apply_filters( 'foogallery_preview_arguments-' . $template, $args, $_POST );
119
 
 
 
 
 
120
  foogallery_render_gallery( $foogallery_id, $args );
121
 
122
  $foogallery_gallery_preview = false;
117
  $args = apply_filters( 'foogallery_preview_arguments', $args, $_POST, $template );
118
  $args = apply_filters( 'foogallery_preview_arguments-' . $template, $args, $_POST );
119
 
120
+ if ( foogallery_is_debug() ) {
121
+ echo '<pre>' . __('Preview Debug Arguments:', 'foogallery') . '<br>' . print_r( $args, true ) . '</pre>';
122
+ }
123
+
124
  foogallery_render_gallery( $foogallery_id, $args );
125
 
126
  $foogallery_gallery_preview = false;
includes/class-foogallery-common-fields.php CHANGED
@@ -96,7 +96,7 @@ if ( ! class_exists( 'FooGallery_Common_Fields' ) ) {
96
  'row_data' => array(
97
  'data-foogallery-change-selector' => 'input:radio',
98
  'data-foogallery-value-selector' => 'input:checked',
99
- 'data-foogallery-preview' => 'class'
100
  )
101
  );
102
 
@@ -408,6 +408,24 @@ if ( ! class_exists( 'FooGallery_Common_Fields' ) ) {
408
  'data-foogallery-preview' => 'class'
409
  )
410
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  //endregion Hover Effects Fields
412
 
413
  //region Caption Fields
@@ -528,7 +546,7 @@ if ( ! class_exists( 'FooGallery_Common_Fields' ) ) {
528
  function get_setting_from_gallery( $gallery, $key, $default ) {
529
  global $current_foogallery;
530
 
531
- if ( isset( $current_foogallery ) && $current_foogallery === $gallery ) {
532
  return foogallery_gallery_template_setting( $key, $default );
533
  }
534
 
@@ -572,6 +590,7 @@ if ( ! class_exists( 'FooGallery_Common_Fields' ) ) {
572
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_caption_visibility', 'fg-caption-hover' );
573
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_transition', 'fg-hover-fade' );
574
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_icon', 'fg-hover-zoom' );
 
575
  } else if ( strpos( $caption_preset, 'fg-preset' ) !== false ) {
576
  //set a preset size
577
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_preset_size', 'fg-preset-small' );
@@ -628,6 +647,7 @@ if ( ! class_exists( 'FooGallery_Common_Fields' ) ) {
628
  * @return mixed
629
  */
630
  function preview_arguments( $args, $post_data, $template ) {
 
631
  $args['caption_title_source'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_caption_title_source'];
632
  $args['caption_desc_source'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_caption_desc_source'];
633
  $args['captions_limit_length'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_captions_limit_length'];
96
  'row_data' => array(
97
  'data-foogallery-change-selector' => 'input:radio',
98
  'data-foogallery-value-selector' => 'input:checked',
99
+ 'data-foogallery-preview' => 'shortcode class'
100
  )
101
  );
102
 
408
  'data-foogallery-preview' => 'class'
409
  )
410
  );
411
+
412
+ $fields[] = array(
413
+ 'id' => 'caption_invert_color',
414
+ 'title' => __( 'Invert Colors', 'foogallery' ),
415
+ 'desc' => __( 'You can invert the hover effect and caption colors from dark to light.', 'foogallery' ),
416
+ 'section' => __( 'Hover Effects', 'foogallery' ),
417
+ 'type' => 'radio',
418
+ 'spacer' => '<span class="spacer"></span>',
419
+ 'default' => '',
420
+ 'choices' => apply_filters( 'foogallery_gallery_template_common_thumbnail_fields_caption_invert_color_choices', array(
421
+ '' => __( 'Normal', 'foogallery' ),
422
+ 'fg-light-overlays' => __( 'Inverted', 'foogallery' ),
423
+ ) ),
424
+ 'row_data' => array(
425
+ 'data-foogallery-change-selector' => 'input:radio',
426
+ 'data-foogallery-preview' => 'class'
427
+ )
428
+ );
429
  //endregion Hover Effects Fields
430
 
431
  //region Caption Fields
546
  function get_setting_from_gallery( $gallery, $key, $default ) {
547
  global $current_foogallery;
548
 
549
+ if ( isset( $current_foogallery ) && $current_foogallery->ID === $gallery->ID ) {
550
  return foogallery_gallery_template_setting( $key, $default );
551
  }
552
 
590
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_caption_visibility', 'fg-caption-hover' );
591
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_transition', 'fg-hover-fade' );
592
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_icon', 'fg-hover-zoom' );
593
+ $classes[] = $this->get_setting_from_gallery( $gallery, 'caption_invert_color', '' );
594
  } else if ( strpos( $caption_preset, 'fg-preset' ) !== false ) {
595
  //set a preset size
596
  $classes[] = $this->get_setting_from_gallery( $gallery, 'hover_effect_preset_size', 'fg-preset-small' );
647
  * @return mixed
648
  */
649
  function preview_arguments( $args, $post_data, $template ) {
650
+ $args['theme'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_theme'];
651
  $args['caption_title_source'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_caption_title_source'];
652
  $args['caption_desc_source'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_caption_desc_source'];
653
  $args['captions_limit_length'] = $post_data[FOOGALLERY_META_SETTINGS][$template . '_captions_limit_length'];
includes/class-foogallery-datasource-media_library.php CHANGED
@@ -101,7 +101,7 @@ if ( ! class_exists( 'FooGallery_Datasource_MediaLibrary' ) ) {
101
  <input type="hidden" data-foogallery-preview="include" name='foogallery_attachments' id="foogallery_attachments" value="<?php echo $foogallery->attachment_id_csv(); ?>"/>
102
  <ul class="foogallery-attachments-list <?php echo $has_attachments ? '' : 'hidden'; ?> <?php echo $media_button_start ? 'foogallery-add-media-button-start' : ''; ?>">
103
  <?php if ( $media_button_start ) {
104
- $this->render_add_meda_button( $foogallery->ID );
105
  } ?>
106
  <?php
107
  //render all attachments that have been added to the gallery from the media library
@@ -111,15 +111,23 @@ if ( ! class_exists( 'FooGallery_Datasource_MediaLibrary' ) ) {
111
  }
112
  } ?>
113
  <?php if ( !$media_button_start ) {
114
- $this->render_add_meda_button( $foogallery->ID );
115
  } ?>
116
  </ul>
117
  <div style="clear: both;"></div>
118
  <textarea style="display: none" id="foogallery-attachment-template"><?php $this->render_attachment_item(); ?></textarea>
 
 
 
 
 
 
 
 
119
  <?php
120
  }
121
 
122
- private function render_add_meda_button( $foogallery_id) {
123
  ?>
124
  <li class="add-attachment datasource-medialibrary">
125
  <a href="#" data-uploader-title="<?php _e( 'Add Media To Gallery', 'foogallery' ); ?>"
@@ -146,7 +154,7 @@ if ( ! class_exists( 'FooGallery_Datasource_MediaLibrary' ) ) {
146
  }
147
 
148
  $data_attribute = empty($attachment_id) ? '' : "data-attachment-id=\"{$attachment_id}\"";
149
- $img_tag = empty($attachment) ? '<img width="150" height="150" />' : "<img width=\"150\" height=\"150\" src=\"{$attachment[0]}\" />";
150
  ?>
151
  <li class="attachment details" <?php echo $data_attribute; ?>>
152
  <div class="attachment-preview type-image <?php echo $extra_class; ?>">
101
  <input type="hidden" data-foogallery-preview="include" name='foogallery_attachments' id="foogallery_attachments" value="<?php echo $foogallery->attachment_id_csv(); ?>"/>
102
  <ul class="foogallery-attachments-list <?php echo $has_attachments ? '' : 'hidden'; ?> <?php echo $media_button_start ? 'foogallery-add-media-button-start' : ''; ?>">
103
  <?php if ( $media_button_start ) {
104
+ $this->render_add_media_button( $foogallery->ID );
105
  } ?>
106
  <?php
107
  //render all attachments that have been added to the gallery from the media library
111
  }
112
  } ?>
113
  <?php if ( !$media_button_start ) {
114
+ $this->render_add_media_button( $foogallery->ID );
115
  } ?>
116
  </ul>
117
  <div style="clear: both;"></div>
118
  <textarea style="display: none" id="foogallery-attachment-template"><?php $this->render_attachment_item(); ?></textarea>
119
+ <div class="<?php echo $has_attachments ? '' : 'hidden'; ?> foogallery-attachments-list-bar">
120
+ <button type="button" class="button button-primary button-large alignright upload_image_button"
121
+ data-uploader-title="<?php _e( 'Add Media To Gallery', 'foogallery' ); ?>"
122
+ data-uploader-button-text="<?php _e( 'Add Media', 'foogallery' ); ?>"
123
+ data-post-id="<?php echo $foogallery->ID; ?>">
124
+ <?php _e( 'Add Media', 'foogallery' ); ?>
125
+ </button>
126
+ </div>
127
  <?php
128
  }
129
 
130
+ private function render_add_media_button( $foogallery_id) {
131
  ?>
132
  <li class="add-attachment datasource-medialibrary">
133
  <a href="#" data-uploader-title="<?php _e( 'Add Media To Gallery', 'foogallery' ); ?>"
154
  }
155
 
156
  $data_attribute = empty($attachment_id) ? '' : "data-attachment-id=\"{$attachment_id}\"";
157
+ $img_tag = empty($attachment) ? '<img width="150" height="150" />' : "<img width=\"150\" height=\"150\" data-src=\"{$attachment[0]}\" />";
158
  ?>
159
  <li class="attachment details" <?php echo $data_attribute; ?>>
160
  <div class="attachment-preview type-image <?php echo $extra_class; ?>">
includes/class-foogallery-upgrade.php CHANGED
@@ -32,10 +32,10 @@ if ( ! class_exists( 'FooGallery_Upgrade' ) ) {
32
 
33
  public function add_meta_boxes_to_gallery( $post ) {
34
 
35
- if ( foogallery_get_setting( 'enable_debugging' ) ) {
36
  add_meta_box(
37
  'foogallery_upgrade_debug',
38
- __( 'Settings Upgrade Debugging', 'foogallery' ),
39
  array( $this, 'render_upgrade_debug_metabox' ),
40
  FOOGALLERY_CPT_GALLERY,
41
  'normal',
@@ -65,18 +65,7 @@ if ( ! class_exists( 'FooGallery_Upgrade' ) ) {
65
  #foogallery_upgrade_debug table { font-size: 0.8em; }
66
  #foogallery_upgrade_debug td { vertical-align: top; }
67
  </style>
68
- <table>
69
- <tr>
70
- <td><h3>Old Settings</h3></td>
71
- <td><h3>New Settings</h3></td>
72
- <td><h3>Upgrade Settings</h3></td>
73
- </tr>
74
- <tr>
75
- <td><?php var_dump( $old_settings ); ?></td>
76
- <td><?php var_dump( $new_settings ); ?></td>
77
- <td><?php var_dump( $upgrade_settings ); ?></td>
78
- </tr>
79
- </table>
80
  <?php
81
  }
82
 
32
 
33
  public function add_meta_boxes_to_gallery( $post ) {
34
 
35
+ if ( foogallery_is_debug() ) {
36
  add_meta_box(
37
  'foogallery_upgrade_debug',
38
+ __( 'Settings Debugging', 'foogallery' ),
39
  array( $this, 'render_upgrade_debug_metabox' ),
40
  FOOGALLERY_CPT_GALLERY,
41
  'normal',
65
  #foogallery_upgrade_debug table { font-size: 0.8em; }
66
  #foogallery_upgrade_debug td { vertical-align: top; }
67
  </style>
68
+ <?php var_dump( $new_settings ); ?>
 
 
 
 
 
 
 
 
 
 
 
69
  <?php
70
  }
71
 
includes/class-foogallery.php CHANGED
@@ -483,4 +483,11 @@ class FooGallery extends stdClass {
483
 
484
  return empty( $this->datasource_value );
485
  }
 
 
 
 
 
 
 
486
  }
483
 
484
  return empty( $this->datasource_value );
485
  }
486
+
487
+ /**
488
+ * Returns true if the datasource is not media_library
489
+ */
490
+ public function is_dynamic() {
491
+ return $this->datasource_name !== foogallery_default_datasource();
492
+ }
493
  }
includes/compatibility/class-foobox-compatibility.php CHANGED
@@ -12,7 +12,7 @@ if ( !class_exists( 'FooGallery_FooBox_Compatibility' ) ) {
12
  $this->ensure_outdated_foobox_extensions_never_run();
13
 
14
  //add the FooBox lightbox option no matter if using Free or Pro
15
- add_filter( 'foogallery_gallery_template_field_lightboxes', array($this, 'add_lightbox') );
16
 
17
  //alter the default lightbox to be foobox
18
  add_filter( 'foogallery_alter_gallery_template_field', array( $this, 'make_foobox_default_lightbox' ), 10, 2 );
12
  $this->ensure_outdated_foobox_extensions_never_run();
13
 
14
  //add the FooBox lightbox option no matter if using Free or Pro
15
+ add_filter( 'foogallery_gallery_template_field_lightboxes', array($this, 'add_lightbox'), 11, 2 );
16
 
17
  //alter the default lightbox to be foobox
18
  add_filter( 'foogallery_alter_gallery_template_field', array( $this, 'make_foobox_default_lightbox' ), 10, 2 );
includes/functions.php CHANGED
@@ -403,6 +403,18 @@ function foogallery_build_class_attribute( $gallery ) {
403
 
404
  $classes = apply_filters( 'foogallery_build_class_attribute', $classes, $gallery );
405
 
 
 
 
 
 
 
 
 
 
 
 
 
406
  $classes = array_filter( $classes );
407
 
408
  return implode( ' ', $classes );
@@ -1043,7 +1055,7 @@ function foogallery_build_default_settings_for_gallery_template( $template_name
1043
  */
1044
  function foogallery_gallery_template_field_thumb_link_choices() {
1045
  return apply_filters( 'foogallery_gallery_template_field_thumb_links', array(
1046
- 'image' => __( 'Full Size Image (Lightbox)', 'foogallery' ),
1047
  'page' => __( 'Image Attachment Page', 'foogallery' ),
1048
  'custom' => __( 'Custom URL', 'foogallery' ),
1049
  'none' => __( 'Not linked', 'foogallery' ),
@@ -1411,4 +1423,12 @@ function foogallery_marketing_pro_features() {
1411
  */
1412
  function foogallery_allowed_post_types_for_usage() {
1413
  return apply_filters( 'foogallery_allowed_post_types_for_attachment', array( 'post', 'page' ) );
 
 
 
 
 
 
 
 
1414
  }
403
 
404
  $classes = apply_filters( 'foogallery_build_class_attribute', $classes, $gallery );
405
 
406
+ //extract any classes from the gallery arguments
407
+ global $current_foogallery_arguments;
408
+ if ( isset( $current_foogallery_arguments ) && is_array( $current_foogallery_arguments ) ) {
409
+ if ( array_key_exists( 'className', $current_foogallery_arguments ) ) {
410
+ $classes[] = $current_foogallery_arguments['className'];
411
+ }
412
+
413
+ if ( array_key_exists( 'classes', $current_foogallery_arguments ) ) {
414
+ $classes[] = $current_foogallery_arguments['classes'];
415
+ }
416
+ }
417
+
418
  $classes = array_filter( $classes );
419
 
420
  return implode( ' ', $classes );
1055
  */
1056
  function foogallery_gallery_template_field_thumb_link_choices() {
1057
  return apply_filters( 'foogallery_gallery_template_field_thumb_links', array(
1058
+ 'image' => __( 'Full Size Image', 'foogallery' ),
1059
  'page' => __( 'Image Attachment Page', 'foogallery' ),
1060
  'custom' => __( 'Custom URL', 'foogallery' ),
1061
  'none' => __( 'Not linked', 'foogallery' ),
1423
  */
1424
  function foogallery_allowed_post_types_for_usage() {
1425
  return apply_filters( 'foogallery_allowed_post_types_for_attachment', array( 'post', 'page' ) );
1426
+ }
1427
+
1428
+ /**
1429
+ * Returns true if FooGallery is in debug mode
1430
+ * @return bool
1431
+ */
1432
+ function foogallery_is_debug() {
1433
+ return foogallery_get_setting( 'enable_debugging', false );
1434
  }
includes/includes.php CHANGED
@@ -82,7 +82,8 @@ if ( is_admin() ) {
82
  require_once( FOOGALLERY_PATH . 'includes/public/class-css-load-optimizer.php' );
83
  require_once( FOOGALLERY_PATH . 'includes/public/class-admin-bar.php' );
84
  require_once( FOOGALLERY_PATH . 'includes/public/class-yoast-seo-sitemaps.php' );
 
85
  }
86
 
87
  require_once( FOOGALLERY_PATH . 'includes/public/class-shortcodes.php' );
88
- require_once( FOOGALLERY_PATH . 'includes/class-gallery-advanced-settings.php' );
82
  require_once( FOOGALLERY_PATH . 'includes/public/class-css-load-optimizer.php' );
83
  require_once( FOOGALLERY_PATH . 'includes/public/class-admin-bar.php' );
84
  require_once( FOOGALLERY_PATH . 'includes/public/class-yoast-seo-sitemaps.php' );
85
+ require_once( FOOGALLERY_PATH . 'includes/public/class-rank-math-seo-sitemaps.php' );
86
  }
87
 
88
  require_once( FOOGALLERY_PATH . 'includes/public/class-shortcodes.php' );
89
+ require_once( FOOGALLERY_PATH . 'includes/class-gallery-advanced-settings.php' );
includes/public/class-foogallery-template-loader.php CHANGED
@@ -50,7 +50,18 @@ class FooGallery_Template_Loader {
50
 
51
  //override the template if needed
52
  if ( $current_foogallery->gallery_template !== $current_foogallery_template ) {
 
 
53
  $current_foogallery->gallery_template = $current_foogallery_template;
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
  //potentially override attachment_ids from arguments
@@ -133,6 +144,23 @@ class FooGallery_Template_Loader {
133
  }
134
  }
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  /***
137
  * Loads a gallery template location and wraps the calls so that it can be intercepted
138
  *
50
 
51
  //override the template if needed
52
  if ( $current_foogallery->gallery_template !== $current_foogallery_template ) {
53
+ $old_gallery_template = $current_foogallery->gallery_template;
54
+
55
  $current_foogallery->gallery_template = $current_foogallery_template;
56
+
57
+ //we need to move the settings across
58
+ $new_settings = array();
59
+ foreach ( $current_foogallery->settings as $setting_key=>$setting_value ) {
60
+ $setting_key = $this->str_replace_first( "{$old_gallery_template}_", "{$current_foogallery_template}_", $setting_key );
61
+ $new_settings[$setting_key] = $setting_value;
62
+ }
63
+
64
+ $current_foogallery->settings = $new_settings;
65
  }
66
 
67
  //potentially override attachment_ids from arguments
144
  }
145
  }
146
 
147
+ /**
148
+ * Replaces the first occurrence of a string
149
+ *
150
+ * @param $search
151
+ * @param $replace
152
+ * @param $subject
153
+ *
154
+ * @return string|string[]
155
+ */
156
+ function str_replace_first($search, $replace, $subject) {
157
+ $pos = strpos($subject, $search);
158
+ if ($pos !== false) {
159
+ return substr_replace($subject, $replace, $pos, strlen($search));
160
+ }
161
+ return $subject;
162
+ }
163
+
164
  /***
165
  * Loads a gallery template location and wraps the calls so that it can be intercepted
166
  *
includes/public/class-public.php CHANGED
@@ -12,6 +12,7 @@ if ( ! class_exists( 'FooGallery_Public' ) ) {
12
  new FooGallery_CSS_Load_Optimizer();
13
  new FooGallery_AdminBar();
14
  new FooGallery_Yoast_Seo_Sitemap_Support();
 
15
  }
16
 
17
  }
12
  new FooGallery_CSS_Load_Optimizer();
13
  new FooGallery_AdminBar();
14
  new FooGallery_Yoast_Seo_Sitemap_Support();
15
+ new FooGallery_RankMath_Seo_Sitemap_Support();
16
  }
17
 
18
  }
includes/public/class-rank-math-seo-sitemaps.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Adds support for Rank Math SEO Sitemaps
4
+ *
5
+ * Created by Rank Math.
6
+ * Date: 27/09/2019
7
+ */
8
+ if ( ! class_exists( 'FooGallery_RankMath_Seo_Sitemap_Support' ) ) {
9
+
10
+ class FooGallery_RankMath_Seo_Sitemap_Support {
11
+
12
+ function __construct() {
13
+ add_filter( 'rank_math/sitemap/urlimages', [ $this, 'add_images_to_sitemap' ], 10, 2 );
14
+ }
15
+
16
+ function add_images_to_sitemap( $images, $post_id ) {
17
+ //check the content for $post_id contains a foogallery shortcode
18
+
19
+ //get all the foogalleries used in the posts
20
+ $galleries = get_post_meta( $post_id, FOOGALLERY_META_POST_USAGE );
21
+ foreach ( $galleries as $gallery_id ) {
22
+
23
+ //load each gallery
24
+ $gallery = FooGallery::get_by_id( $gallery_id );
25
+
26
+ if ( false === $gallery ) continue;
27
+
28
+ //add each image to the sitemap image array
29
+ foreach ( $gallery->attachments() as $attachment ) {
30
+ $image = [
31
+ 'src' => $attachment->url,
32
+ 'title' => $attachment->caption,
33
+ 'alt' => $attachment->alt
34
+ ];
35
+ $images[] = $image;
36
+ }
37
+ }
38
+
39
+ return $images;
40
+ }
41
+ }
42
+ }
includes/public/class-yoast-seo-sitemaps.php CHANGED
@@ -41,4 +41,4 @@ if ( ! class_exists( 'FooGallery_Yoast_Seo_Sitemap_Support' ) ) {
41
  return $images;
42
  }
43
  }
44
- }
41
  return $images;
42
  }
43
  }
44
+ }
includes/render-functions.php CHANGED
@@ -224,77 +224,96 @@ function foogallery_attachment_html_anchor( $foogallery_attachment, $args = arra
224
  *
225
  * @return array|bool
226
  */
227
- function foogallery_build_attachment_html_caption( $foogallery_attachment, $args = array() ) {
228
- $captions = array();
229
-
230
- $preset = foogallery_gallery_template_setting( 'caption_preset', 'fg-custom' );
231
-
232
- if ( 'none' !== $preset ) {
233
- $caption_html = array();
234
-
235
- $show_caption_title = false;
236
- $show_caption_desc = false;
237
-
238
- //check if we have provided overrides for the caption title
239
- if ( isset( $args['override_caption_title'] ) ) {
240
- $caption_title = $args['override_caption_title'];
241
- $show_caption_title = true;
242
- } else {
243
- $caption_title_source = foogallery_gallery_template_setting( 'caption_title_source', '' );
244
-
245
- //if we need to use the settings, then make sure our source is false
246
- if ( empty( $caption_title_source ) ) { $caption_title_source = false; }
247
-
248
- if ( 'fg-custom' === $preset ) {
249
- $show_caption_title = $caption_title_source !== 'none';
250
- } else {
251
- //always show both title and desc for the presets
252
- $show_caption_title = true;
253
- }
254
-
255
- //get the correct captions
256
- if ( $foogallery_attachment->_post ) {
257
- $caption_title = foogallery_get_caption_title_for_attachment( $foogallery_attachment->_post, $caption_title_source );
258
- } else {
259
- $caption_title = foogallery_get_caption_by_source( $foogallery_attachment, $caption_title_source, 'title' );
260
- }
261
- }
262
-
263
- //check if we have provided overrides for the caption description
264
- if ( isset( $args['override_caption_desc'] ) ) {
265
- $caption_desc = $args['override_caption_desc'];
266
- $show_caption_desc = true;
267
- } else {
268
-
269
- $caption_desc_source = foogallery_gallery_template_setting( 'caption_desc_source', '' );
270
-
271
- //if we need to use the settings, then make sure our source is false
272
- if ( empty( $caption_desc_source ) ) { $caption_desc_source = false; }
273
-
274
- if ( 'fg-custom' === $preset ) {
275
- $show_caption_desc = $caption_desc_source !== 'none';
276
- } else {
277
- //always show both title and desc for the presets
278
- $show_caption_desc = true;
279
- }
280
-
281
- if ( $foogallery_attachment->_post ) {
282
- $caption_desc = foogallery_get_caption_desc_for_attachment( $foogallery_attachment->_post, $caption_desc_source );
283
- } else {
284
- $caption_desc = foogallery_get_caption_by_source( $foogallery_attachment, $caption_desc_source, 'desc' );
285
- }
286
- }
287
-
288
- if ( $caption_title && $show_caption_title ) {
289
- $captions['title'] = $caption_title;
290
- }
291
- if ( $caption_desc && $show_caption_desc ) {
292
- $captions['desc'] = $caption_desc;
293
- }
294
-
295
- } else {
296
- $captions = false;
297
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
 
299
  return apply_filters( 'foogallery_build_attachment_html_caption', $captions, $foogallery_attachment, $args );
300
  }
@@ -370,13 +389,15 @@ function foogallery_attachment_html( $foogallery_attachment, $args = array() ) {
370
  $args = foogallery_gallery_template_arguments();
371
  }
372
 
 
 
373
  $html = foogallery_attachment_html_item_opening( $foogallery_attachment, $args );
374
  $html .= foogallery_attachment_html_anchor_opening( $foogallery_attachment, $args );
375
  $html .= '<span class="fg-image-wrap">';
376
  $html .= foogallery_attachment_html_image( $foogallery_attachment, $args );
377
  $html .= '</span>';
378
  $html .= '</a>';
379
- $html .= foogallery_attachment_html_caption( $foogallery_attachment, $args );
380
  $html .= '</figure><div class="fg-loader"></div></div>';
381
  return $html;
382
  }
224
  *
225
  * @return array|bool
226
  */
227
+ function foogallery_build_attachment_html_caption( &$foogallery_attachment, $args = array() ) {
228
+ $captions = apply_filters( 'foogallery_build_attachment_html_caption_custom', false, $foogallery_attachment, $args);
229
+
230
+ if ( false === $captions ) {
231
+
232
+ $captions = array();
233
+
234
+ $preset = foogallery_gallery_template_setting('caption_preset', 'fg-custom');
235
+
236
+ if ('none' !== $preset) {
237
+
238
+ $show_caption_title = false;
239
+ $show_caption_desc = false;
240
+
241
+ //check if we have provided overrides for the caption title
242
+ if (isset($args['override_caption_title'])) {
243
+ $caption_title = $args['override_caption_title'];
244
+ $show_caption_title = true;
245
+ } else {
246
+ $caption_title_source = foogallery_gallery_template_setting('caption_title_source', '');
247
+
248
+ //if we need to use the settings, then make sure our source is false
249
+ if (empty($caption_title_source)) {
250
+ $caption_title_source = false;
251
+ }
252
+
253
+ if ('fg-custom' === $preset) {
254
+ $show_caption_title = $caption_title_source !== 'none';
255
+ } else {
256
+ //always show both title and desc for the presets
257
+ $show_caption_title = true;
258
+ }
259
+
260
+ //get the correct captions
261
+ if ($foogallery_attachment->_post) {
262
+ $caption_title = foogallery_get_caption_title_for_attachment($foogallery_attachment->_post, $caption_title_source);
263
+ } else {
264
+ $caption_title = foogallery_get_caption_by_source($foogallery_attachment, $caption_title_source, 'title');
265
+ }
266
+ }
267
+
268
+ //check if we have provided overrides for the caption description
269
+ if (isset($args['override_caption_desc'])) {
270
+ $caption_desc = $args['override_caption_desc'];
271
+ $show_caption_desc = true;
272
+ } else {
273
+
274
+ $caption_desc_source = foogallery_gallery_template_setting('caption_desc_source', '');
275
+
276
+ //if we need to use the settings, then make sure our source is false
277
+ if (empty($caption_desc_source)) {
278
+ $caption_desc_source = false;
279
+ }
280
+
281
+ if ('fg-custom' === $preset) {
282
+ $show_caption_desc = $caption_desc_source !== 'none';
283
+ } else {
284
+ //always show both title and desc for the presets
285
+ $show_caption_desc = true;
286
+ }
287
+
288
+ if ($foogallery_attachment->_post) {
289
+ $caption_desc = foogallery_get_caption_desc_for_attachment($foogallery_attachment->_post, $caption_desc_source);
290
+ } else {
291
+ $caption_desc = foogallery_get_caption_by_source($foogallery_attachment, $caption_desc_source, 'desc');
292
+ }
293
+ }
294
+
295
+ if ($caption_title && $show_caption_title) {
296
+ $captions['title'] = $caption_title;
297
+ }
298
+ if ($caption_desc && $show_caption_desc) {
299
+ $captions['desc'] = $caption_desc;
300
+ }
301
+
302
+ } else {
303
+ $captions = false;
304
+ }
305
+ } else {
306
+ if ( isset( $captions['title']) ) {
307
+ $foogallery_attachment->caption = $captions['title'];
308
+ } else {
309
+ $foogallery_attachment->caption = '';
310
+ }
311
+ if ( isset( $captions['desc'] ) ) {
312
+ $foogallery_attachment->description = $captions['desc'];
313
+ } else {
314
+ $foogallery_attachment->description = '';
315
+ }
316
+ }
317
 
318
  return apply_filters( 'foogallery_build_attachment_html_caption', $captions, $foogallery_attachment, $args );
319
  }
389
  $args = foogallery_gallery_template_arguments();
390
  }
391
 
392
+ $caption = foogallery_attachment_html_caption( $foogallery_attachment, $args );
393
+
394
  $html = foogallery_attachment_html_item_opening( $foogallery_attachment, $args );
395
  $html .= foogallery_attachment_html_anchor_opening( $foogallery_attachment, $args );
396
  $html .= '<span class="fg-image-wrap">';
397
  $html .= foogallery_attachment_html_image( $foogallery_attachment, $args );
398
  $html .= '</span>';
399
  $html .= '</a>';
400
+ $html .= $caption;
401
  $html .= '</figure><div class="fg-loader"></div></div>';
402
  return $html;
403
  }
js/admin-foogallery-attachment-autosave.js CHANGED
@@ -1,4 +1,4 @@
1
- (function($, view, model){
2
 
3
  var EXCLUDE_SELECTOR = '.foogallery-attachment-ignore-change';
4
 
@@ -11,19 +11,21 @@
11
  * @description We override the original here so we can hook into the controllers "close" event. The controller
12
  * is the wp.media.view.MediaFrame.Select so in essence this is hooking into the modal close event.
13
  */
14
- ready: function(){
15
- this.listenTo(this.controller, "close", this.saveAll);
 
 
16
  },
17
  /**
18
- * @summary Removes the view and its' `el` from the DOM and unbinds any events.
19
- * @description We override the original here so we can force a save of all fields just prior to the view being
20
- * removed. This also offers us the chance to unbind from the controllers' "close" event.
21
- * @returns {*}
22
  */
23
- remove: function(){
24
- this.saveAll();
25
- this.stopListening(this.controller, "close", this.saveAll);
26
- return original.remove.apply(this, arguments);
27
  },
28
  /**
29
  * @summary Forces all fields to be saved regardless of the exclude selector.
@@ -44,27 +46,14 @@
44
  */
45
  save: function(event){
46
  if (event && event.target && $(event.target).is(EXCLUDE_SELECTOR)){
47
- console.log("excluded-field:", event.target.name);
 
48
  return;
49
  }
50
  original.save.apply(this, arguments);
51
  }
52
-
53
- // initialize: function() {
54
- // original.initialize.apply( this, arguments );
55
- // this.stopListening( this.model, 'change:compat', this.render );
56
- // }
57
  });
58
-
59
- // if you want to sanitize the data being sent back to the server we can override the original
60
- // wp.media.model.Attachment#saveCompat function using the below.
61
- // var saveCompat = model.Attachment.prototype.saveCompat;
62
- // model.Attachment.prototype.saveCompat = function(data){
63
- // console.log("saveCompat", data);
64
- // return saveCompat.apply(this, arguments);
65
- // };
66
  })(
67
  jQuery,
68
- wp.media.view,
69
- wp.media.model
70
  );
1
+ (function($, view){
2
 
3
  var EXCLUDE_SELECTOR = '.foogallery-attachment-ignore-change';
4
 
11
  * @description We override the original here so we can hook into the controllers "close" event. The controller
12
  * is the wp.media.view.MediaFrame.Select so in essence this is hooking into the modal close event.
13
  */
14
+ initialize: function(){
15
+ this.dirty = false;
16
+ this.controller.on("close", this.saveAll.bind(this));
17
+ original.initialize.apply(this, arguments);
18
  },
19
  /**
20
+ * @summary Disposes of the current view. This method is called prior to removing the view.
21
+ * @description We override the dispose method so we can check if one of the excluded fields has been changed and the
22
+ * view needs to be saved.
23
+ * @returns {wp.media.view.AttachmentCompat}
24
  */
25
+ dispose: function(){
26
+ if (this.dirty) this.saveAll();
27
+ this.dirty = false;
28
+ return original.dispose.apply(this, arguments);
29
  },
30
  /**
31
  * @summary Forces all fields to be saved regardless of the exclude selector.
46
  */
47
  save: function(event){
48
  if (event && event.target && $(event.target).is(EXCLUDE_SELECTOR)){
49
+ // console.log("excluded-field:", event.target.name);
50
+ this.dirty = true;
51
  return;
52
  }
53
  original.save.apply(this, arguments);
54
  }
 
 
 
 
 
55
  });
 
 
 
 
 
 
 
 
56
  })(
57
  jQuery,
58
+ wp.media.view
 
59
  );
js/admin-foogallery.js CHANGED
@@ -27,10 +27,12 @@
27
  $('.foogallery-items-add').removeClass('hidden');
28
  $('.foogallery-attachments-list').addClass('hidden');
29
  $('.foogallery-items-empty').removeClass('hidden');
 
30
  } else {
31
  $('.foogallery-items-add').addClass('hidden');
32
  $('.foogallery-attachments-list').removeClass('hidden');
33
  $('.foogallery-items-empty').addClass('hidden');
 
34
  }
35
  };
36
 
@@ -80,24 +82,25 @@
80
 
81
  FOOGALLERY.updateGalleryPreview = function( initGallery, setContainerHeight ) {
82
  var $preview = $('.foogallery_preview_container .foogallery'),
83
- $preview_container = $('.foogallery_preview_container');
 
84
 
85
  if ( setContainerHeight ) {
86
  $preview_container.css('height', $preview_container.height());
87
  }
88
 
89
  //build up the container class
90
- var $classFields = $('.foogallery-settings-container-active .foogallery-metabox-settings .foogallery_template_field[data-foogallery-preview="class"]');
91
 
92
  if ($classFields.length) {
93
 
94
  var array = $classFields.find(' :input').serializeArray(),
95
- mandatory_classes = $('#FooGallerySettings_GalleryTemplate').find(":selected").data('mandatory-classes'),
96
- classes = $.map(array, function (item) {
97
  return item.value;
98
  }).concat(['foogallery', mandatory_classes]).join(' ');
99
 
100
- $preview.attr('class', classes);
101
  }
102
 
103
  //this allows any extensions to hook into the template change event
@@ -107,10 +110,17 @@
107
  if ( $preview.data('fg-common-fields') ) {
108
  if ( initGallery ) {
109
  $preview.foogallery( {}, function() {
110
- $preview_container.css( 'height', '' )
111
- .find(".fg-thumb").off("click.foogallery").on("click", function(e){
112
- e.preventDefault();
113
- });
 
 
 
 
 
 
 
114
  } );
115
  } else {
116
  $preview.foogallery( 'layout' );
@@ -130,7 +140,7 @@
130
  $('.foogallery_preview_container').css('height', $('.foogallery_preview_container').height());
131
 
132
  //build up all the data to generate a preview
133
- var $shortcodeFields = $('.foogallery-settings-container-active .foogallery-metabox-settings .foogallery_template_field[data-foogallery-preview="shortcode"]'),
134
  data = [],
135
  foogallery_id = $('#post_ID').val();
136
 
@@ -220,7 +230,8 @@
220
  if (showField) {
221
  $item.show()
222
  .removeClass('foogallery_template_field_template_hidden')
223
- .find(':input').removeAttr('disabled');
 
224
  }
225
  });
226
  });
@@ -307,10 +318,10 @@
307
  selector = $fieldContainer.data('foogallery-change-selector');
308
 
309
  $fieldContainer.find(selector).change(function() {
310
- if ( $fieldContainer.data('foogallery-preview') === 'shortcode' ) {
311
  FOOGALLERY.reloadGalleryPreview();
312
  } else {
313
- FOOGALLERY.handleSettingFieldChange( $fieldContainer.data('foogallery-preview') !== 'class', true );
314
  }
315
  });
316
  });
@@ -548,6 +559,23 @@
548
  showInput: true,
549
  clickoutFiresChange: true
550
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  };
552
 
553
  }(window.FOOGALLERY = window.FOOGALLERY || {}, jQuery));
27
  $('.foogallery-items-add').removeClass('hidden');
28
  $('.foogallery-attachments-list').addClass('hidden');
29
  $('.foogallery-items-empty').removeClass('hidden');
30
+ $('.foogallery-attachments-list-bar').hide();
31
  } else {
32
  $('.foogallery-items-add').addClass('hidden');
33
  $('.foogallery-attachments-list').removeClass('hidden');
34
  $('.foogallery-items-empty').addClass('hidden');
35
+ $('.foogallery-attachments-list-bar').show();
36
  }
37
  };
38
 
82
 
83
  FOOGALLERY.updateGalleryPreview = function( initGallery, setContainerHeight ) {
84
  var $preview = $('.foogallery_preview_container .foogallery'),
85
+ $preview_container = $('.foogallery_preview_container'),
86
+ overrideClasses = false;
87
 
88
  if ( setContainerHeight ) {
89
  $preview_container.css('height', $preview_container.height());
90
  }
91
 
92
  //build up the container class
93
+ var $classFields = $('.foogallery-settings-container-active .foogallery-metabox-settings .foogallery_template_field[data-foogallery-preview*="class"]');
94
 
95
  if ($classFields.length) {
96
 
97
  var array = $classFields.find(' :input').serializeArray(),
98
+ mandatory_classes = $('#FooGallerySettings_GalleryTemplate').find(":selected").data('mandatory-classes');
99
+ overrideClasses = $.map(array, function (item) {
100
  return item.value;
101
  }).concat(['foogallery', mandatory_classes]).join(' ');
102
 
103
+ $preview.attr('class', overrideClasses);
104
  }
105
 
106
  //this allows any extensions to hook into the template change event
110
  if ( $preview.data('fg-common-fields') ) {
111
  if ( initGallery ) {
112
  $preview.foogallery( {}, function() {
113
+ //set the classes
114
+ if ( overrideClasses !== false ) {
115
+ $preview.attr('class', overrideClasses);
116
+ }
117
+
118
+ $preview_container.css( 'height', '' );
119
+ if ( !$preview_container.find('.foogallery').data('foogallery-lightbox') ) {
120
+ $preview_container.find(".fg-thumb").off("click.foogallery").on("click", function (e) {
121
+ e.preventDefault();
122
+ });
123
+ }
124
  } );
125
  } else {
126
  $preview.foogallery( 'layout' );
140
  $('.foogallery_preview_container').css('height', $('.foogallery_preview_container').height());
141
 
142
  //build up all the data to generate a preview
143
+ var $shortcodeFields = $('.foogallery-settings-container-active .foogallery-metabox-settings .foogallery_template_field[data-foogallery-preview*="shortcode"]'),
144
  data = [],
145
  foogallery_id = $('#post_ID').val();
146
 
230
  if (showField) {
231
  $item.show()
232
  .removeClass('foogallery_template_field_template_hidden')
233
+ .find(':input').removeAttr('disabled')
234
+ .end().find('.colorpicker').spectrum("enable");
235
  }
236
  });
237
  });
318
  selector = $fieldContainer.data('foogallery-change-selector');
319
 
320
  $fieldContainer.find(selector).change(function() {
321
+ if ( $fieldContainer.data('foogallery-preview').indexOf('shortcode') !== -1 ) {
322
  FOOGALLERY.reloadGalleryPreview();
323
  } else {
324
+ FOOGALLERY.handleSettingFieldChange( $fieldContainer.data('foogallery-preview').indexOf('class') !== -1, true );
325
  }
326
  });
327
  });
559
  showInput: true,
560
  clickoutFiresChange: true
561
  });
562
+
563
+ //lazy loading of images on the gallery edit page
564
+ var io = new IntersectionObserver(function(entries){
565
+ entries.forEach(function(entry){
566
+ if (entry.isIntersecting){
567
+ var $target = $(entry.target);
568
+ $target.attr("src", $target.data("src"));
569
+ io.unobserve(entry.target);
570
+ }
571
+ });
572
+ }, {
573
+ root: $(".foogallery-attachments-list").get(0)
574
+ });
575
+
576
+ $(".foogallery-attachments-list .attachment .thumbnail img").each(function(i, img){
577
+ io.observe(img);
578
+ });
579
  };
580
 
581
  }(window.FOOGALLERY = window.FOOGALLERY || {}, jQuery));
js/foogallery.admin.min.js CHANGED
@@ -1,6 +1,6 @@
1
  /*
2
  * FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
3
- * @version 1.3.4
4
  * @link
5
  * @copyright Steven Usher & Brad Vincent 2015
6
  * @license Released under the GPLv3 license.
1
  /*
2
  * FooGallery - The Most Intuitive and Extensible Gallery Creation and Management Tool Ever Created for WordPress
3
+ * @version 1.4.1
4
  * @link
5
  * @copyright Steven Usher & Brad Vincent 2015
6
  * @license Released under the GPLv3 license.